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

[Xen-devel] [PATCH] support protected mode mmio with non-zero CS base

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] support protected mode mmio with non-zero CS base
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Tue, 21 Nov 2006 16:55:20 +0000
Delivery-date: Tue, 21 Nov 2006 08:53:33 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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
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);
+    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