Re: [PATCH 4/7] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry

From: Jim Mattson

Date: Mon Nov 02 2026 - 18:39:44 EST


On Mon, Nov 2, 2026 at 3:19 PM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
>
> From: Sean Christopherson <seanjc@xxxxxxxxxx>
>
> Add a missing "break" in the inner for-loop of the open coded mess that
> unwinds MSRs back to the pre-VM-Enter state when VMLAUNCH/VMRESUME VM-Fails
> due to a consistency check that is caught by hardware but missed by KVM.

That sentence does not accurately describe what the code does.

> I.e. move on to the next MSR in the VM-Entry load list after performing a
> write using a value found in the VM-Exit load list. Processing *every*
> matching entry in the VM-Exit load list makes the processing quadratic,
> which is problematic if the load lists are full of MSRs that are expensive
> to emulate. E.g. writing APIC_BASE triggers kvm_recalculate_apic_map() and
> a whole pile of unnecessary work.
>
> Functionally, arbitrarily restoring the value of the first matching entry
> is "fine", because none of this is architecturally correct: the load lists
> are never supposed to have been used in the first place. In practice, it's
> likely a moot point as no well-behaved VMM will have multiple, diverging
> entries in the load lists.

This isn't "fine." This is disgusting.

The assumption that the VM-exit MSR-load list will "undo" every
assignment made by the VM-entry MSR-load list is misguided and wrong.

Xen, for instance, puts SPEC_CTRL on the VM-entry MSR-load list, but
it does not put it on the VM-exit MSR-load list. Instead, after a
normal VM-exit, it restores the host value in
vmx_asm_vmexit_handler():

/*
* Restore Xen's MSR_SPEC_CTRL setting. The guest's value resides in
* the MSR load/save list. For Legacy IBRS, this flushes/inhibits
* indirect predictions and does not flush the RSB. For eIBRS, this
* prevents CALLs/JMPs using predictions learnt at a lower predictor
* mode, and it flushes the RSB. On eIBRS parts that also suffer from
* PBRSB, the prior RSB stuffing suffices to make the RSB safe.
*/
.macro restore_spec_ctrl
mov $MSR_SPEC_CTRL, %ecx
mov CPUINFO_xen_spec_ctrl(%rsp), %eax
xor %edx, %edx
wrmsr
.endm
ALTERNATIVE "", restore_spec_ctrl, X86_FEATURE_SC_MSR_HVM

After VM-entry failure, Xen executes this code:

.Lvmx_vmentry_fail:
sti
PUSH_AND_CLEAR_GPRS

/*
* SPEC_CTRL_ENTRY notes
*
* If we end up here, no guest code has executed. The MSR lists have
* not been processed, so we still have Xen's choice of MSR_SPEC_CTRL
* in context, and the RSB is unchanged.
*/

call vmx_vmentry_failure

KVM needs to do better.