ia64/xen-unstable

changeset 17476:cd5dc735bdf3

x86, hvm: Lots of MTRR/PAT emulation cleanup.

- Move MTRR MSR initialisation into hvmloader.
- Simplify initialisation logic by overlaying UC on default WB rather
than vice versa.
- Clean up hypervisor HVM MTRR/PAE code's interface with rest of
hypervisor.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Apr 16 13:36:44 2008 +0100 (2008-04-16)
parents 06242949ff56
children da4042899fd2
files tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/cacheattr.c tools/firmware/hvmloader/config.h tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/smp.c xen/arch/x86/cpu/mtrr/main.c xen/arch/x86/hvm/emulate.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/mtrr.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/mtrr.h
line diff
     1.1 --- a/tools/firmware/hvmloader/Makefile	Wed Apr 16 10:21:08 2008 +0100
     1.2 +++ b/tools/firmware/hvmloader/Makefile	Wed Apr 16 13:36:44 2008 +0100
     1.3 @@ -28,8 +28,9 @@ LOADADDR = 0x100000
     1.4  
     1.5  CFLAGS += $(CFLAGS_include) -I.
     1.6  
     1.7 -SRCS = hvmloader.c mp_tables.c util.c smbios.c 32bitbios_support.c smp.c
     1.8 -OBJS = $(patsubst %.c,%.o,$(SRCS))
     1.9 +SRCS  = hvmloader.c mp_tables.c util.c smbios.c 
    1.10 +SRCS += 32bitbios_support.c smp.c cacheattr.c
    1.11 +OBJS  = $(patsubst %.c,%.o,$(SRCS))
    1.12  
    1.13  .PHONY: all
    1.14  all: hvmloader
     2.1 --- a/tools/firmware/hvmloader/acpi/build.c	Wed Apr 16 10:21:08 2008 +0100
     2.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Wed Apr 16 13:36:44 2008 +0100
     2.3 @@ -84,8 +84,8 @@ static int construct_bios_info_table(uin
     2.4  
     2.5      bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
     2.6  
     2.7 -    bios_info->pci_min = 0xf0000000;
     2.8 -    bios_info->pci_len = 0x0c000000;
     2.9 +    bios_info->pci_min = PCI_MEMBASE;
    2.10 +    bios_info->pci_len = PCI_MEMSIZE;
    2.11  
    2.12      return align16(sizeof(*bios_info));
    2.13  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/firmware/hvmloader/cacheattr.c	Wed Apr 16 13:36:44 2008 +0100
     3.3 @@ -0,0 +1,99 @@
     3.4 +/*
     3.5 + * cacheattr.c: MTRR and PAT initialisation.
     3.6 + *
     3.7 + * Copyright (c) 2008, Citrix Systems, Inc.
     3.8 + * 
     3.9 + * Authors:
    3.10 + *    Keir Fraser <keir.fraser@citrix.com>
    3.11 + * 
    3.12 + * This program is free software; you can redistribute it and/or modify it
    3.13 + * under the terms and conditions of the GNU General Public License,
    3.14 + * version 2, as published by the Free Software Foundation.
    3.15 + *
    3.16 + * This program is distributed in the hope it will be useful, but WITHOUT
    3.17 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.18 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.19 + * more details.
    3.20 + *
    3.21 + * You should have received a copy of the GNU General Public License along with
    3.22 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.23 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.24 + */
    3.25 +
    3.26 +#include "util.h"
    3.27 +#include "config.h"
    3.28 +
    3.29 +#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
    3.30 +#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
    3.31 +#define MSR_MTRRcap          0x00fe
    3.32 +#define MSR_MTRRfix64K_00000 0x0250
    3.33 +#define MSR_MTRRfix16K_80000 0x0258
    3.34 +#define MSR_MTRRfix16K_A0000 0x0259
    3.35 +#define MSR_MTRRfix4K_C0000  0x0268
    3.36 +#define MSR_MTRRfix4K_C8000  0x0269
    3.37 +#define MSR_MTRRfix4K_D0000  0x026a
    3.38 +#define MSR_MTRRfix4K_D8000  0x026b
    3.39 +#define MSR_MTRRfix4K_E0000  0x026c
    3.40 +#define MSR_MTRRfix4K_E8000  0x026d
    3.41 +#define MSR_MTRRfix4K_F0000  0x026e
    3.42 +#define MSR_MTRRfix4K_F8000  0x026f
    3.43 +#define MSR_PAT              0x0277
    3.44 +#define MSR_MTRRdefType      0x02ff
    3.45 +
    3.46 +void cacheattr_init(void)
    3.47 +{
    3.48 +    uint32_t eax, ebx, ecx, edx;
    3.49 +    uint64_t mtrr_cap, mtrr_def, content, addr_mask;
    3.50 +    unsigned int i, nr_var_ranges, phys_bits = 36;
    3.51 +
    3.52 +    /* Does the CPU support architectural MTRRs? */
    3.53 +    cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
    3.54 +    if ( !(edx & (1u << 12)) )
    3.55 +         return;
    3.56 +
    3.57 +    /* Find the physical address size for this CPU. */
    3.58 +    cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
    3.59 +    if ( eax >= 0x80000008 )
    3.60 +    {
    3.61 +        cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
    3.62 +        phys_bits = (uint8_t)eax;
    3.63 +    }
    3.64 +
    3.65 +    printf("%u-bit phys ... ", phys_bits);
    3.66 +
    3.67 +    addr_mask = ((1ull << phys_bits) - 1) & ~((1ull << 12) - 1);
    3.68 +    mtrr_cap = rdmsr(MSR_MTRRcap);
    3.69 +    mtrr_def = (1u << 11) | 6; /* E, default type WB */
    3.70 +
    3.71 +    /* Fixed-range MTRRs supported? */
    3.72 +    if ( mtrr_cap & (1u << 8) )
    3.73 +    {
    3.74 +        /* 0x00000-0x9ffff: Write Back (WB) */
    3.75 +        content = 0x0606060606060606ull;
    3.76 +        wrmsr(MSR_MTRRfix64K_00000, content);
    3.77 +        wrmsr(MSR_MTRRfix16K_80000, content);
    3.78 +        /* 0xa0000-0xbffff: Write Combining (WC) */
    3.79 +        if ( mtrr_cap & (1u << 10) ) /* WC supported? */
    3.80 +            content = 0x0101010101010101ull;
    3.81 +        wrmsr(MSR_MTRRfix16K_A0000, content);
    3.82 +        /* 0xc0000-0xfffff: Write Back (WB) */
    3.83 +        content = 0x0606060606060606ull;
    3.84 +        for ( i = 0; i < 8; i++ )
    3.85 +            wrmsr(MSR_MTRRfix4K_C0000 + i, content);
    3.86 +        mtrr_def |= 1u << 10; /* FE */
    3.87 +        printf("fixed MTRRs ... ");
    3.88 +    }
    3.89 +
    3.90 +    /* Variable-range MTRRs supported? */
    3.91 +    nr_var_ranges = (uint8_t)mtrr_cap;
    3.92 +    if ( nr_var_ranges != 0 )
    3.93 +    {
    3.94 +        /* A single UC range covering PCI space. */
    3.95 +        wrmsr(MSR_MTRRphysBase(0), PCI_MEMBASE);
    3.96 +        wrmsr(MSR_MTRRphysMask(0),
    3.97 +              ((uint64_t)(int32_t)PCI_MEMBASE & addr_mask) | (1u << 11));
    3.98 +        printf("var MTRRs ... ");
    3.99 +    }
   3.100 +
   3.101 +    wrmsr(MSR_MTRRdefType, mtrr_def);
   3.102 +}
     4.1 --- a/tools/firmware/hvmloader/config.h	Wed Apr 16 10:21:08 2008 +0100
     4.2 +++ b/tools/firmware/hvmloader/config.h	Wed Apr 16 13:36:44 2008 +0100
     4.3 @@ -11,6 +11,9 @@
     4.4  #define PCI_ISA_DEVFN       0x08    /* dev 1, fn 0 */
     4.5  #define PCI_ISA_IRQ_MASK    0x0c20U /* ISA IRQs 5,10,11 are PCI connected */
     4.6  
     4.7 +#define PCI_MEMBASE         0xf0000000
     4.8 +#define PCI_MEMSIZE         0x0c000000
     4.9 +
    4.10  #define ROMBIOS_SEG            0xF000
    4.11  #define ROMBIOS_BEGIN          0x000F0000
    4.12  #define ROMBIOS_SIZE           0x00010000
     5.1 --- a/tools/firmware/hvmloader/hvmloader.c	Wed Apr 16 10:21:08 2008 +0100
     5.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Wed Apr 16 13:36:44 2008 +0100
     5.3 @@ -159,7 +159,7 @@ static void pci_setup(void)
     5.4      struct resource {
     5.5          uint32_t base, max;
     5.6      } *resource;
     5.7 -    struct resource mem_resource = { 0xf0000000, 0xfc000000 };
     5.8 +    struct resource mem_resource = { PCI_MEMBASE, PCI_MEMBASE + PCI_MEMSIZE };
     5.9      struct resource io_resource  = { 0xc000, 0x10000 };
    5.10  
    5.11      /* Create a list of device BARs in descending order of size. */
     6.1 --- a/tools/firmware/hvmloader/smp.c	Wed Apr 16 10:21:08 2008 +0100
     6.2 +++ b/tools/firmware/hvmloader/smp.c	Wed Apr 16 13:36:44 2008 +0100
     6.3 @@ -69,10 +69,12 @@ asm (
     6.4      "    .text                       \n"
     6.5      );
     6.6  
     6.7 +extern void cacheattr_init(void);
     6.8 +
     6.9  /*static*/ void ap_start(void)
    6.10  {
    6.11      printf(" - CPU%d ... ", ap_cpuid);
    6.12 -
    6.13 +    cacheattr_init();
    6.14      printf("done.\n");
    6.15      wmb();
    6.16      ap_callin = 1;
    6.17 @@ -122,12 +124,10 @@ void smp_initialise(void)
    6.18  {
    6.19      unsigned int i, nr_cpus = get_vcpu_nr();
    6.20  
    6.21 -    if ( nr_cpus <= 1 )
    6.22 -        return;
    6.23 -
    6.24      memcpy((void *)AP_BOOT_EIP, ap_boot_start, ap_boot_end - ap_boot_start);
    6.25  
    6.26      printf("Multiprocessor initialisation:\n");
    6.27 +    ap_start();
    6.28      for ( i = 1; i < nr_cpus; i++ )
    6.29          boot_cpu(i);
    6.30  }
     7.1 --- a/xen/arch/x86/cpu/mtrr/main.c	Wed Apr 16 10:21:08 2008 +0100
     7.2 +++ b/xen/arch/x86/cpu/mtrr/main.c	Wed Apr 16 13:36:44 2008 +0100
     7.3 @@ -586,8 +586,6 @@ struct mtrr_value {
     7.4  	unsigned long	lsize;
     7.5  };
     7.6  
     7.7 -extern void global_init_mtrr_pat(void);
     7.8 -
     7.9  /**
    7.10   * mtrr_bp_init - initialize mtrrs on the boot CPU
    7.11   *
    7.12 @@ -654,11 +652,8 @@ void __init mtrr_bp_init(void)
    7.13  	if (mtrr_if) {
    7.14  		set_num_var_ranges();
    7.15  		init_table();
    7.16 -		if (use_intel()) {
    7.17 +		if (use_intel())
    7.18  			get_mtrr_state();
    7.19 -			/* initialize some global data for MTRR/PAT virutalization */
    7.20 -			global_init_mtrr_pat();
    7.21 -		}
    7.22  	}
    7.23  }
    7.24  
     8.1 --- a/xen/arch/x86/hvm/emulate.c	Wed Apr 16 10:21:08 2008 +0100
     8.2 +++ b/xen/arch/x86/hvm/emulate.c	Wed Apr 16 13:36:44 2008 +0100
     8.3 @@ -603,7 +603,7 @@ static int hvmemul_read_msr(
     8.4  
     8.5      _regs.ecx = (uint32_t)reg;
     8.6  
     8.7 -    if ( (rc = hvm_funcs.msr_read_intercept(&_regs)) != 0 )
     8.8 +    if ( (rc = hvm_msr_read_intercept(&_regs)) != 0 )
     8.9          return rc;
    8.10  
    8.11      *val = ((uint64_t)(uint32_t)_regs.edx << 32) || (uint32_t)_regs.eax;
    8.12 @@ -621,7 +621,7 @@ static int hvmemul_write_msr(
    8.13      _regs.eax = (uint32_t)val;
    8.14      _regs.ecx = (uint32_t)reg;
    8.15  
    8.16 -    return hvm_funcs.msr_write_intercept(&_regs);
    8.17 +    return hvm_msr_write_intercept(&_regs);
    8.18  }
    8.19  
    8.20  static int hvmemul_wbinvd(
     9.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Apr 16 10:21:08 2008 +0100
     9.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Apr 16 13:36:44 2008 +0100
     9.3 @@ -620,8 +620,6 @@ static int hvm_load_cpu_ctxt(struct doma
     9.4  HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, hvm_load_cpu_ctxt,
     9.5                            1, HVMSR_PER_VCPU);
     9.6  
     9.7 -extern int reset_vmsr(struct mtrr_state *m, u64 *p);
     9.8 -
     9.9  int hvm_vcpu_initialise(struct vcpu *v)
    9.10  {
    9.11      int rc;
    9.12 @@ -647,7 +645,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
    9.13      spin_lock_init(&v->arch.hvm_vcpu.tm_lock);
    9.14      INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
    9.15  
    9.16 -    rc = reset_vmsr(&v->arch.hvm_vcpu.mtrr, &v->arch.hvm_vcpu.pat_cr);
    9.17 +    rc = hvm_vcpu_cacheattr_init(v);
    9.18      if ( rc != 0 )
    9.19          goto fail3;
    9.20  
    9.21 @@ -681,8 +679,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
    9.22  
    9.23  void hvm_vcpu_destroy(struct vcpu *v)
    9.24  {
    9.25 -    xfree(v->arch.hvm_vcpu.mtrr.var_ranges);
    9.26 -
    9.27 +    hvm_vcpu_cacheattr_destroy(v);
    9.28      vlapic_destroy(v);
    9.29      hvm_funcs.vcpu_destroy(v);
    9.30  
    9.31 @@ -1606,6 +1603,9 @@ void hvm_cpuid(unsigned int input, unsig
    9.32          *ebx &= 0x0000FFFFu;
    9.33          *ebx |= (current->vcpu_id * 2) << 24;
    9.34  
    9.35 +        /* We always support MTRR MSRs. */
    9.36 +        *edx |= bitmaskof(X86_FEATURE_MTRR);
    9.37 +
    9.38          *ecx &= (bitmaskof(X86_FEATURE_XMM3) |
    9.39                   bitmaskof(X86_FEATURE_SSSE3) |
    9.40                   bitmaskof(X86_FEATURE_CX16) |
    9.41 @@ -1657,6 +1657,146 @@ void hvm_cpuid(unsigned int input, unsig
    9.42      }
    9.43  }
    9.44  
    9.45 +int hvm_msr_read_intercept(struct cpu_user_regs *regs)
    9.46 +{
    9.47 +    uint32_t ecx = regs->ecx;
    9.48 +    uint64_t msr_content = 0;
    9.49 +    struct vcpu *v = current;
    9.50 +    uint64_t *var_range_base, *fixed_range_base;
    9.51 +    int index;
    9.52 +
    9.53 +    var_range_base = (uint64_t *)v->arch.hvm_vcpu.mtrr.var_ranges;
    9.54 +    fixed_range_base = (uint64_t *)v->arch.hvm_vcpu.mtrr.fixed_ranges;
    9.55 +
    9.56 +    switch ( ecx )
    9.57 +    {
    9.58 +    case MSR_IA32_TSC:
    9.59 +        msr_content = hvm_get_guest_time(v);
    9.60 +        break;
    9.61 +
    9.62 +    case MSR_IA32_APICBASE:
    9.63 +        msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
    9.64 +        break;
    9.65 +
    9.66 +    case MSR_IA32_MCG_CAP:
    9.67 +    case MSR_IA32_MCG_STATUS:
    9.68 +    case MSR_IA32_MC0_STATUS:
    9.69 +    case MSR_IA32_MC1_STATUS:
    9.70 +    case MSR_IA32_MC2_STATUS:
    9.71 +    case MSR_IA32_MC3_STATUS:
    9.72 +    case MSR_IA32_MC4_STATUS:
    9.73 +    case MSR_IA32_MC5_STATUS:
    9.74 +        /* No point in letting the guest see real MCEs */
    9.75 +        msr_content = 0;
    9.76 +        break;
    9.77 +
    9.78 +    case MSR_IA32_CR_PAT:
    9.79 +        msr_content = v->arch.hvm_vcpu.pat_cr;
    9.80 +        break;
    9.81 +
    9.82 +    case MSR_MTRRcap:
    9.83 +        msr_content = v->arch.hvm_vcpu.mtrr.mtrr_cap;
    9.84 +        break;
    9.85 +    case MSR_MTRRdefType:
    9.86 +        msr_content = v->arch.hvm_vcpu.mtrr.def_type
    9.87 +                        | (v->arch.hvm_vcpu.mtrr.enabled << 10);
    9.88 +        break;
    9.89 +    case MSR_MTRRfix64K_00000:
    9.90 +        msr_content = fixed_range_base[0];
    9.91 +        break;
    9.92 +    case MSR_MTRRfix16K_80000:
    9.93 +    case MSR_MTRRfix16K_A0000:
    9.94 +        index = regs->ecx - MSR_MTRRfix16K_80000;
    9.95 +        msr_content = fixed_range_base[index + 1];
    9.96 +        break;
    9.97 +    case MSR_MTRRfix4K_C0000...MSR_MTRRfix4K_F8000:
    9.98 +        index = regs->ecx - MSR_MTRRfix4K_C0000;
    9.99 +        msr_content = fixed_range_base[index + 3];
   9.100 +        break;
   9.101 +    case MSR_IA32_MTRR_PHYSBASE0...MSR_IA32_MTRR_PHYSMASK7:
   9.102 +        index = regs->ecx - MSR_IA32_MTRR_PHYSBASE0;
   9.103 +        msr_content = var_range_base[index];
   9.104 +        break;
   9.105 +
   9.106 +    default:
   9.107 +        return hvm_funcs.msr_read_intercept(regs);
   9.108 +    }
   9.109 +
   9.110 +    regs->eax = (uint32_t)msr_content;
   9.111 +    regs->edx = (uint32_t)(msr_content >> 32);
   9.112 +    return X86EMUL_OKAY;
   9.113 +}
   9.114 +
   9.115 +int hvm_msr_write_intercept(struct cpu_user_regs *regs)
   9.116 +{
   9.117 +    extern bool_t mtrr_var_range_msr_set(
   9.118 +        struct mtrr_state *v, u32 msr, u64 msr_content);
   9.119 +    extern bool_t mtrr_fix_range_msr_set(
   9.120 +        struct mtrr_state *v, int row, u64 msr_content);
   9.121 +    extern bool_t mtrr_def_type_msr_set(struct mtrr_state *v, u64 msr_content);
   9.122 +    extern bool_t pat_msr_set(u64 *pat, u64 msr);
   9.123 +
   9.124 +    uint32_t ecx = regs->ecx;
   9.125 +    uint64_t msr_content = (uint32_t)regs->eax | ((uint64_t)regs->edx << 32);
   9.126 +    struct vcpu *v = current;
   9.127 +    int index;
   9.128 +
   9.129 +    switch ( ecx )
   9.130 +    {
   9.131 +     case MSR_IA32_TSC:
   9.132 +        hvm_set_guest_time(v, msr_content);
   9.133 +        pt_reset(v);
   9.134 +        break;
   9.135 +
   9.136 +    case MSR_IA32_APICBASE:
   9.137 +        vlapic_msr_set(vcpu_vlapic(v), msr_content);
   9.138 +        break;
   9.139 +
   9.140 +    case MSR_IA32_CR_PAT:
   9.141 +        if ( !pat_msr_set(&v->arch.hvm_vcpu.pat_cr, msr_content) )
   9.142 +           goto gp_fault;
   9.143 +        break;
   9.144 +
   9.145 +    case MSR_MTRRcap:
   9.146 +        goto gp_fault;
   9.147 +    case MSR_MTRRdefType:
   9.148 +        if ( !mtrr_def_type_msr_set(&v->arch.hvm_vcpu.mtrr, msr_content) )
   9.149 +           goto gp_fault;
   9.150 +        break;
   9.151 +    case MSR_MTRRfix64K_00000:
   9.152 +        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr, 0, msr_content) )
   9.153 +            goto gp_fault;
   9.154 +        break;
   9.155 +    case MSR_MTRRfix16K_80000:
   9.156 +    case MSR_MTRRfix16K_A0000:
   9.157 +        index = regs->ecx - MSR_MTRRfix16K_80000 + 1;
   9.158 +        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr,
   9.159 +                                     index, msr_content) )
   9.160 +            goto gp_fault;
   9.161 +        break;
   9.162 +    case MSR_MTRRfix4K_C0000...MSR_MTRRfix4K_F8000:
   9.163 +        index = regs->ecx - MSR_MTRRfix4K_C0000 + 3;
   9.164 +        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr,
   9.165 +                                     index, msr_content) )
   9.166 +            goto gp_fault;
   9.167 +        break;
   9.168 +    case MSR_IA32_MTRR_PHYSBASE0...MSR_IA32_MTRR_PHYSMASK7:
   9.169 +        if ( !mtrr_var_range_msr_set(&v->arch.hvm_vcpu.mtrr,
   9.170 +                                     regs->ecx, msr_content) )
   9.171 +            goto gp_fault;
   9.172 +        break;
   9.173 +
   9.174 +    default:
   9.175 +        return hvm_funcs.msr_write_intercept(regs);
   9.176 +    }
   9.177 +
   9.178 +    return X86EMUL_OKAY;
   9.179 +
   9.180 +gp_fault:
   9.181 +    hvm_inject_exception(TRAP_gp_fault, 0, 0);
   9.182 +    return X86EMUL_EXCEPTION;
   9.183 +}
   9.184 +
   9.185  enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
   9.186  {
   9.187      unsigned long intr_shadow;
    10.1 --- a/xen/arch/x86/hvm/mtrr.c	Wed Apr 16 10:21:08 2008 +0100
    10.2 +++ b/xen/arch/x86/hvm/mtrr.c	Wed Apr 16 13:36:44 2008 +0100
    10.3 @@ -27,7 +27,6 @@
    10.4  #include <asm/hvm/support.h>
    10.5  #include <asm/hvm/cacheattr.h>
    10.6  
    10.7 -/* Xen holds the native MTRR MSRs */
    10.8  extern struct mtrr_state mtrr_state;
    10.9  
   10.10  static uint64_t phys_base_msr_mask;
   10.11 @@ -35,19 +34,17 @@ static uint64_t phys_mask_msr_mask;
   10.12  static uint32_t size_or_mask;
   10.13  static uint32_t size_and_mask;
   10.14  
   10.15 -static void init_pat_entry_tbl(uint64_t pat);
   10.16 -static void init_mtrr_epat_tbl(void);
   10.17 -static uint8_t get_mtrr_type(struct mtrr_state *m, paddr_t pa);
   10.18 -/* get page attribute fields (PAn) from PAT MSR */
   10.19 +/* Get page attribute fields (PAn) from PAT MSR. */
   10.20  #define pat_cr_2_paf(pat_cr,n)  ((((uint64_t)pat_cr) >> ((n)<<3)) & 0xff)
   10.21 -/* pat entry to PTE flags (PAT, PCD, PWT bits) */
   10.22 +
   10.23 +/* PAT entry to PTE flags (PAT, PCD, PWT bits). */
   10.24  static uint8_t pat_entry_2_pte_flags[8] = {
   10.25      0,           _PAGE_PWT,
   10.26      _PAGE_PCD,   _PAGE_PCD | _PAGE_PWT,
   10.27      _PAGE_PAT,   _PAGE_PAT | _PAGE_PWT,
   10.28      _PAGE_PAT | _PAGE_PCD, _PAGE_PAT | _PAGE_PCD | _PAGE_PWT };
   10.29  
   10.30 -/* effective mm type lookup table, according to MTRR and PAT */
   10.31 +/* Effective mm type lookup table, according to MTRR and PAT. */
   10.32  static uint8_t mm_type_tbl[MTRR_NUM_TYPES][PAT_TYPE_NUMS] = {
   10.33  /********PAT(UC,WC,RS,RS,WT,WP,WB,UC-)*/
   10.34  /* RS means reserved type(2,3), and type is hardcoded here */
   10.35 @@ -67,12 +64,13 @@ static uint8_t mm_type_tbl[MTRR_NUM_TYPE
   10.36              {0, 1, 2, 2, 4, 5, 6, 0}
   10.37  };
   10.38  
   10.39 -/* reverse lookup table, to find a pat type according to MTRR and effective
   10.40 - * memory type. This table is dynamically generated
   10.41 +/*
   10.42 + * Reverse lookup table, to find a pat type according to MTRR and effective
   10.43 + * memory type. This table is dynamically generated.
   10.44   */
   10.45  static uint8_t mtrr_epat_tbl[MTRR_NUM_TYPES][MEMORY_NUM_TYPES];
   10.46  
   10.47 -/* lookup table for PAT entry of a given PAT value in host pat */
   10.48 +/* Lookup table for PAT entry of a given PAT value in host PAT. */
   10.49  static uint8_t pat_entry_tbl[PAT_TYPE_NUMS];
   10.50  
   10.51  static void get_mtrr_range(uint64_t base_msr, uint64_t mask_msr,
   10.52 @@ -139,220 +137,63 @@ bool_t is_var_mtrr_overlapped(struct mtr
   10.53      return 0;
   10.54  }
   10.55  
   10.56 -/* reserved mtrr for guest OS */
   10.57 -#define RESERVED_MTRR 2
   10.58 +#define MTRR_PHYSMASK_VALID_BIT  11
   10.59 +#define MTRR_PHYSMASK_SHIFT      12
   10.60 +
   10.61 +#define MTRR_PHYSBASE_TYPE_MASK  0xff   /* lowest 8 bits */
   10.62 +#define MTRR_PHYSBASE_SHIFT      12
   10.63 +#define MTRR_VCNT                8
   10.64 +
   10.65  #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
   10.66  #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
   10.67  bool_t mtrr_var_range_msr_set(struct mtrr_state *m, uint32_t msr,
   10.68                                uint64_t msr_content);
   10.69 -bool_t mtrr_def_type_msr_set(struct mtrr_state *m, uint64_t msr_content);
   10.70  bool_t mtrr_fix_range_msr_set(struct mtrr_state *m, uint32_t row,
   10.71                                uint64_t msr_content);
   10.72 -static void set_var_mtrr(uint32_t reg, struct mtrr_state *m,
   10.73 -                         uint32_t base, uint32_t size,
   10.74 -                         uint32_t type)
   10.75 +
   10.76 +static int hvm_mtrr_pat_init(void)
   10.77  {
   10.78 -    struct mtrr_var_range *vr;
   10.79 -
   10.80 -    vr = &m->var_ranges[reg];
   10.81 -
   10.82 -    if ( size == 0 )
   10.83 -    {
   10.84 -        /* The invalid bit is kept in the mask, so we simply clear the
   10.85 -         * relevant mask register to disable a range.
   10.86 -         */
   10.87 -        mtrr_var_range_msr_set(m, MTRRphysMask_MSR(reg), 0);
   10.88 -    }
   10.89 -    else
   10.90 -    {
   10.91 -        vr->base_lo = base << PAGE_SHIFT | type;
   10.92 -        vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
   10.93 -        vr->mask_lo = -size << PAGE_SHIFT | 0x800;
   10.94 -        vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
   10.95 +    extern uint64_t host_pat;
   10.96 +    unsigned int i, j, phys_addr;
   10.97  
   10.98 -        mtrr_var_range_msr_set(m, MTRRphysBase_MSR(reg), *(uint64_t *)vr);
   10.99 -        mtrr_var_range_msr_set(m, MTRRphysMask_MSR(reg),
  10.100 -                               *((uint64_t *)vr + 1));
  10.101 -    }
  10.102 -}
  10.103 -/* From Intel Vol. III Section 10.11.4, the Range Size and Base Alignment has
  10.104 - * some kind of requirement:
  10.105 - * 1. The range size must be 2^N byte for N >= 12 (i.e 4KB minimum).
  10.106 - * 2. The base address must be 2^N aligned, where the N here is equal to
  10.107 - * the N in previous requirement. So a 8K range must be 8K aligned not 4K aligned.
  10.108 - */
  10.109 -static uint32_t range_to_mtrr(uint32_t reg, struct mtrr_state *m,
  10.110 -                              uint32_t range_startk, uint32_t range_sizek,
  10.111 -                              uint8_t type)
  10.112 -{
  10.113 -    if ( !range_sizek || (reg >= ((m->mtrr_cap & 0xff) - RESERVED_MTRR)) )
  10.114 +    memset(&mtrr_epat_tbl, INVALID_MEM_TYPE, sizeof(mtrr_epat_tbl));
  10.115 +    for ( i = 0; i < MTRR_NUM_TYPES; i++ )
  10.116      {
  10.117 -        gdprintk(XENLOG_WARNING,
  10.118 -                "Failed to init var mtrr msr[%d]"
  10.119 -                "range_size:%x, total available MSR:%d\n",
  10.120 -                reg, range_sizek,
  10.121 -                (uint32_t)((m->mtrr_cap & 0xff) - RESERVED_MTRR));
  10.122 -        return reg;
  10.123 -    }
  10.124 -
  10.125 -    while ( range_sizek )
  10.126 -    {
  10.127 -        uint32_t max_align, align, sizek;
  10.128 -
  10.129 -        max_align = (range_startk == 0) ? 32 : ffs(range_startk);
  10.130 -        align = min_t(uint32_t, fls(range_sizek), max_align);
  10.131 -        sizek = 1 << (align - 1);
  10.132 -
  10.133 -        set_var_mtrr(reg++, m, range_startk, sizek, type);
  10.134 -
  10.135 -        range_startk += sizek;
  10.136 -        range_sizek  -= sizek;
  10.137 -
  10.138 -        if ( reg >= ((m->mtrr_cap & 0xff) - RESERVED_MTRR) )
  10.139 +        for ( j = 0; j < PAT_TYPE_NUMS; j++ )
  10.140          {
  10.141 -            gdprintk(XENLOG_WARNING,
  10.142 -                    "Failed to init var mtrr msr[%d],"
  10.143 -                    "total available MSR:%d\n",
  10.144 -                    reg, (uint32_t)((m->mtrr_cap & 0xff) - RESERVED_MTRR));
  10.145 -            break;
  10.146 +            int32_t tmp = mm_type_tbl[i][j];
  10.147 +            if ( (tmp >= 0) && (tmp < MEMORY_NUM_TYPES) )
  10.148 +                mtrr_epat_tbl[i][tmp] = j;
  10.149          }
  10.150      }
  10.151  
  10.152 -    return reg;
  10.153 -}
  10.154 -
  10.155 -static void setup_fixed_mtrrs(struct vcpu *v)
  10.156 -{
  10.157 -    uint64_t content;
  10.158 -    int32_t i;
  10.159 -    struct mtrr_state *m = &v->arch.hvm_vcpu.mtrr;
  10.160 -
  10.161 -    /* 1. Map (0~A0000) as WB */
  10.162 -    content = 0x0606060606060606ull;
  10.163 -    mtrr_fix_range_msr_set(m, 0, content);
  10.164 -    mtrr_fix_range_msr_set(m, 1, content);
  10.165 -    /* 2. Map VRAM(A0000~C0000) as WC */
  10.166 -    content = 0x0101010101010101;
  10.167 -    mtrr_fix_range_msr_set(m, 2, content);
  10.168 -    /* 3. Map (C0000~100000) as UC */
  10.169 -    for ( i = 3; i < 11; i++)
  10.170 -        mtrr_fix_range_msr_set(m, i, 0);
  10.171 -}
  10.172 -
  10.173 -static void setup_var_mtrrs(struct vcpu *v)
  10.174 -{
  10.175 -    p2m_type_t p2m;
  10.176 -    uint64_t e820_mfn;
  10.177 -    int8_t *p = NULL;
  10.178 -    uint8_t nr = 0;
  10.179 -    int32_t i;
  10.180 -    uint32_t reg = 0;
  10.181 -    uint64_t size = 0;
  10.182 -    uint64_t addr = 0;
  10.183 -    struct e820entry *e820_table;
  10.184 -
  10.185 -    e820_mfn = mfn_x(gfn_to_mfn(v->domain,
  10.186 -                    HVM_E820_PAGE >> PAGE_SHIFT, &p2m));
  10.187 -
  10.188 -    p = (int8_t *)map_domain_page(e820_mfn);
  10.189 -
  10.190 -    nr = *(uint8_t*)(p + HVM_E820_NR_OFFSET);
  10.191 -    e820_table = (struct e820entry*)(p + HVM_E820_OFFSET);
  10.192 -    /* search E820 table, set MTRR for RAM */
  10.193 -    for ( i = 0; i < nr; i++)
  10.194 +    memset(&pat_entry_tbl, INVALID_MEM_TYPE,
  10.195 +           PAT_TYPE_NUMS * sizeof(pat_entry_tbl[0]));
  10.196 +    for ( i = 0; i < PAT_TYPE_NUMS; i++ )
  10.197      {
  10.198 -        if ( (e820_table[i].addr >= 0x100000) &&
  10.199 -             (e820_table[i].type == E820_RAM) )
  10.200 +        for ( j = 0; j < PAT_TYPE_NUMS; j++ )
  10.201          {
  10.202 -            if ( e820_table[i].addr == 0x100000 )
  10.203 +            if ( pat_cr_2_paf(host_pat, j) == i )
  10.204              {
  10.205 -                size = e820_table[i].size + 0x100000 + PAGE_SIZE * 5;
  10.206 -                addr = 0;
  10.207 +                pat_entry_tbl[i] = j;
  10.208 +                break;
  10.209              }
  10.210 -            else
  10.211 -            {
  10.212 -                /* Larger than 4G */
  10.213 -                size = e820_table[i].size;
  10.214 -                addr = e820_table[i].addr;
  10.215 -            }
  10.216 -
  10.217 -            reg = range_to_mtrr(reg, &v->arch.hvm_vcpu.mtrr,
  10.218 -                                addr >> PAGE_SHIFT, size >> PAGE_SHIFT,
  10.219 -                                MTRR_TYPE_WRBACK);
  10.220          }
  10.221      }
  10.222 -}
  10.223  
  10.224 -void init_mtrr_in_hyper(struct vcpu *v)
  10.225 -{
  10.226 -    /* TODO:MTRR should be initialized in BIOS or other places.
  10.227 -     * workaround to do it in here
  10.228 -     */
  10.229 -    if ( v->arch.hvm_vcpu.mtrr.is_initialized )
  10.230 -        return;
  10.231 -
  10.232 -    setup_fixed_mtrrs(v);
  10.233 -    setup_var_mtrrs(v);
  10.234 -    /* enable mtrr */
  10.235 -    mtrr_def_type_msr_set(&v->arch.hvm_vcpu.mtrr, 0xc00);
  10.236 -
  10.237 -    v->arch.hvm_vcpu.mtrr.is_initialized = 1;
  10.238 -}
  10.239 -
  10.240 -static int32_t reset_mtrr(struct mtrr_state *m)
  10.241 -{
  10.242 -    m->var_ranges = xmalloc_array(struct mtrr_var_range, MTRR_VCNT);
  10.243 -    if ( m->var_ranges == NULL )
  10.244 -        return -ENOMEM;
  10.245 -    memset(m->var_ranges, 0, MTRR_VCNT * sizeof(struct mtrr_var_range));
  10.246 -    memset(m->fixed_ranges, 0, sizeof(m->fixed_ranges));
  10.247 -    m->enabled = 0;
  10.248 -    m->def_type = 0;/*mtrr is disabled*/
  10.249 -    m->mtrr_cap = (0x5<<8)|MTRR_VCNT;/*wc,fix enabled, and vcnt=8*/
  10.250 -    m->overlapped = 0;
  10.251 -    return 0;
  10.252 -}
  10.253 -
  10.254 -/* init global variables for MTRR and PAT */
  10.255 -void global_init_mtrr_pat(void)
  10.256 -{
  10.257 -    extern uint64_t host_pat;
  10.258 -    uint32_t phys_addr;
  10.259 -
  10.260 -    init_mtrr_epat_tbl();
  10.261 -    init_pat_entry_tbl(host_pat);
  10.262 -    /* Get max physical address, set some global variable */
  10.263 -    if ( cpuid_eax(0x80000000) < 0x80000008 )
  10.264 -        phys_addr = 36;
  10.265 -    else
  10.266 -        phys_addr = cpuid_eax(0x80000008);
  10.267 +    phys_addr = 36;
  10.268 +    if ( cpuid_eax(0x80000000) >= 0x80000008 )
  10.269 +        phys_addr = (uint8_t)cpuid_eax(0x80000008);
  10.270  
  10.271      phys_base_msr_mask = ~((((uint64_t)1) << phys_addr) - 1) | 0xf00UL;
  10.272      phys_mask_msr_mask = ~((((uint64_t)1) << phys_addr) - 1) | 0x7ffUL;
  10.273  
  10.274      size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
  10.275      size_and_mask = ~size_or_mask & 0xfff00000;
  10.276 +
  10.277 +    return 0;
  10.278  }
  10.279 -
  10.280 -static void init_pat_entry_tbl(uint64_t pat)
  10.281 -{
  10.282 -    int32_t i, j;
  10.283 -
  10.284 -    memset(&pat_entry_tbl, INVALID_MEM_TYPE,
  10.285 -           PAT_TYPE_NUMS * sizeof(pat_entry_tbl[0]));
  10.286 -
  10.287 -    for ( i = 0; i < PAT_TYPE_NUMS; i++ )
  10.288 -    {
  10.289 -        for ( j = 0; j < PAT_TYPE_NUMS; j++ )
  10.290 -        {
  10.291 -            if ( pat_cr_2_paf(pat, j) == i )
  10.292 -            {
  10.293 -                pat_entry_tbl[i] = j;
  10.294 -                break;
  10.295 -            }
  10.296 -        }
  10.297 -    }
  10.298 -}
  10.299 +__initcall(hvm_mtrr_pat_init);
  10.300  
  10.301  uint8_t pat_type_2_pte_flags(uint8_t pat_type)
  10.302  {
  10.303 @@ -368,26 +209,37 @@ uint8_t pat_type_2_pte_flags(uint8_t pat
  10.304      return pat_entry_2_pte_flags[pat_entry_tbl[PAT_TYPE_UNCACHABLE]];
  10.305  }
  10.306  
  10.307 -int32_t reset_vmsr(struct mtrr_state *m, uint64_t *pat_ptr)
  10.308 +int hvm_vcpu_cacheattr_init(struct vcpu *v)
  10.309  {
  10.310 -    int32_t rc;
  10.311 +    struct mtrr_state *m = &v->arch.hvm_vcpu.mtrr;
  10.312  
  10.313 -    rc = reset_mtrr(m);
  10.314 -    if ( rc != 0 )
  10.315 -        return rc;
  10.316 +    memset(m, 0, sizeof(*m));
  10.317 +
  10.318 +    m->var_ranges = xmalloc_array(struct mtrr_var_range, MTRR_VCNT);
  10.319 +    if ( m->var_ranges == NULL )
  10.320 +        return -ENOMEM;
  10.321 +    memset(m->var_ranges, 0, MTRR_VCNT * sizeof(struct mtrr_var_range));
  10.322  
  10.323 -    *pat_ptr = ((uint64_t)PAT_TYPE_WRBACK) |               /* PAT0: WB */
  10.324 -               ((uint64_t)PAT_TYPE_WRTHROUGH << 8) |       /* PAT1: WT */
  10.325 -               ((uint64_t)PAT_TYPE_UC_MINUS << 16) |       /* PAT2: UC- */
  10.326 -               ((uint64_t)PAT_TYPE_UNCACHABLE << 24) |     /* PAT3: UC */
  10.327 -               ((uint64_t)PAT_TYPE_WRBACK << 32) |         /* PAT4: WB */
  10.328 -               ((uint64_t)PAT_TYPE_WRTHROUGH << 40) |      /* PAT5: WT */
  10.329 -               ((uint64_t)PAT_TYPE_UC_MINUS << 48) |       /* PAT6: UC- */
  10.330 -               ((uint64_t)PAT_TYPE_UNCACHABLE << 56);      /* PAT7: UC */
  10.331 +    m->mtrr_cap = (1u << 10) | (1u << 8) | MTRR_VCNT;
  10.332 +
  10.333 +    v->arch.hvm_vcpu.pat_cr =
  10.334 +        ((uint64_t)PAT_TYPE_WRBACK) |               /* PAT0: WB */
  10.335 +        ((uint64_t)PAT_TYPE_WRTHROUGH << 8) |       /* PAT1: WT */
  10.336 +        ((uint64_t)PAT_TYPE_UC_MINUS << 16) |       /* PAT2: UC- */
  10.337 +        ((uint64_t)PAT_TYPE_UNCACHABLE << 24) |     /* PAT3: UC */
  10.338 +        ((uint64_t)PAT_TYPE_WRBACK << 32) |         /* PAT4: WB */
  10.339 +        ((uint64_t)PAT_TYPE_WRTHROUGH << 40) |      /* PAT5: WT */
  10.340 +        ((uint64_t)PAT_TYPE_UC_MINUS << 48) |       /* PAT6: UC- */
  10.341 +        ((uint64_t)PAT_TYPE_UNCACHABLE << 56);      /* PAT7: UC */
  10.342  
  10.343      return 0;
  10.344  }
  10.345  
  10.346 +void hvm_vcpu_cacheattr_destroy(struct vcpu *v)
  10.347 +{
  10.348 +    xfree(v->arch.hvm_vcpu.mtrr.var_ranges);
  10.349 +}
  10.350 +
  10.351  /*
  10.352   * Get MTRR memory type for physical address pa.
  10.353   */
  10.354 @@ -512,23 +364,6 @@ static uint8_t effective_mm_type(struct 
  10.355      return effective;
  10.356  }
  10.357  
  10.358 -static void init_mtrr_epat_tbl(void)
  10.359 -{
  10.360 -    int32_t i, j;
  10.361 -    /* set default value to an invalid type, just for checking conflict */
  10.362 -    memset(&mtrr_epat_tbl, INVALID_MEM_TYPE, sizeof(mtrr_epat_tbl));
  10.363 -
  10.364 -    for ( i = 0; i < MTRR_NUM_TYPES; i++ )
  10.365 -    {
  10.366 -        for ( j = 0; j < PAT_TYPE_NUMS; j++ )
  10.367 -        {
  10.368 -            int32_t tmp = mm_type_tbl[i][j];
  10.369 -            if ( (tmp >= 0) && (tmp < MEMORY_NUM_TYPES) )
  10.370 -                mtrr_epat_tbl[i][tmp] = j;
  10.371 -        }
  10.372 -    }
  10.373 -}
  10.374 -
  10.375  uint32_t get_pat_flags(struct vcpu *v,
  10.376                         uint32_t gl1e_flags,
  10.377                         paddr_t gpaddr,
  10.378 @@ -856,7 +691,6 @@ static int hvm_load_mtrr_msr(struct doma
  10.379  
  10.380      mtrr_def_type_msr_set(mtrr_state, hw_mtrr.msr_mtrr_def_type);
  10.381  
  10.382 -    v->arch.hvm_vcpu.mtrr.is_initialized = 1;
  10.383      return 0;
  10.384  }
  10.385  
    11.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Apr 16 10:21:08 2008 +0100
    11.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Apr 16 13:36:44 2008 +0100
    11.3 @@ -911,6 +911,9 @@ static void svm_cpuid_intercept(
    11.4              __clear_bit(X86_FEATURE_PAE & 31, edx);
    11.5          __clear_bit(X86_FEATURE_PSE36 & 31, edx);
    11.6  
    11.7 +        /* We always support MTRR MSRs. */
    11.8 +        *edx |= bitmaskof(X86_FEATURE_MTRR);
    11.9 +
   11.10          /* Filter all other features according to a whitelist. */
   11.11          *ecx &= (bitmaskof(X86_FEATURE_LAHF_LM) |
   11.12                   bitmaskof(X86_FEATURE_ALTMOVCR) |
   11.13 @@ -981,14 +984,6 @@ static int svm_msr_read_intercept(struct
   11.14  
   11.15      switch ( ecx )
   11.16      {
   11.17 -    case MSR_IA32_TSC:
   11.18 -        msr_content = hvm_get_guest_time(v);
   11.19 -        break;
   11.20 -
   11.21 -    case MSR_IA32_APICBASE:
   11.22 -        msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
   11.23 -        break;
   11.24 -
   11.25      case MSR_EFER:
   11.26          msr_content = v->arch.hvm_vcpu.guest_efer;
   11.27          break;
   11.28 @@ -1014,18 +1009,6 @@ static int svm_msr_read_intercept(struct
   11.29      case MSR_K8_VM_HSAVE_PA:
   11.30          goto gpf;
   11.31  
   11.32 -    case MSR_IA32_MCG_CAP:
   11.33 -    case MSR_IA32_MCG_STATUS:
   11.34 -    case MSR_IA32_MC0_STATUS:
   11.35 -    case MSR_IA32_MC1_STATUS:
   11.36 -    case MSR_IA32_MC2_STATUS:
   11.37 -    case MSR_IA32_MC3_STATUS:
   11.38 -    case MSR_IA32_MC4_STATUS:
   11.39 -    case MSR_IA32_MC5_STATUS:
   11.40 -        /* No point in letting the guest see real MCEs */
   11.41 -        msr_content = 0;
   11.42 -        break;
   11.43 -
   11.44      case MSR_IA32_DEBUGCTLMSR:
   11.45          msr_content = vmcb->debugctlmsr;
   11.46          break;
   11.47 @@ -1083,15 +1066,6 @@ static int svm_msr_write_intercept(struc
   11.48  
   11.49      switch ( ecx )
   11.50      {
   11.51 -    case MSR_IA32_TSC:
   11.52 -        hvm_set_guest_time(v, msr_content);
   11.53 -        pt_reset(v);
   11.54 -        break;
   11.55 -
   11.56 -    case MSR_IA32_APICBASE:
   11.57 -        vlapic_msr_set(vcpu_vlapic(v), msr_content);
   11.58 -        break;
   11.59 -
   11.60      case MSR_K8_VM_HSAVE_PA:
   11.61          goto gpf;
   11.62  
   11.63 @@ -1152,12 +1126,12 @@ static void svm_do_msr_access(struct cpu
   11.64  
   11.65      if ( vmcb->exitinfo1 == 0 )
   11.66      {
   11.67 -        rc = svm_msr_read_intercept(regs);
   11.68 +        rc = hvm_msr_read_intercept(regs);
   11.69          inst_len = __get_instruction_length(v, INSTR_RDMSR, NULL);
   11.70      }
   11.71      else
   11.72      {
   11.73 -        rc = svm_msr_write_intercept(regs);
   11.74 +        rc = hvm_msr_write_intercept(regs);
   11.75          inst_len = __get_instruction_length(v, INSTR_WRMSR, NULL);
   11.76      }
   11.77  
    12.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Apr 16 10:21:08 2008 +0100
    12.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Apr 16 13:36:44 2008 +0100
    12.3 @@ -1622,17 +1622,11 @@ static int vmx_msr_read_intercept(struct
    12.4      u64 msr_content = 0;
    12.5      u32 ecx = regs->ecx, eax, edx;
    12.6      struct vcpu *v = current;
    12.7 -    int index;
    12.8 -    u64 *var_range_base = (u64*)v->arch.hvm_vcpu.mtrr.var_ranges;
    12.9 -    u64 *fixed_range_base =  (u64*)v->arch.hvm_vcpu.mtrr.fixed_ranges;
   12.10  
   12.11      HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x", ecx);
   12.12  
   12.13      switch ( ecx )
   12.14      {
   12.15 -    case MSR_IA32_TSC:
   12.16 -        msr_content = hvm_get_guest_time(v);
   12.17 -        break;
   12.18      case MSR_IA32_SYSENTER_CS:
   12.19          msr_content = (u32)__vmread(GUEST_SYSENTER_CS);
   12.20          break;
   12.21 @@ -1642,35 +1636,6 @@ static int vmx_msr_read_intercept(struct
   12.22      case MSR_IA32_SYSENTER_EIP:
   12.23          msr_content = __vmread(GUEST_SYSENTER_EIP);
   12.24          break;
   12.25 -    case MSR_IA32_APICBASE:
   12.26 -        msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
   12.27 -        break;
   12.28 -    case MSR_IA32_CR_PAT:
   12.29 -        msr_content = v->arch.hvm_vcpu.pat_cr;
   12.30 -        break;
   12.31 -    case MSR_MTRRcap:
   12.32 -        msr_content = v->arch.hvm_vcpu.mtrr.mtrr_cap;
   12.33 -        break;
   12.34 -    case MSR_MTRRdefType:
   12.35 -        msr_content = v->arch.hvm_vcpu.mtrr.def_type
   12.36 -                        | (v->arch.hvm_vcpu.mtrr.enabled << 10);
   12.37 -        break;
   12.38 -    case MSR_MTRRfix64K_00000:
   12.39 -        msr_content = fixed_range_base[0];
   12.40 -        break;
   12.41 -    case MSR_MTRRfix16K_80000:
   12.42 -    case MSR_MTRRfix16K_A0000:
   12.43 -        index = regs->ecx - MSR_MTRRfix16K_80000;
   12.44 -        msr_content = fixed_range_base[index + 1];
   12.45 -        break;
   12.46 -    case MSR_MTRRfix4K_C0000...MSR_MTRRfix4K_F8000:
   12.47 -        index = regs->ecx - MSR_MTRRfix4K_C0000;
   12.48 -        msr_content = fixed_range_base[index + 3];
   12.49 -        break;
   12.50 -    case MSR_IA32_MTRR_PHYSBASE0...MSR_IA32_MTRR_PHYSMASK7:
   12.51 -        index = regs->ecx - MSR_IA32_MTRR_PHYSBASE0;
   12.52 -        msr_content = var_range_base[index];
   12.53 -        break;
   12.54      case MSR_IA32_DEBUGCTLMSR:
   12.55          msr_content = __vmread(GUEST_IA32_DEBUGCTL);
   12.56  #ifdef __i386__
   12.57 @@ -1679,17 +1644,6 @@ static int vmx_msr_read_intercept(struct
   12.58          break;
   12.59      case MSR_IA32_VMX_BASIC...MSR_IA32_VMX_PROCBASED_CTLS2:
   12.60          goto gp_fault;
   12.61 -    case MSR_IA32_MCG_CAP:
   12.62 -    case MSR_IA32_MCG_STATUS:
   12.63 -    case MSR_IA32_MC0_STATUS:
   12.64 -    case MSR_IA32_MC1_STATUS:
   12.65 -    case MSR_IA32_MC2_STATUS:
   12.66 -    case MSR_IA32_MC3_STATUS:
   12.67 -    case MSR_IA32_MC4_STATUS:
   12.68 -    case MSR_IA32_MC5_STATUS:
   12.69 -        /* No point in letting the guest see real MCEs */
   12.70 -        msr_content = 0;
   12.71 -        break;
   12.72      case MSR_IA32_MISC_ENABLE:
   12.73          rdmsrl(MSR_IA32_MISC_ENABLE, msr_content);
   12.74          /* Debug Trace Store is not supported. */
   12.75 @@ -1729,8 +1683,8 @@ static int vmx_msr_read_intercept(struct
   12.76          goto gp_fault;
   12.77      }
   12.78  
   12.79 -    regs->eax = msr_content & 0xFFFFFFFF;
   12.80 -    regs->edx = msr_content >> 32;
   12.81 +    regs->eax = (uint32_t)msr_content;
   12.82 +    regs->edx = (uint32_t)(msr_content >> 32);
   12.83  
   12.84  done:
   12.85      hvmtrace_msr_read(v, ecx, msr_content);
   12.86 @@ -1833,19 +1787,11 @@ void vmx_vlapic_msr_changed(struct vcpu 
   12.87      vmx_vmcs_exit(v);
   12.88  }
   12.89  
   12.90 -extern bool_t mtrr_var_range_msr_set(struct mtrr_state *v,
   12.91 -        u32 msr, u64 msr_content);
   12.92 -extern bool_t mtrr_fix_range_msr_set(struct mtrr_state *v,
   12.93 -        int row, u64 msr_content);
   12.94 -extern bool_t mtrr_def_type_msr_set(struct mtrr_state *v, u64 msr_content);
   12.95 -extern bool_t pat_msr_set(u64 *pat, u64 msr);
   12.96 -
   12.97  static int vmx_msr_write_intercept(struct cpu_user_regs *regs)
   12.98  {
   12.99      u32 ecx = regs->ecx;
  12.100      u64 msr_content;
  12.101      struct vcpu *v = current;
  12.102 -    int index;
  12.103  
  12.104      HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x",
  12.105                  ecx, (u32)regs->eax, (u32)regs->edx);
  12.106 @@ -1856,10 +1802,6 @@ static int vmx_msr_write_intercept(struc
  12.107  
  12.108      switch ( ecx )
  12.109      {
  12.110 -    case MSR_IA32_TSC:
  12.111 -        hvm_set_guest_time(v, msr_content);
  12.112 -        pt_reset(v);
  12.113 -        break;
  12.114      case MSR_IA32_SYSENTER_CS:
  12.115          __vmwrite(GUEST_SYSENTER_CS, msr_content);
  12.116          break;
  12.117 @@ -1869,41 +1811,6 @@ static int vmx_msr_write_intercept(struc
  12.118      case MSR_IA32_SYSENTER_EIP:
  12.119          __vmwrite(GUEST_SYSENTER_EIP, msr_content);
  12.120          break;
  12.121 -    case MSR_IA32_APICBASE:
  12.122 -        vlapic_msr_set(vcpu_vlapic(v), msr_content);
  12.123 -        break;
  12.124 -    case MSR_IA32_CR_PAT:
  12.125 -        if ( !pat_msr_set(&v->arch.hvm_vcpu.pat_cr, msr_content) )
  12.126 -           goto gp_fault;
  12.127 -        break;
  12.128 -    case MSR_MTRRdefType:
  12.129 -        if ( !mtrr_def_type_msr_set(&v->arch.hvm_vcpu.mtrr, msr_content) )
  12.130 -           goto gp_fault;
  12.131 -        break;
  12.132 -    case MSR_MTRRfix64K_00000:
  12.133 -        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr, 0, msr_content) )
  12.134 -            goto gp_fault;
  12.135 -        break;
  12.136 -    case MSR_MTRRfix16K_80000:
  12.137 -    case MSR_MTRRfix16K_A0000:
  12.138 -        index = regs->ecx - MSR_MTRRfix16K_80000 + 1;
  12.139 -        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr,
  12.140 -                                     index, msr_content) )
  12.141 -            goto gp_fault;
  12.142 -        break;
  12.143 -    case MSR_MTRRfix4K_C0000...MSR_MTRRfix4K_F8000:
  12.144 -        index = regs->ecx - MSR_MTRRfix4K_C0000 + 3;
  12.145 -        if ( !mtrr_fix_range_msr_set(&v->arch.hvm_vcpu.mtrr,
  12.146 -                                     index, msr_content) )
  12.147 -            goto gp_fault;
  12.148 -        break;
  12.149 -    case MSR_IA32_MTRR_PHYSBASE0...MSR_IA32_MTRR_PHYSMASK7:
  12.150 -        if ( !mtrr_var_range_msr_set(&v->arch.hvm_vcpu.mtrr,
  12.151 -                                     regs->ecx, msr_content) )
  12.152 -            goto gp_fault;
  12.153 -        break;
  12.154 -    case MSR_MTRRcap:
  12.155 -        goto gp_fault;
  12.156      case MSR_IA32_DEBUGCTLMSR: {
  12.157          int i, rc = 0;
  12.158  
  12.159 @@ -2330,12 +2237,12 @@ asmlinkage void vmx_vmexit_handler(struc
  12.160          break;
  12.161      case EXIT_REASON_MSR_READ:
  12.162          inst_len = __get_instruction_length(); /* Safe: RDMSR */
  12.163 -        if ( vmx_msr_read_intercept(regs) == X86EMUL_OKAY )
  12.164 +        if ( hvm_msr_read_intercept(regs) == X86EMUL_OKAY )
  12.165              __update_guest_eip(inst_len);
  12.166          break;
  12.167      case EXIT_REASON_MSR_WRITE:
  12.168          inst_len = __get_instruction_length(); /* Safe: WRMSR */
  12.169 -        if ( vmx_msr_write_intercept(regs) == X86EMUL_OKAY )
  12.170 +        if ( hvm_msr_write_intercept(regs) == X86EMUL_OKAY )
  12.171              __update_guest_eip(inst_len);
  12.172          break;
  12.173  
    13.1 --- a/xen/arch/x86/mm.c	Wed Apr 16 10:21:08 2008 +0100
    13.2 +++ b/xen/arch/x86/mm.c	Wed Apr 16 13:36:44 2008 +0100
    13.3 @@ -3279,15 +3279,6 @@ long arch_memory_op(int op, XEN_GUEST_HA
    13.4          case XENMAPSPACE_shared_info:
    13.5              if ( xatp.idx == 0 )
    13.6                  mfn = virt_to_mfn(d->shared_info);
    13.7 -            /* XXX: assumption here, this is called after E820 table is build
    13.8 -             * need the E820 to initialize MTRR.
    13.9 -             */
   13.10 -            if ( is_hvm_domain(d) ) {
   13.11 -                extern void init_mtrr_in_hyper(struct vcpu *);
   13.12 -                struct vcpu *vs;
   13.13 -                for_each_vcpu(d, vs)
   13.14 -                    init_mtrr_in_hyper(vs);
   13.15 -            }
   13.16              break;
   13.17          case XENMAPSPACE_grant_table:
   13.18              spin_lock(&d->grant_table->lock);
    14.1 --- a/xen/include/asm-x86/hvm/hvm.h	Wed Apr 16 10:21:08 2008 +0100
    14.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Wed Apr 16 13:36:44 2008 +0100
    14.3 @@ -139,6 +139,8 @@ void hvm_domain_destroy(struct domain *d
    14.4  int hvm_vcpu_initialise(struct vcpu *v);
    14.5  void hvm_vcpu_destroy(struct vcpu *v);
    14.6  void hvm_vcpu_down(struct vcpu *v);
    14.7 +int hvm_vcpu_cacheattr_init(struct vcpu *v);
    14.8 +void hvm_vcpu_cacheattr_destroy(struct vcpu *v);
    14.9  
   14.10  void hvm_send_assist_req(struct vcpu *v);
   14.11  
    15.1 --- a/xen/include/asm-x86/hvm/support.h	Wed Apr 16 10:21:08 2008 +0100
    15.2 +++ b/xen/include/asm-x86/hvm/support.h	Wed Apr 16 13:36:44 2008 +0100
    15.3 @@ -130,5 +130,7 @@ int hvm_set_efer(uint64_t value);
    15.4  int hvm_set_cr0(unsigned long value);
    15.5  int hvm_set_cr3(unsigned long value);
    15.6  int hvm_set_cr4(unsigned long value);
    15.7 +int hvm_msr_read_intercept(struct cpu_user_regs *regs);
    15.8 +int hvm_msr_write_intercept(struct cpu_user_regs *regs);
    15.9  
   15.10  #endif /* __ASM_X86_HVM_SUPPORT_H__ */
    16.1 --- a/xen/include/asm-x86/mtrr.h	Wed Apr 16 10:21:08 2008 +0100
    16.2 +++ b/xen/include/asm-x86/mtrr.h	Wed Apr 16 13:36:44 2008 +0100
    16.3 @@ -12,13 +12,6 @@
    16.4  #define MTRR_NUM_TYPES       7
    16.5  #define MEMORY_NUM_TYPES     MTRR_NUM_TYPES
    16.6  
    16.7 -#define MTRR_PHYSMASK_VALID_BIT  11
    16.8 -#define MTRR_PHYSMASK_SHIFT      12
    16.9 -
   16.10 -#define MTRR_PHYSBASE_TYPE_MASK  0xff   /* lowest 8 bits */
   16.11 -#define MTRR_PHYSBASE_SHIFT      12
   16.12 -#define MTRR_VCNT            8
   16.13 -
   16.14  #define NORMAL_CACHE_MODE          0
   16.15  #define NO_FILL_CACHE_MODE         2
   16.16  
   16.17 @@ -58,7 +51,6 @@ struct mtrr_state {
   16.18  	u64       mtrr_cap;
   16.19  	/* ranges in var MSRs are overlapped or not:0(no overlapped) */
   16.20  	bool_t    overlapped;
   16.21 -	bool_t    is_initialized;
   16.22  };
   16.23  
   16.24  extern void mtrr_save_fixed_ranges(void *);