ia64/xen-unstable

changeset 16951:0d70e01c0012

vmx realmode: Emulate MSR accesses.
Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 31 09:33:26 2008 +0000 (2008-01-31)
parents a6c037d8cba3
children 0faf620bc749
files xen/arch/x86/hvm/vmx/realmode.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vmx/vmx.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Thu Jan 31 09:13:27 2008 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Thu Jan 31 09:33:26 2008 +0000
     1.3 @@ -410,6 +410,52 @@ realmode_write_cr(
     1.4      return X86EMUL_OKAY;
     1.5  }
     1.6  
     1.7 +static int
     1.8 +realmode_read_msr(
     1.9 +    unsigned long reg,
    1.10 +    uint64_t *val,
    1.11 +    struct x86_emulate_ctxt *ctxt)
    1.12 +{
    1.13 +    struct cpu_user_regs _regs = { .ecx = (uint32_t)reg };
    1.14 +
    1.15 +    if ( !vmx_msr_read_intercept(&_regs) )
    1.16 +    {
    1.17 +        struct realmode_emulate_ctxt *rm_ctxt =
    1.18 +            container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    1.19 +        rm_ctxt->exn_vector = (uint8_t)__vmread(VM_ENTRY_INTR_INFO);
    1.20 +        rm_ctxt->exn_insn_len = 0;
    1.21 +        __vmwrite(VM_ENTRY_INTR_INFO, 0);
    1.22 +        return X86EMUL_EXCEPTION;
    1.23 +    }
    1.24 +
    1.25 +    *val = ((uint64_t)(uint32_t)_regs.edx << 32) || (uint32_t)_regs.eax;
    1.26 +    return X86EMUL_OKAY;
    1.27 +}
    1.28 +
    1.29 +static int
    1.30 +realmode_write_msr(
    1.31 +    unsigned long reg,
    1.32 +    uint64_t val,
    1.33 +    struct x86_emulate_ctxt *ctxt)
    1.34 +{
    1.35 +    struct cpu_user_regs _regs = {
    1.36 +        .edx = (uint32_t)(val >> 32),
    1.37 +        .eax = (uint32_t)val,
    1.38 +        .ecx = (uint32_t)reg };
    1.39 +
    1.40 +    if ( !vmx_msr_write_intercept(&_regs) )
    1.41 +    {
    1.42 +        struct realmode_emulate_ctxt *rm_ctxt =
    1.43 +            container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
    1.44 +        rm_ctxt->exn_vector = (uint8_t)__vmread(VM_ENTRY_INTR_INFO);
    1.45 +        rm_ctxt->exn_insn_len = 0;
    1.46 +        __vmwrite(VM_ENTRY_INTR_INFO, 0);
    1.47 +        return X86EMUL_EXCEPTION;
    1.48 +    }
    1.49 +
    1.50 +    return X86EMUL_OKAY;
    1.51 +}
    1.52 +
    1.53  static int realmode_write_rflags(
    1.54      unsigned long val,
    1.55      struct x86_emulate_ctxt *ctxt)
    1.56 @@ -495,6 +541,8 @@ static struct x86_emulate_ops realmode_e
    1.57      .write_io      = realmode_write_io,
    1.58      .read_cr       = realmode_read_cr,
    1.59      .write_cr      = realmode_write_cr,
    1.60 +    .read_msr      = realmode_read_msr,
    1.61 +    .write_msr     = realmode_write_msr,
    1.62      .write_rflags  = realmode_write_rflags,
    1.63      .wbinvd        = realmode_wbinvd,
    1.64      .cpuid         = realmode_cpuid,
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Jan 31 09:13:27 2008 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Jan 31 09:33:26 2008 +0000
     2.3 @@ -2315,7 +2315,7 @@ static int is_last_branch_msr(u32 ecx)
     2.4      return 0;
     2.5  }
     2.6  
     2.7 -static int vmx_do_msr_read(struct cpu_user_regs *regs)
     2.8 +int vmx_msr_read_intercept(struct cpu_user_regs *regs)
     2.9  {
    2.10      u64 msr_content = 0;
    2.11      u32 ecx = regs->ecx, eax, edx;
    2.12 @@ -2507,7 +2507,7 @@ extern bool_t mtrr_fix_range_msr_set(str
    2.13  extern bool_t mtrr_def_type_msr_set(struct mtrr_state *v, u64 msr_content);
    2.14  extern bool_t pat_msr_set(u64 *pat, u64 msr);
    2.15  
    2.16 -static int vmx_do_msr_write(struct cpu_user_regs *regs)
    2.17 +int vmx_msr_write_intercept(struct cpu_user_regs *regs)
    2.18  {
    2.19      u32 ecx = regs->ecx;
    2.20      u64 msr_content;
    2.21 @@ -2949,12 +2949,12 @@ asmlinkage void vmx_vmexit_handler(struc
    2.22          break;
    2.23      case EXIT_REASON_MSR_READ:
    2.24          inst_len = __get_instruction_length(); /* Safe: RDMSR */
    2.25 -        if ( vmx_do_msr_read(regs) )
    2.26 +        if ( vmx_msr_read_intercept(regs) )
    2.27              __update_guest_eip(inst_len);
    2.28          break;
    2.29      case EXIT_REASON_MSR_WRITE:
    2.30          inst_len = __get_instruction_length(); /* Safe: WRMSR */
    2.31 -        if ( vmx_do_msr_write(regs) )
    2.32 +        if ( vmx_msr_write_intercept(regs) )
    2.33              __update_guest_eip(inst_len);
    2.34          break;
    2.35  
     3.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Thu Jan 31 09:13:27 2008 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Thu Jan 31 09:33:26 2008 +0000
     3.3 @@ -37,6 +37,8 @@ void vmx_do_no_device_fault(void);
     3.4  void vmx_cpuid_intercept(
     3.5      unsigned int *eax, unsigned int *ebx,
     3.6      unsigned int *ecx, unsigned int *edx);
     3.7 +int vmx_msr_read_intercept(struct cpu_user_regs *regs);
     3.8 +int vmx_msr_write_intercept(struct cpu_user_regs *regs);
     3.9  void vmx_wbinvd_intercept(void);
    3.10  void vmx_realmode(struct cpu_user_regs *regs);
    3.11  int vmx_realmode_io_complete(void);