KVM: arm/arm64: vgic-v2: Limit ITARGETSR bits to number of VCPUs
authorAndre Przywara <andre.przywara@arm.com>
Wed, 16 Nov 2016 17:57:16 +0000 (17:57 +0000)
committerMarc Zyngier <marc.zyngier@arm.com>
Fri, 9 Dec 2016 15:46:59 +0000 (15:46 +0000)
The GICv2 spec says in section 4.3.12 that a "CPU targets field bit that
corresponds to an unimplemented CPU interface is RAZ/WI."
Currently we allow the guest to write any value in there and it can
read that back.
Mask the written value with the proper CPU mask to be spec compliant.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic/vgic-mmio-v2.c

index b44b359cbbadeeba46542be870b3e9bbd49f1d26..78e34bc4d89b2ed40b2114bac6dfea5c485e7e0a 100644 (file)
@@ -129,6 +129,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
                                   unsigned long val)
 {
        u32 intid = VGIC_ADDR_TO_INTID(addr, 8);
+       u8 cpu_mask = GENMASK(atomic_read(&vcpu->kvm->online_vcpus) - 1, 0);
        int i;
 
        /* GICD_ITARGETSR[0-7] are read-only */
@@ -141,7 +142,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
 
                spin_lock(&irq->irq_lock);
 
-               irq->targets = (val >> (i * 8)) & 0xff;
+               irq->targets = (val >> (i * 8)) & cpu_mask;
                target = irq->targets ? __ffs(irq->targets) : 0;
                irq->target_vcpu = kvm_get_vcpu(vcpu->kvm, target);