PATCH 0/5] Consolidate the insb/outsb emulation into x86_emulate.c
[PATCH 0/5] Consolidate the insb/outsb emulation into x86_emulate.c
From the TODO, this serie of patches consolidates the insb/outsb emulation into x86_emulate.c.
The prefix decoding part is extracted from x86_emulate_memop() and a function called x86_decode_prefix() is created.
Then, in vmx.c, handle_io() calls x86_decode_prefix() instead of get_io_count(); in svm.c, io_interception() calls x86_decode_prefix() instead of io_address() and io_get_override().
*** WARNING: the SVM part has not been tested because I don't have any AMD system. ***
[PATCH 1/5] x86_ctxt_segment_array: to be able to extract easily prefix decoding from x86_emulate_memop(), change ctxt.*_base to an array ctxt.base[X86EMUL_BASE_*]
[PATCH 2/5] x86_prefix: to be able to extract easily prefix decoding from x86_emulate_memop(), group all prefix decoding results in a structure, called x86_prefix.
[PATCH 3/5] x86_decode_prefix: extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix().
[PATCH 4/5] vmx-decode_prefix: vmx.c uses x86_decode_prefix() instead of get_io_count().
[PATCH 5/5] svm-decode_prefix: svm.c uses x86_decode_prefix() instead of io_address() and io_get_override().
*** WARNING: the SVM part has not been tested because I don't have any AMD system. ***
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B04CCA.2010503-6ktuUTfB/[email protected]
PATCH 1/5 change ctxt.*_base to an array ctxt.base[X86EMUL_BASE_*]
To be able to extract easily prefix decoding from x86_emulate_memop(), change ctxt.*_base to an array ctxt.base[X86EMUL_BASE_*]
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/kvm_main.c +16 -10
@@ -1236,19 +1236,25 @@ ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;if (emulate_ctxt.mode ==X86EMUL_MODE_PROT64 ) { - emulate_ctxt.cs_base =0 ; - emulate_ctxt.ds_base =0 ; - emulate_ctxt.es_base =0 ; - emulate_ctxt.ss_base =0 ; + emulate_ctxt.base[X86EMUL_BASE_CS ] =0 ; + emulate_ctxt.base[X86EMUL_BASE_DS ] =0 ; + emulate_ctxt.base[X86EMUL_BASE_ES ] =0 ; + emulate_ctxt.base[X86EMUL_BASE_SS ] =0 ; }else { - emulate_ctxt.cs_base =get_segment_base (vcpu,VCPU_SREG_CS ); - emulate_ctxt.ds_base =get_segment_base (vcpu,VCPU_SREG_DS ); - emulate_ctxt.es_base =get_segment_base (vcpu,VCPU_SREG_ES ); - emulate_ctxt.ss_base =get_segment_base (vcpu,VCPU_SREG_SS ); + emulate_ctxt.base[X86EMUL_BASE_CS ] = +get_segment_base (vcpu,VCPU_SREG_CS ); + emulate_ctxt.base[X86EMUL_BASE_DS ] = +get_segment_base (vcpu,VCPU_SREG_DS ); + emulate_ctxt.base[X86EMUL_BASE_ES ] = +get_segment_base (vcpu,VCPU_SREG_ES ); + emulate_ctxt.base[X86EMUL_BASE_SS ] = +get_segment_base (vcpu,VCPU_SREG_SS ); } - emulate_ctxt.gs_base =get_segment_base (vcpu,VCPU_SREG_GS ); - emulate_ctxt.fs_base =get_segment_base (vcpu,VCPU_SREG_FS ); + emulate_ctxt.base[X86EMUL_BASE_GS ] = +get_segment_base (vcpu,VCPU_SREG_GS ); + emulate_ctxt.base[X86EMUL_BASE_FS ] = +get_segment_base (vcpu,VCPU_SREG_FS ); vcpu->mmio_is_write =0 ; r =x86_emulate_memop (&emulate_ctxt, &emulate_ops);
drivers/kvm/x86_emulate.c +29 -24
121 lines not on this page · raw message
drivers/kvm/x86_emulate.h +11 -7
@@ -112,6 +112,16 @@ }; +enum { +X86EMUL_BASE_CS , +X86EMUL_BASE_DS , +X86EMUL_BASE_ES , +X86EMUL_BASE_SS , +X86EMUL_BASE_GS , +X86EMUL_BASE_FS , +X86EMUL_BASE_SIZE +}; +struct x86_emulate_ctxt {/* Register state before/after emulation. */ struct kvm_vcpu *vcpu;
@@ -122,13 +132,7 @@/* Emulated execution mode, represented by an X86EMUL_MODE value. */ int mode; - -unsigned long cs_base; -unsigned long ds_base; -unsigned long es_base; -unsigned long ss_base; -unsigned long gs_base; -unsigned long fs_base; +unsigned long base[X86EMUL_BASE_SIZE ]; };/* Execution mode, passed to the emulator. */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B04DD6.7010702-6ktuUTfB/[email protected]
PATCH 2/5 group all prefix decoding results in a structure called x86_prefix
To be able to extract easily prefix decoding from x86_emulate_memop(), group all prefix decoding results in a structure called x86_prefix.
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/x86_emulate.h +15 -0
@@ -141,6 +141,21 @@#define X86EMUL_MODE_PROT32 4/* 32-bit protected mode. */ #define X86EMUL_MODE_PROT64 8/* 64-bit (long) mode. */ +struct x86_prefix { +unsigned int op_bytes; +unsigned int ad_bytes; +int override_base; + +u8 lock;/* LOCK prefix */ +u8 rep;/* REP prefix */ +u8 rex;/* REX prefix */ + +int index_reg; +int base_reg; +u8 modrm_reg; +u8 modrm_rm; +}; +/* Host execution mode. */ #if defined(__i386__)#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
drivers/kvm/x86_emulate.c +102 -100
540 lines not on this page · raw message
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B04EB9.5010103-6ktuUTfB/[email protected]
PATCH 3/5 extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix()
Extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix().
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/x86_emulate.c +73 -45
@@ -480,43 +480,24 @@ }int -x86_emulate_memop (struct x86_emulate_ctxt *ctxt,struct x86_emulate_ops *ops) +x86_decode_prefix (int mode,u8 *inst,struct x86_prefix *prefix) { -unsigned d; -u8 b, sib, twobyte =0 ; -u8 modrm, modrm_mod =0 ; -unsigned int i; -int rc =0 ; -struct operand src, dst; -unsigned long cr2 = ctxt->cr2; -int mode = ctxt->mode; -unsigned long modrm_ea; -int use_modrm_ea, scale, rip_relative =0 ; -int no_wb =0 ; -u64 msr_data; -struct x86_prefix prefix; - -/* Shadow copy of register state. Committed on successful emulation. */ -unsigned long _regs[NR_VCPU_REGS ]; -unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags; -unsigned long modrm_val =0 ; - -memcpy (_regs, ctxt->vcpu->regs,sizeof _regs); -memset (&prefix,0 ,sizeof (prefix)); - prefix.override_base =-1 ; +unsigned int op_bytes, ad_bytes; +int i; +u8 b;switch (mode) {case X86EMUL_MODE_REAL :case X86EMUL_MODE_PROT16 : - prefix.op_bytes = prefix.ad_bytes =2 ; + op_bytes = ad_bytes =2 ;break ;case X86EMUL_MODE_PROT32 : - prefix.op_bytes = prefix.ad_bytes =4 ; + op_bytes = ad_bytes =4 ;break ;#ifdef CONFIG_X86_64 case X86EMUL_MODE_PROT64 : - prefix.op_bytes =4 ; - prefix.ad_bytes =8 ; + op_bytes =4 ; + ad_bytes =8 ;break ;#endif default :
@@ -525,39 +506,39 @@/* Legacy prefixes. */ for (i =0 ; i <8 ; i++) { -switch (b =insn_fetch (u8,1 , _eip)) { +switch (b = inst[i]) {case 0x66 :/* operand-size override */ - prefix.op_bytes ^=6 ;/* switch between 2/4 bytes */ + op_bytes ^=6 ;/* switch between 2/4 bytes */ break ;case 0x67 :/* address-size override */ if (mode ==X86EMUL_MODE_PROT64 ) - prefix.ad_bytes ^=12 ;/* switch between 4/8 bytes */ + ad_bytes ^=12 ;/* switch between 4/8 bytes */ else - prefix.ad_bytes ^=6 ;/* switch between 2/4 bytes */ + ad_bytes ^=6 ;/* switch between 2/4 bytes */ break ;case 0x2e :/* CS override */ - prefix.override_base =X86EMUL_BASE_CS ; + prefix->override_base =X86EMUL_BASE_CS ;break ;case 0x3e :/* DS override */ - prefix.override_base =X86EMUL_BASE_DS ; + prefix->override_base =X86EMUL_BASE_DS ;break ;case 0x26 :/* ES override */ - prefix.override_base =X86EMUL_BASE_ES ; + prefix->override_base =X86EMUL_BASE_ES ;break ;case 0x64 :/* FS override */ - prefix.override_base =X86EMUL_BASE_FS ; + prefix->override_base =X86EMUL_BASE_FS ;break ;case 0x65 :/* GS override */ - prefix.override_base =X86EMUL_BASE_GS ; + prefix->override_base =X86EMUL_BASE_GS ;break ;case 0x36 :/* SS override */ - prefix.override_base =X86EMUL_BASE_SS ; + prefix->override_base =X86EMUL_BASE_SS ;break ;case 0xf0 :/* LOCK */ - prefix.lock =1 ; + prefix->lock =1 ;break ;case 0xf3 :/* REP/REPE/REPZ */ - prefix.rep =1 ; + prefix->rep =1 ;break ;case 0xf2 :/* REPNE/REPNZ */ break ;
@@ -570,15 +551,62 @@/* REX prefix. */ if ((mode ==X86EMUL_MODE_PROT64 ) && ((b &0xf0 ) ==0x40 )) { - prefix.rex = b; + prefix->rex = b;if (b &8 ) - prefix.op_bytes =8 ;/* REX.W */ - prefix.modrm_reg = (b &4 ) <<1 ;/* REX.R */ - prefix.index_reg = (b &2 ) <<2 ;/* REX.X */ - prefix.modrm_rm = prefix.base_reg = (b &1 ) <<3 ;/* REG.B */ - b =insn_fetch (u8,1 , _eip); + op_bytes =8 ;/* REX.W */ + prefix->modrm_reg = (b &4 ) <<1 ;/* REX.R */ + prefix->index_reg = (b &2 ) <<2 ;/* REX.X */ + prefix->modrm_rm = prefix->base_reg = (b &1 ) <<3 ;/* REG.B */ + i++; } + prefix->op_bytes = op_bytes; + prefix->ad_bytes = ad_bytes; + +return i; +} +EXPORT_SYMBOL_GPL (x86_decode_prefix); + +int +x86_emulate_memop (struct x86_emulate_ctxt *ctxt,struct x86_emulate_ops *ops) +{ +unsigned d; +u8 b, sib, twobyte =0 ; +u8 modrm, modrm_mod =0 ; +int rc =0 ; +struct operand src, dst; +unsigned long cr2 = ctxt->cr2; +int mode = ctxt->mode; +unsigned long modrm_ea; +int use_modrm_ea, scale, rip_relative =0 ; +int no_wb =0 ; +u64 msr_data, inst; +struct x86_prefix prefix; +int count; + +/* Shadow copy of register state. Committed on successful emulation. */ +unsigned long _regs[NR_VCPU_REGS ]; +unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags; +unsigned long modrm_val =0 ; + +memcpy (_regs, ctxt->vcpu->regs,sizeof _regs); + +/* decode prefixes */ + + rc = ops->read_std (_eip + ctxt->base[X86EMUL_BASE_CS ], + &inst,sizeof (inst), ctxt->vcpu); +if ( rc !=0 ) + goto done; + +memset (&prefix,0 ,sizeof (prefix)); + prefix.override_base =-1 ; + + count =x86_decode_prefix (mode, (u8 *)&inst, &prefix); +if (count ==-1 ) +return -1 ; + _eip += count; + b =insn_fetch (u8,1 , _eip); +/* Opcode byte(s). */ d = opcode_table[b];if (d ==0 ) {
drivers/kvm/x86_emulate.h +7 -0
@@ -164,6 +164,13 @@#endif /* +* x86_decode_prefix: Decode instruction prefixes +* Returns -1 on failure, 0 on success. +*/ +int +x86_decode_prefix (int mode,u8 *inst,struct x86_prefix *prefix); + +/* * x86_emulate_memop: Emulate an instruction that faulted attempting to * read/write a 'special' memory area. * Returns -1 on failure, 0 on success.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B04F56.60607-6ktuUTfB/[email protected]
PATCH 4/5 vmx.c uses x86_decode_prefix() instead of get_io_count().
vmx.c uses x86_decode_prefix() instead of get_io_count().
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/vmx.c +25 -52
@@ -1761,57 +1761,6 @@return 0 ; } -static int get_io_count (struct kvm_vcpu *vcpu,unsigned long *count) -{ -u64 inst; -gva_t rip; -int countr_size; -int i; - -if ((vmcs_readl (GUEST_RFLAGS ) &X86_EFLAGS_VM )) { - countr_size =2 ; - }else { -u32 cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); - - countr_size = (cs_ar &AR_L_MASK ) ?8 : - (cs_ar &AR_DB_MASK ) ?4 :2 ; - } - - rip =vmcs_readl (GUEST_RIP ); -if (countr_size !=8 ) - rip +=vmcs_readl (GUEST_CS_BASE ); - -if (emulator_read_std (rip, &inst,sizeof (inst), vcpu) != -X86EMUL_CONTINUE ) -return 0 ; - -for (i =0 ; i <sizeof (inst); i++) { -switch (((u8 *)&inst)[i]) { -case 0xf0 : -case 0xf2 : -case 0xf3 : -case 0x2e : -case 0x36 : -case 0x3e : -case 0x26 : -case 0x64 : -case 0x65 : -case 0x66 : -break ; -case 0x67 : - countr_size = (countr_size ==2 ) ?4 : (countr_size >>1 ); -default : - goto done; - } - } -return 0 ; -done: - countr_size *=8 ; - *count = vcpu->regs[VCPU_REGS_RCX ] & (~0ULL >> (64 - countr_size)); -//printk("cx: %lx\n", vcpu->regs[VCPU_REGS_RCX]); -return 1 ; -} -static int handle_io (struct kvm_vcpu *vcpu,struct kvm_run *kvm_run) {u64 exit_qualification;
@@ -1831,8 +1780,32 @@ port = exit_qualification >>16 ; address =0 ;if (string) { -if (rep && !get_io_count (vcpu, &count)) +int mode; +u64 inst; +gva_t rip; +struct x86_prefix prefix; +u32 cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); +unsigned long addr_mask; + + mode = (vmcs_readl (GUEST_RFLAGS ) &X86_EFLAGS_VM ) ? +X86EMUL_MODE_REAL : (cs_ar &AR_L_MASK ) + ?X86EMUL_MODE_PROT64 : (cs_ar &AR_DB_MASK ) + ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ; + + rip =vmcs_readl (GUEST_RIP ); +if (mode !=X86EMUL_MODE_PROT64 ) + rip +=vmcs_readl (GUEST_CS_BASE ); +if (emulator_read_std (rip, &inst,sizeof (inst), vcpu) + !=X86EMUL_CONTINUE ) +return 1 ; + +if (x86_decode_prefix (mode, (u8 *)&inst, &prefix) ==-1 )return 1 ; + + addr_mask = (~0ULL >> (64 - (prefix.ad_bytes <<3 ))); +if (rep) + count = vcpu->regs[VCPU_REGS_RCX ] & addr_mask; + address =vmcs_readl (GUEST_LINEAR_ADDRESS ); } return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B0501C.6060409-6ktuUTfB/[email protected]
PATCH 5/5 svm.c uses x86_decode_prefix() instead of io_address() and io_get_override().
svm.c uses x86_decode_prefix() instead of io_address() and io_get_override().
*** WARNING: the SVM part has not been tested because I don't have any AMD system. ***
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/svm.c +83 -127
@@ -98,20 +98,6 @@return svm_features & feat; } -static unsigned get_addr_size (struct vcpu_svm *svm) -{ -struct vmcb_save_area *sa = &svm->vmcb->save; -u16 cs_attrib; - -if (!(sa->cr0 &X86_CR0_PE ) || (sa->rflags &X86_EFLAGS_VM )) -return 2 ; - - cs_attrib = sa->cs.attrib; - -return (cs_attrib &SVM_SELECTOR_L_MASK ) ?8 : - (cs_attrib &SVM_SELECTOR_DB_MASK ) ?4 :2 ; -} -static inline u8 pop_irq (struct kvm_vcpu *vcpu) {int word_index =__ffs (vcpu->irq_summary);
@@ -996,112 +982,6 @@return 0 ; } -static int io_get_override (struct vcpu_svm *svm, -struct vmcb_seg **seg, -int *addr_override) -{ -u8 inst[MAX_INST_SIZE ]; -unsigned ins_length; -gva_t rip; -int i; - - rip = svm->vmcb->save.rip; - ins_length = svm->next_rip - rip; - rip += svm->vmcb->save.cs.base; - -if (ins_length >MAX_INST_SIZE ) -printk (KERN_DEBUG -"%s: inst length err, cs base 0x%llx rip 0x%llx " -"next rip 0x%llx ins_length %u\n" , - __FUNCTION__, - svm->vmcb->save.cs.base, - svm->vmcb->save.rip, - svm->vmcb->control.exit_info_2, - ins_length); - -if (emulator_read_std (rip, inst, ins_length, &svm->vcpu) - !=X86EMUL_CONTINUE ) -/* #PF */ -return 0 ; - - *addr_override =0 ; - *seg =NULL ; -for (i =0 ; i < ins_length; i++) -switch (inst[i]) { -case 0xf0 : -case 0xf2 : -case 0xf3 : -case 0x66 : -continue ; -case 0x67 : - *addr_override =1 ; -continue ; -case 0x2e : - *seg = &svm->vmcb->save.cs; -continue ; -case 0x36 : - *seg = &svm->vmcb->save.ss; -continue ; -case 0x3e : - *seg = &svm->vmcb->save.ds; -continue ; -case 0x26 : - *seg = &svm->vmcb->save.es; -continue ; -case 0x64 : - *seg = &svm->vmcb->save.fs; -continue ; -case 0x65 : - *seg = &svm->vmcb->save.gs; -continue ; -default : -return 1 ; - } -printk (KERN_DEBUG "%s: unexpected\n" , __FUNCTION__); -return 0 ; -} - -static unsigned long io_address (struct vcpu_svm *svm,int ins,gva_t *address) -{ -unsigned long addr_mask; -unsigned long *reg; -struct vmcb_seg *seg; -int addr_override; -struct vmcb_save_area *save_area = &svm->vmcb->save; -u16 cs_attrib = save_area->cs.attrib; -unsigned addr_size =get_addr_size (svm); - -if (!io_get_override (svm, &seg, &addr_override)) -return 0 ; - -if (addr_override) - addr_size = (addr_size ==2 ) ?4 : (addr_size >>1 ); - -if (ins) { - reg = &svm->vcpu.regs[VCPU_REGS_RDI ]; - seg = &svm->vmcb->save.es; - }else { - reg = &svm->vcpu.regs[VCPU_REGS_RSI ]; - seg = (seg) ? seg : &svm->vmcb->save.ds; - } - - addr_mask = ~0ULL >> (64 - (addr_size *8 )); - -if ((cs_attrib &SVM_SELECTOR_L_MASK ) && - !(svm->vmcb->save.rflags &X86_EFLAGS_VM )) { - *address = (*reg & addr_mask); -return addr_mask; - } - -if (!(seg->attrib &SVM_SELECTOR_P_SHIFT )) { -svm_inject_gp (&svm->vcpu,0 ); -return 0 ; - } - - *address = (*reg & addr_mask) + seg->base; -return addr_mask; -} -static int io_interception (struct vcpu_svm *svm,struct kvm_run *kvm_run) {u32 io_info = svm->vmcb->control.exit_info_1;//address size bug?
@@ -1109,6 +989,7 @@unsigned port;unsigned long count;gva_t address =0 ; +struct vmcb_save_area *sa = &svm->vmcb->save; ++svm->vcpu.stat.io_exits;
@@ -1120,21 +1001,96 @@ string = (io_info &SVM_IOIO_STR_MASK ) !=0 ; rep = (io_info &SVM_IOIO_REP_MASK ) !=0 ; count =1 ; - down = (svm->vmcb->save.rflags &X86_EFLAGS_DF ) !=0 ; + down = (sa->rflags &X86_EFLAGS_DF ) !=0 ;if (string) { -unsigned addr_mask; +int mode; +u8 inst[MAX_INST_SIZE ]; +unsigned ins_length; +gva_t rip; +struct x86_prefix prefix; +u16 cs_ar = sa->cs.attrib; +unsigned long addr_mask; + + mode = (!(sa->cr0 &X86_CR0_PE ) || + (sa->rflags &X86_EFLAGS_VM )) ? +X86EMUL_MODE_REAL : (cs_ar &SVM_SELECTOR_L_MASK ) + ?X86EMUL_MODE_PROT64 : (cs_ar &SVM_SELECTOR_DB_MASK ) + ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ; + + rip = svm->vmcb->save.rip; + ins_length = svm->vmcb->save.rip - rip; +if (mode !=X86EMUL_MODE_PROT64 ) + rip += svm->vmcb->save.cs.base; + +if (ins_length >MAX_INST_SIZE ) +printk (KERN_DEBUG +"%s: inst length err, cs base 0x%llx rip 0x%llx " +"next rip 0x%llx ins_length %u\n" , + __FUNCTION__, + svm->vmcb->save.cs.base, + svm->vmcb->save.rip, + svm->vmcb->control.exit_info_2, + ins_length); - addr_mask =io_address (svm, in, &address); -if (!addr_mask) { -printk (KERN_DEBUG "%s: get io address failed\n" , - __FUNCTION__); +if (emulator_read_std (rip, inst, ins_length, &svm->vcpu) + !=X86EMUL_CONTINUE ) +return 1 ; + + prefix.override_base =-1 ; +if (x86_decode_prefix (mode, (u8 *)&inst, &prefix) ==-1 )return 1 ; - } + addr_mask = (~0ULL >> (64 - (prefix.ad_bytes <<3 )));if (rep) count = svm->vcpu.regs[VCPU_REGS_RCX ] & addr_mask; + +if (in) + address = svm->vcpu.regs[VCPU_REGS_RDI ]; +else + address = svm->vcpu.regs[VCPU_REGS_RSI ]; + + address &= addr_mask; + +if (mode !=X86EMUL_MODE_PROT64 ) { +struct vmcb_seg *seg; + +if (in) + seg = &svm->vmcb->save.es; +else switch (prefix.override_base) { +case -1 : +case X86EMUL_BASE_DS : + seg = &svm->vmcb->save.ds; +break ; +case X86EMUL_BASE_CS : + seg = &svm->vmcb->save.cs; +break ; +case X86EMUL_BASE_ES : + seg = &svm->vmcb->save.es; +break ; +case X86EMUL_BASE_GS : + seg = &svm->vmcb->save.gs; +break ; +case X86EMUL_BASE_SS : + seg = &svm->vmcb->save.ss; +break ; +default : +printk (KERN_DEBUG "%s: unexpected\n" , + __FUNCTION__); +return 1 ; + } + +if (seg->attrib &SVM_SELECTOR_P_SHIFT ) { +svm_inject_gp (&svm->vcpu,0 ); +printk (KERN_DEBUG "%s: get io address failed\n" , + __FUNCTION__); +return 1 ; + } + + address += seg->base; + } } +return kvm_setup_pio (&svm->vcpu, kvm_run, in, size, count, string, down, address, rep, port); }
Index: kvm/drivers/kvm/.svm.c.swp
===================================================================
Binary files kvm.orig/drivers/kvm/.svm.c.swp 2007-08-01 10:12:34.000000000 +0200 and /dev/null 1970-01-01 00:00:00.000000000 +0000 differ
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [PATCH 4/5] vmx.c uses x86_decode_prefix() instead of get_io_count().
In reply to a message not in the archiveQuoted 30 lines · Laurent Vivier
vmx.cusesx86_decode_prefix()instead ofget_io_count().static int
handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run){drivers/kvm/vmx.c +19
-1u64 exit_qualification;@@ -1831,8 +1780,32 @@ port = exit_qualification >>16 ; address =0 ;if (string) { -if (rep && !get_io_count (vcpu, &count)) +int mode; +u64 inst; +gva_t rip; +struct x86_prefix prefix; +u32 cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); +unsigned long addr_mask; + + mode = (vmcs_readl (GUEST_RFLAGS ) &X86_EFLAGS_VM ) ? +X86EMUL_MODE_REAL : (cs_ar &AR_L_MASK ) + ?X86EMUL_MODE_PROT64 : (cs_ar &AR_DB_MASK ) + ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ; + + rip =vmcs_readl (GUEST_RIP ); +if (mode !=X86EMUL_MODE_PROT64 ) + rip +=vmcs_readl (GUEST_CS_BASE ); +if (emulator_read_std (rip, &inst,sizeof (inst), vcpu) + !=X86EMUL_CONTINUE ) +return 1 ; +
drivers/kvm/vmx.c line 1811
Quoted 10 lines
drivers/kvm/vmx.c +6
-0+if (x86_decode_prefix (mode, (u8 *)&inst, &prefix) ==-1 )return 1 ; + + addr_mask = (~0ULL >> (64 - (prefix.ad_bytes <<3 ))); +if (rep) + count = vcpu->regs[VCPU_REGS_RCX ] & addr_mask; + address =vmcs_readl (GUEST_LINEAR_ADDRESS ); } return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
How about just calliing emulate_instruction() from here (just for the string case)? That will eliminate all the setup code.
x86_emulate_memop() will need to be extended to decode ins/outs, but that's fairly easy.
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
A message that is not in the archive (sent off-list or not yet received): 46B19A7B.2030109-atKUWr5tajBWk0Htik3J/[email protected]
Re: [PATCH 4/5] vmx.c uses x86_decode_prefix() instead of get_io_count().
Quoted 35 lines · Avi Kivity
Quoted 34 lines · Laurent Vivier
vmx.cusesx86_decode_prefix()instead ofget_io_count().static int
handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run){ u64 exit_qualification;drivers/kvm/vmx.c +23
-1@@ -1831,8 +1780,32 @@ port = exit_qualification >>16 ; address =0 ;if (string) { -if (rep && !get_io_count (vcpu, &count)) +int mode; +u64 inst; +gva_t rip; +struct x86_prefix prefix; +u32 cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); +unsigned long addr_mask; + + mode = (vmcs_readl (GUEST_RFLAGS ) &X86_EFLAGS_VM ) ? +X86EMUL_MODE_REAL : (cs_ar &AR_L_MASK ) + ?X86EMUL_MODE_PROT64 : (cs_ar &AR_DB_MASK ) + ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ; + + rip =vmcs_readl (GUEST_RIP ); +if (mode !=X86EMUL_MODE_PROT64 ) + rip +=vmcs_readl (GUEST_CS_BASE ); +if (emulator_read_std (rip, &inst,sizeof (inst), vcpu) + !=X86EMUL_CONTINUE ) +return 1 ; + +if (x86_decode_prefix (mode, (u8 *)&inst, &prefix) ==-1 )return 1 ; + + addr_mask = (~0ULL >> (64 - (prefix.ad_bytes <<3 ))); +if (rep)
Quoted 8 lines
drivers/kvm/vmx.c line 1811
Quoted 5 lines
drivers/kvm/vmx.c +2
-0+ count = vcpu->regs[VCPU_REGS_RCX ] & addr_mask; + address =vmcs_readl (GUEST_LINEAR_ADDRESS ); } return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,How about just calliing
emulate_instruction()from here (just for the string case)? That will eliminate all the setup code.
But this setup is in emulate_instruction() so it will be executed anyway.
Quoted 2 lines
x86_emulate_memop()will need to be extended to decode ins/outs, but that's fairly easy.
X86_decode_prefix() is a subset of instruction decoding part of x86_emulate_memop(), kvm_setup_pio() can be seen as a subset of instruction emulating part of x86_emulate_memop(). So I think in term of performance it is better to do like that, but I agree by doing:
if (string)
return emulate_instruction(vcpu, kvm_run, 0, 0); else return kvm_setup_pio(vcpu, kvm_run, in, size, port);
it is more more ... more simple.
If you prefer simplicity, I can do like that ?
(but I know you prefer simplicity...)
BTW, I think PATCH 1,2 and 3 should be applied anyway because they allow to introduce the separation between instruction decoding and instruction emulation requested by the TODO "Split the emulator into two functions: one to decode into the emulation context, and the other to actually execute the instruction."
Laurent
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
A message that is not in the archive (sent off-list or not yet received): 46B1A51C.2040104-6ktuUTfB/[email protected]
Re: [PATCH 4/5] vmx.c uses x86_decode_prefix() instead of get_io_count().
Quoted 8 lines · Laurent Vivier
Quoted 4 lines
How about just calliing
emulate_instruction()from here (just for the string case)? That will eliminate all the setup code.But this setup is in
emulate_instruction()so it will be executed anyway.
I'm not worried about run-time overhead, but about the amount of code.
Quoted 10 lines
Quoted 3 lines
x86_emulate_memop()will need to be extended to decode ins/outs, but that's fairly easy.
X86_decode_prefix()is a subset of instruction decoding part ofx86_emulate_memop(),kvm_setup_pio()can be seen as a subset of instruction emulating part ofx86_emulate_memop(). So I think in term of performance it is better to do like that, but I agree by doing:if (string)
Quoted 10 lines
return emulate_instruction(vcpu, kvm_run, 0, 0); else return kvm_setup_pio(vcpu, kvm_run, in, size, port);it is more more ... more simple.
If you prefer simplicity, I can do like that ?
(but I know you prefer simplicity...)
Yes. Note that x86_emulate_memop() will eventually call kvm_setup_pio() to complete the emulation.
Quoted 5 lines
BTW, I think PATCH 1,2 and 3 should be applied anyway because they allow to introduce the separation between instruction decoding and instruction emulation requested by the TODO "Split the emulator into two functions: one to decode into the emulation context, and the other to actually execute the instruction."
I agree. I'll look into it with more detail.
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
A message that is not in the archive (sent off-list or not yet received): 46B1A6B8.7020404-atKUWr5tajBWk0Htik3J/[email protected]
Re: [PATCH 4/5] vmx.c uses x86_decode_prefix() instead of get_io_count().
Quoted 30 lines · Avi Kivity
Quoted 8 lines · Laurent Vivier
Quoted 4 lines
How about just calliing
emulate_instruction()from here (just for the string case)? That will eliminate all the setup code.But this setup is in
emulate_instruction()so it will be executed anyway.I'm not worried about run-time overhead, but about the amount of code.
Quoted 18 lines
Quoted 3 lines
x86_emulate_memop()will need to be extended to decode ins/outs, but that's fairly easy.
X86_decode_prefix()is a subset of instruction decoding part ofx86_emulate_memop(),kvm_setup_pio()can be seen as a subset of instruction
emulating part ofx86_emulate_memop(). So I think in term of performance it is
better to do like that, but I agree by doing:if (string)
return emulate_instruction(vcpu, kvm_run, 0, 0); else return kvm_setup_pio(vcpu, kvm_run, in, size, port);it is more more ... more simple.
Quoted 7 lines
Quoted 4 lines
If you prefer simplicity, I can do like that ?
(but I know you prefer simplicity...)Yes. Note that
x86_emulate_memop()will eventually callkvm_setup_pio()to complete the emulation.
Just to have some comments, have a look to my little dirty patch (see attachment)
Laurent
Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected] -------------- "Software is hard" - Donald Knuth
drivers/kvm/kvm_main.c +2 -0
@@ -1222,6 +1222,8 @@ vcpu->mmio_is_write =0 ; r =x86_emulate_memop (&emulate_ctxt, &emulate_ops); +if (vcpu->pio.count) +return EMULATE_DO_MMIO ;if ((r || vcpu->mmio_is_write) && run) { run->exit_reason =KVM_EXIT_MMIO ;
drivers/kvm/svm.c +10 -139
177 lines not on this page · raw message
drivers/kvm/vmx.c +12 -64
94 lines not on this page · raw message
drivers/kvm/x86_emulate.c +42 -5
67 lines not on this page · raw message
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel