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

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



> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@xxxxxxxxxx]
> Sent: 09 January 2017 11:03
> To: Xen-devel <xen-devel@xxxxxxxxxxxxx>
> Cc: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; Jan Beulich
> <JBeulich@xxxxxxxx>; Paul Durrant <Paul.Durrant@xxxxxxxxxx>; Jun
> Nakajima <jun.nakajima@xxxxxxxxx>; Kevin Tian <kevin.tian@xxxxxxxxx>;
> Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>; Suravee Suthikulpanit
> <suravee.suthikulpanit@xxxxxxx>
> Subject: [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>

Emulation changes...

Reviewed-by: Paul Durrant <paul.durrant@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®.