public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent
@ 2025-11-21 20:47 Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0 Yosry Ahmed
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Yosry Ahmed @ 2025-11-21 20:47 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Jim Mattson, kvm, linux-kernel, Yosry Ahmed

Clearing EFER.SVME is not architected to set GIF, so GIF may be clear
even when EFER.SVME is clear.

This is covered in the discussion at [1].

v2 -> v3:
- Keep setting GIF when force-leaving nested (Sean).
- Moved the relevant selftests patches from the series at [2] here
  (Sean).

v2: https://lore.kernel.org/kvm/20251009223153.3344555-1-jmattson@google.com/

[1]https://lore.kernel.org/all/5b8787b8-16e9-13dc-7fca-0dc441d673f9@citrix.com/
[2]https://lore.kernel.org/kvm/20251021074736.1324328-1-yosry.ahmed@linux.dev/

Jim Mattson (2):
  KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
  KVM: SVM: Don't set GIF when clearing EFER.SVME

Yosry Ahmed (2):
  KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state()
  KVM: selftests: Extend vmx_set_nested_state_test to cover SVM

 arch/x86/kvm/svm/nested.c                     |   6 +-
 arch/x86/kvm/svm/svm.c                        |   1 -
 tools/testing/selftests/kvm/Makefile.kvm      |   2 +-
 ...d_state_test.c => nested_set_state_test.c} | 128 ++++++++++++++++--
 4 files changed, 120 insertions(+), 17 deletions(-)
 rename tools/testing/selftests/kvm/x86/{vmx_set_nested_state_test.c => nested_set_state_test.c} (70%)


base-commit: 115d5de2eef32ac5cd488404b44b38789362dbe6
-- 
2.52.0.rc2.455.g230fcf2819-goog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
  2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
@ 2025-11-21 20:48 ` Yosry Ahmed
  2026-01-08 18:58   ` Sean Christopherson
  2025-11-21 20:48 ` [PATCH v3 2/4] KVM: SVM: Don't set GIF when clearing EFER.SVME Yosry Ahmed
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Yosry Ahmed @ 2025-11-21 20:48 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Jim Mattson, kvm, linux-kernel, Yosry Ahmed

From: Jim Mattson <jmattson@google.com>

GIF==0 together with EFER.SVME==0 is a valid architectural
state. Don't return -EINVAL for KVM_SET_NESTED_STATE when this
combination is specified.

Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 arch/x86/kvm/svm/nested.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index c81005b24522..3e4bd8d69788 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1784,8 +1784,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
 	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
 	 */
 	if (!(vcpu->arch.efer & EFER_SVME)) {
-		/* GIF=1 and no guest mode are required if SVME=0.  */
-		if (kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
+		/* GUEST_MODE must be clear when SVME==0 */
+		if (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)
 			return -EINVAL;
 	}
 
-- 
2.52.0.rc2.455.g230fcf2819-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/4] KVM: SVM: Don't set GIF when clearing EFER.SVME
  2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0 Yosry Ahmed
@ 2025-11-21 20:48 ` Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 3/4] KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state() Yosry Ahmed
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Yosry Ahmed @ 2025-11-21 20:48 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Jim Mattson, kvm, linux-kernel, Yosry Ahmed

From: Jim Mattson <jmattson@google.com>

Clearing EFER.SVME is not architected to set GIF. Don't set GIF when
emulating a change to EFER that clears EFER.SVME.

However, keep setting GIF if clearing EFER.SVME causes force-leaving the
nested guest through svm_leave_nested(), to maintain a sane behavior of
not leaving GIF cleared after exiting the guest.  In every other path,
setting GIF is either correct/desirable, or irrelevant because the
caller immediately and unconditionally sets/clears GIF.

This is more-or-less KVM defining HW behavior, but leaving GIF cleared
would also be defining HW behavior anyway.

Note that if force-leaving the nested guest is considered a SHUTDOWN,
then this could violate the APM-specified behavior:

  If the processor enters the shutdown state (due to a triple fault for
  instance) while GIF is clear, it can only be restarted by means of a
  RESET.

However, a SHUTDOWN leaves the VMCB undefined, so there's not a lot that
KVM can do in this case. Also, if vGIF is enabled on SHUTDOWN, KVM has
no way of finding out of GIF was cleared.

The only way for KVM to handle this without making up HW behavior is to
completely terminate the VM, so settle for doing the relatively "sane"
thing of setting GIF when force-leaving nested.

Fixes: c513f484c558 ("KVM: nSVM: leave guest mode when clearing EFER.SVME")
Signed-off-by: Jim Mattson <jmattson@google.com>
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
[yosry.ahmed: stitched together jmattson's patch and seanjc's diff]
Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 arch/x86/kvm/svm/nested.c | 2 ++
 arch/x86/kvm/svm/svm.c    | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index 3e4bd8d69788..9f91272fb735 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1363,6 +1363,8 @@ void svm_leave_nested(struct kvm_vcpu *vcpu)
 		nested_svm_uninit_mmu_context(vcpu);
 		vmcb_mark_all_dirty(svm->vmcb);
 
+		svm_set_gif(svm, true);
+
 		if (kvm_apicv_activated(vcpu->kvm))
 			kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
 	}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index f56c2d895011..f62e94b404f4 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -215,7 +215,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
 	if ((old_efer & EFER_SVME) != (efer & EFER_SVME)) {
 		if (!(efer & EFER_SVME)) {
 			svm_leave_nested(vcpu);
-			svm_set_gif(svm, true);
 			/* #GP intercept is still needed for vmware backdoor */
 			if (!enable_vmware_backdoor)
 				clr_exception_intercept(svm, GP_VECTOR);
-- 
2.52.0.rc2.455.g230fcf2819-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/4] KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state()
  2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0 Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 2/4] KVM: SVM: Don't set GIF when clearing EFER.SVME Yosry Ahmed
