ia64/xen-unstable

changeset 16481:f676c0dacbb9

x86_emulate: Emulate LMSW and SMSW.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Nov 26 17:54:54 2007 +0000 (2007-11-26)
parents 4deb65519d9b
children 4d6f92fa1014
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Mon Nov 26 16:57:57 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Mon Nov 26 17:54:54 2007 +0000
     1.3 @@ -2666,6 +2666,7 @@ x86_emulate(
     1.4      {
     1.5      case 0x01: /* Grp7 */ {
     1.6          struct segment_register reg;
     1.7 +        unsigned long base, limit, cr0, cr0w;
     1.8  
     1.9          switch ( modrm_reg & 7 )
    1.10          {
    1.11 @@ -2691,11 +2692,12 @@ x86_emulate(
    1.12              fail_if(ops->write_segment == NULL);
    1.13              memset(&reg, 0, sizeof(reg));
    1.14              if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0,
    1.15 -                                 (unsigned long *)&reg.limit, 2, ctxt)) ||
    1.16 +                                 &limit, 2, ctxt)) ||
    1.17                   (rc = ops->read(ea.mem.seg, ea.mem.off+2,
    1.18 -                                 (unsigned long *)&reg.base,
    1.19 -                                 mode_64bit() ? 8 : 4, ctxt)) )
    1.20 +                                 &base, mode_64bit() ? 8 : 4, ctxt)) )
    1.21                  goto done;
    1.22 +            reg.base = base;
    1.23 +            reg.limit = limit;
    1.24              if ( op_bytes == 2 )
    1.25                  reg.base &= 0xffffff;
    1.26              if ( (rc = ops->write_segment((modrm_reg & 1) ?
    1.27 @@ -2703,6 +2705,29 @@ x86_emulate(
    1.28                                            &reg, ctxt)) )
    1.29                  goto done;
    1.30              break;
    1.31 +        case 4: /* smsw */
    1.32 +            dst = ea;
    1.33 +            dst.bytes = 2;
    1.34 +            fail_if(ops->read_cr == NULL);
    1.35 +            if ( (rc = ops->read_cr(0, &dst.val, ctxt)) )
    1.36 +                goto done;
    1.37 +            d |= Mov; /* force writeback */
    1.38 +            break;
    1.39 +        case 6: /* lmsw */
    1.40 +            fail_if(ops->read_cr == NULL);
    1.41 +            fail_if(ops->write_cr == NULL);
    1.42 +            if ( (rc = ops->read_cr(0, &cr0, ctxt)) )
    1.43 +                goto done;
    1.44 +            if ( ea.type == OP_REG )
    1.45 +                cr0w = *ea.reg;
    1.46 +            else if ( (rc = ops->read(ea.mem.seg, ea.mem.off,
    1.47 +                                      &cr0w, 2, ctxt)) )
    1.48 +                goto done;
    1.49 +            cr0 &= 0xffff0000;
    1.50 +            cr0 |= (uint16_t)cr0w;
    1.51 +            if ( (rc = ops->write_cr(0, cr0, ctxt)) )
    1.52 +                goto done;
    1.53 +            break;
    1.54          default:
    1.55              goto cannot_emulate;
    1.56          }