diff options
author | Avi Kivity <avi@redhat.com> | 2010-01-21 08:31:48 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:04 -0500 |
commit | 3eeb3288bcbf64da90afc26389b8844df7c34912 (patch) | |
tree | 1b7bc55641015605da0b415a928ecf39aac64a2e /arch/x86/kvm | |
parent | 6b52d18605f580bdffaffd48c8da228c3e848deb (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.c | 9 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 7 | ||||
-rw-r--r-- | arch/x86/kvm/x86.h | 6 |
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 | ||
1846 | static int vmx_get_cpl(struct kvm_vcpu *vcpu) | 1846 | static 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) | |||
2100 | static bool guest_state_valid(struct kvm_vcpu *vcpu) | 2100 | static 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 | ||
6 | static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) | 7 | static 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) | |||
35 | struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, | 36 | struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, |
36 | u32 function, u32 index); | 37 | u32 function, u32 index); |
37 | 38 | ||
39 | static 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 |