@@ -455,6 +455,43 @@ asmlinkage void __init __copy_data(void)
455455}
456456#endif
457457
458+ #ifdef CONFIG_STRICT_KERNEL_RWX
459+ static __init pgprot_t pgprot_from_va (uintptr_t va )
460+ {
461+ if (is_va_kernel_text (va ))
462+ return PAGE_KERNEL_READ_EXEC ;
463+
464+ /*
465+ * In 64-bit kernel, the kernel mapping is outside the linear mapping so
466+ * we must protect its linear mapping alias from being executed and
467+ * written.
468+ * And rodata section is marked readonly in mark_rodata_ro.
469+ */
470+ if (IS_ENABLED (CONFIG_64BIT ) && is_va_kernel_lm_alias_text (va ))
471+ return PAGE_KERNEL_READ ;
472+
473+ return PAGE_KERNEL ;
474+ }
475+
476+ void mark_rodata_ro (void )
477+ {
478+ set_kernel_memory (__start_rodata , _data , set_memory_ro );
479+ if (IS_ENABLED (CONFIG_64BIT ))
480+ set_kernel_memory (lm_alias (__start_rodata ), lm_alias (_data ),
481+ set_memory_ro );
482+
483+ debug_checkwx ();
484+ }
485+ #else
486+ static __init pgprot_t pgprot_from_va (uintptr_t va )
487+ {
488+ if (IS_ENABLED (CONFIG_64BIT ) && !is_kernel_mapping (va ))
489+ return PAGE_KERNEL ;
490+
491+ return PAGE_KERNEL_EXEC ;
492+ }
493+ #endif /* CONFIG_STRICT_KERNEL_RWX */
494+
458495/*
459496 * setup_vm() is called from head.S with MMU-off.
460497 *
@@ -474,7 +511,7 @@ asmlinkage void __init __copy_data(void)
474511#endif
475512
476513static uintptr_t load_pa __initdata ;
477- static uintptr_t load_sz __initdata ;
514+ uintptr_t load_sz ;
478515#ifdef CONFIG_XIP_KERNEL
479516#define load_pa (*((uintptr_t *)XIP_FIXUP(&load_pa)))
480517#define load_sz (*((uintptr_t *)XIP_FIXUP(&load_sz)))
@@ -486,7 +523,8 @@ static uintptr_t xiprom_sz __initdata;
486523#define xiprom_sz (*((uintptr_t *)XIP_FIXUP(&xiprom_sz)))
487524#define xiprom (*((uintptr_t *)XIP_FIXUP(&xiprom)))
488525
489- static void __init create_kernel_page_table (pgd_t * pgdir , uintptr_t map_size )
526+ static void __init create_kernel_page_table (pgd_t * pgdir , uintptr_t map_size ,
527+ __always_unused bool early )
490528{
491529 uintptr_t va , end_va ;
492530
@@ -505,15 +543,18 @@ static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size)
505543 map_size , PAGE_KERNEL );
506544}
507545#else
508- static void __init create_kernel_page_table (pgd_t * pgdir , uintptr_t map_size )
546+ static void __init create_kernel_page_table (pgd_t * pgdir , uintptr_t map_size ,
547+ bool early )
509548{
510549 uintptr_t va , end_va ;
511550
512551 end_va = kernel_virt_addr + load_sz ;
513552 for (va = kernel_virt_addr ; va < end_va ; va += map_size )
514553 create_pgd_mapping (pgdir , va ,
515554 load_pa + (va - kernel_virt_addr ),
516- map_size , PAGE_KERNEL_EXEC );
555+ map_size ,
556+ early ?
557+ PAGE_KERNEL_EXEC : pgprot_from_va (va ));
517558}
518559#endif
519560
@@ -590,7 +631,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
590631 * us to reach paging_init(). We map all memory banks later
591632 * in setup_vm_final() below.
592633 */
593- create_kernel_page_table (early_pg_dir , map_size );
634+ create_kernel_page_table (early_pg_dir , map_size , true );
594635
595636#ifndef __PAGETABLE_PMD_FOLDED
596637 /* Setup early PMD for DTB */
@@ -666,22 +707,6 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
666707#endif
667708}
668709
669- #if defined(CONFIG_64BIT ) && defined(CONFIG_STRICT_KERNEL_RWX )
670- void __init protect_kernel_linear_mapping_text_rodata (void )
671- {
672- unsigned long text_start = (unsigned long )lm_alias (_start );
673- unsigned long init_text_start = (unsigned long )lm_alias (__init_text_begin );
674- unsigned long rodata_start = (unsigned long )lm_alias (__start_rodata );
675- unsigned long data_start = (unsigned long )lm_alias (_data );
676-
677- set_memory_ro (text_start , (init_text_start - text_start ) >> PAGE_SHIFT );
678- set_memory_nx (text_start , (init_text_start - text_start ) >> PAGE_SHIFT );
679-
680- set_memory_ro (rodata_start , (data_start - rodata_start ) >> PAGE_SHIFT );
681- set_memory_nx (rodata_start , (data_start - rodata_start ) >> PAGE_SHIFT );
682- }
683- #endif
684-
685710static void __init setup_vm_final (void )
686711{
687712 uintptr_t va , map_size ;
@@ -714,21 +739,15 @@ static void __init setup_vm_final(void)
714739 map_size = best_map_size (start , end - start );
715740 for (pa = start ; pa < end ; pa += map_size ) {
716741 va = (uintptr_t )__va (pa );
717- create_pgd_mapping (swapper_pg_dir , va , pa ,
718- map_size ,
719- #ifdef CONFIG_64BIT
720- PAGE_KERNEL
721- #else
722- PAGE_KERNEL_EXEC
723- #endif
724- );
725742
743+ create_pgd_mapping (swapper_pg_dir , va , pa , map_size ,
744+ pgprot_from_va (va ));
726745 }
727746 }
728747
729748#ifdef CONFIG_64BIT
730749 /* Map the kernel */
731- create_kernel_page_table (swapper_pg_dir , PMD_SIZE );
750+ create_kernel_page_table (swapper_pg_dir , PMD_SIZE , false );
732751#endif
733752
734753 /* Clear fixmap PTE and PMD mappings */
@@ -759,35 +778,6 @@ static inline void setup_vm_final(void)
759778}
760779#endif /* CONFIG_MMU */
761780
762- #ifdef CONFIG_STRICT_KERNEL_RWX
763- void __init protect_kernel_text_data (void )
764- {
765- unsigned long text_start = (unsigned long )_start ;
766- unsigned long init_text_start = (unsigned long )__init_text_begin ;
767- unsigned long init_data_start = (unsigned long )__init_data_begin ;
768- unsigned long rodata_start = (unsigned long )__start_rodata ;
769- unsigned long data_start = (unsigned long )_data ;
770- unsigned long max_low = (unsigned long )(__va (PFN_PHYS (max_low_pfn )));
771-
772- set_memory_ro (text_start , (init_text_start - text_start ) >> PAGE_SHIFT );
773- set_memory_ro (init_text_start , (init_data_start - init_text_start ) >> PAGE_SHIFT );
774- set_memory_nx (init_data_start , (rodata_start - init_data_start ) >> PAGE_SHIFT );
775- /* rodata section is marked readonly in mark_rodata_ro */
776- set_memory_nx (rodata_start , (data_start - rodata_start ) >> PAGE_SHIFT );
777- set_memory_nx (data_start , (max_low - data_start ) >> PAGE_SHIFT );
778- }
779-
780- void mark_rodata_ro (void )
781- {
782- unsigned long rodata_start = (unsigned long )__start_rodata ;
783- unsigned long data_start = (unsigned long )_data ;
784-
785- set_memory_ro (rodata_start , (data_start - rodata_start ) >> PAGE_SHIFT );
786-
787- debug_checkwx ();
788- }
789- #endif
790-
791781#ifdef CONFIG_KEXEC_CORE
792782/*
793783 * reserve_crashkernel() - reserves memory for crash kernel
0 commit comments