@@ -738,11 +738,12 @@ static unsigned long __init sme_pgtable_calc(unsigned long len)
738
738
return total ;
739
739
}
740
740
741
- void __init sme_encrypt_kernel (void )
741
+ void __init sme_encrypt_kernel (struct boot_params * bp )
742
742
{
743
743
unsigned long workarea_start , workarea_end , workarea_len ;
744
744
unsigned long execute_start , execute_end , execute_len ;
745
745
unsigned long kernel_start , kernel_end , kernel_len ;
746
+ unsigned long initrd_start , initrd_end , initrd_len ;
746
747
struct sme_populate_pgd_data ppd ;
747
748
unsigned long pgtable_area_len ;
748
749
unsigned long decrypted_base ;
@@ -751,14 +752,15 @@ void __init sme_encrypt_kernel(void)
751
752
return ;
752
753
753
754
/*
754
- * Prepare for encrypting the kernel by building new pagetables with
755
- * the necessary attributes needed to encrypt the kernel in place.
755
+ * Prepare for encrypting the kernel and initrd by building new
756
+ * pagetables with the necessary attributes needed to encrypt the
757
+ * kernel in place.
756
758
*
757
759
* One range of virtual addresses will map the memory occupied
758
- * by the kernel as encrypted.
760
+ * by the kernel and initrd as encrypted.
759
761
*
760
762
* Another range of virtual addresses will map the memory occupied
761
- * by the kernel as decrypted and write-protected.
763
+ * by the kernel and initrd as decrypted and write-protected.
762
764
*
763
765
* The use of write-protect attribute will prevent any of the
764
766
* memory from being cached.
@@ -769,6 +771,20 @@ void __init sme_encrypt_kernel(void)
769
771
kernel_end = ALIGN (__pa_symbol (_end ), PMD_PAGE_SIZE );
770
772
kernel_len = kernel_end - kernel_start ;
771
773
774
+ initrd_start = 0 ;
775
+ initrd_end = 0 ;
776
+ initrd_len = 0 ;
777
+ #ifdef CONFIG_BLK_DEV_INITRD
778
+ initrd_len = (unsigned long )bp -> hdr .ramdisk_size |
779
+ ((unsigned long )bp -> ext_ramdisk_size << 32 );
780
+ if (initrd_len ) {
781
+ initrd_start = (unsigned long )bp -> hdr .ramdisk_image |
782
+ ((unsigned long )bp -> ext_ramdisk_image << 32 );
783
+ initrd_end = PAGE_ALIGN (initrd_start + initrd_len );
784
+ initrd_len = initrd_end - initrd_start ;
785
+ }
786
+ #endif
787
+
772
788
/* Set the encryption workarea to be immediately after the kernel */
773
789
workarea_start = kernel_end ;
774
790
@@ -791,6 +807,8 @@ void __init sme_encrypt_kernel(void)
791
807
*/
792
808
pgtable_area_len = sizeof (pgd_t ) * PTRS_PER_PGD ;
793
809
pgtable_area_len += sme_pgtable_calc (execute_end - kernel_start ) * 2 ;
810
+ if (initrd_len )
811
+ pgtable_area_len += sme_pgtable_calc (initrd_len ) * 2 ;
794
812
795
813
/* PUDs and PMDs needed in the current pagetables for the workarea */
796
814
pgtable_area_len += sme_pgtable_calc (execute_len + pgtable_area_len );
@@ -829,9 +847,9 @@ void __init sme_encrypt_kernel(void)
829
847
830
848
/*
831
849
* A new pagetable structure is being built to allow for the kernel
832
- * to be encrypted. It starts with an empty PGD that will then be
833
- * populated with new PUDs and PMDs as the encrypted and decrypted
834
- * kernel mappings are created.
850
+ * and initrd to be encrypted. It starts with an empty PGD that will
851
+ * then be populated with new PUDs and PMDs as the encrypted and
852
+ * decrypted kernel mappings are created.
835
853
*/
836
854
ppd .pgd = ppd .pgtable_area ;
837
855
memset (ppd .pgd , 0 , sizeof (pgd_t ) * PTRS_PER_PGD );
@@ -844,6 +862,12 @@ void __init sme_encrypt_kernel(void)
844
862
* the base of the mapping.
845
863
*/
846
864
decrypted_base = (pgd_index (workarea_end ) + 1 ) & (PTRS_PER_PGD - 1 );
865
+ if (initrd_len ) {
866
+ unsigned long check_base ;
867
+
868
+ check_base = (pgd_index (initrd_end ) + 1 ) & (PTRS_PER_PGD - 1 );
869
+ decrypted_base = max (decrypted_base , check_base );
870
+ }
847
871
decrypted_base <<= PGDIR_SHIFT ;
848
872
849
873
/* Add encrypted kernel (identity) mappings */
@@ -858,6 +882,21 @@ void __init sme_encrypt_kernel(void)
858
882
ppd .vaddr_end = kernel_end + decrypted_base ;
859
883
sme_map_range_decrypted_wp (& ppd );
860
884
885
+ if (initrd_len ) {
886
+ /* Add encrypted initrd (identity) mappings */
887
+ ppd .paddr = initrd_start ;
888
+ ppd .vaddr = initrd_start ;
889
+ ppd .vaddr_end = initrd_end ;
890
+ sme_map_range_encrypted (& ppd );
891
+ /*
892
+ * Add decrypted, write-protected initrd (non-identity) mappings
893
+ */
894
+ ppd .paddr = initrd_start ;
895
+ ppd .vaddr = initrd_start + decrypted_base ;
896
+ ppd .vaddr_end = initrd_end + decrypted_base ;
897
+ sme_map_range_decrypted_wp (& ppd );
898
+ }
899
+
861
900
/* Add decrypted workarea mappings to both kernel mappings */
862
901
ppd .paddr = workarea_start ;
863
902
ppd .vaddr = workarea_start ;
@@ -873,6 +912,11 @@ void __init sme_encrypt_kernel(void)
873
912
sme_encrypt_execute (kernel_start , kernel_start + decrypted_base ,
874
913
kernel_len , workarea_start , (unsigned long )ppd .pgd );
875
914
915
+ if (initrd_len )
916
+ sme_encrypt_execute (initrd_start , initrd_start + decrypted_base ,
917
+ initrd_len , workarea_start ,
918
+ (unsigned long )ppd .pgd );
919
+
876
920
/*
877
921
* At this point we are running encrypted. Remove the mappings for
878
922
* the decrypted areas - all that is needed for this is to remove
@@ -882,6 +926,12 @@ void __init sme_encrypt_kernel(void)
882
926
ppd .vaddr_end = kernel_end + decrypted_base ;
883
927
sme_clear_pgd (& ppd );
884
928
929
+ if (initrd_len ) {
930
+ ppd .vaddr = initrd_start + decrypted_base ;
931
+ ppd .vaddr_end = initrd_end + decrypted_base ;
932
+ sme_clear_pgd (& ppd );
933
+ }
934
+
885
935
ppd .vaddr = workarea_start + decrypted_base ;
886
936
ppd .vaddr_end = workarea_end + decrypted_base ;
887
937
sme_clear_pgd (& ppd );
0 commit comments