Patch "KVM: VMX: simplify and fix vmx_vcpu_pi_load" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: VMX: simplify and fix vmx_vcpu_pi_load
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-vmx-simplify-and-fix-vmx_vcpu_pi_load.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
31afb2ea2b10a7d17ce3db4cdb0a12b63b2fe08aMon Sep 17 00:00:00 2001
From: Paolo Bonzini <[email protected]>
Date: Tue, 6 Jun 2017 12:57:06 +0200
Subject: KVM: VMX: simplify and fix vmx_vcpu_pi_load
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Paolo Bonzini <[email protected]>
commit 31afb2ea2b10a7d17ce3db4cdb0a12b63b2fe08a upstream.
The simplify part: do not touch pi_desc.nv, we can set it when the VCPU is first created. Likewise, pi_desc.sn is only handled by vmx_vcpu_pi_load, do not touch it in __pi_post_block.
The fix part: do not check kvm_arch_has_assigned_device, instead check the SN bit to figure out whether vmx_vcpu_pi_put ran before. This matches what the previous patch did in pi_post_block.
--- arch/x86/kvm/vmx.c | 68 +++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 33 deletions(-)
arch/x86/kvm/vmx.c +35 -33
@@ -2167,43 +2167,41 @@ static void vmx_vcpu_pi_load(struct kvm_struct pi_desc old, new;unsigned int dest; -if (!kvm_arch_has_assigned_device (vcpu->kvm) || - !irq_remapping_cap (IRQ_POSTING_CAP ) || - !kvm_vcpu_apicv_active (vcpu)) +/* +* In case of hot-plug or hot-unplug, we may have to undo +* vmx_vcpu_pi_put even if there is no assigned device. And we +* always keep PI.NDST up to date for simplicity: it makes the +* code easier, and CPU migration is not a fast path. +*/ +if (!pi_test_sn (pi_desc) && vcpu->cpu == cpu) +return ; + +/* +* First handle the simple case where no cmpxchg is necessary; just +* allow posting non-urgent interrupts. +* +* If the 'nv' field is POSTED_INTR_WAKEUP_VECTOR, do not change +* PI.NDST: pi_post_block will do it for us and the wakeup_handler +* expects the VCPU to be on the blocked_vcpu_list that matches +* PI.NDST. +*/ +if (pi_desc->nv ==POSTED_INTR_WAKEUP_VECTOR || + vcpu->cpu == cpu) { +pi_clear_sn (pi_desc);return ; + } +/* The full case. */ do { old.control = new.control = pi_desc->control; -/* -* If 'nv' field is POSTED_INTR_WAKEUP_VECTOR, there -* are two possible cases: -* 1. After running 'pre_block', context switch -* happened. For this case, 'sn' was set in -* vmx_vcpu_put(), so we need to clear it here. -* 2. After running 'pre_block', we were blocked, -* and woken up by some other guy. For this case, -* we don't need to do anything, 'pi_post_block' -* will do everything for us. However, we cannot -* check whether it is case #1 or case #2 here -* (maybe, not needed), so we also clear sn here, -* I think it is not a big deal. -*/ -if (pi_desc->nv !=POSTED_INTR_WAKEUP_VECTOR ) { -if (vcpu->cpu != cpu) { - dest =cpu_physical_id (cpu); - -if (x2apic_enabled ()) - new.ndst = dest; -else - new.ndst = (dest <<8 ) &0xFF00 ; - } + dest =cpu_physical_id (cpu); -/* set 'NV' to 'notification vector' */ - new.nv =POSTED_INTR_VECTOR ; - } +if (x2apic_enabled ()) + new.ndst = dest; +else + new.ndst = (dest <<8 ) &0xFF00 ; -/* Allow posting non-urgent interrupts */ new.sn =0 ; }while (cmpxchg (&pi_desc->control, old.control, new.control) != old.control);
@@ -9187,6 +9185,13 @@ static struct kvm_vcpu *vmx_create_vcpu( vmx->msr_ia32_feature_control_valid_bits =FEATURE_CONTROL_LOCKED ; +/* +* Enforce invariant: pi_desc.nv is always either POSTED_INTR_VECTOR +* or POSTED_INTR_WAKEUP_VECTOR. +*/ + vmx->pi_desc.nv =POSTED_INTR_VECTOR ; + vmx->pi_desc.sn =1 ; +return &vmx->vcpu; free_vmcs:
@@ -11018,9 +11023,6 @@ static void __pi_post_block(struct kvm_velse new.ndst = (dest <<8 ) &0xFF00 ; -/* Allow posting non-urgent interrupts */ - new.sn =0 ; -/* set 'NV' to 'notification vector' */ new.nv =POSTED_INTR_VECTOR ; } while (cmpxchg(&pi_desc->control, old.control,
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/kvm-vmx-simplify-and-fix-vmx_vcpu_pi_load.patch queue-4.9/kvm-vmx-avoid-double-list-add-with-vt-d-posted-interrupts.patch queue-4.9/kvm-nvmx-don-t-allow-l2-to-access-the-hardware-cr8.patch queue-4.9/kvm-x86-handle-async-pf-in-rcu-read-side-critical-sections.patch queue-4.9/kvm-vmx-extract-__pi_post_block.patch queue-4.9/kvm-vmx-do-not-bug-on-out-of-bounds-guest-irq.patch