aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/emulate.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index a1a7b27adf41..4dade6ac0827 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1599,7 +1599,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt)
1599 1599
1600 /* syscall is not available in real mode */ 1600 /* syscall is not available in real mode */
1601 if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) 1601 if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86)
1602 return -1; 1602 return X86EMUL_UNHANDLEABLE;
1603 1603
1604 setup_syscalls_segments(ctxt, &cs, &ss); 1604 setup_syscalls_segments(ctxt, &cs, &ss);
1605 1605
@@ -1636,7 +1636,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt)
1636 ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); 1636 ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
1637 } 1637 }
1638 1638
1639 return 0; 1639 return X86EMUL_CONTINUE;
1640} 1640}
1641 1641
1642static int 1642static int
@@ -1649,14 +1649,14 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
1649 /* inject #GP if in real mode */ 1649 /* inject #GP if in real mode */
1650 if (ctxt->mode == X86EMUL_MODE_REAL) { 1650 if (ctxt->mode == X86EMUL_MODE_REAL) {
1651 kvm_inject_gp(ctxt->vcpu, 0); 1651 kvm_inject_gp(ctxt->vcpu, 0);
1652 return -1; 1652 return X86EMUL_UNHANDLEABLE;
1653 } 1653 }
1654 1654
1655 /* XXX sysenter/sysexit have not been tested in 64bit mode. 1655 /* XXX sysenter/sysexit have not been tested in 64bit mode.
1656 * Therefore, we inject an #UD. 1656 * Therefore, we inject an #UD.
1657 */ 1657 */
1658 if (ctxt->mode == X86EMUL_MODE_PROT64) 1658 if (ctxt->mode == X86EMUL_MODE_PROT64)
1659 return -1; 1659 return X86EMUL_UNHANDLEABLE;
1660 1660
1661 setup_syscalls_segments(ctxt, &cs, &ss); 1661 setup_syscalls_segments(ctxt, &cs, &ss);
1662 1662
@@ -1665,13 +1665,13 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
1665 case X86EMUL_MODE_PROT32: 1665 case X86EMUL_MODE_PROT32:
1666 if ((msr_data & 0xfffc) == 0x0) { 1666 if ((msr_data & 0xfffc) == 0x0) {
1667 kvm_inject_gp(ctxt->vcpu, 0); 1667 kvm_inject_gp(ctxt->vcpu, 0);
1668 return -1; 1668 return X86EMUL_PROPAGATE_FAULT;
1669 } 1669 }
1670 break; 1670 break;
1671 case X86EMUL_MODE_PROT64: 1671 case X86EMUL_MODE_PROT64:
1672 if (msr_data == 0x0) { 1672 if (msr_data == 0x0) {
1673 kvm_inject_gp(ctxt->vcpu, 0); 1673 kvm_inject_gp(ctxt->vcpu, 0);
1674 return -1; 1674 return X86EMUL_PROPAGATE_FAULT;
1675 } 1675 }
1676 break; 1676 break;
1677 } 1677 }
@@ -1696,7 +1696,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
1696 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data); 1696 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
1697 c->regs[VCPU_REGS_RSP] = msr_data; 1697 c->regs[VCPU_REGS_RSP] = msr_data;
1698 1698
1699 return 0; 1699 return X86EMUL_CONTINUE;
1700} 1700}
1701 1701
1702static int 1702static int
@@ -1711,7 +1711,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1711 if (ctxt->mode == X86EMUL_MODE_REAL || 1711 if (ctxt->mode == X86EMUL_MODE_REAL ||
1712 ctxt->mode == X86EMUL_MODE_VM86) { 1712 ctxt->mode == X86EMUL_MODE_VM86) {
1713 kvm_inject_gp(ctxt->vcpu, 0); 1713 kvm_inject_gp(ctxt->vcpu, 0);
1714 return -1; 1714 return X86EMUL_UNHANDLEABLE;
1715 } 1715 }
1716 1716
1717 setup_syscalls_segments(ctxt, &cs, &ss); 1717 setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1729,7 +1729,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1729 cs.selector = (u16)(msr_data + 16); 1729 cs.selector = (u16)(msr_data + 16);
1730 if ((msr_data & 0xfffc) == 0x0) { 1730 if ((msr_data & 0xfffc) == 0x0) {
1731 kvm_inject_gp(ctxt->vcpu, 0); 1731 kvm_inject_gp(ctxt->vcpu, 0);
1732 return -1; 1732 return X86EMUL_PROPAGATE_FAULT;
1733 } 1733 }
1734 ss.selector = (u16)(msr_data + 24); 1734 ss.selector = (u16)(msr_data + 24);
1735 break; 1735 break;
@@ -1737,7 +1737,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1737 cs.selector = (u16)(msr_data + 32); 1737 cs.selector = (u16)(msr_data + 32);
1738 if (msr_data == 0x0) { 1738 if (msr_data == 0x0) {
1739 kvm_inject_gp(ctxt->vcpu, 0); 1739 kvm_inject_gp(ctxt->vcpu, 0);
1740 return -1; 1740 return X86EMUL_PROPAGATE_FAULT;
1741 } 1741 }
1742 ss.selector = cs.selector + 8; 1742 ss.selector = cs.selector + 8;
1743 cs.db = 0; 1743 cs.db = 0;
@@ -1753,7 +1753,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1753 c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; 1753 c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
1754 c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX]; 1754 c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
1755 1755
1756 return 0; 1756 return X86EMUL_CONTINUE;
1757} 1757}
1758 1758
1759static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) 1759static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
@@ -2476,8 +2476,9 @@ twobyte_insn:
2476 } 2476 }
2477 break; 2477 break;
2478 case 0x05: /* syscall */ 2478 case 0x05: /* syscall */
2479 if (emulate_syscall(ctxt) == -1) 2479 rc = emulate_syscall(ctxt);
2480 goto cannot_emulate; 2480 if (rc != X86EMUL_CONTINUE)
2481 goto done;
2481 else 2482 else
2482 goto writeback; 2483 goto writeback;
2483 break; 2484 break;
@@ -2548,14 +2549,16 @@ twobyte_insn:
2548 c->dst.type = OP_NONE; 2549 c->dst.type = OP_NONE;
2549 break; 2550 break;
2550 case 0x34: /* sysenter */ 2551 case 0x34: /* sysenter */
2551 if (emulate_sysenter(ctxt) == -1) 2552 rc = emulate_sysenter(ctxt);
2552 goto cannot_emulate; 2553 if (rc != X86EMUL_CONTINUE)
2554 goto done;
2553 else 2555 else
2554 goto writeback; 2556 goto writeback;
2555 break; 2557 break;
2556 case 0x35: /* sysexit */ 2558 case 0x35: /* sysexit */
2557 if (emulate_sysexit(ctxt) == -1) 2559 rc = emulate_sysexit(ctxt);
2558 goto cannot_emulate; 2560 if (rc != X86EMUL_CONTINUE)
2561 goto done;
2559 else 2562 else
2560 goto writeback; 2563 goto writeback;
2561 break; 2564 break;