ia64/xen-unstable

changeset 16483:f9a43c6b5be1

vmx realmode: When returning to protected mode we have to massage the
segment state to pass VMENTER's stringent 'sanity checks'.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Nov 26 22:20:21 2007 +0000 (2007-11-26)
parents 4d6f92fa1014
children 26e766e0c628
files xen/arch/x86/hvm/vmx/realmode.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Mon Nov 26 17:55:23 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Mon Nov 26 22:20:21 2007 +0000
     1.3 @@ -524,7 +524,8 @@ void vmx_realmode(struct cpu_user_regs *
     1.4          if ( rc == X86EMUL_UNHANDLEABLE )
     1.5          {
     1.6              gdprintk(XENLOG_DEBUG,
     1.7 -                     "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n",
     1.8 +                     "Real-mode emulation failed @ %04x:%08lx: "
     1.9 +                     "%02x %02x %02x %02x %02x %02x\n",
    1.10                       rm_ctxt.seg_reg[x86_seg_cs].sel, rm_ctxt.insn_buf_eip,
    1.11                       rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1],
    1.12                       rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3],
    1.13 @@ -534,6 +535,26 @@ void vmx_realmode(struct cpu_user_regs *
    1.14          }
    1.15      }
    1.16  
    1.17 +    /*
    1.18 +     * Cannot enter protected mode with bogus selector RPLs and DPLs. Hence we
    1.19 +     * fix up as best we can, even though this deviates from native execution
    1.20 +     */
    1.21 +    if  ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
    1.22 +    {
    1.23 +        /* CS.RPL == SS.RPL == SS.DPL == 0. */
    1.24 +        rm_ctxt.seg_reg[x86_seg_cs].sel &= ~3;
    1.25 +        rm_ctxt.seg_reg[x86_seg_ss].sel &= ~3;
    1.26 +        /* DS,ES,FS,GS: The most uninvasive trick is to set DPL == RPL. */
    1.27 +        rm_ctxt.seg_reg[x86_seg_ds].attr.fields.dpl =
    1.28 +            rm_ctxt.seg_reg[x86_seg_ds].sel & 3;
    1.29 +        rm_ctxt.seg_reg[x86_seg_es].attr.fields.dpl =
    1.30 +            rm_ctxt.seg_reg[x86_seg_es].sel & 3;
    1.31 +        rm_ctxt.seg_reg[x86_seg_fs].attr.fields.dpl =
    1.32 +            rm_ctxt.seg_reg[x86_seg_fs].sel & 3;
    1.33 +        rm_ctxt.seg_reg[x86_seg_gs].attr.fields.dpl =
    1.34 +            rm_ctxt.seg_reg[x86_seg_gs].sel & 3;
    1.35 +    }
    1.36 +
    1.37      for ( i = 0; i < 10; i++ )
    1.38          hvm_set_segment_register(curr, i, &rm_ctxt.seg_reg[i]);
    1.39  }
    1.40 @@ -546,12 +567,6 @@ int vmx_realmode_io_complete(void)
    1.41      if ( !curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.42          return 0;
    1.43  
    1.44 -#if 0
    1.45 -    gdprintk(XENLOG_DEBUG, "RM I/O %d %c bytes=%d addr=%lx data=%lx\n",
    1.46 -             p->type, p->dir ? 'R' : 'W',
    1.47 -             (int)p->size, (long)p->addr, (long)p->data);
    1.48 -#endif
    1.49 -
    1.50      curr->arch.hvm_vmx.real_mode_io_in_progress = 0;
    1.51      if ( p->dir == IOREQ_READ )
    1.52      {