powerpc/fsl_booke: Allocate separate TLBCAMs for readonly memory
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Fri, 15 Oct 2021 10:02:47 +0000 (12:02 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 22 Oct 2021 04:22:03 +0000 (15:22 +1100)
Reorganise TLBCAM allocation so that when STRICT_KERNEL_RWX is
enabled, TLBCAMs are allocated such that readonly memory uses
different TLBCAMs.

This results in an allocation looking like:

Memory CAM mapping: 4/4/4/1/1/1/1/16/16/16/64/64/64/256/256 Mb, residual: 256Mb

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/8ca169bc288261a0e0558712f979023c3a960ebb.1634292136.git.christophe.leroy@csgroup.eu
arch/powerpc/mm/nohash/fsl_book3e.c

index 375b2b8238c1616e84707a525b61ee86adf48fab..c1bc11f46344ff1c3e0cbb8c110a9e8c8c9a7e93 100644 (file)
@@ -171,15 +171,34 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
 {
        int i;
        unsigned long amount_mapped = 0;
+       unsigned long boundary;
+
+       if (strict_kernel_rwx_enabled())
+               boundary = (unsigned long)(_sinittext - _stext);
+       else
+               boundary = ram;
 
        /* Calculate CAM values */
-       for (i = 0; ram && i < max_cam_idx; i++) {
+       for (i = 0; boundary && i < max_cam_idx; i++) {
+               unsigned long cam_sz;
+               pgprot_t prot = PAGE_KERNEL_X;
+
+               cam_sz = calc_cam_sz(boundary, virt, phys);
+               if (!dryrun)
+                       settlbcam(i, virt, phys, cam_sz, pgprot_val(prot), 0);
+
+               boundary -= cam_sz;
+               amount_mapped += cam_sz;
+               virt += cam_sz;
+               phys += cam_sz;
+       }
+       for (ram -= amount_mapped; ram && i < max_cam_idx; i++) {
                unsigned long cam_sz;
+               pgprot_t prot = PAGE_KERNEL_X;
 
                cam_sz = calc_cam_sz(ram, virt, phys);
                if (!dryrun)
-                       settlbcam(i, virt, phys, cam_sz,
-                                 pgprot_val(PAGE_KERNEL_X), 0);
+                       settlbcam(i, virt, phys, cam_sz, pgprot_val(prot), 0);
 
                ram -= cam_sz;
                amount_mapped += cam_sz;