[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 01/25] x86/cpuid: Introduce guest_cpuid() and struct cpuid_leaf



Longterm, pv_cpuid() and hvm_cpuid() will be merged into a single
guest_cpuid(), which is also capable of working outside of current context.

To aid this transtion, introduce guest_cpuid() with the intended API, which
simply defers back to pv_cpuid() or hvm_cpuid() as appropriate.

Introduce struct cpuid_leaf which is used to represent the results of a CPUID
query in a more efficient mannor than passing four pointers through the
calltree.

Update all codepaths which should use the new guest_cpuid() API.  These are
the codepaths which have variable inputs, and (other than some specific
x86_emulate() cases) all pertain to servicing a CPUID instruction from a
guest.

The other codepaths using {pv,hvm}_cpuid() with fixed inputs will later be
adjusted to read their data straight from the policy block.

No intended functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Paul Durrant <paul.durrant@xxxxxxxxxx>
CC: Jun Nakajima <jun.nakajima@xxxxxxxxx>
CC: Kevin Tian <kevin.tian@xxxxxxxxx>
CC: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
CC: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
---
v2:
 * Rename res to cpuid_leaf in x86_emulate(), and make common to functions.
 * Return lost const and newline in pv_emul_cpuid().
 * Extra brackets around EMPTY_LEAF.
 * Consistently use uint32_t.
 * Tweak {hvm,pv}_cpuid() dispatch logic for a reduced delta later in the 
series.
---
 tools/tests/x86_emulator/x86_emulate.c | 15 ++++-----
 tools/tests/x86_emulator/x86_emulate.h | 60 ++++++++++++++++------------------
 xen/arch/x86/cpuid.c                   | 36 ++++++++++++++++++++
 xen/arch/x86/hvm/emulate.c             | 10 ++----
 xen/arch/x86/hvm/svm/svm.c             | 23 ++++++-------
 xen/arch/x86/hvm/vmx/vmx.c             | 35 ++++++--------------
 xen/arch/x86/traps.c                   | 25 +++++++-------
 xen/arch/x86/x86_emulate/x86_emulate.c | 34 +++++++++----------
 xen/arch/x86/x86_emulate/x86_emulate.h | 12 ++++---
 xen/include/asm-x86/cpuid.h            |  4 +++
 xen/include/asm-x86/hvm/emulate.h      |  8 ++---
 xen/include/asm-x86/mm.h               |  4 +--
 12 files changed, 137 insertions(+), 129 deletions(-)

diff --git a/tools/tests/x86_emulator/x86_emulate.c 
b/tools/tests/x86_emulator/x86_emulate.c
index d48f78a..2e8dfbf 100644
--- a/tools/tests/x86_emulator/x86_emulate.c
+++ b/tools/tests/x86_emulator/x86_emulate.c
@@ -41,22 +41,21 @@ bool emul_test_make_stack_executable(void)
 }
 
 int emul_test_cpuid(
-    unsigned int *eax,
-    unsigned int *ebx,
-    unsigned int *ecx,
-    unsigned int *edx,
+    uint32_t leaf,
+    uint32_t subleaf,
+    struct cpuid_leaf *res,
     struct x86_emulate_ctxt *ctxt)
 {
-    unsigned int leaf = *eax;
-
-    asm ("cpuid" : "+a" (*eax), "+c" (*ecx), "=d" (*edx), "=b" (*ebx));
+    asm ("cpuid"
+         : "=a" (res->a), "=b" (res->b), "=c" (res->c), "=d" (res->d)
+         : "a" (leaf), "c" (subleaf));
 
     /*
      * The emulator doesn't itself use MOVBE, so we can always run the
      * respective tests.
      */
     if ( leaf == 1 )
-        *ecx |= 1U << 22;
+        res->c |= 1U << 22;
 
     return X86EMUL_OKAY;
 }
diff --git a/tools/tests/x86_emulator/x86_emulate.h 
b/tools/tests/x86_emulator/x86_emulate.h
index c14c613..8bc2e43 100644
--- a/tools/tests/x86_emulator/x86_emulate.h
+++ b/tools/tests/x86_emulator/x86_emulate.h
@@ -58,61 +58,59 @@ static inline uint64_t xgetbv(uint32_t xcr)
 }
 
 #define cache_line_size() ({                \
-    unsigned int eax = 1, ebx, ecx = 0, edx; \
-    emul_test_cpuid(&eax, &ebx, &ecx, &edx, NULL); \
-    edx & (1U << 19) ? (ebx >> 5) & 0x7f8 : 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    res.d & (1U << 19) ? (res.b >> 5) & 0x7f8 : 0; \
 })
 
 #define cpu_has_mmx ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 23)) != 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    (res.d & (1U << 23)) != 0; \
 })
 
 #define cpu_has_sse ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 25)) != 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    (res.d & (1U << 25)) != 0; \
 })
 
 #define cpu_has_sse2 ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 26)) != 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    (res.d & (1U << 26)) != 0; \
 })
 
 #define cpu_has_xsave ({ \
-    unsigned int eax = 1, ecx = 0; \
-    emul_test_cpuid(&eax, &eax, &ecx, &eax, NULL); \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
     /* Intentionally checking OSXSAVE here. */ \
-    (ecx & (1U << 27)) != 0; \
+    (res.c & (1U << 27)) != 0; \
 })
 
 #define cpu_has_avx ({ \
-    unsigned int eax = 1, ecx = 0; \
-    emul_test_cpuid(&eax, &eax, &ecx, &eax, NULL); \
-    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
-        ecx = 0; \
-    (ecx & (1U << 28)) != 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
+        res.c = 0; \
+    (res.c & (1U << 28)) != 0; \
 })
 
 #define cpu_has_avx2 ({ \
-    unsigned int eax = 1, ebx, ecx = 0; \
-    emul_test_cpuid(&eax, &ebx, &ecx, &eax, NULL); \
-    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
-        ebx = 0; \
+    struct cpuid_leaf res; \
+    emul_test_cpuid(1, 0, &res, NULL); \
+    if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
+        res.b = 0; \
     else { \
-        eax = 7, ecx = 0; \
-        emul_test_cpuid(&eax, &ebx, &ecx, &eax, NULL); \
+        emul_test_cpuid(7, 0, &res, NULL); \
     } \
-    (ebx & (1U << 5)) != 0; \
+    (res.b & (1U << 5)) != 0; \
 })
 
 int emul_test_cpuid(
-    unsigned int *eax,
-    unsigned int *ebx,
-    unsigned int *ecx,
-    unsigned int *edx,
+    uint32_t leaf,
+    uint32_t subleaf,
+    struct cpuid_leaf *res,
     struct x86_emulate_ctxt *ctxt);
 
 int emul_test_read_cr(
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 3e85a63..f3491ed 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -1,5 +1,6 @@
 #include <xen/init.h>
 #include <xen/lib.h>
+#include <xen/sched.h>
 #include <asm/cpuid.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/vmx/vmcs.h>
@@ -17,6 +18,8 @@ uint32_t __read_mostly raw_featureset[FSCAPINTS];
 uint32_t __read_mostly pv_featureset[FSCAPINTS];
 uint32_t __read_mostly hvm_featureset[FSCAPINTS];
 
+#define EMPTY_LEAF ((struct cpuid_leaf){})
+
 static void __init sanitise_featureset(uint32_t *fs)
 {
     /* for_each_set_bit() uses unsigned longs.  Extend with zeroes. */
@@ -215,6 +218,39 @@ const uint32_t * __init lookup_deep_deps(uint32_t feature)
     return NULL;
 }
 
+void guest_cpuid(const struct vcpu *v, uint32_t leaf,
+                 uint32_t subleaf, struct cpuid_leaf *res)
+{
+    const struct vcpu *curr = current;
+    const struct domain *d = v->domain;
+
+    *res = EMPTY_LEAF;
+
+    /* {hvm,pv}_cpuid() have this expectation. */
+    ASSERT(v == curr);
+
+    if ( is_hvm_domain(d) )
+    {
+        res->c = subleaf;
+
+        hvm_cpuid(leaf, &res->a, &res->b, &res->c, &res->d);
+    }
+    else
+    {
+        struct cpu_user_regs regs = *guest_cpu_user_regs();
+
+        regs._eax = leaf;
+        regs._ecx = subleaf;
+
+        pv_cpuid(&regs);
+
+        res->a = regs._eax;
+        res->b = regs._ebx;
+        res->c = regs._ecx;
+        res->d = regs._edx;
+    }
+}
+
 static void __init __maybe_unused build_assertions(void)
 {
     BUILD_BUG_ON(ARRAY_SIZE(known_features) != FSCAPINTS);
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 41bd4f5..ecbac4b 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -1552,12 +1552,8 @@ static int hvmemul_wbinvd(
     return X86EMUL_OKAY;
 }
 
-int hvmemul_cpuid(
-    unsigned int *eax,
-    unsigned int *ebx,
-    unsigned int *ecx,
-    unsigned int *edx,
-    struct x86_emulate_ctxt *ctxt)
+int hvmemul_cpuid(uint32_t leaf, uint32_t subleaf,
+                  struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt)
 {
     /*
      * x86_emulate uses this function to query CPU features for its own 
internal
@@ -1568,7 +1564,7 @@ int hvmemul_cpuid(
          hvm_check_cpuid_faulting(current) )
         return X86EMUL_EXCEPTION;
 
-    hvm_cpuid(*eax, eax, ebx, ecx, edx);
+    guest_cpuid(current, leaf, subleaf, res);
     return X86EMUL_OKAY;
 }
 
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 04a7b60..6fb1cbc 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1572,23 +1572,20 @@ static void svm_fpu_dirty_intercept(void)
 
 static void svm_vmexit_do_cpuid(struct cpu_user_regs *regs)
 {
-    unsigned int eax, ebx, ecx, edx, inst_len;
+    struct vcpu *curr = current;
+    unsigned int inst_len;
+    struct cpuid_leaf res;
 
-    if ( (inst_len = __get_instruction_length(current, INSTR_CPUID)) == 0 )
+    if ( (inst_len = __get_instruction_length(curr, INSTR_CPUID)) == 0 )
         return;
 
-    eax = regs->_eax;
-    ebx = regs->_ebx;
-    ecx = regs->_ecx;
-    edx = regs->_edx;
-
-    hvm_cpuid(regs->_eax, &eax, &ebx, &ecx, &edx);
-    HVMTRACE_5D(CPUID, regs->_eax, eax, ebx, ecx, edx);
+    guest_cpuid(curr, regs->_eax, regs->_ecx, &res);
+    HVMTRACE_5D(CPUID, regs->_eax, res.a, res.b, res.c, res.d);
 
-    regs->rax = eax;
-    regs->rbx = ebx;
-    regs->rcx = ecx;
-    regs->rdx = edx;
+    regs->rax = res.a;
+    regs->rbx = res.b;
+    regs->rcx = res.c;
+    regs->rdx = res.d;
 
     __update_guest_eip(regs, inst_len);
 }
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index e75b190..01c225f 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2361,8 +2361,9 @@ static void vmx_fpu_dirty_intercept(void)
 
 static int vmx_do_cpuid(struct cpu_user_regs *regs)
 {
-    unsigned int eax, ebx, ecx, edx;
-    unsigned int leaf, subleaf;
+    struct vcpu *curr = current;
+    unsigned int leaf = regs->_eax, subleaf = regs->_ecx;
+    struct cpuid_leaf res;
 
     if ( hvm_check_cpuid_faulting(current) )
     {
@@ -2370,21 +2371,13 @@ static int vmx_do_cpuid(struct cpu_user_regs *regs)
         return 1;  /* Don't advance the guest IP! */
     }
 
-    eax = regs->_eax;
-    ebx = regs->_ebx;
-    ecx = regs->_ecx;
-    edx = regs->_edx;
-
-    leaf = regs->_eax;
-    subleaf = regs->_ecx;
+    guest_cpuid(curr, leaf, subleaf, &res);
+    HVMTRACE_5D(CPUID, leaf, res.a, res.b, res.c, res.d);
 
-    hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
-    HVMTRACE_5D(CPUID, leaf, eax, ebx, ecx, edx);
-
-    regs->rax = eax;
-    regs->rbx = ebx;
-    regs->rcx = ecx;
-    regs->rdx = edx;
+    regs->rax = res.a;
+    regs->rbx = res.b;
+    regs->rcx = res.c;
+    regs->rdx = res.d;
 
     return hvm_monitor_cpuid(get_instruction_length(), leaf, subleaf);
 }
@@ -3559,15 +3552,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
     }
     case EXIT_REASON_CPUID:
     {
-        int rc;
-
-        if ( is_pvh_vcpu(v) )
-        {
-            pv_cpuid(regs);
-            rc = 0;
-        }
-        else
-            rc = vmx_do_cpuid(regs);
+        int rc = vmx_do_cpuid(regs);
 
         /*
          * rc < 0 error in monitor/vm_event, crash
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index e45ff71..3acc244 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1412,6 +1412,7 @@ static int emulate_forced_invalid_op(struct cpu_user_regs 
*regs)
 {
     char sig[5], instr[2];
     unsigned long eip, rc;
+    struct cpuid_leaf res;
 
     eip = regs->rip;
 
@@ -1444,7 +1445,12 @@ static int emulate_forced_invalid_op(struct 
cpu_user_regs *regs)
 
     eip += sizeof(instr);
 
-    pv_cpuid(regs);
+    guest_cpuid(current, regs->_eax, regs->_ecx, &res);
+
+    regs->rax = res.a;
+    regs->rbx = res.b;
+    regs->rcx = res.c;
+    regs->rdx = res.d;
 
     instruction_done(regs, eip);
 
@@ -3254,10 +3260,10 @@ static int priv_op_wbinvd(struct x86_emulate_ctxt *ctxt)
     return X86EMUL_OKAY;
 }
 
-int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
-                  unsigned int *edx, struct x86_emulate_ctxt *ctxt)
+int pv_emul_cpuid(uint32_t leaf, uint32_t subleaf,
+                  struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt)
 {
-    struct cpu_user_regs regs = *ctxt->regs;
+    const struct vcpu *curr = current;
 
     /*
      * x86_emulate uses this function to query CPU features for its own
@@ -3266,7 +3272,6 @@ int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, 
unsigned int *ecx,
      */
     if ( ctxt->opcode == X86EMUL_OPC(0x0f, 0xa2) )
     {
-        const struct vcpu *curr = current;
 
         /* If cpuid faulting is enabled and CPL>0 leave the #GP untouched. */
         if ( curr->arch.cpuid_faulting &&
@@ -3274,15 +3279,7 @@ int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, 
unsigned int *ecx,
             return X86EMUL_EXCEPTION;
     }
 
-    regs._eax = *eax;
-    regs._ecx = *ecx;
-
-    pv_cpuid(&regs);
-
-    *eax = regs._eax;
-    *ebx = regs._ebx;
-    *ecx = regs._ecx;
-    *edx = regs._edx;
+    guest_cpuid(curr, leaf, subleaf, res);
 
     return X86EMUL_OKAY;
 }
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 98ba7c5..3dbc3ce 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1265,19 +1265,19 @@ static bool vcpu_has(
     struct x86_emulate_ctxt *ctxt,
     const struct x86_emulate_ops *ops)
 {
-    unsigned int ebx = 0, ecx = 0, edx = 0;
+    struct cpuid_leaf res;
     int rc = X86EMUL_OKAY;
 
     fail_if(!ops->cpuid);
-    rc = ops->cpuid(&eax, &ebx, &ecx, &edx, ctxt);
+    rc = ops->cpuid(eax, 0, &res, ctxt);
     if ( rc == X86EMUL_OKAY )
     {
         switch ( reg )
         {
-        case EAX: reg = eax; break;
-        case EBX: reg = ebx; break;
-        case ECX: reg = ecx; break;
-        case EDX: reg = edx; break;
+        case EAX: reg = res.a; break;
+        case EBX: reg = res.b; break;
+        case ECX: reg = res.c; break;
+        case EDX: reg = res.d; break;
         default: BUG();
         }
         if ( !(reg & (1U << bit)) )
@@ -2722,6 +2722,7 @@ x86_emulate(
     {
         enum x86_segment seg;
         struct segment_register cs, sreg;
+        struct cpuid_leaf cpuid_leaf;
 
     case 0x00 ... 0x05: add: /* add */
         emulate_2op_SrcV("add", src, dst, _regs._eflags);
@@ -4525,15 +4526,14 @@ x86_emulate(
 
         case 0xfc: /* clzero */
         {
-            unsigned int eax = 1, ebx = 0, dummy = 0;
             unsigned long zero = 0;
 
             base = ad_bytes == 8 ? _regs.r(ax) :
                    ad_bytes == 4 ? _regs._eax : _regs.ax;
             limit = 0;
             if ( vcpu_has_clflush() &&
-                 ops->cpuid(&eax, &ebx, &dummy, &dummy, ctxt) == X86EMUL_OKAY )
-                limit = ((ebx >> 8) & 0xff) * 8;
+                 ops->cpuid(1, 0, &cpuid_leaf, ctxt) == X86EMUL_OKAY )
+                limit = ((cpuid_leaf.b >> 8) & 0xff) * 8;
             generate_exception_if(limit < sizeof(long) ||
                                   (limit & (limit - 1)), EXC_UD);
             base &= ~(limit - 1);
@@ -5265,22 +5265,18 @@ x86_emulate(
         dst.val = test_cc(b, _regs._eflags);
         break;
 
-    case X86EMUL_OPC(0x0f, 0xa2): /* cpuid */ {
-        unsigned int eax = _regs._eax, ebx = _regs._ebx;
-        unsigned int ecx = _regs._ecx, edx = _regs._edx;
-
+    case X86EMUL_OPC(0x0f, 0xa2): /* cpuid */
         fail_if(ops->cpuid == NULL);
-        rc = ops->cpuid(&eax, &ebx, &ecx, &edx, ctxt);
+        rc = ops->cpuid(_regs._eax, _regs._ecx, &cpuid_leaf, ctxt);
         generate_exception_if(rc == X86EMUL_EXCEPTION,
                               EXC_GP, 0); /* CPUID Faulting? */
         if ( rc != X86EMUL_OKAY )
             goto done;
-        _regs.r(ax) = eax;
-        _regs.r(bx) = ebx;
-        _regs.r(cx) = ecx;
-        _regs.r(dx) = edx;
+        _regs.r(ax) = cpuid_leaf.a;
+        _regs.r(bx) = cpuid_leaf.b;
+        _regs.r(cx) = cpuid_leaf.c;
+        _regs.r(dx) = cpuid_leaf.d;
         break;
-    }
 
     case X86EMUL_OPC(0x0f, 0xa3): bt: /* bt */
         emulate_2op_SrcV_nobyte("bt", src, dst, _regs._eflags);
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h 
b/xen/arch/x86/x86_emulate/x86_emulate.h
index 43c0c5e..57ebfde 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -164,6 +164,11 @@ enum x86_emulate_fpu_type {
     X86EMUL_FPU_ymm  /* AVX/XOP instruction set (%ymm0-%ymm7/15) */
 };
 
+struct cpuid_leaf
+{
+    uint32_t a, b, c, d;
+};
+
 struct x86_emulate_state;
 
 /*
@@ -415,10 +420,9 @@ struct x86_emulate_ops
      * #GP[0].  Used to implement CPUID faulting.
      */
     int (*cpuid)(
-        unsigned int *eax,
-        unsigned int *ebx,
-        unsigned int *ecx,
-        unsigned int *edx,
+        uint32_t leaf,
+        uint32_t subleaf,
+        struct cpuid_leaf *res,
         struct x86_emulate_ctxt *ctxt);
 
     /*
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index 05f2c9a..4586c7d 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -17,6 +17,7 @@
 
 #ifndef __ASSEMBLY__
 #include <xen/types.h>
+#include <asm/x86_emulate.h>
 #include <public/sysctl.h>
 
 extern const uint32_t known_features[FSCAPINTS];
@@ -64,6 +65,9 @@ extern struct cpuidmasks cpuidmask_defaults;
 /* Whether or not cpuid faulting is available for the current domain. */
 DECLARE_PER_CPU(bool, cpuid_faulting_enabled);
 
+void guest_cpuid(const struct vcpu *v, uint32_t leaf,
+                 uint32_t subleaf, struct cpuid_leaf *res);
+
 #endif /* __ASSEMBLY__ */
 #endif /* !__X86_CPUID_H__ */
 
diff --git a/xen/include/asm-x86/hvm/emulate.h 
b/xen/include/asm-x86/hvm/emulate.h
index 68a95e4..83266bb 100644
--- a/xen/include/asm-x86/hvm/emulate.h
+++ b/xen/include/asm-x86/hvm/emulate.h
@@ -57,12 +57,8 @@ void hvm_emulate_init_per_insn(
     unsigned int insn_bytes);
 void hvm_emulate_writeback(
     struct hvm_emulate_ctxt *hvmemul_ctxt);
-int hvmemul_cpuid(
-    unsigned int *eax,
-    unsigned int *ebx,
-    unsigned int *ecx,
-    unsigned int *edx,
-    struct x86_emulate_ctxt *ctxt);
+int hvmemul_cpuid(uint32_t leaf, uint32_t subleaf,
+                  struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt);
 struct segment_register *hvmemul_get_seg_reg(
     enum x86_segment seg,
     struct hvm_emulate_ctxt *hvmemul_ctxt);
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index a15029c..93a073d 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -504,8 +504,8 @@ extern int mmcfg_intercept_write(enum x86_segment seg,
                                  void *p_data,
                                  unsigned int bytes,
                                  struct x86_emulate_ctxt *ctxt);
-int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
-                  unsigned int *edx, struct x86_emulate_ctxt *ctxt);
+int pv_emul_cpuid(uint32_t leaf, uint32_t subleaf,
+                  struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt);
 
 int  ptwr_do_page_fault(struct vcpu *, unsigned long,
                         struct cpu_user_regs *);
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.