[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


  • To: "Jan Beulich" <jbeulich@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: "Petersson, Mats" <Mats.Petersson@xxxxxxx>
  • Date: Tue, 21 Nov 2006 18:03:49 +0100
  • Delivery-date: Tue, 21 Nov 2006 09:28:10 -0800
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: AccNjfDFVCncyxTgRa6dIdhz6i+4TwAAH28g
  • Thread-topic: [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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.