aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-05-09 05:32:50 -0400
committerGleb Natapov <gleb@redhat.com>2013-05-09 06:14:51 -0400
commit7fa57952d70f5737513d8319395e471d107e4e0d (patch)
tree14f9c0ab4a76f2f065a5f891e381809d20a740ba /arch/x86/kvm
parenta035d5c64d08a8ac12d81b596e7fa6d95a73c347 (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/x86/kvm')
-rw-r--r--arch/x86/kvm/emulate.c15
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;