Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp776093pxp; Fri, 11 Mar 2022 14:50:56 -0800 (PST) X-Google-Smtp-Source: ABdhPJy5yICTcRjCyXqqpX1bWrK4dufbBS9RC6AW1BhIqPrpoCCjBKGkZtvTj8ZvV4zigLuRR/3B X-Received: by 2002:a17:902:e552:b0:14f:bfec:eb2c with SMTP id n18-20020a170902e55200b0014fbfeceb2cmr12584207plf.108.1647039056801; Fri, 11 Mar 2022 14:50:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1647039056; cv=none; d=google.com; s=arc-20160816; b=pqLtha++RFKTqO9kSLu6fMq0U+9NOFG/IqL/7lvBnahGtNhHrXflweC+q/BgSCB2Di fAfU1c5iS9L6H9mafqpxD8SbHxI1QKk4lX6pVUGtR+cq7R2PUz1XuOZKOl1UwdT8gYr/ 1Q2OLZn83SeidchUbuhrHI0/V6CvpVmwLShNKjnKYO3kWrVEranWOXsDo3d/5kSQMwr9 PwvHVYNCXYhWHBwt2cM4ePtafox+xMZLzAGghfjQHvRrPLipnVhTsE8Vc9vR6YoEr6dV uEaiYFplHApOA4M5uVmWhnhRB6xspAiN8wK+FwtCL3BI57fBa7jC37LeX+7s2j1IjBFh 7RgQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=rTJX4212pAlg0gWTYqf1CcyI76TXypnonQQil1moERc=; b=ZwNC9kUX3bLxaMRMMrlltP1PHRPbuj0qTWSoXaEIVaJwpRpQ4jhzwrKptQaPathlYt Zdann7cuHkBbWfn4TB8S7E5dmjFge5nhBpN0w6a/vl3Yjoyxkq/ZfQyvebRVdfCNvvQ7 FDYHYrE8Bd5gGLeBB9pc/58+PZw2kY7rzNrgpgIpG4aVOosE2IRAeQbFme5CmKvw802T SQlRkrgvnjgYbJhI6VF4B5uIMZEjzyqEY5tSyAkhVypm7OmuCKNYXTLK84FkwuVa0WFY jlWRQaNSVQ6Xmg7NphuEZK7ETw9wYlRDeaI0bfGPNiINSoaXq7DINzNkGN61xz0vSIOT wOqg== ARC-Authentication-Results: i=1; mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id p16-20020a639510000000b003738acab21fsi9349737pgd.842.2022.03.11.14.50.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Mar 2022 14:50:56 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id AA32F257A8E; Fri, 11 Mar 2022 13:48:39 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344073AbiCJVkm (ORCPT + 99 others); Thu, 10 Mar 2022 16:40:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344017AbiCJVkc (ORCPT ); Thu, 10 Mar 2022 16:40:32 -0500 Received: from vps-vb.mhejs.net (vps-vb.mhejs.net [37.28.154.113]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DAF8CC084B; Thu, 10 Mar 2022 13:39:30 -0800 (PST) Received: from MUA by vps-vb.mhejs.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nSQV2-0006Ja-IC; Thu, 10 Mar 2022 22:39:08 +0100 From: "Maciej S. Szmigiero" To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Tom Lendacky , Brijesh Singh , Jon Grimm , David Kaplan , Boris Ostrovsky , Liam Merwick , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/5] KVM: nSVM: Restore next_rip when doing L1 -> L2 event re-injection Date: Thu, 10 Mar 2022 22:38:40 +0100 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Maciej S. Szmigiero" According to APM 15.7.1 "State Saved on Exit" the next_rip field can be zero after a VMEXIT in some cases. Yet, it is used by the CPU for the return address pushed on stack when injecting INT3 or INTO exception or a software interrupt. Restore this field to the L1-provided value if zeroed by the CPU when re-injecting a L1-provided event into L2. Signed-off-by: Maciej S. Szmigiero --- arch/x86/kvm/svm/svm.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 5b128baa5e57..760dd0e070ea 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -385,6 +385,44 @@ static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu) return 1; } +/* + * According to APM 15.7.1 "State Saved on Exit" the next_rip field can + * be zero after a VMEXIT in some cases. + * Yet, it is used by the CPU for the return address pushed on stack when + * injecting INT3 or INTO exception or a software interrupt. + * + * Restore this field to the L1-provided value if zeroed by the CPU when + * re-injecting a L1-provided event into L2. + */ +static void maybe_fixup_next_rip(struct kvm_vcpu *vcpu, bool uses_err) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u32 err_vmcb = uses_err ? svm->vmcb->control.event_inj_err : 0; + u32 err_inject = uses_err ? svm->nested.ctl.event_inj_err : 0; + + /* No nRIP Save feature? Then nothing to fix up. */ + if (!nrips) + return; + + /* The fix only applies to event injection into a L2. */ + if (!is_guest_mode(vcpu)) + return; + + /* + * If the current next_rip field is already non-zero assume the CPU had + * returned the correct address during the last VMEXIT. + */ + if (svm->vmcb->control.next_rip) + return; + + /* Is this a L1 -> L2 event re-injection? */ + if (!event_inj_same(svm->vmcb->control.event_inj, err_vmcb, + svm->nested.ctl.event_inj, err_inject)) + return; + + svm->vmcb->control.next_rip = svm->nested.ctl.next_rip; +} + static void svm_queue_exception(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -415,6 +453,9 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu) | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) | SVM_EVTINJ_TYPE_EXEPT; svm->vmcb->control.event_inj_err = error_code; + + if (kvm_exception_is_soft(nr)) + maybe_fixup_next_rip(vcpu, true); } static void svm_init_erratum_383(void) @@ -3331,6 +3372,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu) SVM_EVTINJ_VALID; if (vcpu->arch.interrupt.soft) { svm->vmcb->control.event_inj |= SVM_EVTINJ_TYPE_SOFT; + + maybe_fixup_next_rip(vcpu, false); } else { svm->vmcb->control.event_inj |= SVM_EVTINJ_TYPE_INTR; }