Re: [PATCH v4 4/9] KVM: nSVM: Propagate hardware DecodeAssist bytes to VMCB12

Tina Zhang <[email protected]>
Newsgroups org.kernel.vger.kvm
Message-ID <[email protected]>
On 8/19/2026 2:11 PM, [email protected] wrote:
> 
>> +static void nested_svm_update_vmcb12_insn_bytes(struct kvm_vcpu *vcpu,
>> +						struct vmcb *vmcb12,
>> +						const struct vmcb *vmcb02)
>> +{
>> +	struct vcpu_svm *svm = to_svm(vcpu);
>> +
>> +	nested_svm_clear_insn_bytes(vmcb12);
>> +
>> +	if (!nested_svm_vmexit_supports_insn_bytes(vcpu, vmcb02))
>> +		goto out;
>> +
>> +	if (svm->nested.vmcb02_insn_bytes_fresh)
>> +		nested_svm_copy_insn_bytes(vmcb12, vmcb02);
> 
> [Severity: High]
> If a live migration occurs while KVM has a pending hardware #PF VM-exit
> (where exception_vmexit.pending = true and vmcb02_insn_bytes_fresh = true),
> how does the destination hypervisor know to restore this state?
> 
> It appears svm_get_nested_state() and svm_set_nested_state() aren't updated
> to serialize vmcb02_insn_bytes_fresh or the hardware insn_bytes. Could this
> cause the destination hypervisor to inject a #PF into VMCB12 with an
> insn_len of 0, effectively losing the instruction bytes?
> 
> Additionally, if userspace calls KVM_SET_VCPU_EVENTS to clear a pending
> exception:
> 
> arch/x86/kvm/x86.c:kvm_vcpu_ioctl_x86_set_vcpu_events() {
>      ...
>      vcpu->arch.exception_vmexit.pending = false;
>      ...
> }
> 
> The vmcb02_insn_bytes_fresh flag is not cleared alongside it. Could a
> subsequent emulator-generated #PF then incorrectly copy these stale
> instruction bytes into VMCB12?

Hi Sean and Jim,

Before posting v5, I'd like to get your opinion on how to track the
instruction-byte source for a delayed nested #PF VM-Exit.

A hardware #PF may first be handled by KVM and then queued for 
reflection to L1.  When constructing the nested VM-Exit later, nSVM 
needs to know whether the queued #PF still corresponds to the 
DecodeAssist bytes in VMCB02.  Similarly, an emulator-originated #PF 
needs to retain that provenance so that KVM uses the emulator fetch 
cache only for the exception that actually came from that emulator context.

Keeping this information as independent state in svm_nested_state is 
fragile.  For example, userspace may clear or replace the pending 
exception, leaving the SVM state associated with an event that no longer 
exists.  In v5, I am therefore associating the provenance with the 
queued exception itself.  Userspace-restored exceptions have neither 
hardware nor emulator provenance and use the on-demand fetch fallback.

The part I am unsure about is how this should be represented.  The 
minimal implementation adds:

           bool has_emulator_context;
           bool has_hardware_pf_state;

to struct kvm_queued_exception.  However, these fields are meaningful 
only for vcpu->arch.exception_vmexit, while the same structure is also 
used for the normal vcpu->arch.exception queue.

An alternative would be to introduce a wrapper, for example:

           struct kvm_exception_vmexit {
                   struct kvm_queued_exception exception;
                   bool has_emulator_context;
                   bool has_hardware_pf_state;
           };

This keeps the VM-Exit provenance out of the normal exception structure, 
but requires mechanical change to the generic x86 and VMX references to
exception_vmexit.

Do you have a preference between these approaches, or is there another 
way you would recommend representing this state?


Thanks,
Tina
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.