aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_emulate.h3
-rw-r--r--arch/x86/kvm/emulate.c125
2 files changed, 57 insertions, 71 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index e425444658e8..1e4a72ce301a 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -203,9 +203,6 @@ struct decode_cache {
203 u8 modrm_rm; 203 u8 modrm_rm;
204 u8 modrm_seg; 204 u8 modrm_seg;
205 bool rip_relative; 205 bool rip_relative;
206 unsigned long modrm_ea;
207 void *modrm_ptr;
208 unsigned long modrm_val;
209 struct fetch_cache fetch; 206 struct fetch_cache fetch;
210 struct read_cache io_read; 207 struct read_cache io_read;
211 struct read_cache mem_read; 208 struct read_cache mem_read;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index eda69411d050..955d48074648 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -581,12 +581,14 @@ static void decode_register_operand(struct operand *op,
581} 581}
582 582
583static int decode_modrm(struct x86_emulate_ctxt *ctxt, 583static int decode_modrm(struct x86_emulate_ctxt *ctxt,
584 struct x86_emulate_ops *ops) 584 struct x86_emulate_ops *ops,
585 struct operand *op)
585{ 586{
586 struct decode_cache *c = &ctxt->decode; 587 struct decode_cache *c = &ctxt->decode;
587 u8 sib; 588 u8 sib;
588 int index_reg = 0, base_reg = 0, scale; 589 int index_reg = 0, base_reg = 0, scale;
589 int rc = X86EMUL_CONTINUE; 590 int rc = X86EMUL_CONTINUE;
591 ulong modrm_ea = 0;
590 592
591 if (c->rex_prefix) { 593 if (c->rex_prefix) {
592 c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */ 594 c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */
@@ -598,16 +600,19 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
598 c->modrm_mod |= (c->modrm & 0xc0) >> 6; 600 c->modrm_mod |= (c->modrm & 0xc0) >> 6;
599 c->modrm_reg |= (c->modrm & 0x38) >> 3; 601 c->modrm_reg |= (c->modrm & 0x38) >> 3;
600 c->modrm_rm |= (c->modrm & 0x07); 602 c->modrm_rm |= (c->modrm & 0x07);
601 c->modrm_ea = 0;
602 c->modrm_seg = VCPU_SREG_DS; 603 c->modrm_seg = VCPU_SREG_DS;
603 604
604 if (c->modrm_mod == 3) { 605 if (c->modrm_mod == 3) {
605 c->modrm_ptr = decode_register(c->modrm_rm, 606 op->type = OP_REG;
607 op->bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
608 op->addr.reg = decode_register(c->modrm_rm,
606 c->regs, c->d & ByteOp); 609 c->regs, c->d & ByteOp);
607 c->modrm_val = *(unsigned long *)c->modrm_ptr; 610 fetch_register_operand(op);
608 return rc; 611 return rc;
609 } 612 }
610 613
614 op->type = OP_MEM;
615
611 if (c->ad_bytes == 2) { 616 if (c->ad_bytes == 2) {
612 unsigned bx = c->regs[VCPU_REGS_RBX]; 617 unsigned bx = c->regs[VCPU_REGS_RBX];
613 unsigned bp = c->regs[VCPU_REGS_RBP]; 618 unsigned bp = c->regs[VCPU_REGS_RBP];
@@ -618,46 +623,46 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
618 switch (c->modrm_mod) { 623 switch (c->modrm_mod) {
619 case 0: 624 case 0:
620 if (c->modrm_rm == 6) 625 if (c->modrm_rm == 6)
621 c->modrm_ea += insn_fetch(u16, 2, c->eip); 626 modrm_ea += insn_fetch(u16, 2, c->eip);
622 break; 627 break;
623 case 1: 628 case 1:
624 c->modrm_ea += insn_fetch(s8, 1, c->eip); 629 modrm_ea += insn_fetch(s8, 1, c->eip);
625 break; 630 break;
626 case 2: 631 case 2:
627 c->modrm_ea += insn_fetch(u16, 2, c->eip); 632 modrm_ea += insn_fetch(u16, 2, c->eip);
628 break; 633 break;
629 } 634 }
630 switch (c->modrm_rm) { 635 switch (c->modrm_rm) {
631 case 0: 636 case 0:
632 c->modrm_ea += bx + si; 637 modrm_ea += bx + si;
633 break; 638 break;
634 case 1: 639 case 1:
635 c->modrm_ea += bx + di; 640 modrm_ea += bx + di;
636 break; 641 break;
637 case 2: 642 case 2:
638 c->modrm_ea += bp + si; 643 modrm_ea += bp + si;
639 break; 644 break;
640 case 3: 645 case 3:
641 c->modrm_ea += bp + di; 646 modrm_ea += bp + di;
642 break; 647 break;
643 case 4: 648 case 4:
644 c->modrm_ea += si; 649 modrm_ea += si;
645 break; 650 break;
646 case 5: 651 case 5:
647 c->modrm_ea += di; 652 modrm_ea += di;
648 break; 653 break;
649 case 6: 654 case 6:
650 if (c->modrm_mod != 0) 655 if (c->modrm_mod != 0)
651 c->modrm_ea += bp; 656 modrm_ea += bp;
652 break; 657 break;
653 case 7: 658 case 7:
654 c->modrm_ea += bx; 659 modrm_ea += bx;
655 break; 660 break;
656 } 661 }
657 if (c->modrm_rm == 2 || c->modrm_rm == 3 || 662 if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
658 (c->modrm_rm == 6 && c->modrm_mod != 0)) 663 (c->modrm_rm == 6 && c->modrm_mod != 0))
659 c->modrm_seg = VCPU_SREG_SS; 664 c->modrm_seg = VCPU_SREG_SS;
660 c->modrm_ea = (u16)c->modrm_ea; 665 modrm_ea = (u16)modrm_ea;
661 } else { 666 } else {
662 /* 32/64-bit ModR/M decode. */ 667 /* 32/64-bit ModR/M decode. */
663 if ((c->modrm_rm & 7) == 4) { 668 if ((c->modrm_rm & 7) == 4) {
@@ -667,48 +672,51 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
667 scale = sib >> 6; 672 scale = sib >> 6;
668 673
669 if ((base_reg & 7) == 5 && c->modrm_mod == 0) 674 if ((base_reg & 7) == 5 && c->modrm_mod == 0)
670 c->modrm_ea += insn_fetch(s32, 4, c->eip); 675 modrm_ea += insn_fetch(s32, 4, c->eip);
671 else 676 else
672 c->modrm_ea += c->regs[base_reg]; 677 modrm_ea += c->regs[base_reg];
673 if (index_reg != 4) 678 if (index_reg != 4)
674 c->modrm_ea += c->regs[index_reg] << scale; 679 modrm_ea += c->regs[index_reg] << scale;
675 } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) { 680 } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) {
676 if (ctxt->mode == X86EMUL_MODE_PROT64) 681 if (ctxt->mode == X86EMUL_MODE_PROT64)
677 c->rip_relative = 1; 682 c->rip_relative = 1;
678 } else 683 } else
679 c->modrm_ea += c->regs[c->modrm_rm]; 684 modrm_ea += c->regs[c->modrm_rm];
680 switch (c->modrm_mod) { 685 switch (c->modrm_mod) {
681 case 0: 686 case 0:
682 if (c->modrm_rm == 5) 687 if (c->modrm_rm == 5)
683 c->modrm_ea += insn_fetch(s32, 4, c->eip); 688 modrm_ea += insn_fetch(s32, 4, c->eip);
684 break; 689 break;
685 case 1: 690 case 1:
686 c->modrm_ea += insn_fetch(s8, 1, c->eip); 691 modrm_ea += insn_fetch(s8, 1, c->eip);
687 break; 692 break;
688 case 2: 693 case 2:
689 c->modrm_ea += insn_fetch(s32, 4, c->eip); 694 modrm_ea += insn_fetch(s32, 4, c->eip);
690 break; 695 break;
691 } 696 }
692 } 697 }
698 op->addr.mem = modrm_ea;
693done: 699done:
694 return rc; 700 return rc;
695} 701}
696 702
697static int decode_abs(struct x86_emulate_ctxt *ctxt, 703static int decode_abs(struct x86_emulate_ctxt *ctxt,
698 struct x86_emulate_ops *ops) 704 struct x86_emulate_ops *ops,
705 struct operand *op)
699{ 706{
700 struct decode_cache *c = &ctxt->decode; 707 struct decode_cache *c = &ctxt->decode;
701 int rc = X86EMUL_CONTINUE; 708 int rc = X86EMUL_CONTINUE;
702 709
710 op->type = OP_MEM;
703 switch (c->ad_bytes) { 711 switch (c->ad_bytes) {
704 case 2: 712 case 2:
705 c->modrm_ea = insn_fetch(u16, 2, c->eip); 713 op->addr.mem = insn_fetch(u16, 2, c->eip);
706 break; 714 break;
707 case 4: 715 case 4:
708 c->modrm_ea = insn_fetch(u32, 4, c->eip); 716 op->addr.mem = insn_fetch(u32, 4, c->eip);
709 break; 717 break;
710 case 8: 718 case 8:
711 c->modrm_ea = insn_fetch(u64, 8, c->eip); 719 op->addr.mem = insn_fetch(u64, 8, c->eip);
712 break; 720 break;
713 } 721 }
714done: 722done:
@@ -2280,6 +2288,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
2280 int mode = ctxt->mode; 2288 int mode = ctxt->mode;
2281 int def_op_bytes, def_ad_bytes, dual, goffset; 2289 int def_op_bytes, def_ad_bytes, dual, goffset;
2282 struct opcode opcode, *g_mod012, *g_mod3; 2290 struct opcode opcode, *g_mod012, *g_mod3;
2291 struct operand memop = { .type = OP_NONE };
2283 2292
2284 /* we cannot decode insn before we complete previous rep insn */ 2293 /* we cannot decode insn before we complete previous rep insn */
2285 WARN_ON(ctxt->restart); 2294 WARN_ON(ctxt->restart);
@@ -2418,25 +2427,25 @@ done_prefixes:
2418 2427
2419 /* ModRM and SIB bytes. */ 2428 /* ModRM and SIB bytes. */
2420 if (c->d & ModRM) { 2429 if (c->d & ModRM) {
2421 rc = decode_modrm(ctxt, ops); 2430 rc = decode_modrm(ctxt, ops, &memop);
2422 if (!c->has_seg_override) 2431 if (!c->has_seg_override)
2423 set_seg_override(c, c->modrm_seg); 2432 set_seg_override(c, c->modrm_seg);
2424 } else if (c->d & MemAbs) 2433 } else if (c->d & MemAbs)
2425 rc = decode_abs(ctxt, ops); 2434 rc = decode_abs(ctxt, ops, &memop);
2426 if (rc != X86EMUL_CONTINUE) 2435 if (rc != X86EMUL_CONTINUE)
2427 goto done; 2436 goto done;
2428 2437
2429 if (!c->has_seg_override) 2438 if (!c->has_seg_override)
2430 set_seg_override(c, VCPU_SREG_DS); 2439 set_seg_override(c, VCPU_SREG_DS);
2431 2440
2432 if (!(!c->twobyte && c->b == 0x8d)) 2441 if (memop.type == OP_MEM && !(!c->twobyte && c->b == 0x8d))
2433 c->modrm_ea += seg_override_base(ctxt, ops, c); 2442 memop.addr.mem += seg_override_base(ctxt, ops, c);
2434 2443
2435 if (c->ad_bytes != 8) 2444 if (memop.type == OP_MEM && c->ad_bytes != 8)
2436 c->modrm_ea = (u32)c->modrm_ea; 2445 memop.addr.mem = (u32)memop.addr.mem;
2437 2446
2438 if (c->rip_relative) 2447 if (memop.type == OP_MEM && c->rip_relative)
2439 c->modrm_ea += c->eip; 2448 memop.addr.mem += c->eip;
2440 2449
2441 /* 2450 /*
2442 * Decode and fetch the source operand: register, memory 2451 * Decode and fetch the source operand: register, memory
@@ -2449,31 +2458,16 @@ done_prefixes:
2449 decode_register_operand(&c->src, c, 0); 2458 decode_register_operand(&c->src, c, 0);
2450 break; 2459 break;
2451 case SrcMem16: 2460 case SrcMem16:
2452 c->src.bytes = 2; 2461 memop.bytes = 2;
2453 goto srcmem_common; 2462 goto srcmem_common;
2454 case SrcMem32: 2463 case SrcMem32:
2455 c->src.bytes = 4; 2464 memop.bytes = 4;
2456 goto srcmem_common; 2465 goto srcmem_common;
2457 case SrcMem: 2466 case SrcMem:
2458 c->src.bytes = (c->d & ByteOp) ? 1 : 2467 memop.bytes = (c->d & ByteOp) ? 1 :
2459 c->op_bytes; 2468 c->op_bytes;
2460 /* Don't fetch the address for invlpg: it could be unmapped. */
2461 if (c->d & NoAccess)
2462 break;
2463 srcmem_common: 2469 srcmem_common:
2464 /* 2470 c->src = memop;
2465 * For instructions with a ModR/M byte, switch to register
2466 * access if Mod = 3.
2467 */
2468 if ((c->d & ModRM) && c->modrm_mod == 3) {
2469 c->src.type = OP_REG;
2470 c->src.val = c->modrm_val;
2471 c->src.addr.reg = c->modrm_ptr;
2472 break;
2473 }
2474 c->src.type = OP_MEM;
2475 c->src.addr.mem = c->modrm_ea;
2476 c->src.val = 0;
2477 break; 2471 break;
2478 case SrcImm: 2472 case SrcImm:
2479 case SrcImmU: 2473 case SrcImmU:
@@ -2543,9 +2537,8 @@ done_prefixes:
2543 insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip); 2537 insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
2544 break; 2538 break;
2545 case SrcMemFAddr: 2539 case SrcMemFAddr:
2546 c->src.type = OP_MEM; 2540 memop.bytes = c->op_bytes + 2;
2547 c->src.addr.mem = c->modrm_ea; 2541 goto srcmem_common;
2548 c->src.bytes = c->op_bytes + 2;
2549 break; 2542 break;
2550 } 2543 }
2551 2544
@@ -2583,26 +2576,18 @@ done_prefixes:
2583 break; 2576 break;
2584 case DstMem: 2577 case DstMem:
2585 case DstMem64: 2578 case DstMem64:
2586 if ((c->d & ModRM) && c->modrm_mod == 3) { 2579 c->dst = memop;
2587 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
2588 c->dst.type = OP_REG;
2589 c->dst.val = c->dst.orig_val = c->modrm_val;
2590 c->dst.addr.reg = c->modrm_ptr;
2591 break;
2592 }
2593 c->dst.type = OP_MEM;
2594 c->dst.addr.mem = c->modrm_ea;
2595 if ((c->d & DstMask) == DstMem64) 2580 if ((c->d & DstMask) == DstMem64)
2596 c->dst.bytes = 8; 2581 c->dst.bytes = 8;
2597 else 2582 else
2598 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 2583 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
2599 c->dst.val = 0; 2584 if (c->dst.type == OP_MEM && (c->d & BitOp)) {
2600 if (c->d & BitOp) {
2601 unsigned long mask = ~(c->dst.bytes * 8 - 1); 2585 unsigned long mask = ~(c->dst.bytes * 8 - 1);
2602 2586
2603 c->dst.addr.mem = c->dst.addr.mem + 2587 c->dst.addr.mem = c->dst.addr.mem +
2604 (c->src.val & mask) / 8; 2588 (c->src.val & mask) / 8;
2605 } 2589 }
2590 c->dst.orig_val = c->dst.val;
2606 break; 2591 break;
2607 case DstAcc: 2592 case DstAcc:
2608 c->dst.type = OP_REG; 2593 c->dst.type = OP_REG;
@@ -2682,11 +2667,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
2682 } 2667 }
2683 2668
2684 if (c->src.type == OP_MEM) { 2669 if (c->src.type == OP_MEM) {
2670 if (c->d & NoAccess)
2671 goto no_fetch;
2685 rc = read_emulated(ctxt, ops, c->src.addr.mem, 2672 rc = read_emulated(ctxt, ops, c->src.addr.mem,
2686 c->src.valptr, c->src.bytes); 2673 c->src.valptr, c->src.bytes);
2687 if (rc != X86EMUL_CONTINUE) 2674 if (rc != X86EMUL_CONTINUE)
2688 goto done; 2675 goto done;
2689 c->src.orig_val64 = c->src.val64; 2676 c->src.orig_val64 = c->src.val64;
2677 no_fetch:
2678 ;
2690 } 2679 }
2691 2680
2692 if (c->src2.type == OP_MEM) { 2681 if (c->src2.type == OP_MEM) {