KVM: arm/arm64: Separate guest and uaccess writes to dist {sc}active
authorChristoffer Dall <cdall@linaro.org>
Tue, 16 May 2017 07:44:39 +0000 (09:44 +0200)
committerChristoffer Dall <cdall@linaro.org>
Tue, 23 May 2017 10:48:11 +0000 (12:48 +0200)
Factor out the core register modifier functionality from the entry
points from the register description table, and only call the
prepare/finish functions from the guest path, not the uaccess path.

Signed-off-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic/vgic-mmio-v2.c
virt/kvm/arm/vgic/vgic-mmio-v3.c
virt/kvm/arm/vgic/vgic-mmio.c
virt/kvm/arm/vgic/vgic-mmio.h

index 95543a20513ad9f1bf5240d56c9577fb4207ec48..8bafe9af3205fe6c2d0d1d591a1cc0004ba79318 100644 (file)
@@ -311,10 +311,12 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = {
                vgic_mmio_read_pending, vgic_mmio_write_cpending, NULL, NULL, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET,
-               vgic_mmio_read_active, vgic_mmio_write_sactive, NULL, NULL, 1,
+               vgic_mmio_read_active, vgic_mmio_write_sactive,
+               NULL, vgic_mmio_uaccess_write_sactive, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_CLEAR,
-               vgic_mmio_read_active, vgic_mmio_write_cactive, NULL, NULL, 1,
+               vgic_mmio_read_active, vgic_mmio_write_cactive,
+               NULL, vgic_mmio_uaccess_write_cactive, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PRI,
                vgic_mmio_read_priority, vgic_mmio_write_priority, NULL, NULL,
index 99da1a207c19b0563030bf4ad842d8d805b1b153..23c0d56436a7690651650840cb3b981a4613c9cc 100644 (file)
@@ -456,11 +456,13 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = {
                vgic_mmio_read_raz, vgic_mmio_write_wi, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISACTIVER,
-               vgic_mmio_read_active, vgic_mmio_write_sactive, NULL, NULL, 1,
+               vgic_mmio_read_active, vgic_mmio_write_sactive,
+               NULL, vgic_mmio_uaccess_write_sactive, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICACTIVER,
-               vgic_mmio_read_active, vgic_mmio_write_cactive, NULL, NULL, 1,
-               VGIC_ACCESS_32bit),
+               vgic_mmio_read_active, vgic_mmio_write_cactive,
+               NULL, vgic_mmio_uaccess_write_cactive,
+               1, VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IPRIORITYR,
                vgic_mmio_read_priority, vgic_mmio_write_priority, NULL, NULL,
                8, VGIC_ACCESS_32bit | VGIC_ACCESS_8bit),
index 1c17b2a2f105c0a11cbe1083088e71d94c3e3b51..64cbcb4c47d05b4cd99594bd6f082d48cddd5726 100644 (file)
@@ -251,38 +251,74 @@ static void vgic_change_active_finish(struct kvm_vcpu *vcpu, u32 intid)
                kvm_arm_resume_guest(vcpu->kvm);
 }
 
-void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
-                            gpa_t addr, unsigned int len,
-                            unsigned long val)
+static void __vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
+                                     gpa_t addr, unsigned int len,
+                                     unsigned long val)
 {
        u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
        int i;
 
-       vgic_change_active_prepare(vcpu, intid);
        for_each_set_bit(i, &val, len * 8) {
                struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
                vgic_mmio_change_active(vcpu, irq, false);
                vgic_put_irq(vcpu->kvm, irq);
        }
-       vgic_change_active_finish(vcpu, intid);
 }
 
-void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
+void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
                             gpa_t addr, unsigned int len,
                             unsigned long val)
 {
        u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
-       int i;
 
        vgic_change_active_prepare(vcpu, intid);
+
+       __vgic_mmio_write_cactive(vcpu, addr, len, val);
+
+       vgic_change_active_finish(vcpu, intid);
+}
+
+void vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
+                                    gpa_t addr, unsigned int len,
+                                    unsigned long val)
+{
+       __vgic_mmio_write_cactive(vcpu, addr, len, val);
+}
+
+static void __vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
+                                     gpa_t addr, unsigned int len,
+                                     unsigned long val)
+{
+       u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+       int i;
+
        for_each_set_bit(i, &val, len * 8) {
                struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
                vgic_mmio_change_active(vcpu, irq, true);
                vgic_put_irq(vcpu->kvm, irq);
        }
+}
+
+void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
+                            gpa_t addr, unsigned int len,
+                            unsigned long val)
+{
+       u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+
+       vgic_change_active_prepare(vcpu, intid);
+
+       __vgic_mmio_write_sactive(vcpu, addr, len, val);
+
        vgic_change_active_finish(vcpu, intid);
 }
 
+void vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
+                                    gpa_t addr, unsigned int len,
+                                    unsigned long val)
+{
+       __vgic_mmio_write_sactive(vcpu, addr, len, val);
+}
+
 unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
                                      gpa_t addr, unsigned int len)
 {
index 27924a3d87695e520664c0fbad0ea189962397e1..5693f6df45ecd57e5d7b28aecc1579f87cdcd91e 100644 (file)
@@ -167,6 +167,14 @@ void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
                             gpa_t addr, unsigned int len,
                             unsigned long val);
 
+void vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
+                                    gpa_t addr, unsigned int len,
+                                    unsigned long val);
+
+void vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
+                                    gpa_t addr, unsigned int len,
+                                    unsigned long val);
+
 unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
                                      gpa_t addr, unsigned int len);