aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/emulate.c61
1 files changed, 21 insertions, 40 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b7da0e3e0cc0..898a55ba3e14 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -539,6 +539,24 @@ static int test_cc(unsigned int condition, unsigned int flags)
539 return (!!rc ^ (condition & 1)); 539 return (!!rc ^ (condition & 1));
540} 540}
541 541
542static void fetch_register_operand(struct operand *op)
543{
544 switch (op->bytes) {
545 case 1:
546 op->val = *(u8 *)op->addr.reg;
547 break;
548 case 2:
549 op->val = *(u16 *)op->addr.reg;
550 break;
551 case 4:
552 op->val = *(u32 *)op->addr.reg;
553 break;
554 case 8:
555 op->val = *(u64 *)op->addr.reg;
556 break;
557 }
558}
559
542static void decode_register_operand(struct operand *op, 560static void decode_register_operand(struct operand *op,
543 struct decode_cache *c, 561 struct decode_cache *c,
544 int inhibit_bytereg) 562 int inhibit_bytereg)
@@ -551,23 +569,12 @@ static void decode_register_operand(struct operand *op,
551 op->type = OP_REG; 569 op->type = OP_REG;
552 if ((c->d & ByteOp) && !inhibit_bytereg) { 570 if ((c->d & ByteOp) && !inhibit_bytereg) {
553 op->addr.reg = decode_register(reg, c->regs, highbyte_regs); 571 op->addr.reg = decode_register(reg, c->regs, highbyte_regs);
554 op->val = *(u8 *)op->addr.reg;
555 op->bytes = 1; 572 op->bytes = 1;
556 } else { 573 } else {
557 op->addr.reg = decode_register(reg, c->regs, 0); 574 op->addr.reg = decode_register(reg, c->regs, 0);
558 op->bytes = c->op_bytes; 575 op->bytes = c->op_bytes;
559 switch (op->bytes) {
560 case 2:
561 op->val = *(u16 *)op->addr.reg;
562 break;
563 case 4:
564 op->val = *(u32 *)op->addr.reg;
565 break;
566 case 8:
567 op->val = *(u64 *) op->addr.reg;
568 break;
569 }
570 } 576 }
577 fetch_register_operand(op);
571 op->orig_val = op->val; 578 op->orig_val = op->val;
572} 579}
573 580
@@ -2507,20 +2514,7 @@ done_prefixes:
2507 c->src.type = OP_REG; 2514 c->src.type = OP_REG;
2508 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 2515 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
2509 c->src.addr.reg = &c->regs[VCPU_REGS_RAX]; 2516 c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
2510 switch (c->src.bytes) { 2517 fetch_register_operand(&c->src);
2511 case 1:
2512 c->src.val = *(u8 *)c->src.addr.reg;
2513 break;
2514 case 2:
2515 c->src.val = *(u16 *)c->src.addr.reg;
2516 break;
2517 case 4:
2518 c->src.val = *(u32 *)c->src.addr.reg;
2519 break;
2520 case 8:
2521 c->src.val = *(u64 *)c->src.addr.reg;
2522 break;
2523 }
2524 break; 2518 break;
2525 case SrcOne: 2519 case SrcOne:
2526 c->src.bytes = 1; 2520 c->src.bytes = 1;
@@ -2606,20 +2600,7 @@ done_prefixes:
2606 c->dst.type = OP_REG; 2600 c->dst.type = OP_REG;
2607 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 2601 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
2608 c->dst.addr.reg = &c->regs[VCPU_REGS_RAX]; 2602 c->dst.addr.reg = &c->regs[VCPU_REGS_RAX];
2609 switch (c->dst.bytes) { 2603 fetch_register_operand(&c->dst);
2610 case 1:
2611 c->dst.val = *(u8 *)c->dst.addr.reg;
2612 break;
2613 case 2:
2614 c->dst.val = *(u16 *)c->dst.addr.reg;
2615 break;
2616 case 4:
2617 c->dst.val = *(u32 *)c->dst.addr.reg;
2618 break;
2619 case 8:
2620 c->dst.val = *(u64 *)c->dst.addr.reg;
2621 break;
2622 }
2623 c->dst.orig_val = c->dst.val; 2604 c->dst.orig_val = c->dst.val;
2624 break; 2605 break;
2625 case DstDI: 2606 case DstDI: