* Re: [PATCH RFC 2/2] KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
@ 2020-02-21 3:35 linmiaohe
0 siblings, 0 replies; 2+ messages in thread
From: linmiaohe @ 2020-02-21 3:35 UTC (permalink / raw)
To: Vitaly Kuznetsov
Cc: Paolo Bonzini, Sean Christopherson, Wanpeng Li, linux-kernel,
Jim Mattson, kvm
Hi:
Vitaly Kuznetsov <vkuznets@redhat.com> write:
>Even when APICv is disabled for L1 it can (and, actually, is) still available for L2, this means we need to always call
>vmx_deliver_nested_posted_interrupt() when attempting an interrupt delivery.
>
>Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
>Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Looks good for me. Thanks.
Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH RFC 0/2] KVM: nVMX: fix apicv disablement for L1
@ 2020-02-20 17:22 Vitaly Kuznetsov
2020-02-20 17:22 ` [PATCH RFC 2/2] KVM: nVMX: handle nested posted interrupts when apicv is disabled " Vitaly Kuznetsov
0 siblings, 1 reply; 2+ messages in thread
From: Vitaly Kuznetsov @ 2020-02-20 17:22 UTC (permalink / raw)
To: Jim Mattson, kvm
Cc: Paolo Bonzini, Sean Christopherson, Wanpeng Li, linux-kernel
It was found that fine-grained VMX feature enablement in QEMU is broken
when combined with SynIC:
qemu-system-x86_64 -machine q35,accel=kvm -cpu host,hv_vpindex,hv_synic -smp 2 -m 16384 -vnc :0
qemu-system-x86_64: error: failed to set MSR 0x48d to 0xff00000016
qemu-system-x86_64: <...>: kvm_buf_set_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.
Aborted
QEMU thread: https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg04838.html
Turns out, this is a KVM issue: when SynIC is enabled, PIN_BASED_POSTED_INTR
gets filtered out from VMX MSRs for all newly created (but not existent!)
vCPUS. Patch1 addresses this. Also, apicv disablement for L1 doesn't seem
to disable it for L2 (at least on CPU0) so unless there's a good reason
to not allow this we need to make it work. PATCH2, suggested by Paolo,
is supposed to do the job.
RFC: I looked at the code and ran some tests and nothing suspicious popped
out, however, I'm still not convinced this is a good idea to have apicv
enabled for L2 when it's disabled for L1... Also, we may prefer to merge
or re-order these two patches.
Vitaly Kuznetsov (2):
KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only
when apicv is globally disabled
KVM: nVMX: handle nested posted interrupts when apicv is disabled for
L1
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/lapic.c | 5 +----
arch/x86/kvm/svm.c | 7 ++++++-
arch/x86/kvm/vmx/capabilities.h | 1 +
arch/x86/kvm/vmx/nested.c | 5 ++---
arch/x86/kvm/vmx/nested.h | 3 +--
arch/x86/kvm/vmx/vmx.c | 23 +++++++++++++----------
7 files changed, 25 insertions(+), 21 deletions(-)
--
2.24.1
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH RFC 2/2] KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
2020-02-20 17:22 [PATCH RFC 0/2] KVM: nVMX: fix apicv disablement " Vitaly Kuznetsov
@ 2020-02-20 17:22 ` Vitaly Kuznetsov
0 siblings, 0 replies; 2+ messages in thread
From: Vitaly Kuznetsov @ 2020-02-20 17:22 UTC (permalink / raw)
To: Jim Mattson, kvm
Cc: Paolo Bonzini, Sean Christopherson, Wanpeng Li, linux-kernel
Even when APICv is disabled for L1 it can (and, actually, is) still
available for L2, this means we need to always call
vmx_deliver_nested_posted_interrupt() when attempting an interrupt
delivery.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/lapic.c | 5 +----
arch/x86/kvm/svm.c | 7 ++++++-
arch/x86/kvm/vmx/vmx.c | 13 +++++++++----
4 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 40a0c0fd95ca..a84e8c5acda8 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1146,7 +1146,7 @@ struct kvm_x86_ops {
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
- void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
+ int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index afcd30d44cbb..cc8ee8125712 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1046,11 +1046,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic->regs + APIC_TMR);
}
- if (vcpu->arch.apicv_active)
- kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
- else {
+ if (kvm_x86_ops->deliver_posted_interrupt(vcpu, vector)) {
kvm_lapic_set_irr(vector, apic);
-
kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu);
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index bef0ba35f121..970a3ab2e926 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -5255,8 +5255,11 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
return;
}
-static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
+static int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
{
+ if (!vcpu->arch.apicv_active)
+ return -1;
+
kvm_lapic_set_irr(vec, vcpu->arch.apic);
smp_mb__after_atomic();
@@ -5268,6 +5271,8 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
put_cpu();
} else
kvm_vcpu_wake_up(vcpu);
+
+ return 0;
}
static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 946c74e661e2..92a14ea4be69 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -3818,24 +3818,29 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
* 2. If target vcpu isn't running(root mode), kick it to pick up the
* interrupt from PIR in next vmentry.
*/
-static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
+static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
int r;
r = vmx_deliver_nested_posted_interrupt(vcpu, vector);
if (!r)
- return;
+ return 0;
+
+ if (!vcpu->arch.apicv_active)
+ return -1;
if (pi_test_and_set_pir(vector, &vmx->pi_desc))
- return;
+ return 0;
/* If a previous notification has sent the IPI, nothing to do. */
if (pi_test_and_set_on(&vmx->pi_desc))
- return;
+ return 0;
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
kvm_vcpu_kick(vcpu);
+
+ return 0;
}
/*
--
2.24.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-02-21 3:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-21 3:35 [PATCH RFC 2/2] KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1 linmiaohe
-- strict thread matches above, loose matches on Subject: below --
2020-02-20 17:22 [PATCH RFC 0/2] KVM: nVMX: fix apicv disablement " Vitaly Kuznetsov
2020-02-20 17:22 ` [PATCH RFC 2/2] KVM: nVMX: handle nested posted interrupts when apicv is disabled " Vitaly Kuznetsov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®