diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/emulate.c | 37 |
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 | ||
1642 | static int | 1642 | static 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 | ||
1702 | static int | 1702 | static 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 | ||
1759 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | 1759 | static 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; |