[PATCH 2/2] x86emul: use latched XCR0 in x86emul_get_fpu()

Jan Beulich <[email protected]>
Newsgroups org.xenproject.lists.xen-devel
Message-ID <[email protected]>
Avoid re-reading, and instead pass state into the function. For
get_fpu() to use "s" as new argument, we need a new local variable in
x86_emulate() though.

Signed-off-by: Jan Beulich <[email protected]>
---
That new local "s" can likely be leveraged to replace explicit uses of
"state" in the function (past the point where the alias #define is).
Long term we probably want to aim at consistently using "s" everywhere
where a struct x86_emulate_state * variable/parameter is needed.
x86emul_get_fpu() isn't using "s" right away just because that would end
up inconsistent with adjacent code (put_fpu() first and foremost). I
could certainly change that.

--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -743,12 +743,13 @@ int x86emul_get_cpl(struct x86_emulate_c
                     const struct x86_emulate_ops *ops);
 
 int x86emul_get_fpu(enum x86_emulate_fpu_type type,
+                    const struct x86_emulate_state *state,
                     struct x86_emulate_ctxt *ctxt,
                     const struct x86_emulate_ops *ops);
 
 #define get_fpu(type)                                           \
 do {                                                            \
-    rc = x86emul_get_fpu(fpu_type = (type), ctxt, ops);         \
+    rc = x86emul_get_fpu(fpu_type = (type), s, ctxt, ops);      \
     if ( rc ) goto done;                                        \
 } while (0)
 
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -394,36 +394,30 @@ do {
 
 int x86emul_get_fpu(
     enum x86_emulate_fpu_type type,
+    const struct x86_emulate_state *state,
     struct x86_emulate_ctxt *ctxt,
     const struct x86_emulate_ops *ops)
 {
-    uint64_t xcr0;
     int rc;
 
     fail_if(!ops->get_fpu);
     ASSERT(type != X86EMUL_FPU_none);
 
-    if ( type < X86EMUL_FPU_ymm || !ops->read_xcr ||
-         ops->read_xcr(0, &xcr0, ctxt) != X86EMUL_OKAY )
-    {
-        ASSERT(!ctxt->event_pending);
-        xcr0 = 0;
-    }
-
     switch ( type )
     {
     case X86EMUL_FPU_zmm:
-        if ( !(xcr0 & X86_XCR0_ZMM) || !(xcr0 & X86_XCR0_HI_ZMM) ||
-             !(xcr0 & X86_XCR0_OPMASK) )
+        if ( !(state->xcr0 & X86_XCR0_ZMM) ||
+             !(state->xcr0 & X86_XCR0_HI_ZMM) ||
+             !(state->xcr0 & X86_XCR0_OPMASK) )
             return X86EMUL_UNHANDLEABLE;
         /* fall through */
     case X86EMUL_FPU_ymm:
-        if ( !(xcr0 & X86_XCR0_SSE) || !(xcr0 & X86_XCR0_YMM) )
+        if ( !(state->xcr0 & X86_XCR0_SSE) || !(state->xcr0 & X86_XCR0_YMM) )
             return X86EMUL_UNHANDLEABLE;
         break;
 
     case X86EMUL_FPU_opmask:
-        if ( !(xcr0 & X86_XCR0_SSE) || !(xcr0 & X86_XCR0_OPMASK) )
+        if ( !(state->xcr0 & X86_XCR0_SSE) || !(state->xcr0 & X86_XCR0_OPMASK) )
             return X86EMUL_UNHANDLEABLE;
         break;
 
@@ -1310,7 +1304,7 @@ x86_emulate(
     /* Shadow copy of register state. Committed on successful emulation. */
     struct cpu_user_regs _regs = *ctxt->regs;
     const struct cpu_policy *__maybe_unused cp = ctxt->cpu_policy;
-    struct x86_emulate_state state;
+    struct x86_emulate_state state, *s = &state;
     int rc;
     uint8_t b, d, *opc = NULL;
     unsigned int first_byte = 0, elem_bytes, insn_bytes = 0;
@@ -1439,7 +1433,7 @@ x86_emulate(
     /* With a memory operand, fetch the mask register in use (if any). */
     if ( ea.type == OP_MEM && evex.opmsk &&
          x86emul_get_fpu(fpu_type = X86EMUL_FPU_opmask,
-                         ctxt, ops) == X86EMUL_OKAY )
+                         s, ctxt, ops) == X86EMUL_OKAY )
     {
         uint8_t *stb = get_stub(stub);
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.