diff -r 704151d0e219 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h Thu Mar 29 18:26:12 2007 +0100 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h Thu Mar 29 13:15:54 2007 +0800 @@ -158,8 +158,8 @@ static inline unsigned int cpuid_edx(uns #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ #define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */ #define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ -#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */ -#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */ +#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ #define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow (or USER_GS from kernel) */ /* EFER bits: */ #define _EFER_SCE 0 /* SYSCALL/SYSRET */ diff -r 704151d0e219 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Thu Mar 29 18:26:12 2007 +0100 +++ b/xen/arch/x86/hvm/hvm.c Fri Mar 30 01:35:58 2007 +0800 @@ -59,6 +59,9 @@ struct hvm_function_table hvm_funcs __re /* I/O permission bitmap is globally shared by all HVM guests. */ char __attribute__ ((__section__ (".bss.page_aligned"))) hvm_io_bitmap[3*PAGE_SIZE]; +/* msr bitmap */ +char __attribute__ ((__section__ (".bss.page_aligned"))) + hvm_msr_bitmap[PAGE_SIZE]; void hvm_enable(struct hvm_function_table *fns) { @@ -71,6 +74,9 @@ void hvm_enable(struct hvm_function_tabl */ memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap)); clear_bit(0x80, hvm_io_bitmap); + + /* initialize hvm_msr_bitmap, all MSR accesses cause VMExits still */ + memset(hvm_msr_bitmap, ~0, sizeof(hvm_msr_bitmap)); hvm_funcs = *fns; hvm_enabled = 1; diff -r 704151d0e219 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Mar 29 18:26:12 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Mar 30 01:22:25 2007 +0800 @@ -37,6 +37,43 @@ #include #include +/* MSR bitmap macros */ +#define MSR_BITMAP_READ_LOW_OFFSET 0 +#define MSR_BITMAP_READ_HIGH_OFFSET 1024 +#define MSR_BITMAP_WRITE_LOW_OFFSET 2048 +#define MSR_BITMAP_WRITE_HIGH_OFFSET 3072 + +#define MSR_BITMAP_LOW_START_ADDR 0x00000000 +#define MSR_BITMAP_LOW_END_ADDR 0x00002000 +#define MSR_BITMAP_HIGH_START_ADDR 0xC0000000 +#define MSR_BITMAP_HIGH_END_ADDR 0xC0002000 + +/* set MSR bitmap to avoid vm exit when access MSR */ +#define MSR_BITMAP_NO_VMEXIT_ON(msr) \ + { \ + u32 msr_offset = msr; \ + if ( (msr) >= MSR_BITMAP_LOW_START_ADDR && \ + (msr) < MSR_BITMAP_LOW_END_ADDR ) \ + { \ + msr_offset -= MSR_BITMAP_LOW_START_ADDR; \ + clear_bit(msr_offset, hvm_msr_bitmap + \ + MSR_BITMAP_READ_LOW_OFFSET); \ + clear_bit(msr_offset, hvm_msr_bitmap + \ + MSR_BITMAP_WRITE_LOW_OFFSET); \ + } \ + else if ( (msr) >= MSR_BITMAP_HIGH_START_ADDR && \ + (msr) < MSR_BITMAP_HIGH_END_ADDR ) \ + { \ + msr_offset -= MSR_BITMAP_HIGH_START_ADDR; \ + clear_bit(msr_offset, hvm_msr_bitmap + \ + MSR_BITMAP_READ_HIGH_OFFSET); \ + clear_bit(msr_offset, hvm_msr_bitmap + \ + MSR_BITMAP_WRITE_HIGH_OFFSET); \ + } \ + else \ + BUG(); \ + } + /* Dynamic (run-time adjusted) execution control flags. */ static u32 vmx_pin_based_exec_control; static u32 vmx_cpu_based_exec_control; @@ -78,6 +115,7 @@ void vmx_init_vmcs_config(void) CPU_BASED_MWAIT_EXITING | CPU_BASED_MOV_DR_EXITING | CPU_BASED_ACTIVATE_IO_BITMAP | + CPU_BASED_ACTIVATE_MSR_BITMAP | CPU_BASED_USE_TSC_OFFSETING); #ifdef __x86_64__ min = max |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING; @@ -113,6 +151,12 @@ void vmx_init_vmcs_config(void) BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control); BUG_ON(vmx_vmexit_control != _vmx_vmexit_control); BUG_ON(vmx_vmentry_control != _vmx_vmentry_control); + } + + if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP ) + { + MSR_BITMAP_NO_VMEXIT_ON(MSR_FS_BASE); + MSR_BITMAP_NO_VMEXIT_ON(MSR_GS_BASE); } /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ @@ -287,6 +331,9 @@ static void construct_vmcs(struct vcpu * __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control); v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control; + if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP ) + __vmwrite(MSR_BITMAP, virt_to_maddr(hvm_msr_bitmap)); + /* I/O access bitmap. */ __vmwrite(IO_BITMAP_A, virt_to_maddr(hvm_io_bitmap)); __vmwrite(IO_BITMAP_B, virt_to_maddr(hvm_io_bitmap + PAGE_SIZE)); diff -r 704151d0e219 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Thu Mar 29 18:26:12 2007 +0100 +++ b/xen/include/asm-x86/hvm/support.h Thu Mar 29 13:15:54 2007 +0800 @@ -215,6 +215,7 @@ int hvm_load(struct domain *d, hvm_domai /* End of save/restore */ extern char hvm_io_bitmap[]; +extern char hvm_msr_bitmap[]; extern int hvm_enabled; void hvm_enable(struct hvm_function_table *); diff -r 704151d0e219 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Mar 29 18:26:12 2007 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Mar 29 13:15:54 2007 +0800 @@ -109,6 +109,7 @@ extern int vmcs_version; #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000 +#define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000 #define CPU_BASED_MONITOR_EXITING 0x20000000 #define CPU_BASED_PAUSE_EXITING 0x40000000 @@ -143,6 +144,8 @@ enum vmcs_field { IO_BITMAP_A_HIGH = 0x00002001, IO_BITMAP_B = 0x00002002, IO_BITMAP_B_HIGH = 0x00002003, + MSR_BITMAP = 0x00002004, + MSR_BITMAP_HIGH = 0x00002005, VM_EXIT_MSR_STORE_ADDR = 0x00002006, VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007, VM_EXIT_MSR_LOAD_ADDR = 0x00002008, diff -r 704151d0e219 xen/include/asm-x86/msr.h --- a/xen/include/asm-x86/msr.h Thu Mar 29 18:26:12 2007 +0100 +++ b/xen/include/asm-x86/msr.h Thu Mar 29 13:15:54 2007 +0800 @@ -126,8 +126,8 @@ static inline void wrmsrl(unsigned int m #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ #define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */ #define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ -#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */ -#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */ +#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ #define MSR_SHADOW_GS_BASE 0xc0000102 /* SwapGS GS shadow */ /* EFER bits: */ #define _EFER_SCE 0 /* SYSCALL/SYSRET */