| From 7fa57952d70f5737513d8319395e471d107e4e0d Mon Sep 17 00:00:00 2001 |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| Date: Thu, 9 May 2013 11:32:50 +0200 |
| Subject: KVM: emulator: emulate XLAT |
| |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| |
| commit 7fa57952d70f5737513d8319395e471d107e4e0d upstream. |
| |
| 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> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Gleb Natapov <gleb@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/emulate.c | 15 ++++++++++++++- |
| 1 file changed, 14 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/kvm/emulate.c |
| +++ b/arch/x86/kvm/emulate.c |
| @@ -60,6 +60,7 @@ |
| #define OpGS 25ull /* GS */ |
| #define OpMem8 26ull /* 8-bit zero extended memory operand */ |
| #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ |
| +#define OpXLat 28ull /* memory at BX/EBX/RBX + zero-extended AL */ |
| |
| #define OpBits 5 /* Width of operand field */ |
| #define OpMask ((1ull << OpBits) - 1) |
| @@ -99,6 +100,7 @@ |
| #define SrcImmUByte (OpImmUByte << SrcShift) |
| #define SrcImmU (OpImmU << SrcShift) |
| #define SrcSI (OpSI << SrcShift) |
| +#define SrcXLat (OpXLat << SrcShift) |
| #define SrcImmFAddr (OpImmFAddr << SrcShift) |
| #define SrcMemFAddr (OpMemFAddr << SrcShift) |
| #define SrcAcc (OpAcc << SrcShift) |
| @@ -3949,7 +3951,8 @@ static const struct opcode opcode_table[ |
| G(Src2One | ByteOp, group2), G(Src2One, group2), |
| G(Src2CL | ByteOp, group2), G(Src2CL, group2), |
| I(DstAcc | SrcImmUByte | No64, em_aam), |
| - I(DstAcc | SrcImmUByte | No64, em_aad), N, N, |
| + I(DstAcc | SrcImmUByte | No64, em_aad), N, |
| + I(DstAcc | SrcXLat | ByteOp, em_mov), |
| /* 0xD8 - 0xDF */ |
| N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, |
| /* 0xE0 - 0xE7 */ |
| @@ -4211,6 +4214,16 @@ static int decode_operand(struct x86_emu |
| op->val = 0; |
| op->count = 1; |
| break; |
| + case OpXLat: |
| + op->type = OP_MEM; |
| + op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
| + op->addr.mem.ea = |
| + register_address(ctxt, |
| + reg_read(ctxt, VCPU_REGS_RBX) + |
| + (reg_read(ctxt, VCPU_REGS_RAX) & 0xff)); |
| + op->addr.mem.seg = seg_override(ctxt); |
| + op->val = 0; |
| + break; |
| case OpImmFAddr: |
| op->type = OP_IMM; |
| op->addr.mem.ea = ctxt->_eip; |