* [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns
@ 2026-08-08 8:10 Gokul K
2026-08-08 8:10 ` [PATCH 1/2] KVM: selftests: Free the VM when the SEV smoke test's guest completes Gokul K
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Gokul K @ 2026-08-08 8:10 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Shuah Khan, kvm, linux-kselftest, linux-kernel
Two x86 selftests create a VM and then take an early return that skips the
kvm_vm_free() at the end of the function.
Patch 1 is the plain-SEV path of sev_smoke_test(), which returns straight
out of the UCALL_DONE case instead of leaving the loop. The SEV-ES path
next to it breaks out and frees correctly.
Patch 2 is nx_huge_pages_test, which returns as soon as it has confirmed
that disabling NX huge pages is denied without CAP_SYS_BOOT. This one is
not an unusual error path: nx_huge_pages_test.sh runs the test without
CAP_SYS_BOOT for any non-root user, so a normal run always takes it.
Neither leak causes a failure today, since the process exits shortly
afterwards. They do mean those paths never exercise VM teardown.
The two patches are independent and either can be applied on its own.
Found by auditing every function under tools/testing/selftests/kvm/ that
creates a VM and later calls kvm_vm_free(), looking for returns in
between. Seven other hits were false positives, mostly returns after
REPORT_GUEST_ASSERT() or TEST_FAIL(), which abort the process and make
the return unreachable. Two more that do look real, in get-reg-list.c
and arm64/external_aborts.c, are left out here because they belong to
different maintainers.
Compile-tested only. This host has neither SEV (kvm_amd sev=N) nor
hugetlb configured, so both tests SKIP rather than run.
Note patch 1 touches sev_smoke_test.c, which an unrelated patch I sent
earlier also touches [1]. They modify different functions, do not
conflict, and neither depends on the other.
[1] https://lore.kernel.org/all/20260807071026.195503-1-gokul02k@gmail.com/
Gokul K (2):
KVM: selftests: Free the VM when the SEV smoke test's guest completes
KVM: selftests: Free the VM when NX hugepage disabling is denied
tools/testing/selftests/kvm/x86/nx_huge_pages_test.c | 1 +
tools/testing/selftests/kvm/x86/sev_smoke_test.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
--
2.54.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] KVM: selftests: Free the VM when the SEV smoke test's guest completes
2026-08-08 8:10 [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Gokul K
@ 2026-08-08 8:10 ` Gokul K
2026-08-08 8:10 ` [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied Gokul K
2026-08-10 13:35 ` [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Sean Christopherson
2 siblings, 0 replies; 5+ messages in thread
From: Gokul K @ 2026-08-08 8:10 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Shuah Khan, kvm, linux-kselftest, linux-kernel
test_sev() returns directly out of the UCALL_DONE case rather than
leaving the loop, so the plain-SEV path skips the kvm_vm_free() at the
end of the function. The SEV-ES path is unaffected; it breaks out of
the loop and frees the VM correctly.
main() invokes test_sev() once per supported SEV VM type, so a full run
leaks a VM and its file descriptors. Nothing fails today because the
process exits shortly afterwards, which is presumably why this was not
noticed, but the leak also means the plain-SEV path never exercises VM
teardown.
Use a goto so UCALL_DONE joins the existing exit path. A plain break
would only leave the switch statement and spin the loop again.
Fixes: be250ff437fa ("KVM: selftests: Add a basic SEV smoke test")
Signed-off-by: Gokul K <gokul02k@gmail.com>
---
tools/testing/selftests/kvm/x86/sev_smoke_test.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index 6b2cbe2a90b7..646ae93e3c46 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -178,7 +178,7 @@ static void test_sev(void *guest_code, u32 type, u64 policy)
case UCALL_SYNC:
continue;
case UCALL_DONE:
- return;
+ goto done;
case UCALL_ABORT:
REPORT_GUEST_ASSERT(uc);
default:
@@ -187,6 +187,7 @@ static void test_sev(void *guest_code, u32 type, u64 policy)
}
}
+done:
kvm_vm_free(vm);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied
2026-08-08 8:10 [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Gokul K
2026-08-08 8:10 ` [PATCH 1/2] KVM: selftests: Free the VM when the SEV smoke test's guest completes Gokul K
@ 2026-08-08 8:10 ` Gokul K
2026-08-10 13:37 ` Sean Christopherson
2026-08-10 13:35 ` [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Sean Christopherson
2 siblings, 1 reply; 5+ messages in thread
From: Gokul K @ 2026-08-08 8:10 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: Shuah Khan, kvm, linux-kselftest, linux-kernel
run_test() returns as soon as it has confirmed that disabling NX huge
pages fails with -EPERM, without freeing the VM created a few lines
earlier.
This is not an obscure path. nx_huge_pages_test.sh runs the test a
second time without CAP_SYS_BOOT for any non-root user, and main() calls
run_test() with disable_nx_huge_pages=true on its second invocation, so
an ordinary run of the wrapper script always takes it.
Free the VM before returning.
Fixes: b774da3f2e57 ("KVM: selftests: Test disabling NX hugepages on a VM")
Signed-off-by: Gokul K <gokul02k@gmail.com>
---
tools/testing/selftests/kvm/x86/nx_huge_pages_test.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
index 70950067b989..49b70c05daec 100644
--- a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
+++ b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
@@ -120,6 +120,7 @@ void run_test(int reclaim_period_ms, bool disable_nx_huge_pages,
} else {
TEST_ASSERT(r == -1 && errno == EPERM,
"This process should not have permission to disable NX huge pages");
+ kvm_vm_free(vm);
return;
}
}
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns
2026-08-08 8:10 [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Gokul K
2026-08-08 8:10 ` [PATCH 1/2] KVM: selftests: Free the VM when the SEV smoke test's guest completes Gokul K
2026-08-08 8:10 ` [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied Gokul K
@ 2026-08-10 13:35 ` Sean Christopherson
2 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2026-08-10 13:35 UTC (permalink / raw)
To: Gokul K; +Cc: Paolo Bonzini, Shuah Khan, kvm, linux-kselftest, linux-kernel
On Sat, Aug 08, 2026, Gokul K wrote:
> Two x86 selftests create a VM and then take an early return that skips the
> kvm_vm_free() at the end of the function.
>
> Patch 1 is the plain-SEV path of sev_smoke_test(), which returns straight
> out of the UCALL_DONE case instead of leaving the loop. The SEV-ES path
> next to it breaks out and frees correctly.
>
> Patch 2 is nx_huge_pages_test, which returns as soon as it has confirmed
> that disabling NX huge pages is denied without CAP_SYS_BOOT. This one is
> not an unusual error path: nx_huge_pages_test.sh runs the test without
> CAP_SYS_BOOT for any non-root user, so a normal run always takes it.
>
> Neither leak causes a failure today, since the process exits shortly
> afterwards. They do mean those paths never exercise VM teardown.
Eh, not really, they just exercise VM teardown at a different point in the
processes' lifecycle.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied
2026-08-08 8:10 ` [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied Gokul K
@ 2026-08-10 13:37 ` Sean Christopherson
0 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2026-08-10 13:37 UTC (permalink / raw)
To: Gokul K; +Cc: Paolo Bonzini, Shuah Khan, kvm, linux-kselftest, linux-kernel
On Sat, Aug 08, 2026, Gokul K wrote:
> run_test() returns as soon as it has confirmed that disabling NX huge
> pages fails with -EPERM, without freeing the VM created a few lines
> earlier.
>
> This is not an obscure path.
FWIW, the relative obscurity of the path doesn't really matter.
> nx_huge_pages_test.sh runs the test a
> second time without CAP_SYS_BOOT for any non-root user, and main() calls
> run_test() with disable_nx_huge_pages=true on its second invocation, so
> an ordinary run of the wrapper script always takes it.
>
> Free the VM before returning.
>
> Fixes: b774da3f2e57 ("KVM: selftests: Test disabling NX hugepages on a VM")
> Signed-off-by: Gokul K <gokul02k@gmail.com>
> ---
> tools/testing/selftests/kvm/x86/nx_huge_pages_test.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
> index 70950067b989..49b70c05daec 100644
> --- a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
> +++ b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
> @@ -120,6 +120,7 @@ void run_test(int reclaim_period_ms, bool disable_nx_huge_pages,
> } else {
> TEST_ASSERT(r == -1 && errno == EPERM,
> "This process should not have permission to disable NX huge pages");
> + kvm_vm_free(vm);
> return;
I think I'd prefer the same patter you used in patch 1? I.e.
diff --git a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
index 70950067b989..e3b20033a884 100644
--- a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
+++ b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
@@ -120,7 +120,7 @@ void run_test(int reclaim_period_ms, bool disable_nx_huge_pages,
} else {
TEST_ASSERT(r == -1 && errno == EPERM,
"This process should not have permission to disable NX huge pages");
- return;
+ goto done;
}
}
@@ -213,6 +213,7 @@ void run_test(int reclaim_period_ms, bool disable_nx_huge_pages,
check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 2);
check_split_count(vm, 0);
+done:
kvm_vm_free(vm);
}
> }
> }
> --
> 2.54.0
>
>
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-10 13:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-08 8:10 [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Gokul K
2026-08-08 8:10 ` [PATCH 1/2] KVM: selftests: Free the VM when the SEV smoke test's guest completes Gokul K
2026-08-08 8:10 ` [PATCH 2/2] KVM: selftests: Free the VM when NX hugepage disabling is denied Gokul K
2026-08-10 13:37 ` Sean Christopherson
2026-08-10 13:35 ` [PATCH 0/2] KVM: selftests: Fix two VMs leaked on early returns Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox