diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-05-09 05:32:50 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-05-09 06:14:51 -0400 |
commit | 7fa57952d70f5737513d8319395e471d107e4e0d (patch) | |
tree | 14f9c0ab4a76f2f065a5f891e381809d20a740ba /arch | |
parent | a035d5c64d08a8ac12d81b596e7fa6d95a73c347 (diff) |
KVM: emulator: emulate XLAT
This is used by SGABIOS, KVM breaks with emulate_invalid_guest_state=1.
It is just a MOV in disguise, with a funny source address.
Reported-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Cc: stable@vger.kernel.org # 3.9
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/emulate.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 55322a7c113d..a06a550c2db8 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #define OpGS 25ull /* GS */ | 60 | #define OpGS 25ull /* GS */ |
61 | #define OpMem8 26ull /* 8-bit zero extended memory operand */ | 61 | #define OpMem8 26ull /* 8-bit zero extended memory operand */ |
62 | #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ | 62 | #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ |
63 | #define OpXLat 28ull /* memory at BX/EBX/RBX + zero-extended AL */ | ||
63 | 64 | ||
64 | #define OpBits 5 /* Width of operand field */ | 65 | #define OpBits 5 /* Width of operand field */ |
65 | #define OpMask ((1ull << OpBits) - 1) | 66 | #define OpMask ((1ull << OpBits) - 1) |
@@ -99,6 +100,7 @@ | |||
99 | #define SrcImmUByte (OpImmUByte << SrcShift) | 100 | #define SrcImmUByte (OpImmUByte << SrcShift) |
100 | #define SrcImmU (OpImmU << SrcShift) | 101 | #define SrcImmU (OpImmU << SrcShift) |
101 | #define SrcSI (OpSI << SrcShift) | 102 | #define SrcSI (OpSI << SrcShift) |
103 | #define SrcXLat (OpXLat << SrcShift) | ||
102 | #define SrcImmFAddr (OpImmFAddr << SrcShift) | 104 | #define SrcImmFAddr (OpImmFAddr << SrcShift) |
103 | #define SrcMemFAddr (OpMemFAddr << SrcShift) | 105 | #define SrcMemFAddr (OpMemFAddr << SrcShift) |
104 | #define SrcAcc (OpAcc << SrcShift) | 106 | #define SrcAcc (OpAcc << SrcShift) |
@@ -3959,7 +3961,8 @@ static const struct opcode opcode_table[256] = { | |||
3959 | G(Src2One | ByteOp, group2), G(Src2One, group2), | 3961 | G(Src2One | ByteOp, group2), G(Src2One, group2), |
3960 | G(Src2CL | ByteOp, group2), G(Src2CL, group2), | 3962 | G(Src2CL | ByteOp, group2), G(Src2CL, group2), |
3961 | I(DstAcc | SrcImmUByte | No64, em_aam), | 3963 | I(DstAcc | SrcImmUByte | No64, em_aam), |
3962 | I(DstAcc | SrcImmUByte | No64, em_aad), N, N, | 3964 | I(DstAcc | SrcImmUByte | No64, em_aad), N, |
3965 | I(DstAcc | SrcXLat | ByteOp, em_mov), | ||
3963 | /* 0xD8 - 0xDF */ | 3966 | /* 0xD8 - 0xDF */ |
3964 | N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, | 3967 | N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, |
3965 | /* 0xE0 - 0xE7 */ | 3968 | /* 0xE0 - 0xE7 */ |
@@ -4221,6 +4224,16 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4221 | op->val = 0; | 4224 | op->val = 0; |
4222 | op->count = 1; | 4225 | op->count = 1; |
4223 | break; | 4226 | break; |
4227 | case OpXLat: | ||
4228 | op->type = OP_MEM; | ||
4229 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | ||
4230 | op->addr.mem.ea = | ||
4231 | register_address(ctxt, | ||
4232 | reg_read(ctxt, VCPU_REGS_RBX) + | ||
4233 | (reg_read(ctxt, VCPU_REGS_RAX) & 0xff)); | ||
4234 | op->addr.mem.seg = seg_override(ctxt); | ||
4235 | op->val = 0; | ||
4236 | break; | ||
4224 | case OpImmFAddr: | 4237 | case OpImmFAddr: |
4225 | op->type = OP_IMM; | 4238 | op->type = OP_IMM; |
4226 | op->addr.mem.ea = ctxt->_eip; | 4239 | op->addr.mem.ea = ctxt->_eip; |