4 * Copyright (C) 2015,2016 ARM Ltd.
5 * Author: Andre Przywara <andre.przywara@arm.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/cpu.h>
21 #include <linux/kvm.h>
22 #include <linux/kvm_host.h>
23 #include <linux/interrupt.h>
25 #include <linux/irqchip/arm-gic-v3.h>
27 #include <asm/kvm_emulate.h>
28 #include <asm/kvm_arm.h>
29 #include <asm/kvm_mmu.h>
32 #include "vgic-mmio.h"
34 #define REGISTER_ITS_DESC(off, rd, wr, length, acc) \
38 .access_flags = acc, \
43 static unsigned long its_mmio_read_raz(struct kvm
*kvm
, struct vgic_its
*its
,
44 gpa_t addr
, unsigned int len
)
49 static void its_mmio_write_wi(struct kvm
*kvm
, struct vgic_its
*its
,
50 gpa_t addr
, unsigned int len
, unsigned long val
)
55 static struct vgic_register_region its_registers
[] = {
56 REGISTER_ITS_DESC(GITS_CTLR
,
57 its_mmio_read_raz
, its_mmio_write_wi
, 4,
59 REGISTER_ITS_DESC(GITS_IIDR
,
60 its_mmio_read_raz
, its_mmio_write_wi
, 4,
62 REGISTER_ITS_DESC(GITS_TYPER
,
63 its_mmio_read_raz
, its_mmio_write_wi
, 8,
64 VGIC_ACCESS_64bit
| VGIC_ACCESS_32bit
),
65 REGISTER_ITS_DESC(GITS_CBASER
,
66 its_mmio_read_raz
, its_mmio_write_wi
, 8,
67 VGIC_ACCESS_64bit
| VGIC_ACCESS_32bit
),
68 REGISTER_ITS_DESC(GITS_CWRITER
,
69 its_mmio_read_raz
, its_mmio_write_wi
, 8,
70 VGIC_ACCESS_64bit
| VGIC_ACCESS_32bit
),
71 REGISTER_ITS_DESC(GITS_CREADR
,
72 its_mmio_read_raz
, its_mmio_write_wi
, 8,
73 VGIC_ACCESS_64bit
| VGIC_ACCESS_32bit
),
74 REGISTER_ITS_DESC(GITS_BASER
,
75 its_mmio_read_raz
, its_mmio_write_wi
, 0x40,
76 VGIC_ACCESS_64bit
| VGIC_ACCESS_32bit
),
77 REGISTER_ITS_DESC(GITS_IDREGS_BASE
,
78 its_mmio_read_raz
, its_mmio_write_wi
, 0x30,
82 static int vgic_its_init_its(struct kvm
*kvm
, struct vgic_its
*its
)
84 struct vgic_io_device
*iodev
= &its
->iodev
;
87 if (IS_VGIC_ADDR_UNDEF(its
->vgic_its_base
))
90 iodev
->regions
= its_registers
;
91 iodev
->nr_regions
= ARRAY_SIZE(its_registers
);
92 kvm_iodevice_init(&iodev
->dev
, &kvm_io_gic_ops
);
94 iodev
->base_addr
= its
->vgic_its_base
;
95 iodev
->iodev_type
= IODEV_ITS
;
97 mutex_lock(&kvm
->slots_lock
);
98 ret
= kvm_io_bus_register_dev(kvm
, KVM_MMIO_BUS
, iodev
->base_addr
,
99 KVM_VGIC_V3_ITS_SIZE
, &iodev
->dev
);
100 mutex_unlock(&kvm
->slots_lock
);