[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86_32: handle x87 opcodes in TLS segment fixups
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1248794118 -3600 # Node ID 95eec4e77c3c60e8f4e53436f6a259613a9094d8 # Parent 8af26fef898c88d1b929e597d3b232673b8e777d x86_32: handle x87 opcodes in TLS segment fixups This patch adds support to the TLS fixup code for x87 opcodes. These can be treated like 2-byte opcodes with a weird encoding. The patch includes some extra changes because, now that we have >2 opcode tables and 9 different lead bytes in a two-byte opcode, a simple boolean code will not be enough to differentiate one- and two-byte opcodes. Besides this, the patch is trivial since the segment fixup code cares about the operands of the instruction, not about its semantics. From: Paolo Bonzini <pbonzini@xxxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/x86_32/seg_fixup.c | 55 ++++++++++++++++++++++++++++++++++------ 1 files changed, 47 insertions(+), 8 deletions(-) diff -r 8af26fef898c -r 95eec4e77c3c xen/arch/x86/x86_32/seg_fixup.c --- a/xen/arch/x86/x86_32/seg_fixup.c Fri Jul 24 12:08:54 2009 +0100 +++ b/xen/arch/x86/x86_32/seg_fixup.c Tue Jul 28 16:15:18 2009 +0100 @@ -42,7 +42,7 @@ #define O OPCODE_BYTE #define M HAS_MODRM -static const unsigned char insn_decode[256] = { +static const u8 insn_decode[256] = { /* 0x00 - 0x0F */ O|M, O|M, O|M, O|M, X, X, X, X, O|M, O|M, O|M, O|M, X, X, X, X, @@ -93,7 +93,18 @@ static const unsigned char insn_decode[2 X, X, X, X, X, X, O|M, O|M }; -static const unsigned char twobyte_decode[256] = { +static const u8 float_decode[64] = { + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xD8 */ + O|M, X, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xD9 */ + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xDA */ + O|M, X, O|M, O|M, X, O|M, X, O|M, /* 0xDB */ + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xDC */ + O|M, O|M, O|M, O|M, O|M, X, O|M, O|M, /* 0xDD */ + O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xDE */ + O|M, X, O|M, O|M, O|M, O|M, O|M, O|M, /* 0xDF */ +}; + +static const u8 twobyte_decode[256] = { /* 0x00 - 0x0F */ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, @@ -321,7 +332,8 @@ int gpf_emulate_4gb(struct cpu_user_regs s32 disp32 = 0; u8 *eip; /* ptr to instruction start */ u8 *pb, b; /* ptr into instr. / current instr. byte */ - int gs_override = 0, scale = 0, twobyte = 0; + int gs_override = 0, scale = 0, opcode = -1; + const u8 *table = insn_decode; /* WARNING: We only work for ring-3 segments. */ if ( unlikely(vm86_mode(regs)) || unlikely(!ring_3(regs)) ) @@ -352,8 +364,11 @@ int gpf_emulate_4gb(struct cpu_user_regs goto fail; } - if ( twobyte ) + if ( opcode != -1 ) + { + opcode = (opcode << 8) | b; break; + } switch ( b ) { @@ -374,8 +389,29 @@ int gpf_emulate_4gb(struct cpu_user_regs gs_override = 1; break; case 0x0f: /* Not really a prefix byte */ - twobyte = 1; + table = twobyte_decode; + opcode = b; break; + case 0xd8: /* Math coprocessor instructions. */ + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + /* Float opcodes have a secondary opcode in the modrm byte. */ + table = float_decode; + if ( get_user(modrm, pb + 1) ) + { + dprintk(XENLOG_DEBUG, "Fault while extracting modrm byte\n"); + goto page_fault; + } + + opcode = (b << 8) | modrm; + b = ((b & 7) << 3) + ((modrm >> 3) & 7); + goto done_prefix; + default: /* Not a prefix byte */ goto done_prefix; } @@ -388,13 +424,16 @@ int gpf_emulate_4gb(struct cpu_user_regs goto fail; } - decode = (!twobyte ? insn_decode : twobyte_decode)[b]; + decode = table[b]; pb++; if ( !(decode & OPCODE_BYTE) ) { - dprintk(XENLOG_DEBUG, "Unsupported %sopcode %02x\n", - twobyte ? "two byte " : "", b); + if (opcode == -1) + dprintk(XENLOG_DEBUG, "Unsupported opcode %02x\n", b); + else + dprintk(XENLOG_DEBUG, "Unsupported opcode %02x %02x\n", + opcode >> 8, opcode & 255); goto fail; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |