aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-01-21 08:31:48 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:36:04 -0500
commit3eeb3288bcbf64da90afc26389b8844df7c34912 (patch)
tree1b7bc55641015605da0b415a928ecf39aac64a2e /arch/x86/kvm
parent6b52d18605f580bdffaffd48c8da228c3e848deb (diff)
KVM: Add a helper for checking if the guest is in protected mode
Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/emulate.c9
-rw-r--r--arch/x86/kvm/vmx.c4
-rw-r--r--arch/x86/kvm/x86.c7
-rw-r--r--arch/x86/kvm/x86.h6
4 files changed, 15 insertions, 11 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 48c7f9f8a08f..6a429eefc533 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <asm/kvm_emulate.h> 33#include <asm/kvm_emulate.h>
34 34
35#include "x86.h"
35#include "mmu.h" /* for is_long_mode() */ 36#include "mmu.h" /* for is_long_mode() */
36 37
37/* 38/*
@@ -1515,7 +1516,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt)
1515 1516
1516 /* syscall is not available in real mode */ 1517 /* syscall is not available in real mode */
1517 if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL 1518 if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
1518 || !kvm_read_cr0_bits(ctxt->vcpu, X86_CR0_PE)) 1519 || !is_protmode(ctxt->vcpu))
1519 return -1; 1520 return -1;
1520 1521
1521 setup_syscalls_segments(ctxt, &cs, &ss); 1522 setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1568,8 +1569,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
1568 return -1; 1569 return -1;
1569 1570
1570 /* inject #GP if in real mode or paging is disabled */ 1571 /* inject #GP if in real mode or paging is disabled */
1571 if (ctxt->mode == X86EMUL_MODE_REAL || 1572 if (ctxt->mode == X86EMUL_MODE_REAL || !is_protmode(ctxt->vcpu)) {
1572 !kvm_read_cr0_bits(ctxt->vcpu, X86_CR0_PE)) {
1573 kvm_inject_gp(ctxt->vcpu, 0); 1573 kvm_inject_gp(ctxt->vcpu, 0);
1574 return -1; 1574 return -1;
1575 } 1575 }
@@ -1634,8 +1634,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1634 return -1; 1634 return -1;
1635 1635
1636 /* inject #GP if in real mode or paging is disabled */ 1636 /* inject #GP if in real mode or paging is disabled */
1637 if (ctxt->mode == X86EMUL_MODE_REAL 1637 if (ctxt->mode == X86EMUL_MODE_REAL || !is_protmode(ctxt->vcpu)) {
1638 || !kvm_read_cr0_bits(ctxt->vcpu, X86_CR0_PE)) {
1639 kvm_inject_gp(ctxt->vcpu, 0); 1638 kvm_inject_gp(ctxt->vcpu, 0);
1640 return -1; 1639 return -1;
1641 } 1640 }
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index fad871cbed19..2e894954069f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1845,7 +1845,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
1845 1845
1846static int vmx_get_cpl(struct kvm_vcpu *vcpu) 1846static int vmx_get_cpl(struct kvm_vcpu *vcpu)
1847{ 1847{
1848 if (!kvm_read_cr0_bits(vcpu, X86_CR0_PE)) /* if real mode */ 1848 if (!is_protmode(vcpu))
1849 return 0; 1849 return 0;
1850 1850
1851 if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */ 1851 if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
@@ -2100,7 +2100,7 @@ static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu)
2100static bool guest_state_valid(struct kvm_vcpu *vcpu) 2100static bool guest_state_valid(struct kvm_vcpu *vcpu)
2101{ 2101{
2102 /* real mode guest state checks */ 2102 /* real mode guest state checks */
2103 if (!kvm_read_cr0_bits(vcpu, X86_CR0_PE)) { 2103 if (!is_protmode(vcpu)) {
2104 if (!rmode_segment_valid(vcpu, VCPU_SREG_CS)) 2104 if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
2105 return false; 2105 return false;
2106 if (!rmode_segment_valid(vcpu, VCPU_SREG_SS)) 2106 if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4db0c8a9082e..a4a7d1892f72 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3786,8 +3786,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
3786 * hypercall generates UD from non zero cpl and real mode 3786 * hypercall generates UD from non zero cpl and real mode
3787 * per HYPER-V spec 3787 * per HYPER-V spec
3788 */ 3788 */
3789 if (kvm_x86_ops->get_cpl(vcpu) != 0 || 3789 if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
3790 !kvm_read_cr0_bits(vcpu, X86_CR0_PE)) {
3791 kvm_queue_exception(vcpu, UD_VECTOR); 3790 kvm_queue_exception(vcpu, UD_VECTOR);
3792 return 0; 3791 return 0;
3793 } 3792 }
@@ -4751,7 +4750,7 @@ int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
4751{ 4750{
4752 struct kvm_segment kvm_seg; 4751 struct kvm_segment kvm_seg;
4753 4752
4754 if (is_vm86_segment(vcpu, seg) || !(kvm_read_cr0_bits(vcpu, X86_CR0_PE))) 4753 if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu))
4755 return kvm_load_realmode_segment(vcpu, selector, seg); 4754 return kvm_load_realmode_segment(vcpu, selector, seg);
4756 if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) 4755 if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
4757 return 1; 4756 return 1;
@@ -5103,7 +5102,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
5103 /* Older userspace won't unhalt the vcpu on reset. */ 5102 /* Older userspace won't unhalt the vcpu on reset. */
5104 if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 && 5103 if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
5105 sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 && 5104 sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
5106 !(kvm_read_cr0_bits(vcpu, X86_CR0_PE))) 5105 !is_protmode(vcpu))
5107 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 5106 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
5108 5107
5109 vcpu_put(vcpu); 5108 vcpu_put(vcpu);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 5eadea585d2a..f783d8fe0d1d 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -2,6 +2,7 @@
2#define ARCH_X86_KVM_X86_H 2#define ARCH_X86_KVM_X86_H
3 3
4#include <linux/kvm_host.h> 4#include <linux/kvm_host.h>
5#include "kvm_cache_regs.h"
5 6
6static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) 7static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
7{ 8{
@@ -35,4 +36,9 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
35struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, 36struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
36 u32 function, u32 index); 37 u32 function, u32 index);
37 38
39static inline bool is_protmode(struct kvm_vcpu *vcpu)
40{
41 return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
42}
43
38#endif 44#endif