@ 2025-11-21 20:48 ` Yosry Ahmed
  2025-11-21 20:48 ` [PATCH v3 4/4] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM Yosry Ahmed
  2026-01-12 17:39 ` [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Sean Christopherson
  4 siblings, 0 replies; 9+ messages in thread
From: Yosry Ahmed @ 2025-11-21 20:48 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Jim Mattson, kvm, linux-kernel, Yosry Ahmed

The assert messages do not add much value, so use TEST_ASSERT_EQ(),
which also nicely displays the addresses in hex. While at it, also
assert the values of state->flags.

Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
index 67a62a5a8895..b59a8a17084d 100644
--- a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
@@ -241,8 +241,10 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu)
 	TEST_ASSERT(state->size >= sizeof(*state) && state->size <= state_sz,
 		    "Size must be between %ld and %d.  The size returned was %d.",
 		    sizeof(*state), state_sz, state->size);
-	TEST_ASSERT(state->hdr.vmx.vmxon_pa == -1ull, "vmxon_pa must be -1ull.");
-	TEST_ASSERT(state->hdr.vmx.vmcs12_pa == -1ull, "vmcs_pa must be -1ull.");
+
+	TEST_ASSERT_EQ(state->hdr.vmx.vmxon_pa, -1ull);
+	TEST_ASSERT_EQ(state->hdr.vmx.vmcs12_pa, -1ull);
+	TEST_ASSERT_EQ(state->flags, 0);
 
 	free(state);
 }
-- 
2.52.0.rc2.455.g230fcf2819-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/4] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM
  2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
                   ` (2 preceding siblings ...)
  2025-11-21 20:48 ` [PATCH v3 3/4] KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state() Yosry Ahmed
@ 2025-11-21 20:48 ` Yosry Ahmed
  2026-01-12 17:39 ` [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Sean Christopherson
  4 siblings, 0 replies; 9+ messages in thread
From: Yosry Ahmed @ 2025-11-21 20:48 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Jim Mattson, kvm, linux-kernel, Yosry Ahmed

Add test cases for the validation checks in svm_set_nested_state(), and
allow the test to run with SVM as well as VMX. The SVM test also makes
sure that KVM_SET_NESTED_STATE accepts GIF being set or cleared if
EFER.SVME is cleared, verifying a recently fixed bug where GIF was
incorrectly expected to always be set when EFER.SVME is cleared.

Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 tools/testing/selftests/kvm/Makefile.kvm      |   2 +-
 ...d_state_test.c => nested_set_state_test.c} | 122 ++++++++++++++++--
 2 files changed, 112 insertions(+), 12 deletions(-)
 rename tools/testing/selftests/kvm/x86/{vmx_set_nested_state_test.c => nested_set_state_test.c} (71%)

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 7ebf30a87a2b..7567c936202f 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -92,6 +92,7 @@ TEST_GEN_PROGS_x86 += x86/nested_close_kvm_test
 TEST_GEN_PROGS_x86 += x86/nested_emulation_test
 TEST_GEN_PROGS_x86 += x86/nested_exceptions_test
 TEST_GEN_PROGS_x86 += x86/nested_invalid_cr3_test
+TEST_GEN_PROGS_x86 += x86/nested_set_state_test
 TEST_GEN_PROGS_x86 += x86/nested_tsc_adjust_test
 TEST_GEN_PROGS_x86 += x86/nested_tsc_scaling_test
 TEST_GEN_PROGS_x86 += x86/platform_info_test
@@ -120,7 +121,6 @@ TEST_GEN_PROGS_x86 += x86/vmx_exception_with_invalid_guest_state
 TEST_GEN_PROGS_x86 += x86/vmx_msrs_test
 TEST_GEN_PROGS_x86 += x86/vmx_invalid_nested_guest_state
 TEST_GEN_PROGS_x86 += x86/vmx_nested_la57_state_test
-TEST_GEN_PROGS_x86 += x86/vmx_set_nested_state_test
 TEST_GEN_PROGS_x86 += x86/apic_bus_clock_test
 TEST_GEN_PROGS_x86 += x86/xapic_ipi_test
 TEST_GEN_PROGS_x86 += x86/xapic_state_test
diff --git a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86/nested_set_state_test.c
similarity index 71%
rename from tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
rename to tools/testing/selftests/kvm/x86/nested_set_state_test.c
index b59a8a17084d..0f2102b43629 100644
--- a/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_set_state_test.c
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * vmx_set_nested_state_test
- *
  * Copyright (C) 2019, Google LLC.
  *
  * This test verifies the integrity of calling the ioctl KVM_SET_NESTED_STATE.
@@ -11,6 +9,7 @@
 #include "kvm_util.h"
 #include "processor.h"
 #include "vmx.h"
+#include "svm_util.h"
 
 #include <errno.h>
 #include <linux/kvm.h>
@@ -249,6 +248,104 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu)
 	free(state);
 }
 
+static void vcpu_efer_enable_svm(struct kvm_vcpu *vcpu)
+{
+	uint64_t old_efer = vcpu_get_msr(vcpu, MSR_EFER);
+
+	vcpu_set_msr(vcpu, MSR_EFER, old_efer | EFER_SVME);
+}
+
+static void vcpu_efer_disable_svm(struct kvm_vcpu *vcpu)
+{
+	uint64_t old_efer = vcpu_get_msr(vcpu, MSR_EFER);
+
+	vcpu_set_msr(vcpu, MSR_EFER, old_efer & ~EFER_SVME);
+}
+
+void set_default_svm_state(struct kvm_nested_state *state, int size)
+{
+	memset(state, 0, size);
+	state->format = 1;
+	state->size = size;
+	state->hdr.svm.vmcb_pa = 0x3000;
+}
+
+void test_svm_nested_state(struct kvm_vcpu *vcpu)
+{
+	/* Add a page for VMCB. */
+	const int state_sz = sizeof(struct kvm_nested_state) + getpagesize();
+	struct kvm_nested_state *state =
+		(struct kvm_nested_state *)malloc(state_sz);
+
+	vcpu_set_cpuid_feature(vcpu, X86_FEATURE_SVM);
+
+	/* The format must be set to 1. 0 for VMX, 1 for SVM. */
+	set_default_svm_state(state, state_sz);
+	state->format = 0;
+	test_nested_state_expect_einval(vcpu, state);
+
+	/* Invalid flags are rejected, KVM_STATE_NESTED_EVMCS is VMX-only  */
+	set_default_svm_state(state, state_sz);
+	state->flags = KVM_STATE_NESTED_EVMCS;
+	test_nested_state_expect_einval(vcpu, state);
+
+	/*
+	 * If EFER.SVME is clear, guest mode is disallowed and GIF can be set or
+	 * cleared.
+	 */
+	vcpu_efer_disable_svm(vcpu);
+
+	set_default_svm_state(state, state_sz);
+	state->flags = KVM_STATE_NESTED_GUEST_MODE;
+	test_nested_state_expect_einval(vcpu, state);
+
+	state->flags = 0;
+	test_nested_state(vcpu, state);
+
+	state->flags = KVM_STATE_NESTED_GIF_SET;
+	test_nested_state(vcpu, state);
+
+	/* Enable SVM in the guest EFER. */
+	vcpu_efer_enable_svm(vcpu);
+
+	/* Setting vmcb_pa to a non-aligned address is only fine when not entering guest mode */
+	set_default_svm_state(state, state_sz);
+	state->hdr.svm.vmcb_pa = -1ull;
+	state->flags = 0;
+	test_nested_state(vcpu, state);
+	state->flags = KVM_STATE_NESTED_GUEST_MODE;
+	test_nested_state_expect_einval(vcpu, state);
+
+	/*
+	 * Size must be large enough to fit kvm_nested_state and VMCB
+	 * only when entering guest mode.
+	 */
+	set_default_svm_state(state, state_sz/2);
+	state->flags = 0;
+	test_nested_state(vcpu, state);
+	state->flags = KVM_STATE_NESTED_GUEST_MODE;
+	test_nested_state_expect_einval(vcpu, state);
+
+	/*
+	 * Test that if we leave nesting the state reflects that when we get it
+	 * again, except for vmcb_pa, which is always returned as 0 when not in
+	 * guest mode.
+	 */
+	set_default_svm_state(state, state_sz);
+	state->hdr.svm.vmcb_pa = -1ull;
+	state->flags = KVM_STATE_NESTED_GIF_SET;
+	test_nested_state(vcpu, state);
+	vcpu_nested_state_get(vcpu, state);
+	TEST_ASSERT(state->size >= sizeof(*state) && state->size <= state_sz,
+		    "Size must be between %ld and %d.  The size returned was %d.",
+		    sizeof(*state), state_sz, state->size);
+
+	TEST_ASSERT_EQ(state->hdr.svm.vmcb_pa, 0);
+	TEST_ASSERT_EQ(state->flags, KVM_STATE_NESTED_GIF_SET);
+
+	free(state);
+}
+
 int main(int argc, char *argv[])
 {
 	struct kvm_vm *vm;
@@ -257,20 +354,20 @@ int main(int argc, char *argv[])
 
 	have_evmcs = kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS);
 
+	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) ||
+		     kvm_cpu_has(X86_FEATURE_SVM));
 	TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE));
 
-	/*
-	 * AMD currently does not implement set_nested_state, so for now we
-	 * just early out.
-	 */
-	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
-
 	vm = vm_create_with_one_vcpu(&vcpu, NULL);
 
 	/*
-	 * First run tests with VMX disabled to check error handling.
+	 * First run tests with VMX/SVM disabled to check error handling.
+	 * test_{vmx/svm}_nested_state() will re-enable as needed.
 	 */
-	vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_VMX);
+	if (kvm_cpu_has(X86_FEATURE_VMX))
+		vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_VMX);
+	else
+		vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_SVM);
 
 	/* Passing a NULL kvm_nested_state causes a EFAULT. */
 	test_nested_state_expect_efault(vcpu, NULL);
@@ -299,7 +396,10 @@ int main(int argc, char *argv[])
 	state.flags = KVM_STATE_NESTED_RUN_PENDING;
 	test_nested_state_expect_einval(vcpu, &state);
 
-	test_vmx_nested_state(vcpu);
+	if (kvm_cpu_has(X86_FEATURE_VMX))
+		test_vmx_nested_state(vcpu);
+	else
+		test_svm_nested_state(vcpu);
 
 	kvm_vm_free(vm);
 	return 0;
-- 
2.52.0.rc2.455.g230fcf2819-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
  2025-11-21 20:48 ` [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0 Yosry Ahmed
@ 2026-01-08 18:58   ` Sean Christopherson
  2026-01-08 20:38     ` Yosry Ahmed
  0 siblings, 1 reply; 9+ messages in thread
From: Sean Christopherson @ 2026-01-08 18:58 UTC (permalink / raw)
  To: Yosry Ahmed; +Cc: Paolo Bonzini, Jim Mattson, kvm, linux-kernel

On Fri, Nov 21, 2025, Yosry Ahmed wrote:
> From: Jim Mattson <jmattson@google.com>
> 
> GIF==0 together with EFER.SVME==0 is a valid architectural
> state. Don't return -EINVAL for KVM_SET_NESTED_STATE when this
> combination is specified.
> 
> Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
> Signed-off-by: Jim Mattson <jmattson@google.com>
> Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> ---
>  arch/x86/kvm/svm/nested.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index c81005b24522..3e4bd8d69788 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -1784,8 +1784,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
>  	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
>  	 */
>  	if (!(vcpu->arch.efer & EFER_SVME)) {
> -		/* GIF=1 and no guest mode are required if SVME=0.  */
> -		if (kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
> +		/* GUEST_MODE must be clear when SVME==0 */
> +		if (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)

Hmm, this is technically wrong, as it will allow KVM_STATE_NESTED_RUN_PENDING.
Now, arguably KVM already has a flaw there as KVM allows KVM_STATE_NESTED_RUN_PENDING
without KVM_STATE_NESTED_GUEST_MODE for SVME=1, but I'd prefer not to make the
hole bigger.

The nested if-statement is also unnecessary.

How about this instead?  (not yet tested)

	/*
	 * If in guest mode, vcpu->arch.efer actually refers to the L2 guest's
	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
	 * If SVME is disabled, the only valid states are "none" and GIF=1
	 * (clearing SVME does NOT set GIF, i.e. GIF=0 is allowed).
	 */
	if (!(vcpu->arch.efer & EFER_SVME) && kvm_state->flags &&
	    kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
		return -EINVAL;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
  2026-01-08 18:58   ` Sean Christopherson
@ 2026-01-08 20:38     ` Yosry Ahmed
  2026-01-08 22:17       ` Sean Christopherson
  0 siblings, 1 reply; 9+ messages in thread
From: Yosry Ahmed @ 2026-01-08 20:38 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Paolo Bonzini, Jim Mattson, kvm, linux-kernel

On Thu, Jan 08, 2026 at 10:58:40AM -0800, Sean Christopherson wrote:
> On Fri, Nov 21, 2025, Yosry Ahmed wrote:
> > From: Jim Mattson <jmattson@google.com>
> > 
> > GIF==0 together with EFER.SVME==0 is a valid architectural
> > state. Don't return -EINVAL for KVM_SET_NESTED_STATE when this
> > combination is specified.
> > 
> > Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
> > Signed-off-by: Jim Mattson <jmattson@google.com>
> > Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > ---
> >  arch/x86/kvm/svm/nested.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> > index c81005b24522..3e4bd8d69788 100644
> > --- a/arch/x86/kvm/svm/nested.c
> > +++ b/arch/x86/kvm/svm/nested.c
> > @@ -1784,8 +1784,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
> >  	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
> >  	 */
> >  	if (!(vcpu->arch.efer & EFER_SVME)) {
> > -		/* GIF=1 and no guest mode are required if SVME=0.  */
> > -		if (kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
> > +		/* GUEST_MODE must be clear when SVME==0 */
> > +		if (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)
> 
> Hmm, this is technically wrong, as it will allow KVM_STATE_NESTED_RUN_PENDING.
> Now, arguably KVM already has a flaw there as KVM allows KVM_STATE_NESTED_RUN_PENDING
> without KVM_STATE_NESTED_GUEST_MODE for SVME=1, but I'd prefer not to make the
> hole bigger.
> 
> The nested if-statement is also unnecessary.
> 
> How about this instead?  (not yet tested)
> 
> 	/*
> 	 * If in guest mode, vcpu->arch.efer actually refers to the L2 guest's
> 	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
> 	 * If SVME is disabled, the only valid states are "none" and GIF=1
> 	 * (clearing SVME does NOT set GIF, i.e. GIF=0 is allowed).
> 	 */
> 	if (!(vcpu->arch.efer & EFER_SVME) && kvm_state->flags &&
> 	    kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
> 		return -EINVAL;

Looks good to me, with the tiny exception that at this point clearing
SVME does set GIF. Maybe re-order the patches?

Let me know if you want me to send a new version or if you'll fix it up
while applying.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
  2026-01-08 20:38     ` Yosry Ahmed
@ 2026-01-08 22:17       ` Sean Christopherson
  0 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2026-01-08 22:17 UTC (permalink / raw)
  To: Yosry Ahmed; +Cc: Paolo Bonzini, Jim Mattson, kvm, linux-kernel

On Thu, Jan 08, 2026, Yosry Ahmed wrote:
> On Thu, Jan 08, 2026 at 10:58:40AM -0800, Sean Christopherson wrote:
> > On Fri, Nov 21, 2025, Yosry Ahmed wrote:
> > > From: Jim Mattson <jmattson@google.com>
> > > 
> > > GIF==0 together with EFER.SVME==0 is a valid architectural
> > > state. Don't return -EINVAL for KVM_SET_NESTED_STATE when this
> > > combination is specified.
> > > 
> > > Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
> > > Signed-off-by: Jim Mattson <jmattson@google.com>
> > > Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > > Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > > ---
> > >  arch/x86/kvm/svm/nested.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> > > index c81005b24522..3e4bd8d69788 100644
> > > --- a/arch/x86/kvm/svm/nested.c
> > > +++ b/arch/x86/kvm/svm/nested.c
> > > @@ -1784,8 +1784,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
> > >  	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
> > >  	 */
> > >  	if (!(vcpu->arch.efer & EFER_SVME)) {
> > > -		/* GIF=1 and no guest mode are required if SVME=0.  */
> > > -		if (kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
> > > +		/* GUEST_MODE must be clear when SVME==0 */
> > > +		if (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)
> > 
> > Hmm, this is technically wrong, as it will allow KVM_STATE_NESTED_RUN_PENDING.
> > Now, arguably KVM already has a flaw there as KVM allows KVM_STATE_NESTED_RUN_PENDING
> > without KVM_STATE_NESTED_GUEST_MODE for SVME=1, but I'd prefer not to make the
> > hole bigger.
> > 
> > The nested if-statement is also unnecessary.
> > 
> > How about this instead?  (not yet tested)
> > 
> > 	/*
> > 	 * If in guest mode, vcpu->arch.efer actually refers to the L2 guest's
> > 	 * EFER.SVME, but EFER.SVME still has to be 1 for VMRUN to succeed.
> > 	 * If SVME is disabled, the only valid states are "none" and GIF=1
> > 	 * (clearing SVME does NOT set GIF, i.e. GIF=0 is allowed).
> > 	 */
> > 	if (!(vcpu->arch.efer & EFER_SVME) && kvm_state->flags &&
> > 	    kvm_state->flags != KVM_STATE_NESTED_GIF_SET)
> > 		return -EINVAL;
> 
> Looks good to me, with the tiny exception that at this point clearing
> SVME does set GIF. Maybe re-order the patches?
> 
> Let me know if you want me to send a new version or if you'll fix it up
> while applying.

No need for a new version.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent
  2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
                   ` (3 preceding siblings ...)
  2025-11-21 20:48 ` [PATCH v3 4/4] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM Yosry Ahmed
@ 2026-01-12 17:39 ` Sean Christopherson
  4 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2026-01-12 17:39 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini, Yosry Ahmed
  Cc: Jim Mattson, kvm, linux-kernel

On Fri, 21 Nov 2025 20:47:59 +0000, Yosry Ahmed wrote:
> Clearing EFER.SVME is not architected to set GIF, so GIF may be clear
> even when EFER.SVME is clear.
> 
> This is covered in the discussion at [1].
> 
> v2 -> v3:
> - Keep setting GIF when force-leaving nested (Sean).
> - Moved the relevant selftests patches from the series at [2] here
>   (Sean).
> 
> [...]

Applied to kvm-x86 svm, with my suggested fixup and the order of 1 and 2
swapped.  Thanks!

[1/4] KVM: SVM: Don't set GIF when clearing EFER.SVME
      https://github.com/kvm-x86/linux/commit/8312f1b9dd71
[2/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0
      https://github.com/kvm-x86/linux/commit/6f4d3ebc24c6
[3/4] KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state()
      https://github.com/kvm-x86/linux/commit/bda6ae6f2966
[4/4] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM
      https://github.com/kvm-x86/linux/commit/ca2eccb953fd

--
https://github.com/kvm-x86/linux/tree/next

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-01-12 17:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-21 20:47 [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Yosry Ahmed
2025-11-21 20:48 ` [PATCH v3 1/4] KVM: SVM: Allow KVM_SET_NESTED_STATE to clear GIF when SVME==0 Yosry Ahmed
2026-01-08 18:58   ` Sean Christopherson
2026-01-08 20:38     ` Yosry Ahmed
2026-01-08 22:17       ` Sean Christopherson
2025-11-21 20:48 ` [PATCH v3 2/4] KVM: SVM: Don't set GIF when clearing EFER.SVME Yosry Ahmed
2025-11-21 20:48 ` [PATCH v3 3/4] KVM: selftests: Use TEST_ASSERT_EQ() in test_vmx_nested_state() Yosry Ahmed
2025-11-21 20:48 ` [PATCH v3 4/4] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM Yosry Ahmed
2026-01-12 17:39 ` [PATCH v3 0/4] KVM: SVM: GIF and EFER.SVME are independent Sean Christopherson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox