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

Re: [Xen-devel] [PATCH v4 2/2] x86/Intel: virtualize support for cpuid faulting



On 17/10/16 19:51, Kyle Huey wrote:
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index 6ed7486..a713ff3 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -1544,16 +1544,35 @@ static int hvmemul_wbinvd(
>  
>  static int hvmemul_cpuid(
>      unsigned int *eax,
>      unsigned int *ebx,
>      unsigned int *ecx,
>      unsigned int *edx,
>      struct x86_emulate_ctxt *ctxt)
>  {
> +    /*
> +     * x86_emulate uses this function to query CPU features for its own 
> internal
> +     * use. Make sure we're actually emulating CPUID before emulating CPUID
> +     * faulting.

Looking into this, it is all a complete tangle.

Conceptually, the correct way to do this is to introduce
cpuid_faulting_active() to mirror the existing umip_active().  However,
the read_msr() infrastructure latched a #GP fault behind the back of the
emulator, so doesn't work for speculative reads.

Therefore, I am happy to accept the code in this form, because it looks
like the least bad option available at the moment.  I will see about
fixing it when I do the planned MSR overhaul work.

Otherwise, just a few style corrections.

> +     */
> +    if ( ctxt->opcode == X86EMUL_OPC(0x0f, 0xa2) &&
> +         hvm_check_cpuid_fault(current) ) {

Brace on newline please.

> +        struct hvm_emulate_ctxt *hvmemul_ctxt =
> +            container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
> +
> +        hvmemul_ctxt->exn_pending = 1;
> +        hvmemul_ctxt->trap.vector = TRAP_gp_fault;
> +        hvmemul_ctxt->trap.type = X86_EVENTTYPE_HW_EXCEPTION;
> +        hvmemul_ctxt->trap.error_code = 0;
> +        hvmemul_ctxt->trap.insn_len = 0;
> +
> +        return X86EMUL_EXCEPTION;
> +    }
> +
>      hvm_funcs.cpuid_intercept(eax, ebx, ecx, edx);
>      return X86EMUL_OKAY;
>  }
>  
>  static int hvmemul_inject_hw_exception(
>      uint8_t vector,
>      int32_t error_code,
>      struct x86_emulate_ctxt *ctxt)
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index b9102ce..228c1b9 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -2428,16 +2428,21 @@ static void vmx_cpuid_intercept(
>      HVMTRACE_5D (CPUID, input, *eax, *ebx, *ecx, *edx);
>  }
>  
>  static int vmx_do_cpuid(struct cpu_user_regs *regs)
>  {
>      unsigned int eax, ebx, ecx, edx;
>      unsigned int leaf, subleaf;
>  
> +    if ( hvm_check_cpuid_fault(current) ) {

And here please.

> +        hvm_inject_hw_exception(TRAP_gp_fault, 0);
> +        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;
>  
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
> index 293ff8d..12322bd 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -1315,16 +1315,24 @@ static int emulate_forced_invalid_op(struct 
> cpu_user_regs *regs)
>      /* We only emulate CPUID. */
>      if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 )
>      {
>          propagate_page_fault(eip + sizeof(instr) - rc, 0);
>          return EXCRET_fault_fixed;
>      }
>      if ( memcmp(instr, "\xf\xa2", sizeof(instr)) )
>          return 0;
> +
> +    /* If cpuid faulting is enabled and CPL>0 inject a #GP in place of #UD. 
> */
> +    if ( current->arch.cpuid_fault && !guest_kernel_mode(current, regs) ) {

And here.

~Andrew

> +        regs->eip = eip;
> +        do_guest_trap(TRAP_gp_fault, regs);
> +        return EXCRET_fault_fixed;
> +    }
> +
>      eip += sizeof(instr);
>  
>      pv_cpuid(regs);
>  
>      instruction_done(regs, eip, 0);
>  
>      trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->eip);
>  
>

_______________________________________________
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®.