Message ID | 20211009021236.4122790-23-seanjc@google.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | KVM: Halt-polling and x86 APICv overhaul | expand |
On 09/10/21 04:12, Sean Christopherson wrote: > Drop sanity checks on the validity of the previous pCPU when handling > vCPU block/unlock for posted interrupts. Barring a code bug or memory > corruption, the sanity checks will never fire, and any code bug that does > trip the WARN is all but guaranteed to completely break posted interrupts, > i.e. should never get anywhere near production. > > This is the first of several steps toward eliminating kvm_vcpu.pre_cpu. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/vmx/posted_intr.c | 24 ++++++++++-------------- > 1 file changed, 10 insertions(+), 14 deletions(-) The idea here is to avoid making things worse by not making the list inconsistent. But that's impossible to do if pre_pcpu goes away, so fair enough. Paolo > diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c > index 67cbe6ab8f66..6c2110d91b06 100644 > --- a/arch/x86/kvm/vmx/posted_intr.c > +++ b/arch/x86/kvm/vmx/posted_intr.c > @@ -118,12 +118,10 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) > } while (cmpxchg64(&pi_desc->control, old.control, > new.control) != old.control); > > - if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { > - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - list_del(&vcpu->blocked_vcpu_list); > - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - vcpu->pre_pcpu = -1; > - } > + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + list_del(&vcpu->blocked_vcpu_list); > + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + vcpu->pre_pcpu = -1; > } > > /* > @@ -153,14 +151,12 @@ int pi_pre_block(struct kvm_vcpu *vcpu) > > WARN_ON(irqs_disabled()); > local_irq_disable(); > - if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { > - vcpu->pre_pcpu = vcpu->cpu; > - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - list_add_tail(&vcpu->blocked_vcpu_list, > - &per_cpu(blocked_vcpu_on_cpu, > - vcpu->pre_pcpu)); > - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - } > + > + vcpu->pre_pcpu = vcpu->cpu; > + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + list_add_tail(&vcpu->blocked_vcpu_list, > + &per_cpu(blocked_vcpu_on_cpu, vcpu->pre_pcpu)); > + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > > WARN(pi_desc->sn == 1, > "Posted Interrupt Suppress Notification set before blocking"); >
On Fri, 2021-10-08 at 19:12 -0700, Sean Christopherson wrote: > Drop sanity checks on the validity of the previous pCPU when handling > vCPU block/unlock for posted interrupts. Barring a code bug or memory > corruption, the sanity checks will never fire, and any code bug that does > trip the WARN is all but guaranteed to completely break posted interrupts, > i.e. should never get anywhere near production. > > This is the first of several steps toward eliminating kvm_vcpu.pre_cpu. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/vmx/posted_intr.c | 24 ++++++++++-------------- > 1 file changed, 10 insertions(+), 14 deletions(-) > > diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c > index 67cbe6ab8f66..6c2110d91b06 100644 > --- a/arch/x86/kvm/vmx/posted_intr.c > +++ b/arch/x86/kvm/vmx/posted_intr.c > @@ -118,12 +118,10 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) > } while (cmpxchg64(&pi_desc->control, old.control, > new.control) != old.control); > > - if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { > - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - list_del(&vcpu->blocked_vcpu_list); > - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - vcpu->pre_pcpu = -1; > - } > + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + list_del(&vcpu->blocked_vcpu_list); > + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + vcpu->pre_pcpu = -1; > } > > /* > @@ -153,14 +151,12 @@ int pi_pre_block(struct kvm_vcpu *vcpu) > > WARN_ON(irqs_disabled()); > local_irq_disable(); > - if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { > - vcpu->pre_pcpu = vcpu->cpu; > - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - list_add_tail(&vcpu->blocked_vcpu_list, > - &per_cpu(blocked_vcpu_on_cpu, > - vcpu->pre_pcpu)); > - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > - } > + > + vcpu->pre_pcpu = vcpu->cpu; > + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > + list_add_tail(&vcpu->blocked_vcpu_list, > + &per_cpu(blocked_vcpu_on_cpu, vcpu->pre_pcpu)); > + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); > > WARN(pi_desc->sn == 1, > "Posted Interrupt Suppress Notification set before blocking"); Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c index 67cbe6ab8f66..6c2110d91b06 100644 --- a/arch/x86/kvm/vmx/posted_intr.c +++ b/arch/x86/kvm/vmx/posted_intr.c @@ -118,12 +118,10 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) } while (cmpxchg64(&pi_desc->control, old.control, new.control) != old.control); - if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_del(&vcpu->blocked_vcpu_list); - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - vcpu->pre_pcpu = -1; - } + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + list_del(&vcpu->blocked_vcpu_list); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + vcpu->pre_pcpu = -1; } /* @@ -153,14 +151,12 @@ int pi_pre_block(struct kvm_vcpu *vcpu) WARN_ON(irqs_disabled()); local_irq_disable(); - if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { - vcpu->pre_pcpu = vcpu->cpu; - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_add_tail(&vcpu->blocked_vcpu_list, - &per_cpu(blocked_vcpu_on_cpu, - vcpu->pre_pcpu)); - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - } + + vcpu->pre_pcpu = vcpu->cpu; + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + list_add_tail(&vcpu->blocked_vcpu_list, + &per_cpu(blocked_vcpu_on_cpu, vcpu->pre_pcpu)); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); WARN(pi_desc->sn == 1, "Posted Interrupt Suppress Notification set before blocking");
Drop sanity checks on the validity of the previous pCPU when handling vCPU block/unlock for posted interrupts. Barring a code bug or memory corruption, the sanity checks will never fire, and any code bug that does trip the WARN is all but guaranteed to completely break posted interrupts, i.e. should never get anywhere near production. This is the first of several steps toward eliminating kvm_vcpu.pre_cpu. Signed-off-by: Sean Christopherson <seanjc@google.com> --- arch/x86/kvm/vmx/posted_intr.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-)