On 4/1/25 11:10, Paolo Bonzini wrote: > I guess April 1st is not the best date to send out such a large series > after months of radio silence, but here we are. There were some miscellaneous fixes I had to apply to get the series to compile and start working properly. I didn't break them out by patch #, but here they are: diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 21dbc539cbe7..9d078eb001b1 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1316,32 +1316,35 @@ static void kvm_lapic_deliver_interrupt(struct kvm_vcpu *vcpu, struct kvm_lapic { struct kvm_vcpu *plane0_vcpu = vcpu->plane0; struct kvm_plane *running_plane; + int irr_pending_planes; u16 req_exit_planes; kvm_x86_call(deliver_interrupt)(apic, delivery_mode, trig_mode, vector); /* - * test_and_set_bit implies a memory barrier, so IRR is written before + * atomic_fetch_or implies a memory barrier, so IRR is written before * reading irr_pending_planes below... */ - if (!test_and_set_bit(vcpu->plane, &plane0_vcpu->arch.irr_pending_planes)) { - /* - * ... and also running_plane and req_exit_planes are read after writing - * irr_pending_planes. Both barriers pair with kvm_arch_vcpu_ioctl_run(). - */ - smp_mb__after_atomic(); + irr_pending_planes = atomic_fetch_or(BIT(vcpu->plane), &plane0_vcpu->arch.irr_pending_planes); + if (irr_pending_planes & BIT(vcpu->plane)) + return; - running_plane = READ_ONCE(plane0_vcpu->running_plane); - if (!running_plane) - return; + /* + * ... and also running_plane and req_exit_planes are read after writing + * irr_pending_planes. Both barriers pair with kvm_arch_vcpu_ioctl_run(). + */ + smp_mb__after_atomic(); - req_exit_planes = READ_ONCE(plane0_vcpu->req_exit_planes); - if (!(req_exit_planes & BIT(vcpu->plane))) - return; + running_plane = READ_ONCE(plane0_vcpu->running_plane); + if (!running_plane) + return; - kvm_make_request(KVM_REQ_PLANE_INTERRUPT, - kvm_get_plane_vcpu(running_plane, vcpu->vcpu_id)); - } + req_exit_planes = READ_ONCE(plane0_vcpu->req_exit_planes); + if (!(req_exit_planes & BIT(vcpu->plane))) + return; + + kvm_make_request(KVM_REQ_PLANE_INTERRUPT, + kvm_get_plane_vcpu(running_plane, vcpu->vcpu_id)); } /* diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 9d4492862c11..130d895f1d95 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -458,7 +458,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp, INIT_LIST_HEAD(&sev->mirror_vms); sev->need_init = false; - kvm_set_apicv_inhibit(kvm->planes[[0], APICV_INHIBIT_REASON_SEV); + kvm_set_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_SEV); return 0; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 917bfe8db101..656b69eabc59 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3252,7 +3252,7 @@ static int interrupt_window_interception(struct kvm_vcpu *vcpu) * All vCPUs which run still run nested, will remain to have their * AVIC still inhibited due to per-cpu AVIC inhibition. */ - kvm_clear_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_IRQWIN); + kvm_clear_apicv_inhibit(vcpu->kvm->planes[vcpu->plane], APICV_INHIBIT_REASON_IRQWIN); ++vcpu->stat->irq_window_exits; return 1; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 65bc28e82140..704e8f80898f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11742,7 +11742,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) * the other side will certainly see the cleared bit irr_pending_planes * and set it, and vice versa. */ - clear_bit(plane_id, &plane0_vcpu->arch.irr_pending_planes); + atomic_and(~BIT(plane_id), &plane0_vcpu->arch.irr_pending_planes); smp_mb__after_atomic(); if (kvm_lapic_find_highest_irr(vcpu)) atomic_or(BIT(plane_id), &plane0_vcpu->arch.irr_pending_planes); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3a04fdf0865d..efd45e05fddf 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4224,7 +4224,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm_plane *plane, struct kvm_vcpu *pl * release semantics, which ensures the write is visible to kvm_get_vcpu(). */ vcpu->plane = -1; - if (plane->plane) + if (!plane->plane) vcpu->vcpu_idx = atomic_read(&kvm->online_vcpus); else vcpu->vcpu_idx = plane0_vcpu->vcpu_idx; @@ -4249,7 +4249,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm_plane *plane, struct kvm_vcpu *pl if (r < 0) goto kvm_put_xa_erase; - if (!plane0_vcpu) + if (!plane->plane) atomic_inc(&kvm->online_vcpus); /* Thanks, Tom >