aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoffer Dall <cdall@linaro.org>2017-08-31 16:24:25 -0400
committerChristoffer Dall <cdall@linaro.org>2017-09-05 11:33:39 -0400
commit9b87e7a8bfb5098129836757608b3cbbdc11245a (patch)
tree915298210e091afabb92388d32e7256e853d9d96
parent50f5bd5718df9e71d1f4ba69a6480dbad54b2f24 (diff)
KVM: arm/arm64: Support uaccess of GICC_APRn
When migrating guests around we need to know the active priorities to ensure functional virtual interrupt prioritization by the GIC. This commit clarifies the API and how active priorities of interrupts in different groups are represented, and implements the accessor functions for the uaccess register range. We live with a slight layering violation in accessing GICv3 data structures from vgic-mmio-v2.c, because anything else just adds too much complexity for us to deal with (it's not like there's a benefit elsewhere in the code of an intermediate representation as is the case with the VMCR). We accept this, because while doing v3 processing from a file named something-v2.c can look strange at first, this really is specific to dealing with the user space interface for something that looks like a GICv2. Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <cdall@linaro.org>
-rw-r--r--Documentation/virtual/kvm/devices/arm-vgic.txt5
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v2.c47
2 files changed, 51 insertions, 1 deletions
diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt
index b2f60ca8b60c..b3ce12643553 100644
--- a/Documentation/virtual/kvm/devices/arm-vgic.txt
+++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
@@ -83,6 +83,11 @@ Groups:
83 83
84 Bits for undefined preemption levels are RAZ/WI. 84 Bits for undefined preemption levels are RAZ/WI.
85 85
86 Note that this differs from a CPU's view of the APRs on hardware in which
87 a GIC without the security extensions expose group 0 and group 1 active
88 priorities in separate register groups, whereas we show a combined view
89 similar to GICv2's GICH_APR.
90
86 For historical reasons and to provide ABI compatibility with userspace we 91 For historical reasons and to provide ABI compatibility with userspace we
87 export the GICC_PMR register in the format of the GICH_VMCR.VMPriMask 92 export the GICC_PMR register in the format of the GICH_VMCR.VMPriMask
88 field in the lower 5 bits of a word, meaning that userspace must always 93 field in the lower 5 bits of a word, meaning that userspace must always
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
index 37522e65eb53..b3d4a10f09a1 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
@@ -303,6 +303,51 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu,
303 vgic_set_vmcr(vcpu, &vmcr); 303 vgic_set_vmcr(vcpu, &vmcr);
304} 304}
305 305
306static unsigned long vgic_mmio_read_apr(struct kvm_vcpu *vcpu,
307 gpa_t addr, unsigned int len)
308{
309 int n; /* which APRn is this */
310
311 n = (addr >> 2) & 0x3;
312
313 if (kvm_vgic_global_state.type == VGIC_V2) {
314 /* GICv2 hardware systems support max. 32 groups */
315 if (n != 0)
316 return 0;
317 return vcpu->arch.vgic_cpu.vgic_v2.vgic_apr;
318 } else {
319 struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
320
321 if (n > vgic_v3_max_apr_idx(vcpu))
322 return 0;
323 /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
324 return vgicv3->vgic_ap1r[n];
325 }
326}
327
328static void vgic_mmio_write_apr(struct kvm_vcpu *vcpu,
329 gpa_t addr, unsigned int len,
330 unsigned long val)
331{
332 int n; /* which APRn is this */
333
334 n = (addr >> 2) & 0x3;
335
336 if (kvm_vgic_global_state.type == VGIC_V2) {
337 /* GICv2 hardware systems support max. 32 groups */
338 if (n != 0)
339 return;
340 vcpu->arch.vgic_cpu.vgic_v2.vgic_apr = val;
341 } else {
342 struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
343
344 if (n > vgic_v3_max_apr_idx(vcpu))
345 return;
346 /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
347 vgicv3->vgic_ap1r[n] = val;
348 }
349}
350
306static const struct vgic_register_region vgic_v2_dist_registers[] = { 351static const struct vgic_register_region vgic_v2_dist_registers[] = {
307 REGISTER_DESC_WITH_LENGTH(GIC_DIST_CTRL, 352 REGISTER_DESC_WITH_LENGTH(GIC_DIST_CTRL,
308 vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc, 12, 353 vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc, 12,
@@ -364,7 +409,7 @@ static const struct vgic_register_region vgic_v2_cpu_registers[] = {
364 vgic_mmio_read_vcpuif, vgic_mmio_write_vcpuif, 4, 409 vgic_mmio_read_vcpuif, vgic_mmio_write_vcpuif, 4,
365 VGIC_ACCESS_32bit), 410 VGIC_ACCESS_32bit),
366 REGISTER_DESC_WITH_LENGTH(GIC_CPU_ACTIVEPRIO, 411 REGISTER_DESC_WITH_LENGTH(GIC_CPU_ACTIVEPRIO,
367 vgic_mmio_read_raz, vgic_mmio_write_wi, 16, 412 vgic_mmio_read_apr, vgic_mmio_write_apr, 16,
368 VGIC_ACCESS_32bit), 413 VGIC_ACCESS_32bit),
369 REGISTER_DESC_WITH_LENGTH(GIC_CPU_IDENT, 414 REGISTER_DESC_WITH_LENGTH(GIC_CPU_IDENT,
370 vgic_mmio_read_vcpuif, vgic_mmio_write_vcpuif, 4, 415 vgic_mmio_read_vcpuif, vgic_mmio_write_vcpuif, 4,