aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-05-13 06:23:38 -0400
committerAvi Kivity <avi@qumranet.com>2008-07-20 05:41:43 -0400
commit4ecac3fd6dc2629ad76a658a486f081c44aef10e (patch)
treea078acb4c626432ac8cf887b911d912f4a316d06 /arch/x86/kvm/svm.c
parent1b7fcd3263e5f12dba43d27b64e1578bec070c28 (diff)
KVM: Handle virtualization instruction #UD faults during reboot
KVM turns off hardware virtualization extensions during reboot, in order to disassociate the memory used by the virtualization extensions from the processor, and in order to have the system in a consistent state. Unfortunately virtual machines may still be running while this goes on, and once virtualization extensions are turned off, any virtulization instruction will #UD on execution. Fix by adding an exception handler to virtualization instructions; if we get an exception during reboot, we simply spin waiting for the reset to complete. If it's a true exception, BUG() so we can have our stack trace. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 992ab7115871..9390a31c06f4 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -27,6 +27,8 @@
27 27
28#include <asm/desc.h> 28#include <asm/desc.h>
29 29
30#define __ex(x) __kvm_handle_fault_on_reboot(x)
31
30MODULE_AUTHOR("Qumranet"); 32MODULE_AUTHOR("Qumranet");
31MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
32 34
@@ -129,17 +131,17 @@ static inline void push_irq(struct kvm_vcpu *vcpu, u8 irq)
129 131
130static inline void clgi(void) 132static inline void clgi(void)
131{ 133{
132 asm volatile (SVM_CLGI); 134 asm volatile (__ex(SVM_CLGI));
133} 135}
134 136
135static inline void stgi(void) 137static inline void stgi(void)
136{ 138{
137 asm volatile (SVM_STGI); 139 asm volatile (__ex(SVM_STGI));
138} 140}
139 141
140static inline void invlpga(unsigned long addr, u32 asid) 142static inline void invlpga(unsigned long addr, u32 asid)
141{ 143{
142 asm volatile (SVM_INVLPGA :: "a"(addr), "c"(asid)); 144 asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid));
143} 145}
144 146
145static inline unsigned long kvm_read_cr2(void) 147static inline unsigned long kvm_read_cr2(void)
@@ -1758,17 +1760,17 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1758 /* Enter guest mode */ 1760 /* Enter guest mode */
1759 "push %%rax \n\t" 1761 "push %%rax \n\t"
1760 "mov %c[vmcb](%[svm]), %%rax \n\t" 1762 "mov %c[vmcb](%[svm]), %%rax \n\t"
1761 SVM_VMLOAD "\n\t" 1763 __ex(SVM_VMLOAD) "\n\t"
1762 SVM_VMRUN "\n\t" 1764 __ex(SVM_VMRUN) "\n\t"
1763 SVM_VMSAVE "\n\t" 1765 __ex(SVM_VMSAVE) "\n\t"
1764 "pop %%rax \n\t" 1766 "pop %%rax \n\t"
1765#else 1767#else
1766 /* Enter guest mode */ 1768 /* Enter guest mode */
1767 "push %%eax \n\t" 1769 "push %%eax \n\t"
1768 "mov %c[vmcb](%[svm]), %%eax \n\t" 1770 "mov %c[vmcb](%[svm]), %%eax \n\t"
1769 SVM_VMLOAD "\n\t" 1771 __ex(SVM_VMLOAD) "\n\t"
1770 SVM_VMRUN "\n\t" 1772 __ex(SVM_VMRUN) "\n\t"
1771 SVM_VMSAVE "\n\t" 1773 __ex(SVM_VMSAVE) "\n\t"
1772 "pop %%eax \n\t" 1774 "pop %%eax \n\t"
1773#endif 1775#endif
1774 1776