From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Josef Bacik <josef@toxicpanda.com>,
Chris Mason <mason@kernel.org>
Subject: [PATCH 2/2] KVM: selftests: Add regression test for KVM writing but not reporting vmcs12
Date: Wed, 21 Oct 2026 19:18:20 -0700 [thread overview]
Message-ID: <20261022021820.298886-3-seanjc@google.com> (raw)
In-Reply-To: <20261022021820.298886-1-seanjc@google.com>
When saving nested vCPU state, verify that KVM didn't write any more bytes
than it reported, and add a sync+save point in the state test to trigger a
save when L1 is active with a valid shadow VMCS. Before commit <TBD>, KVM
would incorrectly save the shadow VMCS into the userspace buffer without
accounting for the size of the shadow VMCS.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../testing/selftests/kvm/lib/x86/processor.c | 6 +++++
tools/testing/selftests/kvm/x86/state_test.c | 24 ++++++++++---------
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index 8374afd08baf..976d53af6de7 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1282,10 +1282,16 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu)
if (nested_size) {
state->nested.size = sizeof(state->nested_);
+ memset(state->nested_, 0xaa, sizeof(state->nested_));
+
vcpu_nested_state_get(vcpu, &state->nested);
TEST_ASSERT(state->nested.size <= nested_size,
"Nested state size too big, %i (KVM_CHECK_CAP gave %i)",
state->nested.size, nested_size);
+
+ for (i = state->nested.size; i < nested_size; i++)
+ TEST_ASSERT((unsigned char)state->nested_[i] == 0xaa,
+ "KVM killed the canary at offset %u", i);
} else {
state->nested.size = 0;
}
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 500b09762555..5bd9a04a3911 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -60,13 +60,13 @@ void vmx_l2_guest_code(void)
/* L1 has now set up a shadow VMCS for us. */
GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
- GUEST_SYNC(10);
- GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
- vmwrite(GUEST_RIP, 0xc0fffee);
GUEST_SYNC(11);
+ GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
+ vmwrite(GUEST_RIP, 0xc0fffee);
+ GUEST_SYNC(12);
GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0fffee);
vmwrite(GUEST_RIP, 0xc0ffffee);
- GUEST_SYNC(12);
+ GUEST_SYNC(13);
/* Done, exit to L1 and never come back. */
vmcall();
@@ -107,15 +107,17 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
vmwrite(SECONDARY_VM_EXEC_CONTROL, SECONDARY_EXEC_SHADOW_VMCS);
vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
-
- vmptrld(vmx_pages->shadow_vmcs_gpa);
- GUEST_ASSERT(__vmlaunch());
GUEST_SYNC(8);
- GUEST_ASSERT(__vmlaunch());
- GUEST_ASSERT(__vmresume());
- vmwrite(GUEST_RIP, 0xc0ffee);
+ vmptrld(vmx_pages->shadow_vmcs_gpa);
+ GUEST_ASSERT(__vmlaunch());
GUEST_SYNC(9);
+
+ GUEST_ASSERT(__vmlaunch());
+ GUEST_ASSERT(__vmresume());
+
+ vmwrite(GUEST_RIP, 0xc0ffee);
+ GUEST_SYNC(10);
GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
vmptrld(vmx_pages->vmcs_gpa);
@@ -126,7 +128,7 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffffee);
GUEST_ASSERT(__vmlaunch());
GUEST_ASSERT(__vmresume());
- GUEST_SYNC(13);
+ GUEST_SYNC(14);
GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffffee);
GUEST_ASSERT(__vmlaunch());
GUEST_ASSERT(__vmresume());
--
2.56.0.218.g1ec904b173-goog
prev parent reply other threads:[~2026-10-22 2:18 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 2:18 [PATCH 0/2] KVM: nVMX: Fix a (benign) overwrite to a userspace buffer Sean Christopherson
2026-10-22 2:18 ` [PATCH 1/2] KVM: nVMX: Save shadow VMCS when getting nested state iff L2 is active Sean Christopherson
2026-10-22 2:18 ` Sean Christopherson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022021820.298886-3-seanjc@google.com \
--to=seanjc@google.com \
--cc=josef@toxicpanda.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mason@kernel.org \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®