History

arm/arm64: KVM: add virtual GICv3 distributor emulation

With everything separated and prepared, we implement a model of a GICv3 distributor and redistributors by using the existing framework to provide handler functions for each register group. Currently we limit the emulation to a model enforcing a single security state, with SRE==1 (forcing system register access) and ARE==1 (allowing more than 8 VCPUs). We share some of the functions provided for GICv2 emulation, but take the different ways of addressing (v)CPUs into account. Save and restore is currently not implemented. Similar to the split-off of the GICv2 specific code, the new emulation code goes into a new file (vgic-v3-emul.c).

Andre Przywara committed 12 years ago

Commit a0675c21 parent 9fedf148 files · +978 −3Browse files

Unified · Split

8 files
  1. arch/arm64/kvm/Makefile +1 −0
  2. include/kvm/arm_vgic.h +8 −1
  3. include/linux/irqchip/arm-gic-v3.h +32 −0
  4. include/linux/kvm_host.h +1 −0
  5. include/uapi/linux/kvm.h +2 −0
  6. virt/kvm/arm/vgic-v3-emul.c +922 −0
  7. virt/kvm/arm/vgic.c +9 −2
  8. virt/kvm/arm/vgic.h +3 −0
arch/arm64/kvm/Makefile+1−0
@@ -24,5 +24,6 @@ kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o · 23 unmodified lines
2424 kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2-emul.o
2525 kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o
2626 kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o
27+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3-emul.o
2728 kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o
2829 kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
include/kvm/arm_vgic.h+8−1
@@ -162,7 +162,11 @@ struct vgic_dist { · 161 unmodified lines
162162
163163 /* Distributor and vcpu interface mapping in the guest */
164164 phys_addr_t vgic_dist_base;
165− phys_addr_t vgic_cpu_base;
165+ /* GICv2 and GICv3 use different mapped register blocks */
166+ union {
167+ phys_addr_t vgic_cpu_base;
168+ phys_addr_t vgic_redist_base;
169+ };
166170
167171 /* Distributor enabled */
168172 u32 enabled;
@@ -224,6 +228,9 @@ struct vgic_dist { · 55 unmodified lines
224228 */
225229 struct vgic_bitmap *irq_spi_target;
226230
231+ /* Target MPIDR for each IRQ (needed for GICv3 IROUTERn) only */
232+ u32 *irq_spi_mpidr;
233+
227234 /* Bitmap indicating which CPU has something pending */
228235 unsigned long *irq_pending_on_cpu;
229236
include/linux/irqchip/arm-gic-v3.h+32−0
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 #define GICD_SETSPI_SR 0x0050
3434 #define GICD_CLRSPI_SR 0x0058
3535 #define GICD_SEIR 0x0068
36+#define GICD_IGROUPR 0x0080
3637 #define GICD_ISENABLER 0x0100
3738 #define GICD_ICENABLER 0x0180
3839 #define GICD_ISPENDR 0x0200
@@ -41,14 +42,37 @@ · 2 unmodified lines
4142 #define GICD_ICACTIVER 0x0380
4243 #define GICD_IPRIORITYR 0x0400
4344 #define GICD_ICFGR 0x0C00
45+#define GICD_IGRPMODR 0x0D00
46+#define GICD_NSACR 0x0E00
4447 #define GICD_IROUTER 0x6000
48+#define GICD_IDREGS 0xFFD0
4549 #define GICD_PIDR2 0xFFE8
4650
51+/*
52+ * Those registers are actually from GICv2, but the spec demands that they
53+ * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3).
54+ */
55+#define GICD_ITARGETSR 0x0800
56+#define GICD_SGIR 0x0F00
57+#define GICD_CPENDSGIR 0x0F10
58+#define GICD_SPENDSGIR 0x0F20
59+
4760 #define GICD_CTLR_RWP (1U << 31)
61+#define GICD_CTLR_DS (1U << 6)
4862 #define GICD_CTLR_ARE_NS (1U << 4)
4963 #define GICD_CTLR_ENABLE_G1A (1U << 1)
5064 #define GICD_CTLR_ENABLE_G1 (1U << 0)
5165
66+/*
67+ * In systems with a single security state (what we emulate in KVM)
68+ * the meaning of the interrupt group enable bits is slightly different
69+ */
70+#define GICD_CTLR_ENABLE_SS_G1 (1U << 1)
71+#define GICD_CTLR_ENABLE_SS_G0 (1U << 0)
72+
73+#define GICD_TYPER_LPIS (1U << 17)
74+#define GICD_TYPER_MBIS (1U << 16)
75+
5276 #define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1)
5377 #define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32)
5478 #define GICD_TYPER_LPIS (1U << 17)
@@ -60,6 +84,8 @@ · 5 unmodified lines
6084 #define GIC_PIDR2_ARCH_GICv3 0x30
6185 #define GIC_PIDR2_ARCH_GICv4 0x40
6286
87+#define GIC_V3_DIST_SIZE 0x10000
88+
6389 /*
6490 * Re-Distributor registers, offsets from RD_base
6591 */
@@ -78,6 +104,7 @@ · 12 unmodified lines
78104 #define GICR_SYNCR 0x00C0
79105 #define GICR_MOVLPIR 0x0100
80106 #define GICR_MOVALLR 0x0110
107+#define GICR_IDREGS GICD_IDREGS
81108 #define GICR_PIDR2 GICD_PIDR2
82109
83110 #define GICR_CTLR_ENABLE_LPIS (1UL << 0)
@@ -104,6 +131,7 @@ · 20 unmodified lines
104131 /*
105132 * Re-Distributor registers, offsets from SGI_base
106133 */
134+#define GICR_IGROUPR0 GICD_IGROUPR
107135 #define GICR_ISENABLER0 GICD_ISENABLER
108136 #define GICR_ICENABLER0 GICD_ICENABLER
109137 #define GICR_ISPENDR0 GICD_ISPENDR
@@ -112,11 +140,15 @@ · 2 unmodified lines
112140 #define GICR_ICACTIVER0 GICD_ICACTIVER
113141 #define GICR_IPRIORITYR0 GICD_IPRIORITYR
114142 #define GICR_ICFGR0 GICD_ICFGR
143+#define GICR_IGRPMODR0 GICD_IGRPMODR
144+#define GICR_NSACR GICD_NSACR
115145
116146 #define GICR_TYPER_PLPIS (1U << 0)
117147 #define GICR_TYPER_VLPIS (1U << 1)
118148 #define GICR_TYPER_LAST (1U << 4)
119149
150+#define GIC_V3_REDIST_SIZE 0x20000
151+
120152 #define LPI_PROP_GROUP1 (1 << 1)
121153 #define LPI_PROP_ENABLED (1 << 0)
122154
include/linux/kvm_host.h+1−0
@@ -1052,6 +1052,7 @@ void kvm_unregister_device_ops(u32 type); · 1051 unmodified lines
10521052 extern struct kvm_device_ops kvm_mpic_ops;
10531053 extern struct kvm_device_ops kvm_xics_ops;
10541054 extern struct kvm_device_ops kvm_arm_vgic_v2_ops;
1055+extern struct kvm_device_ops kvm_arm_vgic_v3_ops;
10551056
10561057 #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
10571058
include/uapi/linux/kvm.h+2−0
@@ -952,6 +952,8 @@ enum kvm_device_type { · 951 unmodified lines
952952 #define KVM_DEV_TYPE_ARM_VGIC_V2 KVM_DEV_TYPE_ARM_VGIC_V2
953953 KVM_DEV_TYPE_FLIC,
954954 #define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC
955+ KVM_DEV_TYPE_ARM_VGIC_V3,
956+#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3
955957 KVM_DEV_TYPE_MAX,
956958 };
957959
virt/kvm/arm/vgic-v3-emul.c+922−0
@@ -0,0 +1,922 @@
1+/*
2+ * GICv3 distributor and redistributor emulation
3+ *
4+ * GICv3 emulation is currently only supported on a GICv3 host (because
5+ * we rely on the hardware's CPU interface virtualization support), but
6+ * supports both hardware with or without the optional GICv2 backwards
7+ * compatibility features.
8+ *
9+ * Limitations of the emulation:
10+ * (RAZ/WI: read as zero, write ignore, RAO/WI: read as one, write ignore)
11+ * - We do not support LPIs (yet). TYPER.LPIS is reported as 0 and is RAZ/WI.
12+ * - We do not support the message based interrupts (MBIs) triggered by
13+ * writes to the GICD_{SET,CLR}SPI_* registers. TYPER.MBIS is reported as 0.
14+ * - We do not support the (optional) backwards compatibility feature.
15+ * GICD_CTLR.ARE resets to 1 and is RAO/WI. If the _host_ GIC supports
16+ * the compatiblity feature, you can use a GICv2 in the guest, though.
17+ * - We only support a single security state. GICD_CTLR.DS is 1 and is RAO/WI.
18+ * - Priorities are not emulated (same as the GICv2 emulation). Linux
19+ * as a guest is fine with this, because it does not use priorities.
20+ * - We only support Group1 interrupts. Again Linux uses only those.
21+ *
22+ * Copyright (C) 2014 ARM Ltd.
23+ * Author: Andre Przywara <andre.przywara@arm.com>
24+ *
25+ * This program is free software; you can redistribute it and/or modify
26+ * it under the terms of the GNU General Public License version 2 as
27+ * published by the Free Software Foundation.
28+ *
29+ * This program is distributed in the hope that it will be useful,
30+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32+ * GNU General Public License for more details.
33+ *
34+ * You should have received a copy of the GNU General Public License
35+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36+ */
37+
38+#include <linux/cpu.h>
39+#include <linux/kvm.h>
40+#include <linux/kvm_host.h>
41+#include <linux/interrupt.h>
42+
43+#include <linux/irqchip/arm-gic-v3.h>
44+#include <kvm/arm_vgic.h>
45+
46+#include <asm/kvm_emulate.h>
47+#include <asm/kvm_arm.h>
48+#include <asm/kvm_mmu.h>
49+
50+#include "vgic.h"
51+
52+static bool handle_mmio_rao_wi(struct kvm_vcpu *vcpu,
53+ struct kvm_exit_mmio *mmio, phys_addr_t offset)
54+{
55+ u32 reg = 0xffffffff;
56+
57+ vgic_reg_access(mmio, &reg, offset,
58+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
59+
60+ return false;
61+}
62+
63+static bool handle_mmio_ctlr(struct kvm_vcpu *vcpu,
64+ struct kvm_exit_mmio *mmio, phys_addr_t offset)
65+{
66+ u32 reg = 0;
67+
68+ /*
69+ * Force ARE and DS to 1, the guest cannot change this.
70+ * For the time being we only support Group1 interrupts.
71+ */
72+ if (vcpu->kvm->arch.vgic.enabled)
73+ reg = GICD_CTLR_ENABLE_SS_G1;
74+ reg |= GICD_CTLR_ARE_NS | GICD_CTLR_DS;
75+
76+ vgic_reg_access(mmio, &reg, offset,
77+ ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
78+ if (mmio->is_write) {
79+ if (reg & GICD_CTLR_ENABLE_SS_G0)
80+ kvm_info("guest tried to enable unsupported Group0 interrupts\n");
81+ vcpu->kvm->arch.vgic.enabled = !!(reg & GICD_CTLR_ENABLE_SS_G1);
82+ vgic_update_state(vcpu->kvm);
83+ return true;
84+ }
85+ return false;
86+}
87+
88+/*
89+ * As this implementation does not provide compatibility
90+ * with GICv2 (ARE==1), we report zero CPUs in bits [5..7].
91+ * Also LPIs and MBIs are not supported, so we set the respective bits to 0.
92+ * Also we report at most 2**10=1024 interrupt IDs (to match 1024 SPIs).
93+ */
94+#define INTERRUPT_ID_BITS 10
95+static bool handle_mmio_typer(struct kvm_vcpu *vcpu,
96+ struct kvm_exit_mmio *mmio, phys_addr_t offset)
97+{
98+ u32 reg;
99+
100+ reg = (min(vcpu->kvm->arch.vgic.nr_irqs, 1024) >> 5) - 1;
101+
102+ reg |= (INTERRUPT_ID_BITS - 1) << 19;
103+
104+ vgic_reg_access(mmio, &reg, offset,
105+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
106+
107+ return false;
108+}
109+
110+static bool handle_mmio_iidr(struct kvm_vcpu *vcpu,
111+ struct kvm_exit_mmio *mmio, phys_addr_t offset)
112+{
113+ u32 reg;
114+
115+ reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
116+ vgic_reg_access(mmio, &reg, offset,
117+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
118+
119+ return false;
120+}
121+
122+static bool handle_mmio_set_enable_reg_dist(struct kvm_vcpu *vcpu,
123+ struct kvm_exit_mmio *mmio,
124+ phys_addr_t offset)
125+{
126+ if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
127+ return vgic_handle_enable_reg(vcpu->kvm, mmio, offset,
128+ vcpu->vcpu_id,
129+ ACCESS_WRITE_SETBIT);
130+
131+ vgic_reg_access(mmio, NULL, offset,
132+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
133+ return false;
134+}
135+
136+static bool handle_mmio_clear_enable_reg_dist(struct kvm_vcpu *vcpu,
137+ struct kvm_exit_mmio *mmio,
138+ phys_addr_t offset)
139+{
140+ if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
141+ return vgic_handle_enable_reg(vcpu->kvm, mmio, offset,
142+ vcpu->vcpu_id,
143+ ACCESS_WRITE_CLEARBIT);
144+
145+ vgic_reg_access(mmio, NULL, offset,
146+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
147+ return false;
148+}
149+
150+static bool handle_mmio_set_pending_reg_dist(struct kvm_vcpu *vcpu,
151+ struct kvm_exit_mmio *mmio,
152+ phys_addr_t offset)
153+{
154+ if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
155+ return vgic_handle_set_pending_reg(vcpu->kvm, mmio, offset,
156+ vcpu->vcpu_id);
157+
158+ vgic_reg_access(mmio, NULL, offset,
159+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
160+ return false;
161+}
162+
163+static bool handle_mmio_clear_pending_reg_dist(struct kvm_vcpu *vcpu,
164+ struct kvm_exit_mmio *mmio,
165+ phys_addr_t offset)
166+{
167+ if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
168+ return vgic_handle_clear_pending_reg(vcpu->kvm, mmio, offset,
169+ vcpu->vcpu_id);
170+
171+ vgic_reg_access(mmio, NULL, offset,
172+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
173+ return false;
174+}
175+
176+static bool handle_mmio_priority_reg_dist(struct kvm_vcpu *vcpu,
177+ struct kvm_exit_mmio *mmio,
178+ phys_addr_t offset)
179+{
180+ u32 *reg;
181+
182+ if (unlikely(offset < VGIC_NR_PRIVATE_IRQS)) {
183+ vgic_reg_access(mmio, NULL, offset,
184+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
185+ return false;
186+ }
187+
188+ reg = vgic_bytemap_get_reg(&vcpu->kvm->arch.vgic.irq_priority,
189+ vcpu->vcpu_id, offset);
190+ vgic_reg_access(mmio, reg, offset,
191+ ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
192+ return false;
193+}
194+
195+static bool handle_mmio_cfg_reg_dist(struct kvm_vcpu *vcpu,
196+ struct kvm_exit_mmio *mmio,
197+ phys_addr_t offset)
198+{
199+ u32 *reg;
200+
201+ if (unlikely(offset < VGIC_NR_PRIVATE_IRQS / 4)) {
202+ vgic_reg_access(mmio, NULL, offset,
203+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
204+ return false;
205+ }
206+
207+ reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
208+ vcpu->vcpu_id, offset >> 1);
209+
210+ return vgic_handle_cfg_reg(reg, mmio, offset);
211+}
212+
213+/*
214+ * We use a compressed version of the MPIDR (all 32 bits in one 32-bit word)
215+ * when we store the target MPIDR written by the guest.
216+ */
217+static u32 compress_mpidr(unsigned long mpidr)
218+{
219+ u32 ret;
220+
221+ ret = MPIDR_AFFINITY_LEVEL(mpidr, 0);
222+ ret |= MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8;
223+ ret |= MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16;
224+ ret |= MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24;
225+
226+ return ret;
227+}
228+
229+static unsigned long uncompress_mpidr(u32 value)
230+{
231+ unsigned long mpidr;
232+
233+ mpidr = ((value >> 0) & 0xFF) << MPIDR_LEVEL_SHIFT(0);
234+ mpidr |= ((value >> 8) & 0xFF) << MPIDR_LEVEL_SHIFT(1);
235+ mpidr |= ((value >> 16) & 0xFF) << MPIDR_LEVEL_SHIFT(2);
236+ mpidr |= (u64)((value >> 24) & 0xFF) << MPIDR_LEVEL_SHIFT(3);
237+
238+ return mpidr;
239+}
240+
241+/*
242+ * Lookup the given MPIDR value to get the vcpu_id (if there is one)
243+ * and store that in the irq_spi_cpu[] array.
244+ * This limits the number of VCPUs to 255 for now, extending the data
245+ * type (or storing kvm_vcpu pointers) should lift the limit.
246+ * Store the original MPIDR value in an extra array to support read-as-written.
247+ * Unallocated MPIDRs are translated to a special value and caught
248+ * before any array accesses.
249+ */
250+static bool handle_mmio_route_reg(struct kvm_vcpu *vcpu,
251+ struct kvm_exit_mmio *mmio,
252+ phys_addr_t offset)
253+{
254+ struct kvm *kvm = vcpu->kvm;
255+ struct vgic_dist *dist = &kvm->arch.vgic;
256+ int spi;
257+ u32 reg;
258+ int vcpu_id;
259+ unsigned long *bmap, mpidr;
260+
261+ /*
262+ * The upper 32 bits of each 64 bit register are zero,
263+ * as we don't support Aff3.
264+ */
265+ if ((offset & 4)) {
266+ vgic_reg_access(mmio, NULL, offset,
267+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
268+ return false;
269+ }
270+
271+ /* This region only covers SPIs, so no handling of private IRQs here. */
272+ spi = offset / 8;
273+
274+ /* get the stored MPIDR for this IRQ */
275+ mpidr = uncompress_mpidr(dist->irq_spi_mpidr[spi]);
276+ reg = mpidr;
277+
278+ vgic_reg_access(mmio, &reg, offset,
279+ ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
280+
281+ if (!mmio->is_write)
282+ return false;
283+
284+ /*
285+ * Now clear the currently assigned vCPU from the map, making room
286+ * for the new one to be written below
287+ */
288+ vcpu = kvm_mpidr_to_vcpu(kvm, mpidr);
289+ if (likely(vcpu)) {
290+ vcpu_id = vcpu->vcpu_id;
291+ bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[vcpu_id]);
292+ __clear_bit(spi, bmap);
293+ }
294+
295+ dist->irq_spi_mpidr[spi] = compress_mpidr(reg);
296+ vcpu = kvm_mpidr_to_vcpu(kvm, reg & MPIDR_HWID_BITMASK);
297+
298+ /*
299+ * The spec says that non-existent MPIDR values should not be
300+ * forwarded to any existent (v)CPU, but should be able to become
301+ * pending anyway. We simply keep the irq_spi_target[] array empty, so
302+ * the interrupt will never be injected.
303+ * irq_spi_cpu[irq] gets a magic value in this case.
304+ */
305+ if (likely(vcpu)) {
306+ vcpu_id = vcpu->vcpu_id;
307+ dist->irq_spi_cpu[spi] = vcpu_id;
308+ bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[vcpu_id]);
309+ __set_bit(spi, bmap);
310+ } else {
311+ dist->irq_spi_cpu[spi] = VCPU_NOT_ALLOCATED;
312+ }
313+
314+ vgic_update_state(kvm);
315+
316+ return true;
317+}
318+
319+/*
320+ * We should be careful about promising too much when a guest reads
321+ * this register. Don't claim to be like any hardware implementation,
322+ * but just report the GIC as version 3 - which is what a Linux guest
323+ * would check.
324+ */
325+static bool handle_mmio_idregs(struct kvm_vcpu *vcpu,
326+ struct kvm_exit_mmio *mmio,
327+ phys_addr_t offset)
328+{
329+ u32 reg = 0;
330+
331+ switch (offset + GICD_IDREGS) {
332+ case GICD_PIDR2:
333+ reg = 0x3b;
334+ break;
335+ }
336+
337+ vgic_reg_access(mmio, &reg, offset,
338+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
339+
340+ return false;
341+}
342+
343+static const struct kvm_mmio_range vgic_v3_dist_ranges[] = {
344+ {
345+ .base = GICD_CTLR,
346+ .len = 0x04,
347+ .bits_per_irq = 0,
348+ .handle_mmio = handle_mmio_ctlr,
349+ },
350+ {
351+ .base = GICD_TYPER,
352+ .len = 0x04,
353+ .bits_per_irq = 0,
354+ .handle_mmio = handle_mmio_typer,
355+ },
356+ {
357+ .base = GICD_IIDR,
358+ .len = 0x04,
359+ .bits_per_irq = 0,
360+ .handle_mmio = handle_mmio_iidr,
361+ },
362+ {
363+ /* this register is optional, it is RAZ/WI if not implemented */
364+ .base = GICD_STATUSR,
365+ .len = 0x04,
366+ .bits_per_irq = 0,
367+ .handle_mmio = handle_mmio_raz_wi,
368+ },
369+ {
370+ /* this write only register is WI when TYPER.MBIS=0 */
371+ .base = GICD_SETSPI_NSR,
372+ .len = 0x04,
373+ .bits_per_irq = 0,
374+ .handle_mmio = handle_mmio_raz_wi,
375+ },
376+ {
377+ /* this write only register is WI when TYPER.MBIS=0 */
378+ .base = GICD_CLRSPI_NSR,
379+ .len = 0x04,
380+ .bits_per_irq = 0,
381+ .handle_mmio = handle_mmio_raz_wi,
382+ },
383+ {
384+ /* this is RAZ/WI when DS=1 */
385+ .base = GICD_SETSPI_SR,
386+ .len = 0x04,
387+ .bits_per_irq = 0,
388+ .handle_mmio = handle_mmio_raz_wi,
389+ },
390+ {
391+ /* this is RAZ/WI when DS=1 */
392+ .base = GICD_CLRSPI_SR,
393+ .len = 0x04,
394+ .bits_per_irq = 0,
395+ .handle_mmio = handle_mmio_raz_wi,
396+ },
397+ {
398+ .base = GICD_IGROUPR,
399+ .len = 0x80,
400+ .bits_per_irq = 1,
401+ .handle_mmio = handle_mmio_rao_wi,
402+ },
403+ {
404+ .base = GICD_ISENABLER,
405+ .len = 0x80,
406+ .bits_per_irq = 1,
407+ .handle_mmio = handle_mmio_set_enable_reg_dist,
408+ },
409+ {
410+ .base = GICD_ICENABLER,
411+ .len = 0x80,
412+ .bits_per_irq = 1,
413+ .handle_mmio = handle_mmio_clear_enable_reg_dist,
414+ },
415+ {
416+ .base = GICD_ISPENDR,
417+ .len = 0x80,
418+ .bits_per_irq = 1,
419+ .handle_mmio = handle_mmio_set_pending_reg_dist,
420+ },
421+ {
422+ .base = GICD_ICPENDR,
423+ .len = 0x80,
424+ .bits_per_irq = 1,
425+ .handle_mmio = handle_mmio_clear_pending_reg_dist,
426+ },
427+ {
428+ .base = GICD_ISACTIVER,
429+ .len = 0x80,
430+ .bits_per_irq = 1,
431+ .handle_mmio = handle_mmio_raz_wi,
432+ },
433+ {
434+ .base = GICD_ICACTIVER,
435+ .len = 0x80,
436+ .bits_per_irq = 1,
437+ .handle_mmio = handle_mmio_raz_wi,
438+ },
439+ {
440+ .base = GICD_IPRIORITYR,
441+ .len = 0x400,
442+ .bits_per_irq = 8,
443+ .handle_mmio = handle_mmio_priority_reg_dist,
444+ },
445+ {
446+ /* TARGETSRn is RES0 when ARE=1 */
447+ .base = GICD_ITARGETSR,
448+ .len = 0x400,
449+ .bits_per_irq = 8,
450+ .handle_mmio = handle_mmio_raz_wi,
451+ },
452+ {
453+ .base = GICD_ICFGR,
454+ .len = 0x100,
455+ .bits_per_irq = 2,
456+ .handle_mmio = handle_mmio_cfg_reg_dist,
457+ },
458+ {
459+ /* this is RAZ/WI when DS=1 */
460+ .base = GICD_IGRPMODR,
461+ .len = 0x80,
462+ .bits_per_irq = 1,
463+ .handle_mmio = handle_mmio_raz_wi,
464+ },
465+ {
466+ /* this is RAZ/WI when DS=1 */
467+ .base = GICD_NSACR,
468+ .len = 0x100,
469+ .bits_per_irq = 2,
470+ .handle_mmio = handle_mmio_raz_wi,
471+ },
472+ {
473+ /* this is RAZ/WI when ARE=1 */
474+ .base = GICD_SGIR,
475+ .len = 0x04,
476+ .handle_mmio = handle_mmio_raz_wi,
477+ },
478+ {
479+ /* this is RAZ/WI when ARE=1 */
480+ .base = GICD_CPENDSGIR,
481+ .len = 0x10,
482+ .handle_mmio = handle_mmio_raz_wi,
483+ },
484+ {
485+ /* this is RAZ/WI when ARE=1 */
486+ .base = GICD_SPENDSGIR,
487+ .len = 0x10,
488+ .handle_mmio = handle_mmio_raz_wi,
489+ },
490+ {
491+ .base = GICD_IROUTER + 0x100,
492+ .len = 0x1ee0,
493+ .bits_per_irq = 64,
494+ .handle_mmio = handle_mmio_route_reg,
495+ },
496+ {
497+ .base = GICD_IDREGS,
498+ .len = 0x30,
499+ .bits_per_irq = 0,
500+ .handle_mmio = handle_mmio_idregs,
501+ },
502+ {},
503+};
504+
505+static bool handle_mmio_set_enable_reg_redist(struct kvm_vcpu *vcpu,
506+ struct kvm_exit_mmio *mmio,
507+ phys_addr_t offset)
508+{
509+ struct kvm_vcpu *redist_vcpu = mmio->private;
510+
511+ return vgic_handle_enable_reg(vcpu->kvm, mmio, offset,
512+ redist_vcpu->vcpu_id,
513+ ACCESS_WRITE_SETBIT);
514+}
515+
516+static bool handle_mmio_clear_enable_reg_redist(struct kvm_vcpu *vcpu,
517+ struct kvm_exit_mmio *mmio,
518+ phys_addr_t offset)
519+{
520+ struct kvm_vcpu *redist_vcpu = mmio->private;
521+
522+ return vgic_handle_enable_reg(vcpu->kvm, mmio, offset,
523+ redist_vcpu->vcpu_id,
524+ ACCESS_WRITE_CLEARBIT);
525+}
526+
527+static bool handle_mmio_set_pending_reg_redist(struct kvm_vcpu *vcpu,
528+ struct kvm_exit_mmio *mmio,
529+ phys_addr_t offset)
530+{
531+ struct kvm_vcpu *redist_vcpu = mmio->private;
532+
533+ return vgic_handle_set_pending_reg(vcpu->kvm, mmio, offset,
534+ redist_vcpu->vcpu_id);
535+}
536+
537+static bool handle_mmio_clear_pending_reg_redist(struct kvm_vcpu *vcpu,
538+ struct kvm_exit_mmio *mmio,
539+ phys_addr_t offset)
540+{
541+ struct kvm_vcpu *redist_vcpu = mmio->private;
542+
543+ return vgic_handle_clear_pending_reg(vcpu->kvm, mmio, offset,
544+ redist_vcpu->vcpu_id);
545+}
546+
547+static bool handle_mmio_priority_reg_redist(struct kvm_vcpu *vcpu,
548+ struct kvm_exit_mmio *mmio,
549+ phys_addr_t offset)
550+{
551+ struct kvm_vcpu *redist_vcpu = mmio->private;
552+ u32 *reg;
553+
554+ reg = vgic_bytemap_get_reg(&vcpu->kvm->arch.vgic.irq_priority,
555+ redist_vcpu->vcpu_id, offset);
556+ vgic_reg_access(mmio, reg, offset,
557+ ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
558+ return false;
559+}
560+
561+static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu *vcpu,
562+ struct kvm_exit_mmio *mmio,
563+ phys_addr_t offset)
564+{
565+ struct kvm_vcpu *redist_vcpu = mmio->private;
566+
567+ u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
568+ redist_vcpu->vcpu_id, offset >> 1);
569+
570+ return vgic_handle_cfg_reg(reg, mmio, offset);
571+}
572+
573+static const struct kvm_mmio_range vgic_redist_sgi_ranges[] = {
574+ {
575+ .base = GICR_IGROUPR0,
576+ .len = 0x04,
577+ .bits_per_irq = 1,
578+ .handle_mmio = handle_mmio_rao_wi,
579+ },
580+ {
581+ .base = GICR_ISENABLER0,
582+ .len = 0x04,
583+ .bits_per_irq = 1,
584+ .handle_mmio = handle_mmio_set_enable_reg_redist,
585+ },
586+ {
587+ .base = GICR_ICENABLER0,
588+ .len = 0x04,
589+ .bits_per_irq = 1,
590+ .handle_mmio = handle_mmio_clear_enable_reg_redist,
591+ },
592+ {
593+ .base = GICR_ISPENDR0,
594+ .len = 0x04,
595+ .bits_per_irq = 1,
596+ .handle_mmio = handle_mmio_set_pending_reg_redist,
597+ },
598+ {
599+ .base = GICR_ICPENDR0,
600+ .len = 0x04,
601+ .bits_per_irq = 1,
602+ .handle_mmio = handle_mmio_clear_pending_reg_redist,
603+ },
604+ {
605+ .base = GICR_ISACTIVER0,
606+ .len = 0x04,
607+ .bits_per_irq = 1,
608+ .handle_mmio = handle_mmio_raz_wi,
609+ },
610+ {
611+ .base = GICR_ICACTIVER0,
612+ .len = 0x04,
613+ .bits_per_irq = 1,
614+ .handle_mmio = handle_mmio_raz_wi,
615+ },
616+ {
617+ .base = GICR_IPRIORITYR0,
618+ .len = 0x20,
619+ .bits_per_irq = 8,
620+ .handle_mmio = handle_mmio_priority_reg_redist,
621+ },
622+ {
623+ .base = GICR_ICFGR0,
624+ .len = 0x08,
625+ .bits_per_irq = 2,
626+ .handle_mmio = handle_mmio_cfg_reg_redist,
627+ },
628+ {
629+ .base = GICR_IGRPMODR0,
630+ .len = 0x04,
631+ .bits_per_irq = 1,
632+ .handle_mmio = handle_mmio_raz_wi,
633+ },
634+ {
635+ .base = GICR_NSACR,
636+ .len = 0x04,
637+ .handle_mmio = handle_mmio_raz_wi,
638+ },
639+ {},
640+};
641+
642+static bool handle_mmio_ctlr_redist(struct kvm_vcpu *vcpu,
643+ struct kvm_exit_mmio *mmio,
644+ phys_addr_t offset)
645+{
646+ /* since we don't support LPIs, this register is zero for now */
647+ vgic_reg_access(mmio, NULL, offset,
648+ ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
649+ return false;
650+}
651+
652+static bool handle_mmio_typer_redist(struct kvm_vcpu *vcpu,
653+ struct kvm_exit_mmio *mmio,
654+ phys_addr_t offset)
655+{
656+ u32 reg;
657+ u64 mpidr;
658+ struct kvm_vcpu *redist_vcpu = mmio->private;
659+ int target_vcpu_id = redist_vcpu->vcpu_id;
660+
661+ /* the upper 32 bits contain the affinity value */
662+ if ((offset & ~3) == 4) {
663+ mpidr = kvm_vcpu_get_mpidr_aff(redist_vcpu);
664+ reg = compress_mpidr(mpidr);
665+
666+ vgic_reg_access(mmio, &reg, offset,
667+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
668+ return false;
669+ }
670+
671+ reg = redist_vcpu->vcpu_id << 8;
672+ if (target_vcpu_id == atomic_read(&vcpu->kvm->online_vcpus) - 1)
673+ reg |= GICR_TYPER_LAST;
674+ vgic_reg_access(mmio, &reg, offset,
675+ ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
676+ return false;
677+}
678+
679+static const struct kvm_mmio_range vgic_redist_ranges[] = {
680+ {
681+ .base = GICR_CTLR,
682+ .len = 0x04,
683+ .bits_per_irq = 0,
684+ .handle_mmio = handle_mmio_ctlr_redist,
685+ },
686+ {
687+ .base = GICR_TYPER,
688+ .len = 0x08,
689+ .bits_per_irq = 0,
690+ .handle_mmio = handle_mmio_typer_redist,
691+ },
692+ {
693+ .base = GICR_IIDR,
694+ .len = 0x04,
695+ .bits_per_irq = 0,
696+ .handle_mmio = handle_mmio_iidr,
697+ },
698+ {
699+ .base = GICR_WAKER,
700+ .len = 0x04,
701+ .bits_per_irq = 0,
702+ .handle_mmio = handle_mmio_raz_wi,
703+ },
704+ {
705+ .base = GICR_IDREGS,
706+ .len = 0x30,
707+ .bits_per_irq = 0,
708+ .handle_mmio = handle_mmio_idregs,
709+ },
710+ {},
711+};
712+
713+/*
714+ * This function splits accesses between the distributor and the two
715+ * redistributor parts (private/SPI). As each redistributor is accessible
716+ * from any CPU, we have to determine the affected VCPU by taking the faulting
717+ * address into account. We then pass this VCPU to the handler function via
718+ * the private parameter.
719+ */
720+#define SGI_BASE_OFFSET SZ_64K
721+static bool vgic_v3_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
722+ struct kvm_exit_mmio *mmio)
723+{
724+ struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
725+ unsigned long dbase = dist->vgic_dist_base;
726+ unsigned long rdbase = dist->vgic_redist_base;
727+ int nrcpus = atomic_read(&vcpu->kvm->online_vcpus);
728+ int vcpu_id;
729+ const struct kvm_mmio_range *mmio_range;
730+
731+ if (is_in_range(mmio->phys_addr, mmio->len, dbase, GIC_V3_DIST_SIZE)) {
732+ return vgic_handle_mmio_range(vcpu, run, mmio,
733+ vgic_v3_dist_ranges, dbase);
734+ }
735+
736+ if (!is_in_range(mmio->phys_addr, mmio->len, rdbase,
737+ GIC_V3_REDIST_SIZE * nrcpus))
738+ return false;
739+
740+ vcpu_id = (mmio->phys_addr - rdbase) / GIC_V3_REDIST_SIZE;
741+ rdbase += (vcpu_id * GIC_V3_REDIST_SIZE);
742+ mmio->private = kvm_get_vcpu(vcpu->kvm, vcpu_id);
743+
744+ if (mmio->phys_addr >= rdbase + SGI_BASE_OFFSET) {
745+ rdbase += SGI_BASE_OFFSET;
746+ mmio_range = vgic_redist_sgi_ranges;
747+ } else {
748+ mmio_range = vgic_redist_ranges;
749+ }
750+ return vgic_handle_mmio_range(vcpu, run, mmio, mmio_range, rdbase);
751+}
752+
753+static bool vgic_v3_queue_sgi(struct kvm_vcpu *vcpu, int irq)
754+{
755+ if (vgic_queue_irq(vcpu, 0, irq)) {
756+ vgic_dist_irq_clear_pending(vcpu, irq);
757+ vgic_cpu_irq_clear(vcpu, irq);
758+ return true;
759+ }
760+
761+ return false;
762+}
763+
764+static int vgic_v3_map_resources(struct kvm *kvm,
765+ const struct vgic_params *params)
766+{
767+ int ret = 0;
768+ struct vgic_dist *dist = &kvm->arch.vgic;
769+
770+ if (!irqchip_in_kernel(kvm))
771+ return 0;
772+
773+ mutex_lock(&kvm->lock);
774+
775+ if (vgic_ready(kvm))
776+ goto out;
777+
778+ if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) ||
779+ IS_VGIC_ADDR_UNDEF(dist->vgic_redist_base)) {
780+ kvm_err("Need to set vgic distributor addresses first\n");
781+ ret = -ENXIO;
782+ goto out;
783+ }
784+
785+ /*
786+ * For a VGICv3 we require the userland to explicitly initialize
787+ * the VGIC before we need to use it.
788+ */
789+ if (!vgic_initialized(kvm)) {
790+ ret = -EBUSY;
791+ goto out;
792+ }
793+
794+ kvm->arch.vgic.ready = true;
795+out:
796+ if (ret)
797+ kvm_vgic_destroy(kvm);
798+ mutex_unlock(&kvm->lock);
799+ return ret;
800+}
801+
802+static int vgic_v3_init_model(struct kvm *kvm)
803+{
804+ int i;
805+ u32 mpidr;
806+ struct vgic_dist *dist = &kvm->arch.vgic;
807+ int nr_spis = dist->nr_irqs - VGIC_NR_PRIVATE_IRQS;
808+
809+ dist->irq_spi_mpidr = kcalloc(nr_spis, sizeof(dist->irq_spi_mpidr[0]),
810+ GFP_KERNEL);
811+
812+ if (!dist->irq_spi_mpidr)
813+ return -ENOMEM;
814+
815+ /* Initialize the target VCPUs for each IRQ to VCPU 0 */
816+ mpidr = compress_mpidr(kvm_vcpu_get_mpidr_aff(kvm_get_vcpu(kvm, 0)));
817+ for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i++) {
818+ dist->irq_spi_cpu[i - VGIC_NR_PRIVATE_IRQS] = 0;
819+ dist->irq_spi_mpidr[i - VGIC_NR_PRIVATE_IRQS] = mpidr;
820+ vgic_bitmap_set_irq_val(dist->irq_spi_target, 0, i, 1);
821+ }
822+
823+ return 0;
824+}
825+
826+/* GICv3 does not keep track of SGI sources anymore. */
827+static void vgic_v3_add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source)
828+{
829+}
830+
831+void vgic_v3_init_emulation(struct kvm *kvm)
832+{
833+ struct vgic_dist *dist = &kvm->arch.vgic;
834+
835+ dist->vm_ops.handle_mmio = vgic_v3_handle_mmio;
836+ dist->vm_ops.queue_sgi = vgic_v3_queue_sgi;
837+ dist->vm_ops.add_sgi_source = vgic_v3_add_sgi_source;
838+ dist->vm_ops.init_model = vgic_v3_init_model;
839+ dist->vm_ops.map_resources = vgic_v3_map_resources;
840+
841+ kvm->arch.max_vcpus = KVM_MAX_VCPUS;
842+}
843+
844+static int vgic_v3_create(struct kvm_device *dev, u32 type)
845+{
846+ return kvm_vgic_create(dev->kvm, type);
847+}
848+
849+static void vgic_v3_destroy(struct kvm_device *dev)
850+{
851+ kfree(dev);
852+}
853+
854+static int vgic_v3_set_attr(struct kvm_device *dev,
855+ struct kvm_device_attr *attr)
856+{
857+ int ret;
858+
859+ ret = vgic_set_common_attr(dev, attr);
860+ if (ret != -ENXIO)
861+ return ret;
862+
863+ switch (attr->group) {
864+ case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
865+ case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:
866+ return -ENXIO;
867+ }
868+
869+ return -ENXIO;
870+}
871+
872+static int vgic_v3_get_attr(struct kvm_device *dev,
873+ struct kvm_device_attr *attr)
874+{
875+ int ret;
876+
877+ ret = vgic_get_common_attr(dev, attr);
878+ if (ret != -ENXIO)
879+ return ret;
880+
881+ switch (attr->group) {
882+ case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
883+ case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:
884+ return -ENXIO;
885+ }
886+
887+ return -ENXIO;
888+}
889+
890+static int vgic_v3_has_attr(struct kvm_device *dev,
891+ struct kvm_device_attr *attr)
892+{
893+ switch (attr->group) {
894+ case KVM_DEV_ARM_VGIC_GRP_ADDR:
895+ switch (attr->attr) {
896+ case KVM_VGIC_V2_ADDR_TYPE_DIST:
897+ case KVM_VGIC_V2_ADDR_TYPE_CPU:
898+ return -ENXIO;
899+ }
900+ break;
901+ case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
902+ case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:
903+ return -ENXIO;
904+ case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
905+ return 0;
906+ case KVM_DEV_ARM_VGIC_GRP_CTRL:
907+ switch (attr->attr) {
908+ case KVM_DEV_ARM_VGIC_CTRL_INIT:
909+ return 0;
910+ }
911+ }
912+ return -ENXIO;
913+}
914+
915+struct kvm_device_ops kvm_arm_vgic_v3_ops = {
916+ .name = "kvm-arm-vgic-v3",
917+ .create = vgic_v3_create,
918+ .destroy = vgic_v3_destroy,
919+ .set_attr = vgic_v3_set_attr,
920+ .get_attr = vgic_v3_get_attr,
921+ .has_attr = vgic_v3_has_attr,
922+};
virt/kvm/arm/vgic.c+9−2
@@ -1249,7 +1249,7 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid, · 1248 unmodified lines
12491249 struct kvm_vcpu *vcpu;
12501250 int edge_triggered, level_triggered;
12511251 int enabled;
1252− bool ret = true;
1252+ bool ret = true, can_inject = true;
12531253
12541254 spin_lock(&dist->lock);
12551255
@@ -1264,6 +1264,11 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid, · 8 unmodified lines
12641264
12651265 if (irq_num >= VGIC_NR_PRIVATE_IRQS) {
12661266 cpuid = dist->irq_spi_cpu[irq_num - VGIC_NR_PRIVATE_IRQS];
1267+ if (cpuid == VCPU_NOT_ALLOCATED) {
1268+ /* Pretend we use CPU0, and prevent injection */
1269+ cpuid = 0;
1270+ can_inject = false;
1271+ }
12671272 vcpu = kvm_get_vcpu(kvm, cpuid);
12681273 }
12691274
@@ -1286,7 +1291,7 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid, · 16 unmodified lines
12861291
12871292 enabled = vgic_irq_is_enabled(vcpu, irq_num);
12881293
1289− if (!enabled) {
1294+ if (!enabled || !can_inject) {
12901295 ret = false;
12911296 goto out;
12921297 }
@@ -1439,6 +1444,7 @@ void kvm_vgic_destroy(struct kvm *kvm) · 146 unmodified lines
14391444 }
14401445 kfree(dist->irq_sgi_sources);
14411446 kfree(dist->irq_spi_cpu);
1447+ kfree(dist->irq_spi_mpidr);
14421448 kfree(dist->irq_spi_target);
14431449 kfree(dist->irq_pending_on_cpu);
14441450 dist->irq_sgi_sources = NULL;
@@ -1594,6 +1600,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) · 149 unmodified lines
15941600 kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
15951601 kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
15961602 kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
1603+ kvm->arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF;
15971604
15981605 out_unlock:
15991606 for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
virt/kvm/arm/vgic.h+3−0
@@ -35,6 +35,8 @@ · 34 unmodified lines
3535 #define ACCESS_WRITE_VALUE (3 << 1)
3636 #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1))
3737
38+#define VCPU_NOT_ALLOCATED ((u8)-1)
39+
3840 unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x);
3941
4042 void vgic_update_state(struct kvm *kvm);
@@ -116,5 +118,6 @@ int vgic_get_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr); · 75 unmodified lines
116118
117119 int vgic_init(struct kvm *kvm);
118120 void vgic_v2_init_emulation(struct kvm *kvm);
121+void vgic_v3_init_emulation(struct kvm *kvm);
119122
120123 #endif