If unsure, say Y.
 
+config RODATA_FULL_DEFAULT_ENABLED
+       bool "Apply r/o permissions of VM areas also to their linear aliases"
+       default y
+       help
+         Apply read-only attributes of VM areas to the linear alias of
+         the backing pages as well. This prevents code or read-only data
+         from being modified (inadvertently or intentionally) via another
+         mapping of the same memory page. This additional enhancement can
+         be turned off at runtime by passing rodata=[off|on] (and turned on
+         with rodata=full if this option is set to 'n')
+
+         This requires the linear region to be mapped down to pages,
+         which may adversely affect performance in some cases.
+
 menuconfig ARMV8_DEPRECATED
        bool "Emulate deprecated/obsolete ARMv8 instructions"
        depends on COMPAT
 
 #include <asm/sysreg.h>
 #include <asm/tlbflush.h>
 
+extern bool rodata_full;
+
 static inline void contextidr_thread_switch(struct task_struct *next)
 {
        if (!IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR))
 
        struct memblock_region *reg;
        int flags = 0;
 
-       if (debug_pagealloc_enabled())
+       if (rodata_full || debug_pagealloc_enabled())
                flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 
        /*
 
 static int __init parse_rodata(char *arg)
 {
-       return strtobool(arg, &rodata_enabled);
+       int ret = strtobool(arg, &rodata_enabled);
+       if (!ret) {
+               rodata_full = false;
+               return 0;
+       }
+
+       /* permit 'full' in addition to boolean options */
+       if (strcmp(arg, "full"))
+               return -EINVAL;
+
+       rodata_enabled = true;
+       rodata_full = true;
+       return 0;
 }
 early_param("rodata", parse_rodata);
 
 
        pgprot_t clear_mask;
 };
 
+bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED);
+
 static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
                        void *data)
 {
        unsigned long size = PAGE_SIZE*numpages;
        unsigned long end = start + size;
        struct vm_struct *area;
+       int i;
 
        if (!PAGE_ALIGNED(addr)) {
                start &= PAGE_MASK;
        if (!numpages)
                return 0;
 
+       /*
+        * If we are manipulating read-only permissions, apply the same
+        * change to the linear mapping of the pages that back this VM area.
+        */
+       if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
+                           pgprot_val(clear_mask) == PTE_RDONLY)) {
+               for (i = 0; i < area->nr_pages; i++) {
+                       __change_memory_common((u64)page_address(area->pages[i]),
+                                              PAGE_SIZE, set_mask, clear_mask);
+               }
+       }
+
        /*
         * Get rid of potentially aliasing lazily unmapped vm areas that may
         * have permissions set that deviate from the ones we are setting here.