On 9/5/2026 6:34 AM, Jim Mattson wrote:
+static u64 get_intercept_linear_addr(struct x86_emulate_ctxt *ctxt,
+                                    enum x86_intercept intercept)
+{
+       u64 la;
+
+       if (intercept != x86_intercept_invlpg)
+               return 0;
+
+       la = seg_base(ctxt, ctxt->src.addr.mem.seg) + ctxt->src.addr.mem.ea;
+       return ctxt->mode == X86EMUL_MODE_PROT64 ? la : (u32)la;
+}

The linear address calculation here is replicated from __linearize().
Perhaps something like:
static u64 get_invlpg_linear_addr(struct x86_emulate_ctxt *ctxt)
{
         unsigned int max_size;
         ulong linear;

         if (intercept != x86_intercept_invlpg)
                 return 0;

         __linearize(ctxt, ctxt->src.addr.mem, &max_size, 1,
ctxt->mode, &linear, X86EMUL_F_INVLPG);
         return linear;
}

I initially used the minimal calculation needed for EXITINFO1 because I thought some of the additional processing in __linearize() was unnecessary when reporting the linear address to L1. However, reusing __linearize() keeps the intercepted path consistent with em_invlpg(). I will switch to __linearize() with X86EMUL_F_INVLPG.



  static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
                                     enum x86_intercept intercept,
                                     enum x86_intercept_stage stage)
@@ -427,6 +447,7 @@ static int emulator_check_intercept(struct x86_emulate_ctxt 
*ctxt,
                 .src_type   = ctxt->src.type,
                 .dst_type   = ctxt->dst.type,
                 .ad_bytes   = ctxt->ad_bytes,
+               .intercept_linear_addr = get_intercept_linear_addr(ctxt, 
intercept),

Maybe:
+               .invlpg_linear_addr = get_invlpg_linear_addr(ctxt, intercept),

Yes, this is clearer.


Thanks,
Tina


Reply via email to