]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: arm/arm64: VGIC: Properly initialise private IRQ affinity
authorAndre Przywara <andre.przywara@arm.com>
Fri, 23 Aug 2019 10:34:16 +0000 (11:34 +0100)
committerMarc Zyngier <maz@kernel.org>
Fri, 23 Aug 2019 16:23:01 +0000 (17:23 +0100)
commit46a44b93677b611107b4b6dc1cdf41d886edbe18
tree7346a39537b2e2e4d78d4014c2198abcc2d81898
parentc51be18c9d5d53e144588506d352eab1095b1b06
KVM: arm/arm64: VGIC: Properly initialise private IRQ affinity

At the moment we initialise the target *mask* of a virtual IRQ to the
VCPU it belongs to, even though this mask is only defined for GICv2 and
quickly runs out of bits for many GICv3 guests.
This behaviour triggers an UBSAN complaint for more than 32 VCPUs:
------
[ 5659.462377] UBSAN: Undefined behaviour in virt/kvm/arm/vgic/vgic-init.c:223:21
[ 5659.471689] shift exponent 32 is too large for 32-bit type 'unsigned int'
------
Also for GICv3 guests the reporting of TARGET in the "vgic-state" debugfs
dump is wrong, due to this very same problem.

Because there is no requirement to create the VGIC device before the
VCPUs (and QEMU actually does it the other way round), we can't safely
initialise mpidr or targets in kvm_vgic_vcpu_init(). But since we touch
every private IRQ for each VCPU anyway later (in vgic_init()), we can
just move the initialisation of those fields into there, where we
definitely know the VGIC type.

On the way make sure we really have either a VGICv2 or a VGICv3 device,
since the existing code is just checking for "VGICv3 or not", silently
ignoring the uninitialised case.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reported-by: Dave Martin <dave.martin@arm.com>
Tested-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
virt/kvm/arm/vgic/vgic-init.c