[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vmx: Make use of VMX_INSTRUCTION_INFO field to obtain the segment
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1182974037 -3600 # Node ID 6e934c7990514adfe6f882f37a71a26fbe3cd2d4 # Parent 87d34c8c2fe1a444b24c4f6a7a3cde3d1baebb93 vmx: Make use of VMX_INSTRUCTION_INFO field to obtain the segment register of OUTS Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/vmx/vmcs.c | 3 ++ xen/arch/x86/hvm/vmx/vmx.c | 49 ++++++++++++++++++++++++++----------- xen/include/asm-x86/hvm/vmx/vmcs.h | 2 + 3 files changed, 40 insertions(+), 14 deletions(-) diff -r 87d34c8c2fe1 -r 6e934c799051 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Wed Jun 27 20:17:54 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Jun 27 20:53:57 2007 +0100 @@ -43,6 +43,7 @@ u32 vmx_secondary_exec_control __read_mo u32 vmx_secondary_exec_control __read_mostly; u32 vmx_vmexit_control __read_mostly; u32 vmx_vmentry_control __read_mostly; +bool_t cpu_has_vmx_ins_outs_instr_info __read_mostly; static u32 vmcs_revision_id __read_mostly; @@ -133,6 +134,7 @@ void vmx_init_vmcs_config(void) vmx_secondary_exec_control = _vmx_secondary_exec_control; vmx_vmexit_control = _vmx_vmexit_control; vmx_vmentry_control = _vmx_vmentry_control; + cpu_has_vmx_ins_outs_instr_info = !!(vmx_msr_high & (1U<<22)); } else { @@ -142,6 +144,7 @@ void vmx_init_vmcs_config(void) BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control); BUG_ON(vmx_vmexit_control != _vmx_vmexit_control); BUG_ON(vmx_vmentry_control != _vmx_vmentry_control); + BUG_ON(cpu_has_vmx_ins_outs_instr_info != !!(vmx_msr_high & (1U<<22))); } /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ diff -r 87d34c8c2fe1 -r 6e934c799051 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Jun 27 20:17:54 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Jun 27 20:53:57 2007 +0100 @@ -1466,16 +1466,34 @@ static void vmx_do_invlpg(unsigned long paging_invlpg(v, va); } -/* - * get segment for string pio according to guest instruction - */ -static void vmx_str_pio_get_segment(int long_mode, unsigned long eip, - int inst_len, enum x86_segment *seg) +/* Get segment for OUTS according to guest instruction. */ +static enum x86_segment vmx_outs_get_segment( + int long_mode, unsigned long eip, int inst_len) { unsigned char inst[MAX_INST_LEN]; + enum x86_segment seg = x86_seg_ds; int i; extern int inst_copy_from_guest(unsigned char *, unsigned long, int); + if ( likely(cpu_has_vmx_ins_outs_instr_info) ) + { + unsigned int instr_info = __vmread(VMX_INSTRUCTION_INFO); + + /* Get segment register according to bits 17:15. */ + switch ( (instr_info >> 15) & 7 ) + { + case 0: seg = x86_seg_es; break; + case 1: seg = x86_seg_cs; break; + case 2: seg = x86_seg_ss; break; + case 3: seg = x86_seg_ds; break; + case 4: seg = x86_seg_fs; break; + case 5: seg = x86_seg_gs; break; + default: BUG(); + } + + goto out; + } + if ( !long_mode ) eip += __vmread(GUEST_CS_BASE); @@ -1484,7 +1502,7 @@ static void vmx_str_pio_get_segment(int { gdprintk(XENLOG_ERR, "Get guest instruction failed\n"); domain_crash(current->domain); - return; + goto out; } for ( i = 0; i < inst_len; i++ ) @@ -1501,25 +1519,28 @@ static void vmx_str_pio_get_segment(int #endif continue; case 0x2e: /* CS */ - *seg = x86_seg_cs; + seg = x86_seg_cs; continue; case 0x36: /* SS */ - *seg = x86_seg_ss; + seg = x86_seg_ss; continue; case 0x26: /* ES */ - *seg = x86_seg_es; + seg = x86_seg_es; continue; case 0x64: /* FS */ - *seg = x86_seg_fs; + seg = x86_seg_fs; continue; case 0x65: /* GS */ - *seg = x86_seg_gs; + seg = x86_seg_gs; continue; case 0x3e: /* DS */ - *seg = x86_seg_ds; + seg = x86_seg_ds; continue; } } + + out: + return seg; } static int vmx_str_pio_check_descriptor(int long_mode, unsigned long eip, @@ -1532,7 +1553,7 @@ static int vmx_str_pio_check_descriptor( *base = 0; *limit = 0; if ( seg != x86_seg_es ) - vmx_str_pio_get_segment(long_mode, eip, inst_len, &seg); + seg = vmx_outs_get_segment(long_mode, eip, inst_len); switch ( seg ) { @@ -1578,7 +1599,7 @@ static int vmx_str_pio_check_descriptor( } *ar_bytes = __vmread(ar_field); - return !(*ar_bytes & 0x10000); + return !(*ar_bytes & X86_SEG_AR_SEG_UNUSABLE); } diff -r 87d34c8c2fe1 -r 6e934c799051 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Wed Jun 27 20:17:54 2007 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Wed Jun 27 20:53:57 2007 +0100 @@ -130,6 +130,8 @@ extern u32 vmx_vmentry_control; #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 extern u32 vmx_secondary_exec_control; + +extern bool_t cpu_has_vmx_ins_outs_instr_info; #define cpu_has_vmx_virtualize_apic_accesses \ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |