summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos López <clopez@suse.de>2026-05-29 17:00:14 +0300
committerSean Christopherson <seanjc@google.com>2026-06-02 18:30:50 +0300
commit376e118551545190debb3901ea4d0e46aa4c1dc4 (patch)
treec259f7a6c63e858edb261aab6c079e03ab1b2850
parent555aa0e83b16b55f47f1940f89ae30595de4f414 (diff)
downloadlinux-376e118551545190debb3901ea4d0e46aa4c1dc4.tar.xz
KVM: x86: Take PIC lock on KVM_GET_IRQCHIP path
When userspace issues the KVM_SET_IRQCHIP ioctl to set the state of the PIC, kvm_vm_ioctl_set_irqchip() grabs @kvm->arch.vpic->lock before updating the state. However, the KVM_GET_IRQCHIP ioctl to retrieve the same PIC state does not grab such lock, potentially causing torn reads for userspace. Fix this by grabbing the lock on the read path. This issue goes all the way back. The bug was introduced with the addition of PIC ioctl code itself in 6ceb9d791eee ("KVM: Add get/ set irqchip ioctls for in-kernel PIC live migration support"). Later, 894a9c5543ab ("KVM: x86: missing locking in PIT/IRQCHIP/SET_BSP_CPU ioctl paths") added the locking for kvm_vm_ioctl_set_irqchip(), but missed kvm_vm_ioctl_get_irqchip(). Fixes: 6ceb9d791eee ("KVM: Add get/set irqchip ioctls for in-kernel PIC live migration support") Fixes: 894a9c5543ab ("KVM: x86: missing locking in PIT/IRQCHIP/SET_BSP_CPU ioctl paths") Reported-by: Claude Code:claude-opus-4.6 Signed-off-by: Carlos López <clopez@suse.de> Link: https://patch.msgid.link/20260529140013.14925-2-clopez@suse.de Signed-off-by: Sean Christopherson <seanjc@google.com>
-rw-r--r--arch/x86/kvm/irq.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 9519fec09ee6..8c62c6d4d5c1 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -585,12 +585,16 @@ int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
r = 0;
switch (chip->chip_id) {
case KVM_IRQCHIP_PIC_MASTER:
+ spin_lock(&pic->lock);
memcpy(&chip->chip.pic, &pic->pics[0],
sizeof(struct kvm_pic_state));
+ spin_unlock(&pic->lock);
break;
case KVM_IRQCHIP_PIC_SLAVE:
+ spin_lock(&pic->lock);
memcpy(&chip->chip.pic, &pic->pics[1],
sizeof(struct kvm_pic_state));
+ spin_unlock(&pic->lock);
break;
case KVM_IRQCHIP_IOAPIC:
kvm_get_ioapic(kvm, &chip->chip.ioapic);