KVM: arm64: vgic-its: Introduce ITS emulation file with MMIO framework
[deliverable/linux.git] / virt / kvm / arm / vgic / vgic-its.c
1 /*
2 * GICv3 ITS emulation
3 *
4 * Copyright (C) 2015,2016 ARM Ltd.
5 * Author: Andre Przywara <andre.przywara@arm.com>
6 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include <linux/cpu.h>
21 #include <linux/kvm.h>
22 #include <linux/kvm_host.h>
23 #include <linux/interrupt.h>
24
25 #include <linux/irqchip/arm-gic-v3.h>
26
27 #include <asm/kvm_emulate.h>
28 #include <asm/kvm_arm.h>
29 #include <asm/kvm_mmu.h>
30
31 #include "vgic.h"
32 #include "vgic-mmio.h"
33
34 #define REGISTER_ITS_DESC(off, rd, wr, length, acc) \
35 { \
36 .reg_offset = off, \
37 .len = length, \
38 .access_flags = acc, \
39 .its_read = rd, \
40 .its_write = wr, \
41 }
42
43 static unsigned long its_mmio_read_raz(struct kvm *kvm, struct vgic_its *its,
44 gpa_t addr, unsigned int len)
45 {
46 return 0;
47 }
48
49 static void its_mmio_write_wi(struct kvm *kvm, struct vgic_its *its,
50 gpa_t addr, unsigned int len, unsigned long val)
51 {
52 /* Ignore */
53 }
54
55 static struct vgic_register_region its_registers[] = {
56 REGISTER_ITS_DESC(GITS_CTLR,
57 its_mmio_read_raz, its_mmio_write_wi, 4,
58 VGIC_ACCESS_32bit),
59 REGISTER_ITS_DESC(GITS_IIDR,
60 its_mmio_read_raz, its_mmio_write_wi, 4,
61 VGIC_ACCESS_32bit),
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,
79 VGIC_ACCESS_32bit),
80 };
81
82 static int vgic_its_init_its(struct kvm *kvm, struct vgic_its *its)
83 {
84 struct vgic_io_device *iodev = &its->iodev;
85 int ret;
86
87 if (IS_VGIC_ADDR_UNDEF(its->vgic_its_base))
88 return -ENXIO;
89
90 iodev->regions = its_registers;
91 iodev->nr_regions = ARRAY_SIZE(its_registers);
92 kvm_iodevice_init(&iodev->dev, &kvm_io_gic_ops);
93
94 iodev->base_addr = its->vgic_its_base;
95 iodev->iodev_type = IODEV_ITS;
96 iodev->its = 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);
101
102 return ret;
103 }
This page took 0.036964 seconds and 6 git commands to generate.