Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp220950iob; Mon, 2 May 2022 17:37:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwDIT43skdyzM8vk/6ezZ5F+1Lvq355gPAM5GFjYD9hNZiE1PnpZVWYdpg4lt189Ht6v+c2 X-Received: by 2002:a63:8843:0:b0:3ab:18d:a91f with SMTP id l64-20020a638843000000b003ab018da91fmr11748831pgd.119.1651538259212; Mon, 02 May 2022 17:37:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651538259; cv=none; d=google.com; s=arc-20160816; b=rpS6DKtxtzvTW5UYhImsh5scJJaYbX6lN/N7iWIrQnMKB9kuo1ic3EtCxncBoBWyOG kzAcj4COV1rDOgu0rx7hRKz+Dde9pqzQyw5BljLgOtRHXBpeS4WiPJKM4ek63EdrhkwU 7S3x7j87rYxbtmdrFz2Tbjq8LgGcntXzjYLzJtyeQffY/4rG01SQvt58D9oW7T6ewC4t Qs+WuasjCIAanVCL/a0yPTS5x4bsZSH7EsnfkZhuutCsRnqQMdK+DozkPM0Z1yugs+An yUhblVdTf5nCnEb7y9gH+/pOfHOPKpPDsYhyhjh4JO2X19ZweDTyS0wzOX43KLuLslxI 7XnQ== 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=TND08505pQ8DLUgjdZw7kyYWKo9xcg1v16YQpEEcoS8=; b=Z9Bsja3cgucTzys3p6nsfSpGpBLKQwRVGcPPZgndrrsNFjJfERGorM94XHsUbmbKrK SuWxarYJJOSXFbSU4hoWsVZt9sIn2f1TOlQFSbLbonlzqX3IDQx1CFMvXFSPohWYf5EA iiLGGM02KvBLwcK27om2U7ddF9Cqwu0VSWmL+hr68kfhJ7fN1VUd481bC23VGgbzUDMk br0rRQS2MjLiKkBj6rlIQdZvBoemk79gHi+jRS+dDiy5fPdINCxmhhRbvf+qUqKtZ1RB 4uzTeTM1jm9r4XGNgP94wJPzUefSu0b06AjyEfEbWE5qXSTGSynHwZuWV3xDohN0WPgs JbLw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id h62-20020a638341000000b003ab19f55566si3910061pge.359.2022.05.02.17.37.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 May 2022 17:37:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 5E720117C; Mon, 2 May 2022 17:29:24 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376859AbiEAWLl (ORCPT + 99 others); Sun, 1 May 2022 18:11:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376843AbiEAWLg (ORCPT ); Sun, 1 May 2022 18:11:36 -0400 Received: from vps-vb.mhejs.net (vps-vb.mhejs.net [37.28.154.113]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EF4B1DA73; Sun, 1 May 2022 15:08:07 -0700 (PDT) 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 1nlHjS-0008Mw-12; Mon, 02 May 2022 00:07:58 +0200 From: "Maciej S. Szmigiero" To: Paolo Bonzini , Sean Christopherson Cc: Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Maxim Levitsky , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 03/12] KVM: SVM: Unwind "speculative" RIP advancement if INTn injection "fails" Date: Mon, 2 May 2022 00:07:27 +0200 Message-Id: <450133cf0a026cb9825a2ff55d02cb136a1cb111.1651440202.git.maciej.szmigiero@oracle.com> 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: Sean Christopherson Unwind the RIP advancement done by svm_queue_exception() when injecting an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while vectoring the injected event, even if the exception reported by the CPU isn't the same event that was injected. If vectoring INT3 encounters an exception, e.g. #NP, and vectoring the #NP encounters an intercepted exception, e.g. #PF when KVM is using shadow paging, then the #NP will be reported as the event that was in-progress. Note, this is still imperfect, as it will get a false positive if the INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3 handler in the guest, the instruction following the INT3 generates an exception (directly or indirectly), _and_ vectoring that exception encounters an exception that is intercepted by KVM. The false positives could theoretically be solved by further analyzing the vectoring event, e.g. by comparing the error code against the expected error code were an exception to occur when vectoring the original injected exception, but SVM without NRIPS is a complete disaster, trying to make it 100% correct is a waste of time. Reviewed-by: Maxim Levitsky Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson Signed-off-by: Maciej S. Szmigiero --- arch/x86/kvm/svm/svm.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 1cec671fc668..1a719f47a964 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3698,6 +3698,18 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK; type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK; + /* + * If NextRIP isn't enabled, KVM must manually advance RIP prior to + * injecting the soft exception/interrupt. That advancement needs to + * be unwound if vectoring didn't complete. Note, the _new_ event may + * not be the injected event, e.g. if KVM injected an INTn, the INTn + * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will + * be the reported vectored event, but RIP still needs to be unwound. + */ + if (int3_injected && type == SVM_EXITINTINFO_TYPE_EXEPT && + kvm_is_linear_rip(vcpu, svm->int3_rip)) + kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected); + switch (type) { case SVM_EXITINTINFO_TYPE_NMI: vcpu->arch.nmi_injected = true; @@ -3711,16 +3723,11 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) /* * In case of software exceptions, do not reinject the vector, - * but re-execute the instruction instead. Rewind RIP first - * if we emulated INT3 before. + * but re-execute the instruction instead. */ - if (kvm_exception_is_soft(vector)) { - if (vector == BP_VECTOR && int3_injected && - kvm_is_linear_rip(vcpu, svm->int3_rip)) - kvm_rip_write(vcpu, - kvm_rip_read(vcpu) - int3_injected); + if (kvm_exception_is_soft(vector)) break; - } + if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err = svm->vmcb->control.exit_int_info_err; kvm_requeue_exception_e(vcpu, vector, err);