aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:05 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:15:57 -0400
commit9c5372445c1ad4fcdb4128957ec89334223b8113 (patch)
tree7b3a8f46941cb1a46da5c9e1764ed078df0fe878 /arch/x86/kvm
parent93a152be5af3d651ff0ab5459f5e0f9662b22438 (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.c15
-rw-r--r--arch/x86/kvm/x86.c6
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
1761static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) 1761static 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
1772static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, 1773static 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
3482static int emulator_get_cpl(struct kvm_vcpu *vcpu)
3483{
3484 return kvm_x86_ops->get_cpl(vcpu);
3485}
3486
3482static struct x86_emulate_ops emulate_ops = { 3487static 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
3492static void cache_all_regs(struct kvm_vcpu *vcpu) 3498static void cache_all_regs(struct kvm_vcpu *vcpu)