|
@@ -150,6 +150,8 @@ static int hv_check_hv ( struct hv_hypervisor *hv ) {
|
150
|
150
|
uint32_t discard_ebx;
|
151
|
151
|
uint32_t discard_ecx;
|
152
|
152
|
uint32_t discard_edx;
|
|
153
|
+ uint32_t available;
|
|
154
|
+ uint32_t permissions;
|
153
|
155
|
|
154
|
156
|
/* Check for presence of a hypervisor (not necessarily Hyper-V) */
|
155
|
157
|
x86_features ( &features );
|
|
@@ -167,6 +169,30 @@ static int hv_check_hv ( struct hv_hypervisor *hv ) {
|
167
|
169
|
return -ENODEV;
|
168
|
170
|
}
|
169
|
171
|
|
|
172
|
+ /* Check that required features and privileges are available */
|
|
173
|
+ cpuid ( HV_CPUID_FEATURES, &available, &permissions, &discard_ecx,
|
|
174
|
+ &discard_edx );
|
|
175
|
+ if ( ! ( available & HV_FEATURES_AVAIL_HYPERCALL_MSR ) ) {
|
|
176
|
+ DBGC ( hv, "HV %p has no hypercall MSRs (features %08x:%08x)\n",
|
|
177
|
+ hv, available, permissions );
|
|
178
|
+ return -ENODEV;
|
|
179
|
+ }
|
|
180
|
+ if ( ! ( available & HV_FEATURES_AVAIL_SYNIC_MSR ) ) {
|
|
181
|
+ DBGC ( hv, "HV %p has no SynIC MSRs (features %08x:%08x)\n",
|
|
182
|
+ hv, available, permissions );
|
|
183
|
+ return -ENODEV;
|
|
184
|
+ }
|
|
185
|
+ if ( ! ( permissions & HV_FEATURES_PERM_POST_MESSAGES ) ) {
|
|
186
|
+ DBGC ( hv, "HV %p cannot post messages (features %08x:%08x)\n",
|
|
187
|
+ hv, available, permissions );
|
|
188
|
+ return -EACCES;
|
|
189
|
+ }
|
|
190
|
+ if ( ! ( permissions & HV_FEATURES_PERM_SIGNAL_EVENTS ) ) {
|
|
191
|
+ DBGC ( hv, "HV %p cannot signal events (features %08x:%08x)",
|
|
192
|
+ hv, available, permissions );
|
|
193
|
+ return -EACCES;
|
|
194
|
+ }
|
|
195
|
+
|
170
|
196
|
return 0;
|
171
|
197
|
}
|
172
|
198
|
|