@@ -126,7 +126,6 @@ static uint64_t get_address_mask(uint8_t limit)
126
126
static void get_cpu_capabilities (void )
127
127
{
128
128
uint32_t eax , unused ;
129
- uint32_t max_extended_function_idx ;
130
129
uint32_t family , model ;
131
130
132
131
cpuid (CPUID_FEATURES , & eax , & unused ,
@@ -149,28 +148,28 @@ static void get_cpu_capabilities(void)
149
148
& boot_cpu_data .cpuid_leaves [FEAT_7_0_EDX ]);
150
149
151
150
cpuid (CPUID_MAX_EXTENDED_FUNCTION ,
152
- & max_extended_function_idx ,
151
+ & boot_cpu_data . extended_cpuid_level ,
153
152
& unused , & unused , & unused );
154
- boot_cpu_data .cpuid_leaves [FEAT_8000_0000_EAX ] =
155
- max_extended_function_idx ;
156
153
157
- if (max_extended_function_idx < CPUID_EXTEND_ADDRESS_SIZE ) {
158
- panic ("CPU w/o CPUID.80000008H is not supported" );
154
+ if (boot_cpu_data .extended_cpuid_level >= CPUID_EXTEND_FUNCTION_1 )
155
+ cpuid (CPUID_EXTEND_FUNCTION_1 , & unused , & unused ,
156
+ & boot_cpu_data .cpuid_leaves [FEAT_8000_0001_ECX ],
157
+ & boot_cpu_data .cpuid_leaves [FEAT_8000_0001_EDX ]);
158
+
159
+ if (boot_cpu_data .extended_cpuid_level >= CPUID_EXTEND_ADDRESS_SIZE ) {
160
+ cpuid (CPUID_EXTEND_ADDRESS_SIZE , & eax ,
161
+ & boot_cpu_data .cpuid_leaves [FEAT_8000_0008_EBX ],
162
+ & unused , & unused );
163
+
164
+ /* EAX bits 07-00: #Physical Address Bits
165
+ * bits 15-08: #Linear Address Bits
166
+ */
167
+ boot_cpu_data .x86_virt_bits = (eax >> 8 ) & 0xff ;
168
+ boot_cpu_data .x86_phys_bits = eax & 0xff ;
169
+ boot_cpu_data .physical_address_mask =
170
+ get_address_mask (boot_cpu_data .x86_phys_bits );
159
171
}
160
172
161
- cpuid (CPUID_EXTEND_FUNCTION_1 , & unused , & unused ,
162
- & boot_cpu_data .cpuid_leaves [FEAT_8000_0001_ECX ],
163
- & boot_cpu_data .cpuid_leaves [FEAT_8000_0001_EDX ]);
164
-
165
- cpuid (CPUID_EXTEND_ADDRESS_SIZE ,
166
- & eax , & unused , & unused , & unused );
167
- boot_cpu_data .cpuid_leaves [FEAT_8000_0008_EAX ] = eax ;
168
- /* EAX bits 07-00: #Physical Address Bits
169
- * bits 15-08: #Linear Address Bits
170
- */
171
- boot_cpu_data .physical_address_mask =
172
- get_address_mask (eax & 0xff );
173
-
174
173
/* For speculation defence.
175
174
* The default way is to set IBRS at vmexit and then do IBPB at vcpu
176
175
* context switch(ibrs_type == IBRS_RAW).
@@ -195,6 +194,64 @@ static void get_cpu_capabilities(void)
195
194
#endif
196
195
}
197
196
197
+ /*
198
+ * basic hardware capability check
199
+ * we should supplement which feature/capability we must support
200
+ * here later.
201
+ */
202
+ static int hardware_detect_support (void )
203
+ {
204
+ int ret ;
205
+
206
+ /* Long Mode (x86-64, 64-bit support) */
207
+ if (!cpu_has_cap (X86_FEATURE_LM )) {
208
+ pr_fatal ("%s, LM not supported\n" , __func__ );
209
+ return - ENODEV ;
210
+ }
211
+ if ((boot_cpu_data .x86_phys_bits == 0 ) ||
212
+ (boot_cpu_data .x86_virt_bits == 0 )) {
213
+ pr_fatal ("%s, can't detect Linear/Physical Address size\n" ,
214
+ __func__ );
215
+ return - ENODEV ;
216
+ }
217
+
218
+ /* lapic TSC deadline timer */
219
+ if (!cpu_has_cap (X86_FEATURE_TSC_DEADLINE )) {
220
+ pr_fatal ("%s, TSC deadline not supported\n" , __func__ );
221
+ return - ENODEV ;
222
+ }
223
+
224
+ /* Execute Disable */
225
+ if (!cpu_has_cap (X86_FEATURE_NX )) {
226
+ pr_fatal ("%s, NX not supported\n" , __func__ );
227
+ return - ENODEV ;
228
+ }
229
+
230
+ /* Supervisor-Mode Execution Prevention */
231
+ if (!cpu_has_cap (X86_FEATURE_SMEP )) {
232
+ pr_fatal ("%s, SMEP not supported\n" , __func__ );
233
+ return - ENODEV ;
234
+ }
235
+
236
+ /* Supervisor-Mode Access Prevention */
237
+ if (!cpu_has_cap (X86_FEATURE_SMAP )) {
238
+ pr_fatal ("%s, SMAP not supported\n" , __func__ );
239
+ return - ENODEV ;
240
+ }
241
+
242
+ if (!cpu_has_cap (X86_FEATURE_VMX )) {
243
+ pr_fatal ("%s, vmx not supported\n" , __func__ );
244
+ return - ENODEV ;
245
+ }
246
+
247
+ ret = check_vmx_mmu_cap ();
248
+ if (ret )
249
+ return ret ;
250
+
251
+ printf ("hardware support HV\n" );
252
+ return 0 ;
253
+ }
254
+
198
255
static void alloc_phy_cpu_data (int pcpu_num )
199
256
{
200
257
phy_cpu_num = pcpu_num ;
@@ -458,6 +515,11 @@ void bsp_boot_init(void)
458
515
459
516
pr_dbg ("Core %d is up" , CPU_BOOT_ID );
460
517
518
+ if (hardware_detect_support () != 0 ) {
519
+ pr_fatal ("hardware not support!\n" );
520
+ return ;
521
+ }
522
+
461
523
/* Warn for security feature not ready */
462
524
if (!cpu_has_cap (X86_FEATURE_IBRS_IBPB ) &&
463
525
!cpu_has_cap (X86_FEATURE_STIBP )) {
@@ -492,7 +554,10 @@ void bsp_boot_init(void)
492
554
493
555
ASSERT (get_cpu_id () == CPU_BOOT_ID , "" );
494
556
495
- init_iommu ();
557
+ if (init_iommu () != 0 ) {
558
+ pr_fatal ("%s, init iommu failed\n" , __func__ );
559
+ return ;
560
+ }
496
561
497
562
console_setup_timer ();
498
563
0 commit comments