From patchwork Tue Dec 5 08:16:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liran Alon X-Patchwork-Id: 10092431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3DC8060348 for ; Tue, 5 Dec 2017 08:17:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C8632950F for ; Tue, 5 Dec 2017 08:17:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F41129546; Tue, 5 Dec 2017 08:17:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15A0B2950F for ; Tue, 5 Dec 2017 08:17:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752676AbdLEIRT (ORCPT ); Tue, 5 Dec 2017 03:17:19 -0500 Received: from userp1040.oracle.com ([156.151.31.81]:25306 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752653AbdLEIRR (ORCPT ); Tue, 5 Dec 2017 03:17:17 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id vB58HCG9014001 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 5 Dec 2017 08:17:13 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id vB58HCaB028793 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 5 Dec 2017 08:17:12 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vB58HCqp024505; Tue, 5 Dec 2017 08:17:12 GMT Received: from localhost.localdomain (/172.58.43.69) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 05 Dec 2017 00:17:11 -0800 From: Liran Alon To: pbonzini@redhat.com, rkrcmar@redhat.com, kvm@vger.kernel.org Cc: jmattson@google.com, wanpeng.li@hotmail.com, idan.brown@oracle.com, Liran Alon , Konrad Rzeszutek Wilk Subject: [PATCH v2 5/5] KVM: nVMX: Wake halted L2 on nested posted-interrupt Date: Tue, 5 Dec 2017 10:16:26 +0200 Message-Id: <1512461786-6465-6-git-send-email-liran.alon@oracle.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1512461786-6465-1-git-send-email-liran.alon@oracle.com> References: <1512461786-6465-1-git-send-email-liran.alon@oracle.com> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If L1 don't intercept L2 HLT (doesn't set CPU_BASED_HLT_EXITING), then when L2 executes HLT instruction, KVM will block vCPU from further execution (just like what happens when L1 executes HLT). Therefore, when some CPU sends nested-posted-interrupts to L2 there are 2 important cases to handle: 1. vmx_deliver_nested_posted_interrupt() note that vcpu->mode != IN_GUEST_MODE and therefore doesn't send a physical IPI. Because the dest vCPU could be blocked by HLT, we should kick it. 2. vmx_deliver_nested_posted_interrupt() sees that vcpu->mode == IN_GUEST_MODE and therefore sends a physical IPI but before it sends the physical IPI, the dest CPU executing L2 executes HLT which caused the dest vCPU to be blocked. Therefore, the physical IPI will be received at host and it's handler should make sure to unblock the vCPU. Fixes: 705699a13994 ("KVM: nVMX: Enable nested posted interrupt processing") Signed-off-by: Liran Alon Reviewed-by: Nikita Leshenko Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/kernel/irq.c | 1 + arch/x86/kvm/vmx.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 49cfd9fe7589..48c5e4a49279 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -326,6 +326,7 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs) entering_ack_irq(); inc_irq_stat(kvm_posted_intr_nested_ipis); + kvm_posted_intr_wakeup_handler(); exiting_irq(); set_irq_regs(old_regs); } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 517822f94158..dcbc4ce5a32a 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5082,7 +5082,8 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, if (is_guest_mode(vcpu) && vector == vmx->nested.posted_intr_nv) { /* the PIR and ON have been set by L1. */ - kvm_vcpu_trigger_posted_interrupt(vcpu, true); + if (!kvm_vcpu_trigger_posted_interrupt(vcpu, true)) + kvm_vcpu_kick(vcpu); return 0; } return -1; @@ -6680,9 +6681,11 @@ static void wakeup_handler(void) spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu), blocked_vcpu_list) { - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + struct vcpu_vmx *vmx = to_vmx(vcpu); - if (pi_test_on(pi_desc) == 1) + if ((pi_test_on(&vmx->pi_desc) == 1) || + (is_guest_mode(vcpu) && vmx->nested.pi_desc && + (pi_test_on(vmx->nested.pi_desc) == 1))) kvm_vcpu_kick(vcpu); } spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));