On Mon, Aug 24, 2026 at 5:40 AM Tina Zhang <[email protected]> wrote: > > When the x86 emulator encounters an instruction intercepted by L1, > svm_check_intercept() synthesizes a nested VM-Exit without fresh hardware > DecodeAssist state. Populate the architectural EXITINFO fields when > DecodeAssists is exposed to L1. > > Generate EXITINFO1 with the GPR number for MOV CR/DR, the interrupt vector > for INTn, and the linear address for INVLPG. Set EXITINFO1 to zero for > CLTS, LMSW, SMSW, and INVLPGA; the INVLPGA address remains in guest rAX. > Clear EXITINFO2 for all covered intercepts and leave unrelated intercepts > unchanged. > > Signed-off-by: Tina Zhang <[email protected]> > --- > arch/x86/kvm/svm/svm.c | 48 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 48 insertions(+) > > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > index 9d607b98bd06..c7c1f1527c3c 100644 > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -4810,6 +4810,52 @@ static const struct __x86_intercept { > #undef POST_EX > #undef POST_MEM > > +static void svm_prepare_decode_assist_exit_info(struct kvm_vcpu *vcpu, > + const struct > x86_instruction_info *info) > +{ > + struct vmcb *vmcb = to_svm(vcpu)->vmcb; > + u64 exit_info_1; > + > + if (!guest_cpu_cap_has(vcpu, X86_FEATURE_DECODEASSISTS)) > + return; > + > + switch (info->intercept) { > + case x86_intercept_cr_read: > + case x86_intercept_cr_write: > + /* MOV CRx: bit 63 set, GPR number in bits 3:0. */ > + exit_info_1 = BIT_ULL(63) | (info->modrm_rm & 0xf); > + break; > + case x86_intercept_clts: > + case x86_intercept_lmsw: > + case x86_intercept_smsw: > + /* CLTS/LMSW/SMSW: no decode information, bit 63 clear. */ > + exit_info_1 = 0; > + break; > + case x86_intercept_dr_read: > + case x86_intercept_dr_write: > + /* MOV DRx: GPR number in bits 3:0. */ > + exit_info_1 = info->modrm_rm & 0xf; > + break; > + case x86_intercept_intn: > + /* INTn: software interrupt number in bits 7:0. */ > + exit_info_1 = info->src_val & 0xff; > + break; > + case x86_intercept_invlpg: > + /* INVLPG: linear address of the target page. */ > + exit_info_1 = info->intercept_linear_addr; > + break; > + case x86_intercept_invlpga: > + /* INVLPGA: the address remains available in guest rAX. */ > + exit_info_1 = 0; > + break; > + default: > + return; > + } > + > + vmcb->control.exit_info_1 = exit_info_1; > + vmcb->control.exit_info_2 = 0; > +}
Can this entire function be integrated into the existing switch statement in svm_check_intercept()? And, if !guest_cpu_cap_has(vcpu, X86_FEATURE_DECODEASSISTS), should exit_info_1 be cleared for these intercepts? > static int svm_check_intercept(struct kvm_vcpu *vcpu, > struct x86_instruction_info *info, > enum x86_intercept_stage stage, > @@ -4931,6 +4977,8 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, > break; > } > > + svm_prepare_decode_assist_exit_info(vcpu, info); > + > /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ > if (static_cpu_has(X86_FEATURE_NRIPS)) > vmcb->control.next_rip = info->next_rip; > -- > 2.43.7 >

