diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-03-18 09:20:05 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:15:57 -0400 |
commit | 9c5372445c1ad4fcdb4128957ec89334223b8113 (patch) | |
tree | 7b3a8f46941cb1a46da5c9e1764ed078df0fe878 /arch/x86/kvm | |
parent | 93a152be5af3d651ff0ab5459f5e0f9662b22438 (diff) |
KVM: Provide x86_emulate_ctxt callback to get current cpl
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 15 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 6 |
2 files changed, 14 insertions, 7 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5e2fa61e8104..8bd05571672c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1257,7 +1257,7 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, | |||
1257 | int rc; | 1257 | int rc; |
1258 | unsigned long val, change_mask; | 1258 | unsigned long val, change_mask; |
1259 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 1259 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; |
1260 | int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu); | 1260 | int cpl = ops->cpl(ctxt->vcpu); |
1261 | 1261 | ||
1262 | rc = emulate_pop(ctxt, ops, &val, len); | 1262 | rc = emulate_pop(ctxt, ops, &val, len); |
1263 | if (rc != X86EMUL_CONTINUE) | 1263 | if (rc != X86EMUL_CONTINUE) |
@@ -1758,7 +1758,8 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1758 | return X86EMUL_CONTINUE; | 1758 | return X86EMUL_CONTINUE; |
1759 | } | 1759 | } |
1760 | 1760 | ||
1761 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | 1761 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt, |
1762 | struct x86_emulate_ops *ops) | ||
1762 | { | 1763 | { |
1763 | int iopl; | 1764 | int iopl; |
1764 | if (ctxt->mode == X86EMUL_MODE_REAL) | 1765 | if (ctxt->mode == X86EMUL_MODE_REAL) |
@@ -1766,7 +1767,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | |||
1766 | if (ctxt->mode == X86EMUL_MODE_VM86) | 1767 | if (ctxt->mode == X86EMUL_MODE_VM86) |
1767 | return true; | 1768 | return true; |
1768 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 1769 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; |
1769 | return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl; | 1770 | return ops->cpl(ctxt->vcpu) > iopl; |
1770 | } | 1771 | } |
1771 | 1772 | ||
1772 | static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, | 1773 | static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, |
@@ -1803,7 +1804,7 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, | |||
1803 | struct x86_emulate_ops *ops, | 1804 | struct x86_emulate_ops *ops, |
1804 | u16 port, u16 len) | 1805 | u16 port, u16 len) |
1805 | { | 1806 | { |
1806 | if (emulator_bad_iopl(ctxt)) | 1807 | if (emulator_bad_iopl(ctxt, ops)) |
1807 | if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) | 1808 | if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) |
1808 | return false; | 1809 | return false; |
1809 | return true; | 1810 | return true; |
@@ -1842,7 +1843,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1842 | } | 1843 | } |
1843 | 1844 | ||
1844 | /* Privileged instruction can be executed only in CPL=0 */ | 1845 | /* Privileged instruction can be executed only in CPL=0 */ |
1845 | if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { | 1846 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { |
1846 | kvm_inject_gp(ctxt->vcpu, 0); | 1847 | kvm_inject_gp(ctxt->vcpu, 0); |
1847 | goto done; | 1848 | goto done; |
1848 | } | 1849 | } |
@@ -2378,7 +2379,7 @@ special_insn: | |||
2378 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2379 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2379 | break; | 2380 | break; |
2380 | case 0xfa: /* cli */ | 2381 | case 0xfa: /* cli */ |
2381 | if (emulator_bad_iopl(ctxt)) | 2382 | if (emulator_bad_iopl(ctxt, ops)) |
2382 | kvm_inject_gp(ctxt->vcpu, 0); | 2383 | kvm_inject_gp(ctxt->vcpu, 0); |
2383 | else { | 2384 | else { |
2384 | ctxt->eflags &= ~X86_EFLAGS_IF; | 2385 | ctxt->eflags &= ~X86_EFLAGS_IF; |
@@ -2386,7 +2387,7 @@ special_insn: | |||
2386 | } | 2387 | } |
2387 | break; | 2388 | break; |
2388 | case 0xfb: /* sti */ | 2389 | case 0xfb: /* sti */ |
2389 | if (emulator_bad_iopl(ctxt)) | 2390 | if (emulator_bad_iopl(ctxt, ops)) |
2390 | kvm_inject_gp(ctxt->vcpu, 0); | 2391 | kvm_inject_gp(ctxt->vcpu, 0); |
2391 | else { | 2392 | else { |
2392 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); | 2393 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c382e9721099..9cb28a943c9a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3479,6 +3479,11 @@ static void emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) | |||
3479 | } | 3479 | } |
3480 | } | 3480 | } |
3481 | 3481 | ||
3482 | static int emulator_get_cpl(struct kvm_vcpu *vcpu) | ||
3483 | { | ||
3484 | return kvm_x86_ops->get_cpl(vcpu); | ||
3485 | } | ||
3486 | |||
3482 | static struct x86_emulate_ops emulate_ops = { | 3487 | static struct x86_emulate_ops emulate_ops = { |
3483 | .read_std = kvm_read_guest_virt_system, | 3488 | .read_std = kvm_read_guest_virt_system, |
3484 | .fetch = kvm_fetch_guest_virt, | 3489 | .fetch = kvm_fetch_guest_virt, |
@@ -3487,6 +3492,7 @@ static struct x86_emulate_ops emulate_ops = { | |||
3487 | .cmpxchg_emulated = emulator_cmpxchg_emulated, | 3492 | .cmpxchg_emulated = emulator_cmpxchg_emulated, |
3488 | .get_cr = emulator_get_cr, | 3493 | .get_cr = emulator_get_cr, |
3489 | .set_cr = emulator_set_cr, | 3494 | .set_cr = emulator_set_cr, |
3495 | .cpl = emulator_get_cpl, | ||
3490 | }; | 3496 | }; |
3491 | 3497 | ||
3492 | static void cache_all_regs(struct kvm_vcpu *vcpu) | 3498 | static void cache_all_regs(struct kvm_vcpu *vcpu) |