aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-03-31 10:52:26 -0400
committerAvi Kivity <avi@redhat.com>2011-05-11 07:57:06 -0400
commit3ca3ac4dae5da5af375a9e80d2316ccfa7f0c6ab (patch)
tree74ac07a23cfd88fefe1fadbb94786bfeed29c3fb /arch/x86/kvm/emulate.c
parente3e9ed3d2c443fd90a04fb7ff231ad53ef087417 (diff)
KVM: x86 emulator: Add helpers for memory access using segmented addresses
Will help later adding proper segment checks. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 50bffb98ca82..8c38f6ca935b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -540,6 +540,15 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
540 return emulate_exception(ctxt, NM_VECTOR, 0, false); 540 return emulate_exception(ctxt, NM_VECTOR, 0, false);
541} 541}
542 542
543static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
544 struct segmented_address addr,
545 void *data,
546 unsigned size)
547{
548 return ctxt->ops->read_std(linear(ctxt, addr), data, size, ctxt->vcpu,
549 &ctxt->exception);
550}
551
543static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, 552static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
544 struct x86_emulate_ops *ops, 553 struct x86_emulate_ops *ops,
545 unsigned long eip, u8 *dest) 554 unsigned long eip, u8 *dest)
@@ -604,13 +613,11 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
604 if (op_bytes == 2) 613 if (op_bytes == 2)
605 op_bytes = 3; 614 op_bytes = 3;
606 *address = 0; 615 *address = 0;
607 rc = ops->read_std(linear(ctxt, addr), (unsigned long *)size, 2, 616 rc = segmented_read_std(ctxt, addr, size, 2);
608 ctxt->vcpu, &ctxt->exception);
609 if (rc != X86EMUL_CONTINUE) 617 if (rc != X86EMUL_CONTINUE)
610 return rc; 618 return rc;
611 addr.ea += 2; 619 addr.ea += 2;
612 rc = ops->read_std(linear(ctxt, addr), address, op_bytes, 620 rc = segmented_read_std(ctxt, addr, address, op_bytes);
613 ctxt->vcpu, &ctxt->exception);
614 return rc; 621 return rc;
615} 622}
616 623
@@ -950,6 +957,32 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
950 return X86EMUL_CONTINUE; 957 return X86EMUL_CONTINUE;
951} 958}
952 959
960static int segmented_read(struct x86_emulate_ctxt *ctxt,
961 struct segmented_address addr,
962 void *data,
963 unsigned size)
964{
965 return read_emulated(ctxt, ctxt->ops, linear(ctxt, addr), data, size);
966}
967
968static int segmented_write(struct x86_emulate_ctxt *ctxt,
969 struct segmented_address addr,
970 const void *data,
971 unsigned size)
972{
973 return ctxt->ops->write_emulated(linear(ctxt, addr), data, size,
974 &ctxt->exception, ctxt->vcpu);
975}
976
977static int segmented_cmpxchg(struct x86_emulate_ctxt *ctxt,
978 struct segmented_address addr,
979 const void *orig_data, const void *data,
980 unsigned size)
981{
982 return ctxt->ops->cmpxchg_emulated(linear(ctxt, addr), orig_data, data,
983 size, &ctxt->exception, ctxt->vcpu);
984}
985
953static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, 986static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
954 struct x86_emulate_ops *ops, 987 struct x86_emulate_ops *ops,
955 unsigned int size, unsigned short port, 988 unsigned int size, unsigned short port,
@@ -1197,20 +1230,16 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
1197 break; 1230 break;
1198 case OP_MEM: 1231 case OP_MEM:
1199 if (c->lock_prefix) 1232 if (c->lock_prefix)
1200 rc = ops->cmpxchg_emulated( 1233 rc = segmented_cmpxchg(ctxt,
1201 linear(ctxt, c->dst.addr.mem), 1234 c->dst.addr.mem,
1202 &c->dst.orig_val, 1235 &c->dst.orig_val,
1203 &c->dst.val, 1236 &c->dst.val,
1204 c->dst.bytes, 1237 c->dst.bytes);
1205 &ctxt->exception,
1206 ctxt->vcpu);
1207 else 1238 else
1208 rc = ops->write_emulated( 1239 rc = segmented_write(ctxt,
1209 linear(ctxt, c->dst.addr.mem), 1240 c->dst.addr.mem,
1210 &c->dst.val, 1241 &c->dst.val,
1211 c->dst.bytes, 1242 c->dst.bytes);
1212 &ctxt->exception,
1213 ctxt->vcpu);
1214 if (rc != X86EMUL_CONTINUE) 1243 if (rc != X86EMUL_CONTINUE)
1215 return rc; 1244 return rc;
1216 break; 1245 break;
@@ -1249,7 +1278,7 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
1249 1278
1250 addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]); 1279 addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
1251 addr.seg = VCPU_SREG_SS; 1280 addr.seg = VCPU_SREG_SS;
1252 rc = read_emulated(ctxt, ops, linear(ctxt, addr), dest, len); 1281 rc = segmented_read(ctxt, addr, dest, len);
1253 if (rc != X86EMUL_CONTINUE) 1282 if (rc != X86EMUL_CONTINUE)
1254 return rc; 1283 return rc;
1255 1284
@@ -3440,16 +3469,16 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
3440 } 3469 }
3441 3470
3442 if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) { 3471 if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) {
3443 rc = read_emulated(ctxt, ops, linear(ctxt, c->src.addr.mem), 3472 rc = segmented_read(ctxt, c->src.addr.mem,
3444 c->src.valptr, c->src.bytes); 3473 c->src.valptr, c->src.bytes);
3445 if (rc != X86EMUL_CONTINUE) 3474 if (rc != X86EMUL_CONTINUE)
3446 goto done; 3475 goto done;
3447 c->src.orig_val64 = c->src.val64; 3476 c->src.orig_val64 = c->src.val64;
3448 } 3477 }
3449 3478
3450 if (c->src2.type == OP_MEM) { 3479 if (c->src2.type == OP_MEM) {
3451 rc = read_emulated(ctxt, ops, linear(ctxt, c->src2.addr.mem), 3480 rc = segmented_read(ctxt, c->src2.addr.mem,
3452 &c->src2.val, c->src2.bytes); 3481 &c->src2.val, c->src2.bytes);
3453 if (rc != X86EMUL_CONTINUE) 3482 if (rc != X86EMUL_CONTINUE)
3454 goto done; 3483 goto done;
3455 } 3484 }
@@ -3460,7 +3489,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
3460 3489
3461 if ((c->dst.type == OP_MEM) && !(c->d & Mov)) { 3490 if ((c->dst.type == OP_MEM) && !(c->d & Mov)) {
3462 /* optimisation - avoid slow emulated read if Mov */ 3491 /* optimisation - avoid slow emulated read if Mov */
3463 rc = read_emulated(ctxt, ops, linear(ctxt, c->dst.addr.mem), 3492 rc = segmented_read(ctxt, c->dst.addr.mem,
3464 &c->dst.val, c->dst.bytes); 3493 &c->dst.val, c->dst.bytes);
3465 if (rc != X86EMUL_CONTINUE) 3494 if (rc != X86EMUL_CONTINUE)
3466 goto done; 3495 goto done;