All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted
@ 2026-07-21  6:08 Hao Zhang
  2026-07-21  6:24 ` sashiko-bot
  0 siblings, 1 reply; 3+ messages in thread
From: Hao Zhang @ 2026-07-21  6:08 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Paolo Bonzini, kvm

From: Hao Zhang <zhanghao1@kylinos.cn>

RSM can restore state that indicates the vCPU was running L2 when SMI
arrived.  KVM then re-enters nested guest mode and marks nested_run_pending
so that the next KVM_RUN completes the pending nested transition.

Unlike a normal nested VMLAUNCH/VMRESUME, the state restored by RSM comes
from SMRAM.  Userspace can modify SMRAM before RSM.  The resulting L2 state
may require invalid-guest-state emulation.  If KVM trusts that pending run,
VMX can synthesize EXIT_REASON_INVALID_STATE before hardware VM-Entry
completes the pending run and trip the nested_run_pending invariant.

Do not treat an RSM-created pending nested run as KVM-trusted state.  Mark
the run as KVM_NESTED_RUN_PENDING_UNTRUSTED for both VMX and SVM, matching
the existing userspace-modified-state handling in kvm_x86_vcpu_pre_run().

Fixes: 2bb8cafea80b ("KVM: vVMX: signal failure for nested VMEntry if emulation_required")
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Hao Zhang <zhanghao1@kylinos.cn>
---
Changes in v2:
- Mark nested state restored by RSM from SMRAM as KVM_NESTED_RUN_PENDING_UNTRUSTED.
- Keep the BUG check in __vmx_handle_exit(), but make it apply only to KVM_NESTED_RUN_PENDING.

Link to v1: https://lore.kernel.org/all/al3Qbq-jUYE-_72N@192.168.1.215/ 

 arch/x86/kvm/svm/svm.c | 2 +-
 arch/x86/kvm/vmx/vmx.c | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 4d2bacd00ec4..f54757bd8382 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -5096,7 +5096,7 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
 		goto unmap_save;
 
 	ret = 0;
-	vcpu->arch.nested_run_pending = KVM_NESTED_RUN_PENDING;
+	vcpu->arch.nested_run_pending = KVM_NESTED_RUN_PENDING_UNTRUSTED;
 
 unmap_save:
 	kvm_vcpu_unmap(vcpu, &map_save);
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index cc75feec05da..333072cc9bce 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6720,7 +6720,8 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
 	 * invalid guest state should never happen as that means KVM knowingly
 	 * allowed a nested VM-Enter with an invalid vmcs12.  More below.
 	 */
-	if (KVM_BUG_ON(vcpu->arch.nested_run_pending, vcpu->kvm))
+	if (KVM_BUG_ON(vcpu->arch.nested_run_pending == KVM_NESTED_RUN_PENDING,
+		       vcpu->kvm))
 		return -EIO;
 
 	if (is_guest_mode(vcpu)) {
@@ -8436,7 +8437,7 @@ int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
 		if (ret != NVMX_VMENTRY_SUCCESS)
 			return 1;
 
-		vcpu->arch.nested_run_pending = KVM_NESTED_RUN_PENDING;
+		vcpu->arch.nested_run_pending = KVM_NESTED_RUN_PENDING_UNTRUSTED;
 		vmx->nested.smm.guest_mode = false;
 	}
 	return 0;

base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.15.0


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

* Re: [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted
  2026-07-21  6:08 [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted Hao Zhang
@ 2026-07-21  6:24 ` sashiko-bot
  2026-07-21 14:42   ` Sean Christopherson
  0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-07-21  6:24 UTC (permalink / raw)
  To: Hao Zhang; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Leaked `nested_run_pending` flag in VMX permanently blocks event injection to L1 after recovering from an invalid untrusted nested state.
--

--- Patch [1]: [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted ---
commit 096beaf30ae7e6e858dddc7bb2b2a980624ad7d1
Author: Hao Zhang <zhanghao1@kylinos.cn>

KVM: x86: Mark nested RSM-created VM-Enter as untrusted

RSM can restore state that indicates the vCPU was running L2 when SMI
arrived.  KVM then re-enters nested guest mode and marks nested_run_pending
so that the next KVM_RUN completes the pending nested transition.

Link to v1: https://lore.kernel.org/all/al3Qbq-jUYE-_72N@192.168.1.215/

> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 4d2bacd00ec4f..f54757bd83821 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c

[ ... ]

> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index cc75feec05daa..333072cc9bce4 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -6720,7 +6720,8 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
>  	 * invalid guest state should never happen as that means KVM knowingly
>  	 * allowed a nested VM-Enter with an invalid vmcs12.  More below.
>  	 */
> -	if (KVM_BUG_ON(vcpu->arch.nested_run_pending, vcpu->kvm))
> +	if (KVM_BUG_ON(vcpu->arch.nested_run_pending == KVM_NESTED_RUN_PENDING,
> +		       vcpu->kvm))
>  		return -EIO;

[Severity: High]
Does this allow the KVM_NESTED_RUN_PENDING_UNTRUSTED flag to leak and lock up
the vCPU?

If a malicious L2 guest modifies SMRAM to create an invalid nested state, then
executes RSM, vmx_leave_smm() restores this state and sets nested_run_pending
to KVM_NESTED_RUN_PENDING_UNTRUSTED.

During vmx_vcpu_run(), the invalid state triggers an early return because of
vmx->vt.emulation_required:

	if (unlikely(vmx->vt.emulation_required)) {
		vmx->fail = 0;
		vmx->vt.exit_reason.full = EXIT_REASON_INVALID_STATE;
		...
		return EXIT_FASTPATH_NONE;
	}

This skips the code block at the end of vmx_vcpu_run() that normally clears
vcpu->arch.nested_run_pending = 0.

When __vmx_handle_exit() is subsequently called, the modified KVM_BUG_ON
allows this UNTRUSTED state to fall through without returning -EIO.  KVM then
reaches this block:

		if (vmx->vt.emulation_required) {
			nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0);
			return 1;
		}

This synthesizes a TRIPLE_FAULT and transitions the vCPU back to L1, but it
doesn't clear the nested_run_pending flag before doing so.

Once back in L1, vmx_interrupt_allowed() unconditionally returns -EBUSY
because the flag is still set:

	if (vcpu->arch.nested_run_pending)
		return -EBUSY;

Will this cause kvm_check_and_inject_events() to constantly request an
immediate exit, permanently livelocking the host vCPU thread in an infinite
VM-Enter/VM-Exit loop?

>  
>  	if (is_guest_mode(vcpu)) {

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/al8M4gCwsWXS_jMs@192.168.1.215?part=1

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

* Re: [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted
  2026-07-21  6:24 ` sashiko-bot
