ia64/xen-unstable

changeset 17921:a9fff28d4f06

x86: Emulation of LMSW must only affect CR0 bits 0-3.
Emulation of SMSW is only restricted to 16-bit operation on memory
operands.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 27 17:24:54 2008 +0100 (2008-06-27)
parents 6b0663901174
children 87e1f23a06f0
files xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/x86_emulate/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Jun 27 16:20:59 2008 +0100
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Jun 27 17:24:54 2008 +0100
     1.3 @@ -1523,8 +1523,8 @@ static int vmx_cr_access(unsigned long e
     1.4          break;
     1.5      case VMX_CONTROL_REG_ACCESS_TYPE_LMSW:
     1.6          value = v->arch.hvm_vcpu.guest_cr[0];
     1.7 -        /* NB. LMSW can set, but never clear, PE. */
     1.8 -        value = (value & 0xFFFF0001) | ((exit_qualification >> 16) & 0xFFFF);
     1.9 +        /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */
    1.10 +        value = (value & ~0xe) | ((exit_qualification >> 16) & 0xf);
    1.11          HVMTRACE_LONG_1D(LMSW, current, value);
    1.12          return !hvm_set_cr0(value);
    1.13      default:
     2.1 --- a/xen/arch/x86/x86_emulate/x86_emulate.c	Fri Jun 27 16:20:59 2008 +0100
     2.2 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c	Fri Jun 27 17:24:54 2008 +0100
     2.3 @@ -3267,7 +3267,8 @@ x86_emulate(
     2.4                  goto done;
     2.5              break;
     2.6          case 4: /* smsw */
     2.7 -            ea.bytes = 2;
     2.8 +            if ( ea.type == OP_MEM )
     2.9 +                ea.bytes = 2;
    2.10              dst = ea;
    2.11              fail_if(ops->read_cr == NULL);
    2.12              if ( (rc = ops->read_cr(0, &dst.val, ctxt)) )
    2.13 @@ -3284,8 +3285,8 @@ x86_emulate(
    2.14              else if ( (rc = ops->read(ea.mem.seg, ea.mem.off,
    2.15                                        &cr0w, 2, ctxt)) )
    2.16                  goto done;
    2.17 -            cr0 &= 0xffff0001; /* lmsw can set, but never clear, PE */
    2.18 -            cr0 |= (uint16_t)cr0w;
    2.19 +            /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */
    2.20 +            cr0 = (cr0 & ~0xe) | (cr0w & 0xf);
    2.21              if ( (rc = ops->write_cr(0, cr0, ctxt)) )
    2.22                  goto done;
    2.23              break;