direct-io.hg

changeset 12516:18cd7d886949

[HVM] Fix instruction linear address computation.
This helps newer isolinux' graphical boot code (which crashes without
this).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Wed Nov 22 10:31:50 2006 +0000 (2006-11-22)
parents cc180acf4693
children 40a61d01e9dc
files xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h
line diff
     1.1 --- a/xen/arch/x86/hvm/platform.c	Wed Nov 22 10:30:05 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/platform.c	Wed Nov 22 10:31:50 2006 +0000
     1.3 @@ -895,9 +895,10 @@ void handle_mmio(unsigned long gpa)
     1.4  
     1.5      realmode = hvm_realmode(v);
     1.6      if ( realmode )
     1.7 -        inst_addr = (regs->cs << 4) + regs->eip;
     1.8 +        inst_addr = regs->cs << 4;
     1.9      else
    1.10 -        inst_addr = regs->eip;
    1.11 +        inst_addr = hvm_get_segment_base(current, seg_cs);
    1.12 +    inst_addr += regs->eip;
    1.13  
    1.14      memset(inst, 0, MAX_INST_LEN);
    1.15      if ( inst_copy_from_guest(inst, inst_addr, inst_len) != inst_len ) {
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Nov 22 10:30:05 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Nov 22 10:31:50 2006 +0000
     2.3 @@ -510,6 +510,24 @@ unsigned long svm_get_ctrl_reg(struct vc
     2.4      return 0;                   /* dummy */
     2.5  }
     2.6  
     2.7 +static unsigned long svm_get_segment_base(struct vcpu *v, enum segment seg)
     2.8 +{
     2.9 +    switch ( seg )
    2.10 +    {
    2.11 +    case seg_cs: return v->arch.hvm_svm.vmcb->cs.base;
    2.12 +    case seg_ds: return v->arch.hvm_svm.vmcb->ds.base;
    2.13 +    case seg_es: return v->arch.hvm_svm.vmcb->es.base;
    2.14 +    case seg_fs: return v->arch.hvm_svm.vmcb->fs.base;
    2.15 +    case seg_gs: return v->arch.hvm_svm.vmcb->gs.base;
    2.16 +    case seg_ss: return v->arch.hvm_svm.vmcb->ss.base;
    2.17 +    case seg_tr: return v->arch.hvm_svm.vmcb->tr.base;
    2.18 +    case seg_gdtr: return v->arch.hvm_svm.vmcb->gdtr.base;
    2.19 +    case seg_idtr: return v->arch.hvm_svm.vmcb->idtr.base;
    2.20 +    case seg_ldtr: return v->arch.hvm_svm.vmcb->ldtr.base;
    2.21 +    }
    2.22 +    BUG();
    2.23 +    return 0;
    2.24 +}
    2.25  
    2.26  /* Make sure that xen intercepts any FP accesses from current */
    2.27  static void svm_stts(struct vcpu *v) 
    2.28 @@ -821,6 +839,7 @@ int start_svm(void)
    2.29      hvm_funcs.pae_enabled = svm_pae_enabled;
    2.30      hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
    2.31      hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
    2.32 +    hvm_funcs.get_segment_base = svm_get_segment_base;
    2.33  
    2.34      hvm_funcs.update_host_cr3 = svm_update_host_cr3;
    2.35      
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Nov 22 10:30:05 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Nov 22 10:31:50 2006 +0000
     3.3 @@ -501,6 +501,28 @@ static unsigned long vmx_get_ctrl_reg(st
     3.4      return 0;                   /* dummy */
     3.5  }
     3.6  
     3.7 +static unsigned long vmx_get_segment_base(struct vcpu *v, enum segment seg)
     3.8 +{
     3.9 +    unsigned long base;
    3.10 +
    3.11 +    BUG_ON(v != current);
    3.12 +    switch ( seg )
    3.13 +    {
    3.14 +    case seg_cs: __vmread(GUEST_CS_BASE, &base); break;
    3.15 +    case seg_ds: __vmread(GUEST_DS_BASE, &base); break;
    3.16 +    case seg_es: __vmread(GUEST_ES_BASE, &base); break;
    3.17 +    case seg_fs: __vmread(GUEST_FS_BASE, &base); break;
    3.18 +    case seg_gs: __vmread(GUEST_GS_BASE, &base); break;
    3.19 +    case seg_ss: __vmread(GUEST_SS_BASE, &base); break;
    3.20 +    case seg_tr: __vmread(GUEST_TR_BASE, &base); break;
    3.21 +    case seg_gdtr: __vmread(GUEST_GDTR_BASE, &base); break;
    3.22 +    case seg_idtr: __vmread(GUEST_IDTR_BASE, &base); break;
    3.23 +    case seg_ldtr: __vmread(GUEST_LDTR_BASE, &base); break;
    3.24 +    default: BUG(); base = 0; break;
    3.25 +    }
    3.26 +    return base;
    3.27 +}
    3.28 +
    3.29  /* Make sure that xen intercepts any FP accesses from current */
    3.30  static void vmx_stts(struct vcpu *v)
    3.31  {
    3.32 @@ -619,6 +641,7 @@ static void vmx_setup_hvm_funcs(void)
    3.33      hvm_funcs.pae_enabled = vmx_pae_enabled;
    3.34      hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
    3.35      hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
    3.36 +    hvm_funcs.get_segment_base = vmx_get_segment_base;
    3.37  
    3.38      hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
    3.39  
     4.1 --- a/xen/include/asm-x86/hvm/hvm.h	Wed Nov 22 10:30:05 2006 +0000
     4.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Wed Nov 22 10:31:50 2006 +0000
     4.3 @@ -20,6 +20,19 @@
     4.4  #ifndef __ASM_X86_HVM_HVM_H__
     4.5  #define __ASM_X86_HVM_HVM_H__
     4.6  
     4.7 +enum segment {
     4.8 +    seg_cs,
     4.9 +    seg_ss,
    4.10 +    seg_ds,
    4.11 +    seg_es,
    4.12 +    seg_fs,
    4.13 +    seg_gs,
    4.14 +    seg_tr,
    4.15 +    seg_ldtr,
    4.16 +    seg_gdtr,
    4.17 +    seg_idtr
    4.18 +};
    4.19 +
    4.20  /*
    4.21   * The hardware virtual machine (HVM) interface abstracts away from the
    4.22   * x86/x86_64 CPU virtualization assist specifics. Currently this interface
    4.23 @@ -52,6 +65,7 @@ struct hvm_function_table {
    4.24       * 1) determine whether the guest is in real or vm8086 mode,
    4.25       * 2) determine whether paging is enabled,
    4.26       * 3) return the current guest control-register value
    4.27 +     * 4) return the current guest segment descriptor base
    4.28       */
    4.29      int (*realmode)(struct vcpu *v);
    4.30      int (*paging_enabled)(struct vcpu *v);
    4.31 @@ -59,6 +73,7 @@ struct hvm_function_table {
    4.32      int (*pae_enabled)(struct vcpu *v);
    4.33      int (*guest_x86_mode)(struct vcpu *v);
    4.34      unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
    4.35 +    unsigned long (*get_segment_base)(struct vcpu *v, enum segment seg);
    4.36  
    4.37      /* 
    4.38       * Re-set the value of CR3 that Xen runs on when handling VM exits
    4.39 @@ -161,6 +176,12 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u
    4.40      return 0;                   /* force to fail */
    4.41  }
    4.42  
    4.43 +static inline unsigned long
    4.44 +hvm_get_segment_base(struct vcpu *v, enum segment seg)
    4.45 +{
    4.46 +    return hvm_funcs.get_segment_base(v, seg);
    4.47 +}
    4.48 +
    4.49  void hvm_stts(struct vcpu *v);
    4.50  void hvm_set_guest_time(struct vcpu *v, u64 gtime);
    4.51  void hvm_freeze_time(struct vcpu *v);