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