Re: [PATCH v5 2/8] KVM: nSVM: Synthesize DecodeAssists EXITINFO for emulated intercepts
From: Jim Mattson
Date: Fri Sep 04 2026 - 19:07:44 EST
On Mon, Aug 24, 2026 at 5:40 AM Tina Zhang <zhang_wei@xxxxxxxxxxxxxx> 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 <zhang_wei@xxxxxxxxxxxxxx>
> ---
> 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
>