[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [Xen-devel] [PATCH] support protected mode mmio with non-zero CS base
> -----Original Message----- > From: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx > [mailto:xen-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of > Jan Beulich > Sent: 21 November 2006 16:55 > To: xen-devel@xxxxxxxxxxxxxxxxxxx > Subject: [Xen-devel] [PATCH] support protected mode mmio with > non-zero CS base > > This helps newer isolinux' graphical boot code (which crashes > without this). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> > > Index: 2006-11-17/xen/arch/x86/hvm/platform.c > =================================================================== > --- 2006-11-17.orig/xen/arch/x86/hvm/platform.c > 2006-10-16 20:56:36.000000000 +0200 > +++ 2006-11-17/xen/arch/x86/hvm/platform.c 2006-11-21 > 13:29:03.000000000 +0100 > @@ -895,9 +895,10 @@ void handle_mmio(unsigned long va, unsig > > realmode = hvm_realmode(v); > if ( realmode ) > - inst_addr = (regs->cs << 4) + regs->eip; > + inst_addr = regs->cs << 4; > else > - inst_addr = regs->eip; > + inst_addr = hvm_get_segment_base(current, seg_cs); Remove the "if ( realmode ) " and just use the segment base address. The base-address in the register should be correct even in realmod, or the processor is broken. [I don't think this code is being executed from vmxassist - if it is, then that's a different special case!]. Theoretically, you should also check that (eip <= segment.limit), and issue GP-fault if not true. -- Mats > + inst_addr += regs->eip; > > memset(inst, 0, MAX_INST_LEN); > if ( inst_copy_from_guest(inst, inst_addr, inst_len) != > inst_len ) { > Index: 2006-11-17/xen/arch/x86/hvm/svm/svm.c > =================================================================== > --- 2006-11-17.orig/xen/arch/x86/hvm/svm/svm.c > 2006-11-21 11:29:10.000000000 +0100 > +++ 2006-11-17/xen/arch/x86/hvm/svm/svm.c 2006-11-21 > 13:22:35.000000000 +0100 > @@ -510,6 +510,24 @@ unsigned long svm_get_ctrl_reg(struct vc > return 0; /* dummy */ > } > > +static unsigned long svm_get_segment_base(struct vcpu *v, > enum segment seg) > +{ > + switch ( seg ) > + { > + case seg_cs: return v->arch.hvm_svm.vmcb->cs.base; > + case seg_ds: return v->arch.hvm_svm.vmcb->ds.base; > + case seg_es: return v->arch.hvm_svm.vmcb->es.base; > + case seg_fs: return v->arch.hvm_svm.vmcb->fs.base; > + case seg_gs: return v->arch.hvm_svm.vmcb->gs.base; > + case seg_ss: return v->arch.hvm_svm.vmcb->ss.base; > + case seg_tr: return v->arch.hvm_svm.vmcb->tr.base; > + case seg_gdtr: return v->arch.hvm_svm.vmcb->gdtr.base; > + case seg_idtr: return v->arch.hvm_svm.vmcb->idtr.base; > + case seg_ldtr: return v->arch.hvm_svm.vmcb->ldtr.base; > + } > + BUG(); > + return 0; > +} > > /* Make sure that xen intercepts any FP accesses from current */ > static void svm_stts(struct vcpu *v) > @@ -821,6 +839,7 @@ int start_svm(void) > hvm_funcs.pae_enabled = svm_pae_enabled; > hvm_funcs.guest_x86_mode = svm_guest_x86_mode; > hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg; > + hvm_funcs.get_segment_base = svm_get_segment_base; > > hvm_funcs.update_host_cr3 = svm_update_host_cr3; > > Index: 2006-11-17/xen/arch/x86/hvm/vmx/vmx.c > =================================================================== > --- 2006-11-17.orig/xen/arch/x86/hvm/vmx/vmx.c > 2006-11-21 11:29:10.000000000 +0100 > +++ 2006-11-17/xen/arch/x86/hvm/vmx/vmx.c 2006-11-21 > 13:27:45.000000000 +0100 > @@ -501,6 +501,28 @@ static unsigned long vmx_get_ctrl_reg(st > return 0; /* dummy */ > } > > +static unsigned long vmx_get_segment_base(struct vcpu *v, > enum segment seg) > +{ > + unsigned long base; > + > + BUG_ON(v != current); > + switch ( seg ) > + { > + case seg_cs: __vmread(GUEST_CS_BASE, &base); break; > + case seg_ds: __vmread(GUEST_DS_BASE, &base); break; > + case seg_es: __vmread(GUEST_ES_BASE, &base); break; > + case seg_fs: __vmread(GUEST_FS_BASE, &base); break; > + case seg_gs: __vmread(GUEST_GS_BASE, &base); break; > + case seg_ss: __vmread(GUEST_SS_BASE, &base); break; > + case seg_tr: __vmread(GUEST_TR_BASE, &base); break; > + case seg_gdtr: __vmread(GUEST_GDTR_BASE, &base); break; > + case seg_idtr: __vmread(GUEST_IDTR_BASE, &base); break; > + case seg_ldtr: __vmread(GUEST_LDTR_BASE, &base); break; > + default: BUG(); base = 0; break; > + } > + return base; > +} > + > /* Make sure that xen intercepts any FP accesses from current */ > static void vmx_stts(struct vcpu *v) > { > @@ -619,6 +640,7 @@ static void vmx_setup_hvm_funcs(void) > hvm_funcs.pae_enabled = vmx_pae_enabled; > hvm_funcs.guest_x86_mode = vmx_guest_x86_mode; > hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg; > + hvm_funcs.get_segment_base = vmx_get_segment_base; > > hvm_funcs.update_host_cr3 = vmx_update_host_cr3; > > Index: 2006-11-17/xen/include/asm-x86/hvm/hvm.h > =================================================================== > --- 2006-11-17.orig/xen/include/asm-x86/hvm/hvm.h > 2006-09-27 21:51:56.000000000 +0200 > +++ 2006-11-17/xen/include/asm-x86/hvm/hvm.h 2006-11-21 > 13:09:55.000000000 +0100 > @@ -20,6 +20,19 @@ > #ifndef __ASM_X86_HVM_HVM_H__ > #define __ASM_X86_HVM_HVM_H__ > > +enum segment { > + seg_cs, > + seg_ss, > + seg_ds, > + seg_es, > + seg_fs, > + seg_gs, > + seg_tr, > + seg_ldtr, > + seg_gdtr, > + seg_idtr > +}; > + > /* > * The hardware virtual machine (HVM) interface abstracts > away from the > * x86/x86_64 CPU virtualization assist specifics. Currently > this interface > @@ -52,6 +65,7 @@ struct hvm_function_table { > * 1) determine whether the guest is in real or vm8086 mode, > * 2) determine whether paging is enabled, > * 3) return the current guest control-register value > + * 4) return the current guest segment descriptor base > */ > int (*realmode)(struct vcpu *v); > int (*paging_enabled)(struct vcpu *v); > @@ -59,6 +73,7 @@ struct hvm_function_table { > int (*pae_enabled)(struct vcpu *v); > int (*guest_x86_mode)(struct vcpu *v); > unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, > unsigned int num); > + unsigned long (*get_segment_base)(struct vcpu *v, enum > segment seg); > > /* > * Re-set the value of CR3 that Xen runs on when > handling VM exits > @@ -161,6 +186,12 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u > return 0; /* force to fail */ > } > > +static inline unsigned long > +hvm_get_segment_base(struct vcpu *v, enum segment seg) > +{ > + return hvm_funcs.get_segment_base(v, seg); > +} > + > void hvm_stts(struct vcpu *v); > void hvm_set_guest_time(struct vcpu *v, u64 gtime); > void hvm_freeze_time(struct vcpu *v); > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |