From patchwork Sun Dec 24 16:13:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liran Alon X-Patchwork-Id: 10132083 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 B70F960318 for ; Sun, 24 Dec 2017 16:14:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA79228D8F for ; Sun, 24 Dec 2017 16:14:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F53A28D91; Sun, 24 Dec 2017 16:14: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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, 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 303F728D8F for ; Sun, 24 Dec 2017 16:14:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753149AbdLXQOU (ORCPT ); Sun, 24 Dec 2017 11:14:20 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:39192 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752632AbdLXQOQ (ORCPT ); Sun, 24 Dec 2017 11:14:16 -0500 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vBOGDNIL089282; Sun, 24 Dec 2017 16:14:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2017-10-26; bh=WhKsnC+xN6ZpQXLNgjpsf1BEwyUzCtk28DstvVSziQs=; b=q3F9aPkb+E7yN/knEmXjaK1VkrQJdvVPbO9jcib6ToW5kQmrmDtclapY3kn7Yxucu4IE objxBInCkZi0T3AgkbS+bSE+/mlk+yxy4bR+H9YU5vr91xbH9SN64lRm7hVTi55CkBKh XAJ0hl35y1uWOxW2NKNwOD3Zq8z1x/6k5WisXRaOBG3ddAMaAJrE8vasY0NcbtpQ5Hda ERJ/UHoZCft6yUpn2eaMuD7Vqz3ekWZ2YiuEuczd1kFdnAHmUoKKYsjZE6mhoiYEaLw7 LAavmJCkyNvUDlPS6Wm6tGweozlpcKkSC+9bl62EfT/kNPJhgtcJizJarhyk44AuaCGr jA== Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp2130.oracle.com with ESMTP id 2f2ey101t3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 24 Dec 2017 16:14:11 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id vBOGDwwi023772 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 24 Dec 2017 16:13:58 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id vBOGDvFp031101; Sun, 24 Dec 2017 16:13:57 GMT Received: from liran-pc.ravello.local (/213.57.127.2) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 24 Dec 2017 08:13:57 -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 , Liam Merwick Subject: [PATCH v3 11/11] KVM: nVMX: Wake L2 from HLT when nested posted-interrupt pending Date: Sun, 24 Dec 2017 18:13:03 +0200 Message-Id: <1514131983-24305-12-git-send-email-liran.alon@oracle.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1514131983-24305-1-git-send-email-liran.alon@oracle.com> References: <1514131983-24305-1-git-send-email-liran.alon@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8755 signatures=668650 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=860 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712240223 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 doesn'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). Consider the case where vmx_deliver_nested_posted_interrupt() sees that vcpu->mode == IN_GUEST_MODE and therefore sends a physical IPI. Assume that before it sends the physical IPI, the dest CPU executing L2 executes HLT which causes the dest vCPU to be blocked. Before the dest vCPU is blocked, a call to kvm_arch_vcpu_runnable() is made which calls kvm_vcpu_has_events(). In addition, after the vCPU is blocked, every time it is interrupted (by IPI) then kvm_vcpu_check_block() is called which also calls kvm_arch_vcpu_runnable(). kvm_vcpu_has_events() should return if there is a pending event for vCPU that should be processed and therefore vCPU should be unblocked. In order to handle the above mentioned case, kvm_vcpu_has_events() should check if there is a pending nested posted-interrupt on vCPU that should be dispatched to guest. Fixes: 705699a13994 ("KVM: nVMX: Enable nested posted interrupt processing") Signed-off-by: Liran Alon Reviewed-by: Nikita Leshenko Reviewed-by: Liam Merwick Signed-off-by: Liam Merwick --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm.c | 7 +++++++ arch/x86/kvm/vmx.c | 13 +++++++++++++ arch/x86/kvm/x86.c | 3 ++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 4b8caff83dc7..71c240bbb685 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -994,6 +994,7 @@ struct kvm_x86_ops { void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); void (*complete_nested_posted_interrupt)(struct kvm_vcpu *vcpu); + bool (*cpu_has_nested_posted_interrupt)(struct kvm_vcpu *vcpu); int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); int (*get_tdp_level)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 183f7aec29ca..a559c26d7bff 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4458,6 +4458,11 @@ static void svm_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) { } +static bool svm_cpu_has_nested_posted_interrupt(struct kvm_vcpu *vcpu) +{ + return false; +} + /* Note: Currently only used by Hyper-V. */ static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) { @@ -5593,6 +5598,8 @@ static int enable_smi_window(struct kvm_vcpu *vcpu) .sync_pir_to_irr = svm_sync_pir_to_irr, .complete_nested_posted_interrupt = svm_complete_nested_posted_interrupt, + .cpu_has_nested_posted_interrupt = + svm_cpu_has_nested_posted_interrupt, .apicv_post_state_restore = avic_post_state_restore, .set_tss_addr = svm_set_tss_addr, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c2d012d9d16d..8b414dd5e07c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5141,6 +5141,17 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) } } +static bool vmx_cpu_has_nested_posted_interrupt(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + return (vcpu->arch.apicv_active && + is_guest_mode(vcpu) && + vmx->nested.pi_pending && + vmx->nested.pi_desc && + pi_test_on(vmx->nested.pi_desc)); +} + /* * Set up the vmcs's constant host-state fields, i.e., host-state fields that * will not change in the lifetime of the guest. @@ -12142,6 +12153,8 @@ static int enable_smi_window(struct kvm_vcpu *vcpu) .deliver_posted_interrupt = vmx_deliver_posted_interrupt, .complete_nested_posted_interrupt = vmx_complete_nested_posted_interrupt, + .cpu_has_nested_posted_interrupt = + vmx_cpu_has_nested_posted_interrupt, .set_tss_addr = vmx_set_tss_addr, .get_tdp_level = get_ept_level, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fa088951afc9..a840f2c9bd66 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8542,7 +8542,8 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu) return true; if (kvm_arch_interrupt_allowed(vcpu) && - kvm_cpu_has_interrupt(vcpu)) + (kvm_cpu_has_interrupt(vcpu) || + kvm_x86_ops->cpu_has_nested_posted_interrupt(vcpu))) return true; if (kvm_hv_has_stimer_pending(vcpu))