@@ -171,6 +171,30 @@ static bool check_mmu_1gb_support(struct map_params *map_params)
171
171
return status ;
172
172
}
173
173
174
+ static inline uint32_t check_page_table_present (int page_table_type ,
175
+ uint64_t table_entry )
176
+ {
177
+ if (page_table_type == PTT_EPT ) {
178
+ table_entry &= (IA32E_EPT_R_BIT | IA32E_EPT_W_BIT |
179
+ IA32E_EPT_X_BIT );
180
+ /* RWX misconfiguration for:
181
+ * - write-only
182
+ * - write-execute
183
+ * - execute-only (if cap not support)
184
+ * no check for reserved bits
185
+ */
186
+ if ((table_entry == IA32E_EPT_W_BIT ) ||
187
+ (table_entry == (IA32E_EPT_W_BIT | IA32E_EPT_X_BIT )) ||
188
+ ((table_entry == IA32E_EPT_X_BIT ) &&
189
+ !check_ept_x_only_support ()))
190
+ return PT_MISCFG_PRESENT ;
191
+ } else {
192
+ table_entry &= (IA32E_COMM_P_BIT );
193
+ }
194
+
195
+ return (table_entry ) ? PT_PRESENT : PT_NOT_PRESENT ;
196
+ }
197
+
174
198
static uint32_t map_mem_region (void * vaddr , void * paddr ,
175
199
void * table_base , uint64_t attr , uint32_t table_level ,
176
200
int table_type , enum mem_map_request_type request_type )
@@ -345,19 +369,6 @@ static uint32_t fetch_page_table_offset(void *addr, uint32_t table_level)
345
369
return table_offset ;
346
370
}
347
371
348
- static inline uint32_t check_page_table_present (struct map_params * map_params ,
349
- uint64_t table_entry )
350
- {
351
- if (map_params -> page_table_type == PTT_EPT ) {
352
- table_entry &= (IA32E_EPT_R_BIT | IA32E_EPT_W_BIT |
353
- IA32E_EPT_X_BIT );
354
- } else {
355
- table_entry &= (IA32E_COMM_P_BIT );
356
- }
357
-
358
- return (table_entry ) ? PT_PRESENT : PT_NOT_PRESENT ;
359
- }
360
-
361
372
static int get_table_entry (void * addr , void * table_base ,
362
373
uint32_t table_level , uint64_t * table_entry )
363
374
{
@@ -381,7 +392,7 @@ static void *walk_paging_struct(void *addr, void *table_base,
381
392
{
382
393
uint32_t table_offset ;
383
394
uint64_t table_entry ;
384
- uint64_t table_present ;
395
+ uint64_t entry_present ;
385
396
/* if table_level == IA32E_PT Just return the same address
386
397
* can't walk down any further
387
398
*/
@@ -405,15 +416,15 @@ static void *walk_paging_struct(void *addr, void *table_base,
405
416
/* Set table present bits to any of the
406
417
* read/write/execute bits
407
418
*/
408
- table_present = (IA32E_EPT_R_BIT | IA32E_EPT_W_BIT |
419
+ entry_present = (IA32E_EPT_R_BIT | IA32E_EPT_W_BIT |
409
420
IA32E_EPT_X_BIT );
410
421
} else {
411
422
/* Set table preset bits to P bit or r/w bit */
412
- table_present = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT );
423
+ entry_present = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT );
413
424
}
414
425
415
426
/* Determine if a valid entry exists */
416
- if ((table_entry & table_present ) == 0 ) {
427
+ if ((table_entry & entry_present ) == 0 ) {
417
428
/* No entry present - need to allocate a new table */
418
429
sub_table_addr = alloc_paging_struct ();
419
430
/* Check to ensure memory available for this structure*/
@@ -431,7 +442,7 @@ static void *walk_paging_struct(void *addr, void *table_base,
431
442
* sub-table
432
443
*/
433
444
MEM_WRITE64 (table_base + table_offset ,
434
- HVA2HPA (sub_table_addr ) | table_present );
445
+ HVA2HPA (sub_table_addr ) | entry_present );
435
446
} else {
436
447
/* Get address of the sub-table */
437
448
sub_table_addr = HPA2HVA (table_entry & IA32E_REF_MASK );
@@ -610,7 +621,7 @@ int obtain_last_page_table_entry(struct map_params *map_params,
610
621
struct entry_params * entry , void * addr , bool direct )
611
622
{
612
623
uint64_t table_entry ;
613
- uint32_t table_present = 0 ;
624
+ uint32_t entry_present = 0 ;
614
625
int ret = 0 ;
615
626
/* Obtain the PML4 address */
616
627
void * table_addr = direct ? (map_params -> pml4_base )
@@ -620,8 +631,12 @@ int obtain_last_page_table_entry(struct map_params *map_params,
620
631
ret = get_table_entry (addr , table_addr , IA32E_PML4 , & table_entry );
621
632
if (ret < 0 )
622
633
return ret ;
623
- table_present = check_page_table_present (map_params , table_entry );
624
- if (table_present == PT_NOT_PRESENT ) {
634
+ entry_present = check_page_table_present (map_params -> page_table_type ,
635
+ table_entry );
636
+ if (entry_present == PT_MISCFG_PRESENT ) {
637
+ pr_err ("Present bits misconfigurated" );
638
+ return - EINVAL ;
639
+ } else if (entry_present == PT_NOT_PRESENT ) {
625
640
/* PML4E not present, return PML4 base address */
626
641
entry -> entry_level = IA32E_PML4 ;
627
642
entry -> entry_base = table_addr ;
@@ -638,8 +653,12 @@ int obtain_last_page_table_entry(struct map_params *map_params,
638
653
ret = get_table_entry (addr , table_addr , IA32E_PDPT , & table_entry );
639
654
if (ret < 0 )
640
655
return ret ;
641
- table_present = check_page_table_present (map_params , table_entry );
642
- if (table_present == PT_NOT_PRESENT ) {
656
+ entry_present = check_page_table_present (map_params -> page_table_type ,
657
+ table_entry );
658
+ if (entry_present == PT_MISCFG_PRESENT ) {
659
+ pr_err ("Present bits misconfigurated" );
660
+ return - EINVAL ;
661
+ } else if (entry_present == PT_NOT_PRESENT ) {
643
662
/* PDPTE not present, return PDPT base address */
644
663
entry -> entry_level = IA32E_PDPT ;
645
664
entry -> entry_base = table_addr ;
@@ -667,8 +686,12 @@ int obtain_last_page_table_entry(struct map_params *map_params,
667
686
ret = get_table_entry (addr , table_addr , IA32E_PD , & table_entry );
668
687
if (ret < 0 )
669
688
return ret ;
670
- table_present = check_page_table_present (map_params , table_entry );
671
- if (table_present == PT_NOT_PRESENT ) {
689
+ entry_present = check_page_table_present (map_params -> page_table_type ,
690
+ table_entry );
691
+ if (entry_present == PT_MISCFG_PRESENT ) {
692
+ pr_err ("Present bits misconfigurated" );
693
+ return - EINVAL ;
694
+ } else if (entry_present == PT_NOT_PRESENT ) {
672
695
/* PDE not present, return PDE base address */
673
696
entry -> entry_level = IA32E_PD ;
674
697
entry -> entry_base = table_addr ;
@@ -677,7 +700,6 @@ int obtain_last_page_table_entry(struct map_params *map_params,
677
700
entry -> entry_off = fetch_page_table_offset (addr , IA32E_PD );
678
701
entry -> entry_val = table_entry ;
679
702
return 0 ;
680
-
681
703
}
682
704
if (table_entry & IA32E_PDE_PS_BIT ) {
683
705
/* 2MB page size, return the base addr of the pg entry*/
@@ -695,8 +717,13 @@ int obtain_last_page_table_entry(struct map_params *map_params,
695
717
ret = get_table_entry (addr , table_addr , IA32E_PT , & table_entry );
696
718
if (ret < 0 )
697
719
return ret ;
698
- table_present = check_page_table_present (map_params , table_entry );
699
- entry -> entry_present = ((table_present == PT_PRESENT )
720
+ entry_present = check_page_table_present (map_params -> page_table_type ,
721
+ table_entry );
722
+ if (entry_present == PT_MISCFG_PRESENT ) {
723
+ pr_err ("Present bits misconfigurated" );
724
+ return - EINVAL ;
725
+ }
726
+ entry -> entry_present = ((entry_present == PT_PRESENT )
700
727
? (PT_PRESENT ):(PT_NOT_PRESENT ));
701
728
entry -> entry_level = IA32E_PT ;
702
729
entry -> entry_base = table_addr ;
0 commit comments