ia64/xen-unstable
changeset 15500:f1b62eb7f8be
[x86/32] Support two byte CMOVcc opcodes in 4G segment fixup.
These are present in Debian Etch's libc6-i686 package.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
These are present in Debian Etch's libc6-i686 package.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Tue Jul 03 17:04:50 2007 +0100 (2007-07-03) |
parents | 56da8753ba8d |
children | 9fa9346e1c70 |
files | xen/arch/x86/x86_32/seg_fixup.c |
line diff
1.1 --- a/xen/arch/x86/x86_32/seg_fixup.c Tue Jul 03 16:02:31 2007 +0100 1.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c Tue Jul 03 17:04:50 2007 +0100 1.3 @@ -93,6 +93,57 @@ static unsigned char insn_decode[256] = 1.4 X, X, X, X, X, X, O|M, O|M 1.5 }; 1.6 1.7 +static unsigned char twobyte_decode[256] = { 1.8 + /* 0x00 - 0x0F */ 1.9 + X, X, X, X, X, X, X, X, 1.10 + X, X, X, X, X, X, X, X, 1.11 + /* 0x10 - 0x1F */ 1.12 + X, X, X, X, X, X, X, X, 1.13 + X, X, X, X, X, X, X, X, 1.14 + /* 0x20 - 0x2F */ 1.15 + X, X, X, X, X, X, X, X, 1.16 + X, X, X, X, X, X, X, X, 1.17 + /* 0x30 - 0x3F */ 1.18 + X, X, X, X, X, X, X, X, 1.19 + X, X, X, X, X, X, X, X, 1.20 + /* 0x40 - 0x4F */ 1.21 + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, 1.22 + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, 1.23 + /* 0x50 - 0x5F */ 1.24 + X, X, X, X, X, X, X, X, 1.25 + X, X, X, X, X, X, X, X, 1.26 + /* 0x60 - 0x6F */ 1.27 + X, X, X, X, X, X, X, X, 1.28 + X, X, X, X, X, X, X, X, 1.29 + /* 0x70 - 0x7F */ 1.30 + X, X, X, X, X, X, X, X, 1.31 + X, X, X, X, X, X, X, X, 1.32 + /* 0x80 - 0x8F */ 1.33 + X, X, X, X, X, X, X, X, 1.34 + X, X, X, X, X, X, X, X, 1.35 + /* 0x90 - 0x9F */ 1.36 + X, X, X, X, X, X, X, X, 1.37 + X, X, X, X, X, X, X, X, 1.38 + /* 0xA0 - 0xAF */ 1.39 + X, X, X, X, X, X, X, X, 1.40 + X, X, X, X, X, X, X, X, 1.41 + /* 0xB0 - 0xBF */ 1.42 + X, X, X, X, X, X, X, X, 1.43 + X, X, X, X, X, X, X, X, 1.44 + /* 0xC0 - 0xCF */ 1.45 + X, X, X, X, X, X, X, X, 1.46 + X, X, X, X, X, X, X, X, 1.47 + /* 0xD0 - 0xDF */ 1.48 + X, X, X, X, X, X, X, X, 1.49 + X, X, X, X, X, X, X, X, 1.50 + /* 0xE0 - 0xEF */ 1.51 + X, X, X, X, X, X, X, X, 1.52 + X, X, X, X, X, X, X, X, 1.53 + /* 0xF0 - 0xFF */ 1.54 + X, X, X, X, X, X, X, X, 1.55 + X, X, X, X, X, X, X, X 1.56 +}; 1.57 + 1.58 /* 1.59 * Obtain the base and limit associated with the given segment selector. 1.60 * The selector must identify a 32-bit code or data segment. Any segment that 1.61 @@ -275,6 +326,7 @@ int gpf_emulate_4gb(struct cpu_user_regs 1.62 u8 *eip; /* ptr to instruction start */ 1.63 u8 *pb, b; /* ptr into instr. / current instr. byte */ 1.64 int gs_override = 0; 1.65 + int twobyte = 0; 1.66 1.67 /* WARNING: We only work for ring-3 segments. */ 1.68 if ( unlikely(vm86_mode(regs)) || unlikely(!ring_3(regs)) ) 1.69 @@ -337,12 +389,36 @@ int gpf_emulate_4gb(struct cpu_user_regs 1.70 1.71 decode = insn_decode[b]; /* opcode byte */ 1.72 pb++; 1.73 + if ( decode == 0 && b == 0x0f ) 1.74 + { 1.75 + twobyte = 1; 1.76 + 1.77 + if ( get_user(b, pb) ) 1.78 + { 1.79 + dprintk(XENLOG_DEBUG, 1.80 + "Fault while accessing byte %ld of instruction\n", 1.81 + (long)(pb-eip)); 1.82 + goto page_fault; 1.83 + } 1.84 + 1.85 + if ( (pb - eip) >= 15 ) 1.86 + { 1.87 + dprintk(XENLOG_DEBUG, "Too many opcode bytes for a " 1.88 + "legal instruction\n"); 1.89 + goto fail; 1.90 + } 1.91 + 1.92 + decode = twobyte_decode[b]; 1.93 + pb++; 1.94 + } 1.95 + 1.96 if ( decode == 0 ) 1.97 { 1.98 - dprintk(XENLOG_DEBUG, "Unsupported opcode %02x\n", b); 1.99 + dprintk(XENLOG_DEBUG, "Unsupported %sopcode %02x\n", 1.100 + twobyte ? "two byte " : "", b); 1.101 goto fail; 1.102 } 1.103 - 1.104 + 1.105 if ( !(decode & HAS_MODRM) ) 1.106 { 1.107 /* Must be a <disp32>, or bail. */