From nobody Tue Dec 16 21:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB994EE49AB for ; Fri, 25 Aug 2023 01:37:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238688AbjHYBg7 (ORCPT ); Thu, 24 Aug 2023 21:36:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237330AbjHYBg1 (ORCPT ); Thu, 24 Aug 2023 21:36:27 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCA1B1707 for ; Thu, 24 Aug 2023 18:36:25 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id 98e67ed59e1d1-26f3fce5b0bso420265a91.2 for ; Thu, 24 Aug 2023 18:36:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692927385; x=1693532185; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=bJJ3epqDVWn/KgYpEj6yufH8AAy7yBUMi0zyuddHTI0=; b=XqOqBAKajc/Uga/xASsgoKffklBZQ5azzky229tcolshI77rjyjQMLre9b7dPzSIgj lVG4ew55uuC8R5nZ7nXg2b5A+L2qS52P9RfkYbnzcPJE/4NVnU4xH89WhtRpG4ofsstc uy27UmXSND3YGSD+LBGo/LIhYYA7XV1THT9iHEfQSmAqHdt/Y54W+Vl1lD6cDXhnd43Z UYCZeNDwkAIB7MM/GKjVgTCGdpX1j7846UcfyU2S6YP9AU+ERAsvIctRqa1lccR5EBbU se9PTfEaPArj+ryD0h9Kun/f8ZvK/Xso/s+fZ/k/hC7e3Lna8ETybEyMa2okbU1dH+vj qOAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692927385; x=1693532185; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=bJJ3epqDVWn/KgYpEj6yufH8AAy7yBUMi0zyuddHTI0=; b=EGGRWKB6gXANTwIc4dlCJfUM3A98Jt3iovNYHBJUhnwm2NIom4shbpOUH1lxwc4AgH efeg9v2guf8eRKVGhdCyc2EsQa2UaoPsIHhac4HvrsqNYYj6tAOqo//fULuH/MLAfH3I Jq0s4CO7/QV3WV5B7bsFOfCXdsx6c4bj7U4bKd7yn3EAWRQkWseHWTS8pND4SvhA9t+1 6pRHgLVmxMKhjWogAUQjFOqhyXPzrgJfXyZ0BD0w+n31Lth8gyK599pTUOSaNWggCv2v gRXGvIyym2uXau0usoxbQo3hPG7rQlqEf1O8kxK0wefpswD22np+OB1yX3rr8SxlfS1H B/cg== X-Gm-Message-State: AOJu0Yyz7VAXEH20c/Y9jEDF6JgTYDplWU0jwk3KOux1Lsb4E4lSnt9I bba7fyH4zc1EPL0/uh1G0aMXM42UrNU= X-Google-Smtp-Source: AGHT+IH1W88yr05UABQ3pKkKEY6GI4o4pwaiVeo9ubY08TwPWlJzGKO/s9Bw0wnhW3tjJB3QbnPgiKkjsFg= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:90b:383:b0:268:1d63:b9ae with SMTP id ga3-20020a17090b038300b002681d63b9aemr4281422pjb.3.1692927385357; Thu, 24 Aug 2023 18:36:25 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 24 Aug 2023 18:36:18 -0700 In-Reply-To: <20230825013621.2845700-1-seanjc@google.com> Mime-Version: 1.0 References: <20230825013621.2845700-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.rc2.253.gd59a3bf2b4-goog Message-ID: <20230825013621.2845700-2-seanjc@google.com> Subject: [PATCH v2 1/4] KVM: SVM: Don't inject #UD if KVM attempts to skip SEV guest insn From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Wu Zongyo , Tom Lendacky Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Don't inject a #UD if KVM attempts to "emulate" to skip an instruction for an SEV guest, and instead resume the guest and hope that it can make forward progress. When commit 04c40f344def ("KVM: SVM: Inject #UD on attempted emulation for SEV guest w/o insn buffer") added the completely arbitrary #UD behavior, there were no known scenarios where a well-behaved guest would induce a VM-Exit that triggered emulation, i.e. it was thought that injecting #UD would be helpful. However, now that KVM (correctly) attempts to re-inject INT3/INTO, e.g. if a #NPF is encountered when attempting to deliver the INT3/INTO, an SEV guest can trigger emulation without a buffer, through no fault of its own. Resuming the guest and retrying the INT3/INTO is architecturally wrong, e.g. the vCPU will incorrectly re-hit code #DBs, but for SEV guests there is literally no other option that has a chance of making forward progress. Drop the #UD injection for all "skip" emulation, not just those related to INT3/INTO, even though that means that the guest will likely end up in an infinite loop instead of getting a #UD (the vCPU may also crash, e.g. if KVM emulated everything about an instruction except for advancing RIP). There's no evidence that suggests that an unexpected #UD is actually better than hanging the vCPU, e.g. a soft-hung vCPU can still respond to IRQs and NMIs to generate a backtrace. Reported-by: Wu Zongyo Closes: https://lore.kernel.org/all/8eb933fd-2cf3-d7a9-32fe-2a1d82eac42a@ma= il.ustc.edu.cn Fixes: 6ef88d6e36c2 ("KVM: SVM: Re-inject INT3/INTO instead of retrying the= instruction") Cc: stable@vger.kernel.org Cc: Tom Lendacky Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index a139c626fa8b..bd53b2d497d0 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -364,6 +364,8 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *v= cpu, int mask) svm->vmcb->control.int_state |=3D SVM_INTERRUPT_SHADOW_MASK; =20 } +static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_ty= pe, + void *insn, int insn_len); =20 static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, bool commit_side_effects) @@ -384,6 +386,14 @@ static int __svm_skip_emulated_instruction(struct kvm_= vcpu *vcpu, } =20 if (!svm->next_rip) { + /* + * FIXME: Drop this when kvm_emulate_instruction() does the + * right thing and treats "can't emulate" as outright failure + * for EMULTYPE_SKIP. + */ + if (!svm_can_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0)) + return 0; + if (unlikely(!commit_side_effects)) old_rflags =3D svm->vmcb->save.rflags; =20 @@ -4724,16 +4734,25 @@ static bool svm_can_emulate_instruction(struct kvm_= vcpu *vcpu, int emul_type, * and cannot be decrypted by KVM, i.e. KVM would read cyphertext and * decode garbage. * - * Inject #UD if KVM reached this point without an instruction buffer. - * In practice, this path should never be hit by a well-behaved guest, - * e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path - * is still theoretically reachable, e.g. via unaccelerated fault-like - * AVIC access, and needs to be handled by KVM to avoid putting the - * guest into an infinite loop. Injecting #UD is somewhat arbitrary, - * but its the least awful option given lack of insight into the guest. + * If KVM is NOT trying to simply skip an instruction, inject #UD if + * KVM reached this point without an instruction buffer. In practice, + * this path should never be hit by a well-behaved guest, e.g. KVM + * doesn't intercept #UD or #GP for SEV guests, but this path is still + * theoretically reachable, e.g. via unaccelerated fault-like AVIC + * access, and needs to be handled by KVM to avoid putting the guest + * into an infinite loop. Injecting #UD is somewhat arbitrary, but + * its the least awful option given lack of insight into the guest. + * + * If KVM is trying to skip an instruction, simply resume the guest. + * If a #NPF occurs while the guest is vectoring an INT3/INTO, then KVM + * will attempt to re-inject the INT3/INTO and skip the instruction. + * In that scenario, retrying the INT3/INTO and hoping the guest will + * make forward progress is the only option that has a chance of + * success (and in practice it will work the vast majority of the time). */ if (unlikely(!insn)) { - kvm_queue_exception(vcpu, UD_VECTOR); + if (!(emul_type & EMULTYPE_SKIP)) + kvm_queue_exception(vcpu, UD_VECTOR); return false; } =20 --=20 2.42.0.rc2.253.gd59a3bf2b4-goog From nobody Tue Dec 16 21:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF143EE49A6 for ; Fri, 25 Aug 2023 01:37:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239024AbjHYBhB (ORCPT ); Thu, 24 Aug 2023 21:37:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237436AbjHYBga (ORCPT ); Thu, 24 Aug 2023 21:36:30 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C90BB1707 for ; Thu, 24 Aug 2023 18:36:27 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 41be03b00d2f7-56385c43eaeso490016a12.1 for ; Thu, 24 Aug 2023 18:36:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692927387; x=1693532187; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=772R3fhvb1hJ+WgPywPWa6C7fO5Csuzrt1s6mb5DckI=; b=X+2BvBC6u4TKcVZ++ZGwunu3SE65Gvh4sabEesPL6PDVApqC+rvcTGf9MqAe5Y0R8j kCtoXMGfOylqtra+yu8AUH9NLn53MMLo7SVFskt93r+TipgOuHS2ThDMKGqNmZHYLDqG WPpjG4amQ0WJAVueUBcuOtELYU/v0oZnVSOPO/LdOS8XYoWDYArMmi8I5xts5uYlYAxa JgVf+ItKSjpH1zRuYLCNvIFM+S+hwf6Vi9VPah2pochSNfNKPwek57C/GaAlTPaEDuAR 0758uex/2pgTcV41xNUVwWTCBLV+BNlR1H80eELH7Dek4kH5MJTGi+YqQ0oZ8qeTtQZi wwFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692927387; x=1693532187; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=772R3fhvb1hJ+WgPywPWa6C7fO5Csuzrt1s6mb5DckI=; b=ZRRGW/N0Hy0M5LnIENoSQ/YIZ4gRzi4Ea1M2Qv+5Tt6Vdd0J790yuJqQZiSL/WZaLw NWWBDvVdpNFCmptZEiPdKtGWExJhh87aBcKsoMx3WCqzx9e/Hlm3G7drhz00eOzRP2Yb vLaNGKkQHbKZrcr+PJZxKZdQpQQv0zgvvGK/dn6RJUb58FVkGLwtDDWbKkR64m315Bhh D2qgRwXTUcWk3I2PUQ8zp4xuEta4F6yqtImOtQTHoqbU4OxAh3uFWCAGJTNzjnL066rm Ljt0aL7uTLAJQitEAo1PPOwkjU6jQyjzBqXuwu4xS80n9khsx/3CrTU+37cRI8dsMRFu Q7CQ== X-Gm-Message-State: AOJu0YxCwxt7DPgptLKbKtUCgvev0KWM0msmEJbR4IPPh70Dn1lfXf9R o5GbPPHQdcmtDtnkgxyrNt5a2lRNl4I= X-Google-Smtp-Source: AGHT+IFDstNWi9yd4ZsrD/aOyXNKkLudrxgwtqrCjoQNo0eWK/ax8ovhPQNmwtRTJTChjIOU1w100912sTI= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a63:3383:0:b0:565:eb0b:626a with SMTP id z125-20020a633383000000b00565eb0b626amr2673084pgz.4.1692927387236; Thu, 24 Aug 2023 18:36:27 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 24 Aug 2023 18:36:19 -0700 In-Reply-To: <20230825013621.2845700-1-seanjc@google.com> Mime-Version: 1.0 References: <20230825013621.2845700-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.rc2.253.gd59a3bf2b4-goog Message-ID: <20230825013621.2845700-3-seanjc@google.com> Subject: [PATCH v2 2/4] KVM: SVM: Require nrips support for SEV guests (and beyond) From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Wu Zongyo , Tom Lendacky Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Disallow SEV (and beyond) if nrips is disabled via module param, as KVM can't read guest memory to partially emulate and skip an instruction. All CPUs that support SEV support NRIPS, i.e. this is purely stopping the user from shooting themselves in the foot. Cc: Tom Lendacky Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/sev.c | 2 +- arch/x86/kvm/svm/svm.c | 11 ++++------- arch/x86/kvm/svm/svm.h | 1 + 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 2cd15783dfb9..8ce9ffc8709e 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2185,7 +2185,7 @@ void __init sev_hardware_setup(void) bool sev_es_supported =3D false; bool sev_supported =3D false; =20 - if (!sev_enabled || !npt_enabled) + if (!sev_enabled || !npt_enabled || !nrips) goto out; =20 /* diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index bd53b2d497d0..b21253c9ceb4 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -202,7 +202,7 @@ static int nested =3D true; module_param(nested, int, S_IRUGO); =20 /* enable/disable Next RIP Save */ -static int nrips =3D true; +int nrips =3D true; module_param(nrips, int, 0444); =20 /* enable/disable Virtual VMLOAD VMSAVE */ @@ -5203,9 +5203,11 @@ static __init int svm_hardware_setup(void) =20 svm_adjust_mmio_mask(); =20 + nrips =3D nrips && boot_cpu_has(X86_FEATURE_NRIPS); + /* * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which - * may be modified by svm_adjust_mmio_mask()). + * may be modified by svm_adjust_mmio_mask()), as well as nrips. */ sev_hardware_setup(); =20 @@ -5217,11 +5219,6 @@ static __init int svm_hardware_setup(void) goto err; } =20 - if (nrips) { - if (!boot_cpu_has(X86_FEATURE_NRIPS)) - nrips =3D false; - } - enable_apicv =3D avic =3D avic && avic_hardware_setup(); =20 if (!enable_apicv) { diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 2237230aad98..860511276087 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -34,6 +34,7 @@ #define MSRPM_OFFSETS 32 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; extern bool npt_enabled; +extern int nrips; extern int vgif; extern bool intercept_smi; extern bool x2avic_enabled; --=20 2.42.0.rc2.253.gd59a3bf2b4-goog From nobody Tue Dec 16 21:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2ADFFEE49B0 for ; Fri, 25 Aug 2023 01:37:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239174AbjHYBhC (ORCPT ); Thu, 24 Aug 2023 21:37:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237552AbjHYBgc (ORCPT ); Thu, 24 Aug 2023 21:36:32 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C24291707 for ; Thu, 24 Aug 2023 18:36:29 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-1c09d82dfc7so5909935ad.0 for ; Thu, 24 Aug 2023 18:36:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692927389; x=1693532189; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=qFwlnRwlA9Pcgw83ghVUTUpUbTL5c6TrSmvpVeQlOSI=; b=rWMUp4+UZRDxcj/FmsFEl9Bny446asZs1yvFuXoyswCWJ9T/5fx5ZBm6RATp0dIw94 7vzK3yywp2QNRfP369DeuJKXr4U8PoQm+LM2wni4hix132hGgb4LRDsydTHr0P7nqhN8 MQoEsgyvE4gf3lYfqxwsSavu1HQzHoADCSBAJzxo1EjyLU4y8bLSHENPp9FfnduKmgXk wPpceH6jOlj6T11Azu71IqDuLVlq/LS+0OTpQfOWOxRHTa2ql5HHLQlH0pFWREhnqKFf UDTBHugVZjmByVpL3j/z1o28RbfipAuo4SgE4kBnalJWus3tLh8Rj9TBhS7QleDj66Va mX+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692927389; x=1693532189; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=qFwlnRwlA9Pcgw83ghVUTUpUbTL5c6TrSmvpVeQlOSI=; b=Bi3WREKIm13tocF8baZDgGh1l+K1RN7PqDsw2nZlycpqYPmkbyKZbuaL20XJ6nhZhL AjtnfIJwbiSmOltPE7iXk0rLsv0q899xAHXC+NdH/JYhuWusIAh4nONTPgeXnkzruS0b xDCqZQpEGEJusChhQaLgmrtsQlHaEQ9Y1ixx+/76NE2R0PImYR91I6QRKVK29/4X1rZO Dxzlfbm0Sr8OfPxL5S2R0ZdS25TDFcJOvp3NvKpgmh/Azt1P4YDs2sHiSzykb3lHlkyI lRsuInuliqpWOowtC8HJ6dpuLDnToG8peQS2Mw3WQ1fCiJttNk6ps71+t0hPAkjHJouh Bf1Q== X-Gm-Message-State: AOJu0Yym5o19JxxpA+R52hOEmSFrsu3MtthaNbqP/Hv/vQMgMuGiynw2 edUK5OAFUTA/2Nfo11unJrTBR+7NjHo= X-Google-Smtp-Source: AGHT+IH23uzGSC9Jib75RQ5v6ZuRbT3wj68jmFazJGmVBmw7Q73pT1lRHeuBZrNPglxYSWdNsE2nvNGUc8M= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:902:f683:b0:1bb:e7ce:17d9 with SMTP id l3-20020a170902f68300b001bbe7ce17d9mr7003860plg.6.1692927389308; Thu, 24 Aug 2023 18:36:29 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 24 Aug 2023 18:36:20 -0700 In-Reply-To: <20230825013621.2845700-1-seanjc@google.com> Mime-Version: 1.0 References: <20230825013621.2845700-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.rc2.253.gd59a3bf2b4-goog Message-ID: <20230825013621.2845700-4-seanjc@google.com> Subject: [PATCH v2 3/4] KVM: x86: Refactor can_emulate_instruction() return to be more expressive From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Wu Zongyo , Tom Lendacky Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Refactor and rename can_emulate_instruction() to allow vendor code to return more than true/false, e.g. to explicitly differentiate between "retry", "fault", and "unhandleable". For now, just do the plumbing, a future patch will expand SVM's implementation to signal outright failure if KVM attempts EMULTYPE_SKIP on an SEV guest. No functional change intended (or rather, none that are visible to the guest or userspace). Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm-x86-ops.h | 2 +- arch/x86/include/asm/kvm_host.h | 4 ++-- arch/x86/kvm/svm/svm.c | 31 ++++++++++++++++-------------- arch/x86/kvm/vmx/vmx.c | 12 ++++++------ arch/x86/kvm/x86.c | 15 +++++++++------ 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index 13bc212cd4bc..ac01552316e1 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -125,7 +125,7 @@ KVM_X86_OP_OPTIONAL(vm_copy_enc_context_from) KVM_X86_OP_OPTIONAL(vm_move_enc_context_from) KVM_X86_OP_OPTIONAL(guest_memory_reclaimed) KVM_X86_OP(get_msr_feature) -KVM_X86_OP(can_emulate_instruction) +KVM_X86_OP(check_emulate_instruction) KVM_X86_OP(apic_init_signal_blocked) KVM_X86_OP_OPTIONAL(enable_l2_tlb_flush) KVM_X86_OP_OPTIONAL(migrate_timers) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 9f57aa33798b..4760e60fad44 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1734,8 +1734,8 @@ struct kvm_x86_ops { =20 int (*get_msr_feature)(struct kvm_msr_entry *entry); =20 - bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, int emul_type, - void *insn, int insn_len); + int (*check_emulate_instruction)(struct kvm_vcpu *vcpu, int emul_type, + void *insn, int insn_len); =20 bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu); int (*enable_l2_tlb_flush)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b21253c9ceb4..39ce680013c4 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -364,8 +364,8 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *v= cpu, int mask) svm->vmcb->control.int_state |=3D SVM_INTERRUPT_SHADOW_MASK; =20 } -static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_ty= pe, - void *insn, int insn_len); +static int svm_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_t= ype, + void *insn, int insn_len); =20 static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, bool commit_side_effects) @@ -391,7 +391,7 @@ static int __svm_skip_emulated_instruction(struct kvm_v= cpu *vcpu, * right thing and treats "can't emulate" as outright failure * for EMULTYPE_SKIP. */ - if (!svm_can_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0)) + if (svm_check_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0) !=3D X86= EMUL_CONTINUE) return 0; =20 if (unlikely(!commit_side_effects)) @@ -4698,15 +4698,15 @@ static void svm_enable_smi_window(struct kvm_vcpu *= vcpu) } #endif =20 -static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_ty= pe, - void *insn, int insn_len) +static int svm_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_t= ype, + void *insn, int insn_len) { bool smep, smap, is_user; u64 error_code; =20 /* Emulation is always possible when KVM has access to all guest state. */ if (!sev_guest(vcpu->kvm)) - return true; + return X86EMUL_CONTINUE; =20 /* #UD and #GP should never be intercepted for SEV guests. */ WARN_ON_ONCE(emul_type & (EMULTYPE_TRAP_UD | @@ -4718,14 +4718,14 @@ static bool svm_can_emulate_instruction(struct kvm_= vcpu *vcpu, int emul_type, * to guest register state. */ if (sev_es_guest(vcpu->kvm)) - return false; + return X86EMUL_RETRY_INSTR; =20 /* * Emulation is possible if the instruction is already decoded, e.g. * when completing I/O after returning from userspace. */ if (emul_type & EMULTYPE_NO_DECODE) - return true; + return X86EMUL_CONTINUE; =20 /* * Emulation is possible for SEV guests if and only if a prefilled @@ -4751,9 +4751,11 @@ static bool svm_can_emulate_instruction(struct kvm_v= cpu *vcpu, int emul_type, * success (and in practice it will work the vast majority of the time). */ if (unlikely(!insn)) { - if (!(emul_type & EMULTYPE_SKIP)) - kvm_queue_exception(vcpu, UD_VECTOR); - return false; + if (emul_type & EMULTYPE_SKIP) + return X86EMUL_RETRY_INSTR; + + kvm_queue_exception(vcpu, UD_VECTOR); + return X86EMUL_PROPAGATE_FAULT; } =20 /* @@ -4764,7 +4766,7 @@ static bool svm_can_emulate_instruction(struct kvm_vc= pu *vcpu, int emul_type, * table used to translate CS:RIP resides in emulated MMIO. */ if (likely(insn_len)) - return true; + return X86EMUL_CONTINUE; =20 /* * Detect and workaround Errata 1096 Fam_17h_00_0Fh. @@ -4822,6 +4824,7 @@ static bool svm_can_emulate_instruction(struct kvm_vc= pu *vcpu, int emul_type, kvm_inject_gp(vcpu, 0); else kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); + return X86EMUL_PROPAGATE_FAULT; } =20 resume_guest: @@ -4839,7 +4842,7 @@ static bool svm_can_emulate_instruction(struct kvm_vc= pu *vcpu, int emul_type, * doesn't explicitly define "ignored", i.e. doing nothing and letting * the guest spin is technically "ignoring" the access. */ - return false; + return X86EMUL_RETRY_INSTR; } =20 static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu) @@ -4998,7 +5001,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata =3D { .vm_copy_enc_context_from =3D sev_vm_copy_enc_context_from, .vm_move_enc_context_from =3D sev_vm_move_enc_context_from, =20 - .can_emulate_instruction =3D svm_can_emulate_instruction, + .check_emulate_instruction =3D svm_check_emulate_instruction, =20 .apic_init_signal_blocked =3D svm_apic_init_signal_blocked, =20 diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e6849f780dba..2d4a80c406cb 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1642,8 +1642,8 @@ static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, = u64 data) return 0; } =20 -static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_ty= pe, - void *insn, int insn_len) +static int vmx_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_t= ype, + void *insn, int insn_len) { /* * Emulation of instructions in SGX enclaves is impossible as RIP does @@ -1654,9 +1654,9 @@ static bool vmx_can_emulate_instruction(struct kvm_vc= pu *vcpu, int emul_type, */ if (to_vmx(vcpu)->exit_reason.enclave_mode) { kvm_queue_exception(vcpu, UD_VECTOR); - return false; + return X86EMUL_PROPAGATE_FAULT; } - return true; + return X86EMUL_CONTINUE; } =20 static int skip_emulated_instruction(struct kvm_vcpu *vcpu) @@ -5770,7 +5770,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu) { gpa_t gpa; =20 - if (!vmx_can_emulate_instruction(vcpu, EMULTYPE_PF, NULL, 0)) + if (vmx_check_emulate_instruction(vcpu, EMULTYPE_PF, NULL, 0)) return 1; =20 /* @@ -8317,7 +8317,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata =3D { .enable_smi_window =3D vmx_enable_smi_window, #endif =20 - .can_emulate_instruction =3D vmx_can_emulate_instruction, + .check_emulate_instruction =3D vmx_check_emulate_instruction, .apic_init_signal_blocked =3D vmx_apic_init_signal_blocked, .migrate_timers =3D vmx_migrate_timers, =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e4a939471df1..f897d582d560 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7458,11 +7458,11 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vc= pu, gva_t addr, void *val, } EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); =20 -static int kvm_can_emulate_insn(struct kvm_vcpu *vcpu, int emul_type, - void *insn, int insn_len) +static int kvm_check_emulate_insn(struct kvm_vcpu *vcpu, int emul_type, + void *insn, int insn_len) { - return static_call(kvm_x86_can_emulate_instruction)(vcpu, emul_type, - insn, insn_len); + return static_call(kvm_x86_check_emulate_instruction)(vcpu, emul_type, + insn, insn_len); } =20 int handle_ud(struct kvm_vcpu *vcpu) @@ -7472,8 +7472,10 @@ int handle_ud(struct kvm_vcpu *vcpu) int emul_type =3D EMULTYPE_TRAP_UD; char sig[5]; /* ud2; .ascii "kvm" */ struct x86_exception e; + int r; =20 - if (unlikely(!kvm_can_emulate_insn(vcpu, emul_type, NULL, 0))) + r =3D kvm_check_emulate_insn(vcpu, emul_type, NULL, 0); + if (r !=3D X86EMUL_CONTINUE) return 1; =20 if (fep_flags && @@ -8855,7 +8857,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gp= a_t cr2_or_gpa, struct x86_emulate_ctxt *ctxt =3D vcpu->arch.emulate_ctxt; bool writeback =3D true; =20 - if (unlikely(!kvm_can_emulate_insn(vcpu, emulation_type, insn, insn_len))) + r =3D kvm_check_emulate_insn(vcpu, emulation_type, insn, insn_len); + if (r !=3D X86EMUL_CONTINUE) return 1; =20 vcpu->arch.l1tf_flush_l1d =3D true; --=20 2.42.0.rc2.253.gd59a3bf2b4-goog From nobody Tue Dec 16 21:51:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DC7CEE49B4 for ; Fri, 25 Aug 2023 01:37:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239257AbjHYBhE (ORCPT ); Thu, 24 Aug 2023 21:37:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237659AbjHYBgd (ORCPT ); Thu, 24 Aug 2023 21:36:33 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF8C81707 for ; Thu, 24 Aug 2023 18:36:31 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-1c08a3f7270so6562615ad.0 for ; Thu, 24 Aug 2023 18:36:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692927391; x=1693532191; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=+tFz1o5VJHJBHmwn/iad/HpnjqcKBaGzo/qVU/9dboU=; b=vWt2oom3hr+D86HKSrfN8337aaRbh074j5hyYZl3XQsnBmAl5OwUOzWvZDMFGnkWgS FaV9zOdk4XvEtYn7uIqNZ3mfAjHHOQzCmJVtGhxbLV8rIeZ4U5MKXtgqUOxC3gbUAXSt WJAG9rRCPt2Of204Fm54E1Fwk/TUDzjjw9wjmTF+ytgxEyFL8fBEUzot3zHsE1NLHw3v QQDEoo0847v0PekukiJSX7pwpa+/aYcRActdANx1OKoKhn99u912ITeo6OzXx8TC8PQj IDvFk/LaRCiUTRpXafKC2cVHlzCfPJMhEu2Wia2/d3FmjA2iaFQKmPrDdpzcMRgguySg Gurw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692927391; x=1693532191; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=+tFz1o5VJHJBHmwn/iad/HpnjqcKBaGzo/qVU/9dboU=; b=k5iG/FQ2sB3rGxtNdAF1PoaJXNkzltnjYyBhjvfGKHfela+1HMgkri2DdsQl6jR+2Q tiuMQx2Cx08i9Vf0ikZ0vIcC7oFy2Z+zrJKwQ/o25m2PivEbZI7Ve7IQbqGox/nthBaj LlhJscSRE26SGdAupkQlteo4xdfBN4MkOwwiG35+eD/lyRtesd5EPhQAatg8imFIfq8J i1vhDWE3t+BSlYlPyYIVpVz012m8+8hfH6k9eA7KBBPg1HRemD53r8Wnyg40GZjrSwPj mkrQQVaV433YmV57b3gtj5RFqo5o0ZAuxnKRowXxNzjXuaAFYmMfGP8qYT8aFnrdp3pS uPxA== X-Gm-Message-State: AOJu0YzgOH5mYuA9gwjnpTHJ8a67BuuNUB/LDcycfxvoRcKY07eW7QFz 2X0b2TtEIq11pIWBU2QUkFKIiEv0bcs= X-Google-Smtp-Source: AGHT+IGb6VGxHTuQim1r0jy/sw1CsKGKO85abRuuyUKHLgMrhFUgcxxcFnyqGJ+Mkz4m4hrKo8Eqmwn9wBU= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:903:32ce:b0:1bf:610d:2be3 with SMTP id i14-20020a17090332ce00b001bf610d2be3mr7577973plr.13.1692927391341; Thu, 24 Aug 2023 18:36:31 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 24 Aug 2023 18:36:21 -0700 In-Reply-To: <20230825013621.2845700-1-seanjc@google.com> Mime-Version: 1.0 References: <20230825013621.2845700-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.rc2.253.gd59a3bf2b4-goog Message-ID: <20230825013621.2845700-5-seanjc@google.com> Subject: [PATCH v2 4/4] KVM: SVM: Treat all "skip" emulation for SEV guests as outright failures From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Wu Zongyo , Tom Lendacky Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Treat EMULTYPE_SKIP failures on SEV guests as unhandleable emulation instead of simply resuming the guest, and drop the hack-a-fix which effects that behavior for the INT3/INTO injection path. If KVM can't skip an instruction for which KVM has already done partial emulation, resuming the guest is undesirable as doing so may corrupt guest state. Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 12 +----------- arch/x86/kvm/x86.c | 9 +++++++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 39ce680013c4..fc2cd5585349 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -364,8 +364,6 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *v= cpu, int mask) svm->vmcb->control.int_state |=3D SVM_INTERRUPT_SHADOW_MASK; =20 } -static int svm_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_t= ype, - void *insn, int insn_len); =20 static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, bool commit_side_effects) @@ -386,14 +384,6 @@ static int __svm_skip_emulated_instruction(struct kvm_= vcpu *vcpu, } =20 if (!svm->next_rip) { - /* - * FIXME: Drop this when kvm_emulate_instruction() does the - * right thing and treats "can't emulate" as outright failure - * for EMULTYPE_SKIP. - */ - if (svm_check_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0) !=3D X86= EMUL_CONTINUE) - return 0; - if (unlikely(!commit_side_effects)) old_rflags =3D svm->vmcb->save.rflags; =20 @@ -4752,7 +4742,7 @@ static int svm_check_emulate_instruction(struct kvm_v= cpu *vcpu, int emul_type, */ if (unlikely(!insn)) { if (emul_type & EMULTYPE_SKIP) - return X86EMUL_RETRY_INSTR; + return X86EMUL_UNHANDLEABLE; =20 kvm_queue_exception(vcpu, UD_VECTOR); return X86EMUL_PROPAGATE_FAULT; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f897d582d560..1f4a8fbc5390 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8858,8 +8858,13 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, g= pa_t cr2_or_gpa, bool writeback =3D true; =20 r =3D kvm_check_emulate_insn(vcpu, emulation_type, insn, insn_len); - if (r !=3D X86EMUL_CONTINUE) - return 1; + if (r !=3D X86EMUL_CONTINUE) { + if (r =3D=3D X86EMUL_RETRY_INSTR || r =3D=3D X86EMUL_PROPAGATE_FAULT) + return 1; + + WARN_ON_ONCE(r !=3D X86EMUL_UNHANDLEABLE); + return handle_emulation_failure(vcpu, emulation_type); + } =20 vcpu->arch.l1tf_flush_l1d =3D true; =20 --=20 2.42.0.rc2.253.gd59a3bf2b4-goog