ia64/xen-unstable
changeset 16481:f676c0dacbb9
x86_emulate: Emulate LMSW and SMSW.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
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(®, 0, sizeof(reg)); 1.14 if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, 1.15 - (unsigned long *)®.limit, 2, ctxt)) || 1.16 + &limit, 2, ctxt)) || 1.17 (rc = ops->read(ea.mem.seg, ea.mem.off+2, 1.18 - (unsigned long *)®.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 ®, 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 }