@@ -468,31 +468,39 @@ struct sme_populate_pgd_data {
468
468
void * pgtable_area ;
469
469
pgd_t * pgd ;
470
470
471
- pmdval_t pmd_val ;
471
+ pmdval_t pmd_flags ;
472
+ unsigned long paddr ;
473
+
472
474
unsigned long vaddr ;
475
+ unsigned long vaddr_end ;
473
476
};
474
477
475
- static void __init sme_clear_pgd (pgd_t * pgd_base , unsigned long start ,
476
- unsigned long end )
478
+ static void __init sme_clear_pgd (struct sme_populate_pgd_data * ppd )
477
479
{
478
480
unsigned long pgd_start , pgd_end , pgd_size ;
479
481
pgd_t * pgd_p ;
480
482
481
- pgd_start = start & PGDIR_MASK ;
482
- pgd_end = end & PGDIR_MASK ;
483
+ pgd_start = ppd -> vaddr & PGDIR_MASK ;
484
+ pgd_end = ppd -> vaddr_end & PGDIR_MASK ;
483
485
484
- pgd_size = (((pgd_end - pgd_start ) / PGDIR_SIZE ) + 1 );
485
- pgd_size *= sizeof (pgd_t );
486
+ pgd_size = (((pgd_end - pgd_start ) / PGDIR_SIZE ) + 1 ) * sizeof (pgd_t );
486
487
487
- pgd_p = pgd_base + pgd_index (start );
488
+ pgd_p = ppd -> pgd + pgd_index (ppd -> vaddr );
488
489
489
490
memset (pgd_p , 0 , pgd_size );
490
491
}
491
492
492
- #define PGD_FLAGS _KERNPG_TABLE_NOENC
493
- #define P4D_FLAGS _KERNPG_TABLE_NOENC
494
- #define PUD_FLAGS _KERNPG_TABLE_NOENC
495
- #define PMD_FLAGS (__PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL)
493
+ #define PGD_FLAGS _KERNPG_TABLE_NOENC
494
+ #define P4D_FLAGS _KERNPG_TABLE_NOENC
495
+ #define PUD_FLAGS _KERNPG_TABLE_NOENC
496
+
497
+ #define PMD_FLAGS_LARGE (__PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL)
498
+
499
+ #define PMD_FLAGS_DEC PMD_FLAGS_LARGE
500
+ #define PMD_FLAGS_DEC_WP ((PMD_FLAGS_DEC & ~_PAGE_CACHE_MASK) | \
501
+ (_PAGE_PAT | _PAGE_PWT))
502
+
503
+ #define PMD_FLAGS_ENC (PMD_FLAGS_LARGE | _PAGE_ENC)
496
504
497
505
static void __init sme_populate_pgd_large (struct sme_populate_pgd_data * ppd )
498
506
{
@@ -561,7 +569,35 @@ static void __init sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
561
569
562
570
pmd_p += pmd_index (ppd -> vaddr );
563
571
if (!native_pmd_val (* pmd_p ) || !(native_pmd_val (* pmd_p ) & _PAGE_PSE ))
564
- native_set_pmd (pmd_p , native_make_pmd (ppd -> pmd_val ));
572
+ native_set_pmd (pmd_p , native_make_pmd (ppd -> paddr | ppd -> pmd_flags ));
573
+ }
574
+
575
+ static void __init __sme_map_range (struct sme_populate_pgd_data * ppd ,
576
+ pmdval_t pmd_flags )
577
+ {
578
+ ppd -> pmd_flags = pmd_flags ;
579
+
580
+ while (ppd -> vaddr < ppd -> vaddr_end ) {
581
+ sme_populate_pgd_large (ppd );
582
+
583
+ ppd -> vaddr += PMD_PAGE_SIZE ;
584
+ ppd -> paddr += PMD_PAGE_SIZE ;
585
+ }
586
+ }
587
+
588
+ static void __init sme_map_range_encrypted (struct sme_populate_pgd_data * ppd )
589
+ {
590
+ __sme_map_range (ppd , PMD_FLAGS_ENC );
591
+ }
592
+
593
+ static void __init sme_map_range_decrypted (struct sme_populate_pgd_data * ppd )
594
+ {
595
+ __sme_map_range (ppd , PMD_FLAGS_DEC );
596
+ }
597
+
598
+ static void __init sme_map_range_decrypted_wp (struct sme_populate_pgd_data * ppd )
599
+ {
600
+ __sme_map_range (ppd , PMD_FLAGS_DEC_WP );
565
601
}
566
602
567
603
static unsigned long __init sme_pgtable_calc (unsigned long len )
@@ -621,7 +657,6 @@ void __init sme_encrypt_kernel(void)
621
657
unsigned long kernel_start , kernel_end , kernel_len ;
622
658
struct sme_populate_pgd_data ppd ;
623
659
unsigned long pgtable_area_len ;
624
- unsigned long paddr , pmd_flags ;
625
660
unsigned long decrypted_base ;
626
661
627
662
if (!sme_active ())
@@ -693,14 +728,10 @@ void __init sme_encrypt_kernel(void)
693
728
* addressing the workarea.
694
729
*/
695
730
ppd .pgd = (pgd_t * )native_read_cr3_pa ();
696
- paddr = workarea_start ;
697
- while (paddr < workarea_end ) {
698
- ppd .pmd_val = paddr + PMD_FLAGS ;
699
- ppd .vaddr = paddr ;
700
- sme_populate_pgd_large (& ppd );
701
-
702
- paddr += PMD_PAGE_SIZE ;
703
- }
731
+ ppd .paddr = workarea_start ;
732
+ ppd .vaddr = workarea_start ;
733
+ ppd .vaddr_end = workarea_end ;
734
+ sme_map_range_decrypted (& ppd );
704
735
705
736
/* Flush the TLB - no globals so cr3 is enough */
706
737
native_write_cr3 (__native_read_cr3 ());
@@ -715,17 +746,6 @@ void __init sme_encrypt_kernel(void)
715
746
memset (ppd .pgd , 0 , sizeof (pgd_t ) * PTRS_PER_PGD );
716
747
ppd .pgtable_area += sizeof (pgd_t ) * PTRS_PER_PGD ;
717
748
718
- /* Add encrypted kernel (identity) mappings */
719
- pmd_flags = PMD_FLAGS | _PAGE_ENC ;
720
- paddr = kernel_start ;
721
- while (paddr < kernel_end ) {
722
- ppd .pmd_val = paddr + pmd_flags ;
723
- ppd .vaddr = paddr ;
724
- sme_populate_pgd_large (& ppd );
725
-
726
- paddr += PMD_PAGE_SIZE ;
727
- }
728
-
729
749
/*
730
750
* A different PGD index/entry must be used to get different
731
751
* pagetable entries for the decrypted mapping. Choose the next
@@ -735,29 +755,28 @@ void __init sme_encrypt_kernel(void)
735
755
decrypted_base = (pgd_index (workarea_end ) + 1 ) & (PTRS_PER_PGD - 1 );
736
756
decrypted_base <<= PGDIR_SHIFT ;
737
757
758
+ /* Add encrypted kernel (identity) mappings */
759
+ ppd .paddr = kernel_start ;
760
+ ppd .vaddr = kernel_start ;
761
+ ppd .vaddr_end = kernel_end ;
762
+ sme_map_range_encrypted (& ppd );
763
+
738
764
/* Add decrypted, write-protected kernel (non-identity) mappings */
739
- pmd_flags = (PMD_FLAGS & ~_PAGE_CACHE_MASK ) | (_PAGE_PAT | _PAGE_PWT );
740
- paddr = kernel_start ;
741
- while (paddr < kernel_end ) {
742
- ppd .pmd_val = paddr + pmd_flags ;
743
- ppd .vaddr = paddr + decrypted_base ;
744
- sme_populate_pgd_large (& ppd );
745
-
746
- paddr += PMD_PAGE_SIZE ;
747
- }
765
+ ppd .paddr = kernel_start ;
766
+ ppd .vaddr = kernel_start + decrypted_base ;
767
+ ppd .vaddr_end = kernel_end + decrypted_base ;
768
+ sme_map_range_decrypted_wp (& ppd );
748
769
749
770
/* Add decrypted workarea mappings to both kernel mappings */
750
- paddr = workarea_start ;
751
- while (paddr < workarea_end ) {
752
- ppd .pmd_val = paddr + PMD_FLAGS ;
753
- ppd .vaddr = paddr ;
754
- sme_populate_pgd_large (& ppd );
755
-
756
- ppd .vaddr = paddr + decrypted_base ;
757
- sme_populate_pgd_large (& ppd );
771
+ ppd .paddr = workarea_start ;
772
+ ppd .vaddr = workarea_start ;
773
+ ppd .vaddr_end = workarea_end ;
774
+ sme_map_range_decrypted (& ppd );
758
775
759
- paddr += PMD_PAGE_SIZE ;
760
- }
776
+ ppd .paddr = workarea_start ;
777
+ ppd .vaddr = workarea_start + decrypted_base ;
778
+ ppd .vaddr_end = workarea_end + decrypted_base ;
779
+ sme_map_range_decrypted (& ppd );
761
780
762
781
/* Perform the encryption */
763
782
sme_encrypt_execute (kernel_start , kernel_start + decrypted_base ,
@@ -768,11 +787,13 @@ void __init sme_encrypt_kernel(void)
768
787
* the decrypted areas - all that is needed for this is to remove
769
788
* the PGD entry/entries.
770
789
*/
771
- sme_clear_pgd (ppd .pgd , kernel_start + decrypted_base ,
772
- kernel_end + decrypted_base );
790
+ ppd .vaddr = kernel_start + decrypted_base ;
791
+ ppd .vaddr_end = kernel_end + decrypted_base ;
792
+ sme_clear_pgd (& ppd );
773
793
774
- sme_clear_pgd (ppd .pgd , workarea_start + decrypted_base ,
775
- workarea_end + decrypted_base );
794
+ ppd .vaddr = workarea_start + decrypted_base ;
795
+ ppd .vaddr_end = workarea_end + decrypted_base ;
796
+ sme_clear_pgd (& ppd );
776
797
777
798
/* Flush the TLB - no globals so cr3 is enough */
778
799
native_write_cr3 (__native_read_cr3 ());
0 commit comments