]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86: Take PIC lock on KVM_GET_IRQCHIP path
authorCarlos López <clopez@suse.de>
Fri, 29 May 2026 14:00:14 +0000 (16:00 +0200)
committerSean Christopherson <seanjc@google.com>
Tue, 2 Jun 2026 15:30:50 +0000 (08:30 -0700)
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>
arch/x86/kvm/irq.c

index 9519fec09ee6f519ab0a94c8a1e995884d07b8d2..8c62c6d4d5c173c7f0a88748b18f690fa538f52f 100644 (file)
@@ -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);