@ 2026-07-21 14:42   ` Sean Christopherson
  0 siblings, 0 replies; 3+ messages in thread
From: Sean Christopherson @ 2026-07-21 14:42 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: Hao Zhang, kvm

On Tue, Jul 21, 2026, sashiko-bot@kernel.org wrote:
> > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> > index 4d2bacd00ec4f..f54757bd83821 100644
> > --- a/arch/x86/kvm/svm/svm.c
> > +++ b/arch/x86/kvm/svm/svm.c
> 
> [ ... ]
> 
> > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > index cc75feec05daa..333072cc9bce4 100644
> > --- a/arch/x86/kvm/vmx/vmx.c
> > +++ b/arch/x86/kvm/vmx/vmx.c
> > @@ -6720,7 +6720,8 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
> >  	 * invalid guest state should never happen as that means KVM knowingly
> >  	 * allowed a nested VM-Enter with an invalid vmcs12.  More below.
> >  	 */
> > -	if (KVM_BUG_ON(vcpu->arch.nested_run_pending, vcpu->kvm))
> > +	if (KVM_BUG_ON(vcpu->arch.nested_run_pending == KVM_NESTED_RUN_PENDING,
> > +		       vcpu->kvm))
> >  		return -EIO;
> 
> [Severity: High]
> Does this allow the KVM_NESTED_RUN_PENDING_UNTRUSTED flag to leak and lock up
> the vCPU?
> 
> If a malicious L2 guest modifies SMRAM to create an invalid nested state, then
> executes RSM, vmx_leave_smm() restores this state and sets nested_run_pending
> to KVM_NESTED_RUN_PENDING_UNTRUSTED.

LOL, that is an impressively convoluted hallucination from Sashiko.  SMI is an
unconditional VM-Exit on Intel, and KVM doesn't support emulating parallel SMM,
i.e. it's impossible for L2 to have access to "live" SMRAM.

That said, leaving nested_run_pending set isn't good, and I missed that my
suggested "fix" would require tweaking the above KVM_BUG_ON().  I'll respond to
v3 with an alternative solution.

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

end of thread, other threads:[~2026-07-21 14:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21  6:08 [PATCH v2] KVM: x86: Mark nested RSM-created VM-Enter as untrusted Hao Zhang
2026-07-21  6:24 ` sashiko-bot
2026-07-21 14:42   ` Sean Christopherson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.