ia64/xen-unstable

changeset 16460:a194083696d5

vmx realmode: Support privileged EFLAGS updates in emulated realmode.
Also tweak debug tracing to be much less noisy. We can emulates tens
of thousands of instructions in rombios now.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Sun Nov 25 11:45:02 2007 +0000 (2007-11-25)
parents 368bcf480772
children d40788f07a4f
files xen/arch/x86/hvm/vmx/realmode.c xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Sun Nov 25 11:43:53 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Sun Nov 25 11:45:02 2007 +0000
     1.3 @@ -168,6 +168,14 @@ realmode_write_segment(
     1.4      struct realmode_emulate_ctxt *rm_ctxt =
     1.5          container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
     1.6      memcpy(&rm_ctxt->seg_reg[seg], reg, sizeof(struct segment_register));
     1.7 +
     1.8 +    if ( seg == x86_seg_ss )
     1.9 +    {
    1.10 +        u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
    1.11 +        intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
    1.12 +        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
    1.13 +    }
    1.14 +
    1.15      return X86EMUL_OKAY;
    1.16  }
    1.17  
    1.18 @@ -236,6 +244,20 @@ realmode_read_cr(
    1.19      return X86EMUL_OKAY;
    1.20  }
    1.21  
    1.22 +static int realmode_write_rflags(
    1.23 +    unsigned long val,
    1.24 +    struct x86_emulate_ctxt *ctxt)
    1.25 +{
    1.26 +    if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) )
    1.27 +    {
    1.28 +        u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
    1.29 +        intr_shadow ^= VMX_INTR_SHADOW_STI;
    1.30 +        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
    1.31 +    }
    1.32 +
    1.33 +    return X86EMUL_OKAY;
    1.34 +}
    1.35 +
    1.36  static struct x86_emulate_ops realmode_emulator_ops = {
    1.37      .read          = realmode_emulate_read,
    1.38      .insn_fetch    = realmode_emulate_insn_fetch,
    1.39 @@ -245,7 +267,8 @@ static struct x86_emulate_ops realmode_e
    1.40      .write_segment = realmode_write_segment,
    1.41      .read_io       = realmode_read_io,
    1.42      .write_io      = realmode_write_io,
    1.43 -    .read_cr       = realmode_read_cr
    1.44 +    .read_cr       = realmode_read_cr,
    1.45 +    .write_rflags  = realmode_write_rflags
    1.46  };
    1.47  
    1.48  int vmx_realmode(struct cpu_user_regs *regs)
    1.49 @@ -277,26 +300,22 @@ int vmx_realmode(struct cpu_user_regs *r
    1.50                   rm_ctxt.insn_buf, addr, sizeof(rm_ctxt.insn_buf)))
    1.51              ? sizeof(rm_ctxt.insn_buf) : 0;
    1.52  
    1.53 -        gdprintk(XENLOG_DEBUG,
    1.54 -                 "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n",
    1.55 -                 rm_ctxt.seg_reg[x86_seg_cs].sel, regs->eip,
    1.56 -                 rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1],
    1.57 -                 rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3],
    1.58 -                 rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]);
    1.59 -
    1.60          rc = x86_emulate(&rm_ctxt.ctxt, &realmode_emulator_ops);
    1.61  
    1.62          if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.63          {
    1.64 -            ioreq_t *p = &get_ioreq(curr)->vp_ioreq;
    1.65 -            gdprintk(XENLOG_DEBUG, "RM I/O %d %c addr=%lx data=%lx\n",
    1.66 -                     p->type, p->dir ? 'R' : 'W', p->addr, p->data);
    1.67              rc = 0;
    1.68              break;
    1.69          }
    1.70  
    1.71          if ( rc )
    1.72          {
    1.73 +            gdprintk(XENLOG_DEBUG,
    1.74 +                     "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n",
    1.75 +                     rm_ctxt.seg_reg[x86_seg_cs].sel, rm_ctxt.insn_buf_eip,
    1.76 +                     rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1],
    1.77 +                     rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3],
    1.78 +                     rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]);
    1.79              gdprintk(XENLOG_ERR, "Emulation failed\n");
    1.80              rc = -EINVAL;
    1.81              break;
    1.82 @@ -317,6 +336,12 @@ int vmx_realmode_io_complete(void)
    1.83      if ( !curr->arch.hvm_vmx.real_mode_io_in_progress )
    1.84          return 0;
    1.85  
    1.86 +#if 0
    1.87 +    gdprintk(XENLOG_DEBUG, "RM I/O %d %c bytes=%d addr=%lx data=%lx\n",
    1.88 +             p->type, p->dir ? 'R' : 'W',
    1.89 +             (int)p->size, (long)p->addr, (long)p->data);
    1.90 +#endif
    1.91 +
    1.92      curr->arch.hvm_vmx.real_mode_io_in_progress = 0;
    1.93      if ( p->dir == IOREQ_READ )
    1.94      {
     2.1 --- a/xen/arch/x86/x86_emulate.c	Sun Nov 25 11:43:53 2007 +0000
     2.2 +++ b/xen/arch/x86/x86_emulate.c	Sun Nov 25 11:45:02 2007 +0000
     2.3 @@ -2253,16 +2253,13 @@ x86_emulate(
     2.4          break;
     2.5  
     2.6      case 0xfa: /* cli */
     2.7 -        generate_exception_if(!mode_iopl(), EXC_GP);
     2.8 -        fail_if(ops->write_rflags == NULL);
     2.9 -        if ( (rc = ops->write_rflags(_regs.eflags & ~EFLG_IF, ctxt)) != 0 )
    2.10 -            goto done;
    2.11 -        break;
    2.12 -
    2.13      case 0xfb: /* sti */
    2.14          generate_exception_if(!mode_iopl(), EXC_GP);
    2.15          fail_if(ops->write_rflags == NULL);
    2.16 -        if ( (rc = ops->write_rflags(_regs.eflags | EFLG_IF, ctxt)) != 0 )
    2.17 +        _regs.eflags &= ~EFLG_IF;
    2.18 +        if ( b == 0xfb ) /* sti */
    2.19 +            _regs.eflags |= EFLG_IF;
    2.20 +        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
    2.21              goto done;
    2.22          break;
    2.23