BXE: min->MIN, plus an spatch
[akaros.git] / kern / arch / x86 / virtext.h
1 /* CPU virtualization extensions handling
2  *
3  * This should carry the code for handling CPU virtualization extensions
4  * that needs to live in the kernel core.
5  *
6  * Author: Eduardo Habkost <ehabkost@redhat.com>
7  *
8  * Copyright (C) 2008, Red Hat Inc.
9  *
10  * Contains code from KVM, Copyright (C) 2006 Qumranet, Inc.
11  *
12  * This work is licensed under the terms of the GNU GPL, version 2.  See
13  * the COPYING file in the top-level directory.
14  */
15 #ifndef VIRTEX_H
16 #define VIRTEX_H
17
18 /*
19  * VMX functions:
20  */
21
22 static inline int cpu_has_vmx(void)
23 {
24         unsigned long ecx = cpuid_ecx(1);
25         return ecx & (1<<5); /* CPUID.1:ECX.VMX[bit 5] -> VT */
26 }
27
28
29 /** Disable VMX on the current CPU
30  *
31  * vmxoff causes a undefined-opcode exception if vmxon was not run
32  * on the CPU previously. Only call this function if you know VMX
33  * is enabled.
34  */
35 static inline void cpu_vmxoff(void)
36 {
37         asm volatile (ASM_VMX_VMXOFF : : : "cc");
38         lcr4(rcr4() & ~X86_CR4_VMXE);
39 }
40
41 static inline int cpu_vmx_enabled(void)
42 {
43         return rcr4() & X86_CR4_VMXE;
44 }
45
46 /** Disable VMX if it is enabled on the current CPU
47  *
48  * You shouldn't call this if cpu_has_vmx() returns 0.
49  */
50 static inline void __cpu_emergency_vmxoff(void)
51 {
52         if (cpu_vmx_enabled())
53                 cpu_vmxoff();
54 }
55
56 /** Disable VMX if it is supported and enabled on the current CPU
57  */
58 static inline void cpu_emergency_vmxoff(void)
59 {
60         if (cpu_has_vmx())
61                 __cpu_emergency_vmxoff();
62 }
63
64 #if 0
65
66
67 /*
68  * SVM functions:
69  */
70
71 /** Check if the CPU has SVM support
72  *
73  * You can use the 'msg' arg to get a message describing the problem,
74  * if the function returns zero. Simply pass NULL if you are not interested
75  * on the messages; gcc should take care of not generating code for
76  * the messages on this case.
77  */
78 static inline int cpu_has_svm(const char **msg)
79 {
80         uint32_t eax, ebx, ecx, edx;
81
82         if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
83                 if (msg)
84                         *msg = "not amd";
85                 return 0;
86         }
87
88         cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
89         if (eax < SVM_CPUID_FUNC) {
90                 if (msg)
91                         *msg = "can't execute cpuid_8000000a";
92                 return 0;
93         }
94
95         cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
96         if (!(ecx & (1 << SVM_CPUID_FEATURE_SHIFT))) {
97                 if (msg)
98                         *msg = "svm not available";
99                 return 0;
100         }
101         return 1;
102 }
103
104
105 /** Disable SVM on the current CPU
106  *
107  * You should call this only if cpu_has_svm() returned true.
108  */
109 static inline void cpu_svm_disable(void)
110 {
111         uint64_t efer;
112
113         wrmsrl(MSR_VM_HSAVE_PA, 0);
114         rdmsrl(MSR_EFER, efer);
115         wrmsrl(MSR_EFER, efer & ~EFER_SVME);
116 }
117
118 /** Makes sure SVM is disabled, if it is supported on the CPU
119  */
120 static inline void cpu_emergency_svm_disable(void)
121 {
122         if (cpu_has_svm(NULL))
123                 cpu_svm_disable();
124 }
125 #endif
126 #endif /* _ASM_X86_VIRTEX_H */