WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

RE: [Xen-devel] [PATCH] support protected mode mmio with non-zero CS bas

To: "Jan Beulich" <jbeulich@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: RE: [Xen-devel] [PATCH] support protected mode mmio with non-zero CS base
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
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <45633D88.76E4.0078.0@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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