powerpc/mm/hash64: Map all the kernel regions in the same 0xc range
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Wed, 17 Apr 2019 12:59:14 +0000 (18:29 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 21 Apr 2019 13:12:39 +0000 (23:12 +1000)
This patch maps vmalloc, IO and vmemap regions in the 0xc address range
instead of the current 0xd and 0xf range. This brings the mapping closer
to radix translation mode.

With hash 64K page size each of this region is 512TB whereas with 4K config
we are limited by the max page table range of 64TB and hence there regions
are of 16TB size.

The kernel mapping is now:

 On 4K hash

     kernel_region_map_size = 16TB
     kernel vmalloc start   = 0xc000100000000000
     kernel IO start        = 0xc000200000000000
     kernel vmemmap start   = 0xc000300000000000

64K hash, 64K radix and 4k radix:

     kernel_region_map_size = 512TB
     kernel vmalloc start   = 0xc008000000000000
     kernel IO start        = 0xc00a000000000000
     kernel vmemmap start   = 0xc00c000000000000

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
18 files changed:
arch/powerpc/include/asm/book3s/64/hash-4k.h
arch/powerpc/include/asm/book3s/64/hash-64k.h
arch/powerpc/include/asm/book3s/64/hash.h
arch/powerpc/include/asm/book3s/64/mmu-hash.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/book3s/64/radix.h
arch/powerpc/include/asm/page.h
arch/powerpc/kvm/book3s_hv_rm_xics.c
arch/powerpc/mm/copro_fault.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/ptdump/hashpagetable.c
arch/powerpc/mm/ptdump/ptdump.c
arch/powerpc/mm/slb.c
arch/powerpc/platforms/cell/spu_base.c
drivers/misc/cxl/fault.c
drivers/misc/ocxl/link.c

index 54fab723a8c74ac6e313fda46d57bba6fc24eeaf..4c9dfd6254616fc632d9e0bfefd67859fee082af 100644 (file)
  */
 #define MAX_EA_BITS_PER_CONTEXT                46
 
+/*
+ * Our page table limit us to 64TB. Hence for the kernel mapping,
+ * each MAP area is limited to 16 TB.
+ * The four map areas are:  linear mapping, vmap, IO and vmemmap
+ */
+#define H_KERN_MAP_SIZE                (ASM_CONST(1) << (MAX_EA_BITS_PER_CONTEXT - 2))
+
+/*
+ * Define the address range of the kernel non-linear virtual area
+ * 16TB
+ */
+#define H_KERN_VIRT_START      ASM_CONST(0xc000100000000000)
+
 #ifndef __ASSEMBLY__
 #define H_PTE_TABLE_SIZE       (sizeof(pte_t) << H_PTE_INDEX_SIZE)
 #define H_PMD_TABLE_SIZE       (sizeof(pmd_t) << H_PMD_INDEX_SIZE)
index 81f4eb6e7da4c0eaa3df776790ce49b2d8587708..0d0191cda0507adc15bb2a937de1806c0421633b 100644 (file)
  */
 #define MAX_EA_BITS_PER_CONTEXT                49
 
+/*
+ * We use one context for each MAP area.
+ */
+#define H_KERN_MAP_SIZE                (1UL << MAX_EA_BITS_PER_CONTEXT)
+
+/*
+ * Define the address range of the kernel non-linear virtual area
+ * 2PB
+ */
+#define H_KERN_VIRT_START      ASM_CONST(0xc008000000000000)
+
 /*
  * 64k aligned address free up few of the lower bits of RPN for us
  * We steal that here. For more deatils look at pte_pfn/pfn_pte()
index 8cbc4106d44933d13a66e50afb896a7002394dd6..76741a22191087d3afd7619ff3b26484a4ae46aa 100644 (file)
 #define H_PGTABLE_EADDR_SIZE   (H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE + \
                                 H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + PAGE_SHIFT)
 #define H_PGTABLE_RANGE                (ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
+/*
+ * Top 2 bits are ignored in page table walk.
+ */
+#define EA_MASK                        (~(0xcUL << 60))
 
 /*
  * We store the slot details in the second half of page table.
 #endif
 
 /*
- * Define the address range of the kernel non-linear virtual area. In contrast
- * to the linear mapping, this is managed using the kernel page tables and then
- * inserted into the hash page table to actually take effect, similarly to user
- * mappings.
+ * +------------------------------+
+ * |                              |
+ * |                              |
+ * |                              |
+ * +------------------------------+  Kernel virtual map end (0xc00e000000000000)
+ * |                              |
+ * |                              |
+ * |      512TB/16TB of vmemmap   |
+ * |                              |
+ * |                              |
+ * +------------------------------+  Kernel vmemmap  start
+ * |                              |
+ * |      512TB/16TB of IO map    |
+ * |                              |
+ * +------------------------------+  Kernel IO map start
+ * |                              |
+ * |      512TB/16TB of vmap      |
+ * |                              |
+ * +------------------------------+  Kernel virt start (0xc008000000000000)
+ * |                              |
+ * |                              |
+ * |                              |
+ * +------------------------------+  Kernel linear (0xc.....)
  */
-#define H_KERN_VIRT_START ASM_CONST(0xD000000000000000)
 
-/*
- * Allow virtual mapping of one context size.
- * 512TB for 64K page size
- * 64TB for 4K page size
- */
-#define H_KERN_VIRT_SIZE (1UL << MAX_EA_BITS_PER_CONTEXT)
+#define H_VMALLOC_START                H_KERN_VIRT_START
+#define H_VMALLOC_SIZE         H_KERN_MAP_SIZE
+#define H_VMALLOC_END          (H_VMALLOC_START + H_VMALLOC_SIZE)
 
-/*
- * 8TB IO mapping size
- */
-#define H_KERN_IO_SIZE ASM_CONST(0x80000000000) /* 8T */
-
-/*
- * The vmalloc space starts at the beginning of the kernel non-linear virtual
- * region, and occupies 504T (64K) or 56T (4K)
- */
-#define H_VMALLOC_START H_KERN_VIRT_START
-#define H_VMALLOC_SIZE (H_KERN_VIRT_SIZE - H_KERN_IO_SIZE)
-#define H_VMALLOC_END  (H_VMALLOC_START + H_VMALLOC_SIZE)
+#define H_KERN_IO_START                H_VMALLOC_END
+#define H_KERN_IO_SIZE         H_KERN_MAP_SIZE
+#define H_KERN_IO_END          (H_KERN_IO_START + H_KERN_IO_SIZE)
 
-#define H_KERN_IO_START        H_VMALLOC_END
-#define H_KERN_IO_END  (H_KERN_VIRT_START + H_KERN_VIRT_SIZE)
+#define H_VMEMMAP_START                H_KERN_IO_END
+#define H_VMEMMAP_SIZE         H_KERN_MAP_SIZE
+#define H_VMEMMAP_END          (H_VMEMMAP_START + H_VMEMMAP_SIZE)
 
 /*
  * Region IDs
  */
-#define REGION_SHIFT           60UL
-#define REGION_MASK            (0xfUL << REGION_SHIFT)
-#define REGION_ID(ea)          (((unsigned long)(ea)) >> REGION_SHIFT)
-
-#define VMALLOC_REGION_ID      (REGION_ID(H_VMALLOC_START))
-#define KERNEL_REGION_ID       (REGION_ID(PAGE_OFFSET))
-#define VMEMMAP_REGION_ID      (0xfUL) /* Server only */
-#define USER_REGION_ID         (0UL)
+#define USER_REGION_ID         1
+#define KERNEL_REGION_ID       2
+#define VMALLOC_REGION_ID      3
+#define IO_REGION_ID           4
+#define VMEMMAP_REGION_ID      5
 
 /*
  * Defines the address of the vmemap area, in its own region on
  * hash table CPUs.
  */
-#define H_VMEMMAP_BASE         (VMEMMAP_REGION_ID << REGION_SHIFT)
 
 #ifdef CONFIG_PPC_MM_SLICES
 #define HAVE_ARCH_UNMAPPED_AREA
 #define H_PUD_BAD_BITS         (PMD_TABLE_SIZE-1)
 
 #ifndef __ASSEMBLY__
+static inline int get_region_id(unsigned long ea)
+{
+       int id = (ea >> 60UL);
+
+       if (id == 0)
+               return USER_REGION_ID;
+
+       VM_BUG_ON(id != 0xc);
+       VM_BUG_ON(ea >= H_VMEMMAP_END);
+
+       if (ea >= H_VMEMMAP_START)
+               return VMEMMAP_REGION_ID;
+       else if (ea >= H_KERN_IO_START)
+               return IO_REGION_ID;
+       else if (ea >= H_VMALLOC_START)
+               return VMALLOC_REGION_ID;
+
+       return KERNEL_REGION_ID;
+}
+
 #define        hash__pmd_bad(pmd)              (pmd_val(pmd) & H_PMD_BAD_BITS)
 #define        hash__pud_bad(pud)              (pud_val(pud) & H_PUD_BAD_BITS)
 static inline int hash__pgd_bad(pgd_t pgd)
index eeb40091b46be4e4e64ea53c3ef3b2b55ad6b90d..8a30bf189f1099c1afd80b13e7b666fe10e266d9 100644 (file)
@@ -588,7 +588,8 @@ extern void slb_set_size(u16 size);
 #endif
 
 #define MAX_VMALLOC_CTX_CNT    1
-#define MAX_MEMMAP_CTX_CNT     1
+#define MAX_IO_CTX_CNT         1
+#define MAX_VMEMMAP_CTX_CNT    1
 
 /*
  * 256MB segment
@@ -601,13 +602,10 @@ extern void slb_set_size(u16 size);
  * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
  * because of the modulo operation in vsid scramble.
  *
- * We add one extra context to MIN_USER_CONTEXT so that we can map kernel
- * context easily. The +1 is to map the unused 0xe region mapping.
  */
 #define MAX_USER_CONTEXT       ((ASM_CONST(1) << CONTEXT_BITS) - 2)
 #define MIN_USER_CONTEXT       (MAX_KERNEL_CTX_CNT + MAX_VMALLOC_CTX_CNT + \
-                                MAX_MEMMAP_CTX_CNT + 2)
-
+                                MAX_IO_CTX_CNT + MAX_VMEMMAP_CTX_CNT)
 /*
  * For platforms that support on 65bit VA we limit the context bits
  */
@@ -776,7 +774,7 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
        /*
         * Bad address. We return VSID 0 for that
         */
-       if ((ea & ~REGION_MASK) >= H_PGTABLE_RANGE)
+       if ((ea & EA_MASK)  >= H_PGTABLE_RANGE)
                return 0;
 
        if (!mmu_has_feature(MMU_FTR_68_BIT_VA))
@@ -803,28 +801,29 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
  * 0x00002 -  [ 0xc002000000000000 - 0xc003ffffffffffff]
  * 0x00003 -  [ 0xc004000000000000 - 0xc005ffffffffffff]
  * 0x00004 -  [ 0xc006000000000000 - 0xc007ffffffffffff]
-
- * 0x00005 -  [ 0xd000000000000000 - 0xd001ffffffffffff ]
- * 0x00006 -  Not used - Can map 0xe000000000000000 range.
- * 0x00007 -  [ 0xf000000000000000 - 0xf001ffffffffffff ]
  *
- * So we can compute the context from the region (top nibble) by
- * subtracting 11, or 0xc - 1.
+ * vmap, IO, vmemap
+ *
+ * 0x00005 -  [ 0xc008000000000000 - 0xc009ffffffffffff]
+ * 0x00006 -  [ 0xc00a000000000000 - 0xc00bffffffffffff]
+ * 0x00007 -  [ 0xc00c000000000000 - 0xc00dffffffffffff]
+ *
  */
 static inline unsigned long get_kernel_context(unsigned long ea)
 {
-       unsigned long region_id = REGION_ID(ea);
+       unsigned long region_id = get_region_id(ea);
        unsigned long ctx;
        /*
-        * For linear mapping we do support multiple context
+        * Depending on Kernel config, kernel region can have one context
+        * or more.
         */
        if (region_id == KERNEL_REGION_ID) {
                /*
                 * We already verified ea to be not beyond the addr limit.
                 */
-               ctx =  1 + ((ea & ~REGION_MASK) >> MAX_EA_BITS_PER_CONTEXT);
+               ctx =  1 + ((ea & EA_MASK) >> MAX_EA_BITS_PER_CONTEXT);
        } else
-               ctx = (region_id - 0xc) + MAX_KERNEL_CTX_CNT;
+               ctx = region_id + MAX_KERNEL_CTX_CNT - 2;
        return ctx;
 }
 
index f8ab18f77d1ba9be5988a36672ae9aaba6262c2f..7dede2e34b708958d1ce71adaa7fd34a3d7bfc70 100644 (file)
@@ -279,7 +279,6 @@ extern unsigned long __kernel_virt_size;
 extern unsigned long __kernel_io_start;
 extern unsigned long __kernel_io_end;
 #define KERN_VIRT_START __kernel_virt_start
-#define KERN_VIRT_SIZE  __kernel_virt_size
 #define KERN_IO_START  __kernel_io_start
 #define KERN_IO_END __kernel_io_end
 
index 6d760a083d62169baa1a5554b02b4555136a9d6d..574eca33f8930d4d52bc2c9cebfd8ed696ee0a20 100644 (file)
  * |                              |
  * |                              |
  * |                              |
- * +------------------------------+  Kernel IO map end (0xc010000000000000)
+ * +------------------------------+  Kernel vmemmap end (0xc010000000000000)
  * |                              |
+ * |           512TB             |
  * |                              |
- * |      1/2 of virtual map      |
+ * +------------------------------+  Kernel IO map end/vmemap start
  * |                              |
+ * |           512TB             |
  * |                              |
- * +------------------------------+  Kernel IO map start
+ * +------------------------------+  Kernel vmap end/ IO map start
  * |                              |
- * |      1/4 of virtual map      |
- * |                              |
- * +------------------------------+  Kernel vmemap start
- * |                              |
- * |     1/4 of virtual map       |
+ * |           512TB             |
  * |                              |
  * +------------------------------+  Kernel virt start (0xc008000000000000)
  * |                              |
  * +------------------------------+  Kernel linear (0xc.....)
  */
 
-#define RADIX_KERN_VIRT_START ASM_CONST(0xc008000000000000)
-#define RADIX_KERN_VIRT_SIZE  ASM_CONST(0x0008000000000000)
-
+#define RADIX_KERN_VIRT_START  ASM_CONST(0xc008000000000000)
 /*
- * The vmalloc space starts at the beginning of that region, and
- * occupies a quarter of it on radix config.
- * (we keep a quarter for the virtual memmap)
+ * 49 =  MAX_EA_BITS_PER_CONTEXT (hash specific). To make sure we pick
+ * the same value as hash.
  */
+#define RADIX_KERN_MAP_SIZE    (1UL << 49)
+
 #define RADIX_VMALLOC_START    RADIX_KERN_VIRT_START
-#define RADIX_VMALLOC_SIZE     (RADIX_KERN_VIRT_SIZE >> 2)
+#define RADIX_VMALLOC_SIZE     RADIX_KERN_MAP_SIZE
 #define RADIX_VMALLOC_END      (RADIX_VMALLOC_START + RADIX_VMALLOC_SIZE)
-/*
- * Defines the address of the vmemap area, in its own region on
- * hash table CPUs.
- */
-#define RADIX_VMEMMAP_BASE             (RADIX_VMALLOC_END)
 
-#define RADIX_KERN_IO_START    (RADIX_KERN_VIRT_START + (RADIX_KERN_VIRT_SIZE >> 1))
-#define RADIX_KERN_IO_END       (RADIX_KERN_VIRT_START + RADIX_KERN_VIRT_SIZE)
+#define RADIX_KERN_IO_START    RADIX_VMALLOC_END
+#define RADIX_KERN_IO_SIZE     RADIX_KERN_MAP_SIZE
+#define RADIX_KERN_IO_END      (RADIX_KERN_IO_START + RADIX_KERN_IO_SIZE)
+
+#define RADIX_VMEMMAP_START    RADIX_KERN_IO_END
+#define RADIX_VMEMMAP_SIZE     RADIX_KERN_MAP_SIZE
+#define RADIX_VMEMMAP_END      (RADIX_VMEMMAP_START + RADIX_VMEMMAP_SIZE)
 
 #ifndef __ASSEMBLY__
 #define RADIX_PTE_TABLE_SIZE   (sizeof(pte_t) << RADIX_PTE_INDEX_SIZE)
index ed870468ef6f12562f7833fc8af56bb24d44cc85..918228f2205ba2eea8725d1957490ece61c1a2ad 100644 (file)
@@ -139,7 +139,8 @@ static inline bool pfn_valid(unsigned long pfn)
  * return true for some vmalloc addresses, which is incorrect. So explicitly
  * check that the address is in the kernel region.
  */
-#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \
+/* may be can drop get_region_id */
+#define virt_addr_valid(kaddr) (get_region_id((unsigned long)kaddr) == KERNEL_REGION_ID && \
                                pfn_valid(virt_to_pfn(kaddr)))
 #else
 #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr))
index 3b9662a4207e06125d108a2cd13724dbf665632a..085509148d95fb2b976773056a7ee692c70a1a30 100644 (file)
@@ -822,7 +822,7 @@ static inline void this_cpu_inc_rm(unsigned int __percpu *addr)
        raddr = per_cpu_ptr(addr, cpu);
        l = (unsigned long)raddr;
 
-       if (REGION_ID(l) == VMALLOC_REGION_ID) {
+       if (get_region_id(l) == VMALLOC_REGION_ID) {
                l = vmalloc_to_phys(raddr);
                raddr = (unsigned int *)l;
        }
index c8da352e8686c4ebfba1299ce8d2c69e1b05386f..9b0321061bc87bc33f09c77d145e745db350fe6d 100644 (file)
@@ -105,7 +105,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
        u64 vsid, vsidkey;
        int psize, ssize;
 
-       switch (REGION_ID(ea)) {
+       switch (get_region_id(ea)) {
        case USER_REGION_ID:
                pr_devel("%s: 0x%llx -- USER_REGION_ID\n", __func__, ea);
                if (mm == NULL)
@@ -117,10 +117,14 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
                break;
        case VMALLOC_REGION_ID:
                pr_devel("%s: 0x%llx -- VMALLOC_REGION_ID\n", __func__, ea);
-               if (ea < VMALLOC_END)
-                       psize = mmu_vmalloc_psize;
-               else
-                       psize = mmu_io_psize;
+               psize = mmu_vmalloc_psize;
+               ssize = mmu_kernel_ssize;
+               vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+               vsidkey = SLB_VSID_KERNEL;
+               break;
+       case IO_REGION_ID:
+               pr_devel("%s: 0x%llx -- IO_REGION_ID\n", __func__, ea);
+               psize = mmu_io_psize;
                ssize = mmu_kernel_ssize;
                vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
                vsidkey = SLB_VSID_KERNEL;
index f6ffe8545717f8f204d7337b01f2a8b9c0945966..9c4ae4aa133e57d08c0eef1d4e0eed64bc8df59a 100644 (file)
@@ -1009,12 +1009,11 @@ void __init hash__early_init_mmu(void)
        __pgd_val_bits = HASH_PGD_VAL_BITS;
 
        __kernel_virt_start = H_KERN_VIRT_START;
-       __kernel_virt_size = H_KERN_VIRT_SIZE;
        __vmalloc_start = H_VMALLOC_START;
        __vmalloc_end = H_VMALLOC_END;
        __kernel_io_start = H_KERN_IO_START;
        __kernel_io_end = H_KERN_IO_END;
-       vmemmap = (struct page *)H_VMEMMAP_BASE;
+       vmemmap = (struct page *)H_VMEMMAP_START;
        ioremap_bot = IOREMAP_BASE;
 
 #ifdef CONFIG_PCI
@@ -1241,7 +1240,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
        trace_hash_fault(ea, access, trap);
 
        /* Get region & vsid */
-       switch (REGION_ID(ea)) {
+       switch (get_region_id(ea)) {
        case USER_REGION_ID:
                user_region = 1;
                if (! mm) {
@@ -1255,10 +1254,13 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
                break;
        case VMALLOC_REGION_ID:
                vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
-               if (ea < VMALLOC_END)
-                       psize = mmu_vmalloc_psize;
-               else
-                       psize = mmu_io_psize;
+               psize = mmu_vmalloc_psize;
+               ssize = mmu_kernel_ssize;
+               break;
+
+       case IO_REGION_ID:
+               vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+               psize = mmu_io_psize;
                ssize = mmu_kernel_ssize;
                break;
        default:
@@ -1424,7 +1426,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
        unsigned long flags = 0;
        struct mm_struct *mm = current->mm;
 
-       if (REGION_ID(ea) == VMALLOC_REGION_ID)
+       if ((get_region_id(ea) == VMALLOC_REGION_ID) ||
+           (get_region_id(ea) == IO_REGION_ID))
                mm = &init_mm;
 
        if (dsisr & DSISR_NOHPTE)
@@ -1440,8 +1443,9 @@ int __hash_page(unsigned long ea, unsigned long msr, unsigned long trap,
        unsigned long access = _PAGE_PRESENT | _PAGE_READ;
        unsigned long flags = 0;
        struct mm_struct *mm = current->mm;
+       unsigned int region_id = get_region_id(ea);
 
-       if (REGION_ID(ea) == VMALLOC_REGION_ID)
+       if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
                mm = &init_mm;
 
        if (dsisr & DSISR_NOHPTE)
@@ -1458,7 +1462,7 @@ int __hash_page(unsigned long ea, unsigned long msr, unsigned long trap,
         * 2) user space access kernel space.
         */
        access |= _PAGE_PRIVILEGED;
-       if ((msr & MSR_PR) || (REGION_ID(ea) == USER_REGION_ID))
+       if ((msr & MSR_PR) || (region_id == USER_REGION_ID))
                access &= ~_PAGE_PRIVILEGED;
 
        if (trap == 0x400)
@@ -1502,7 +1506,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
        int rc, ssize, update_flags = 0;
        unsigned long access = _PAGE_PRESENT | _PAGE_READ | (is_exec ? _PAGE_EXEC : 0);
 
-       BUG_ON(REGION_ID(ea) != USER_REGION_ID);
+       BUG_ON(get_region_id(ea) != USER_REGION_ID);
 
        if (!should_hash_preload(mm, ea))
                return;
index 4c1a9843d0f28f414d4aa7a4b92cc12a4872573d..4d9fa9e900d5ba924fe9173c4a2469e5d741663d 100644 (file)
@@ -136,6 +136,10 @@ static int __map_kernel_page(unsigned long ea, unsigned long pa,
         */
        BUILD_BUG_ON(TASK_SIZE_USER64 > RADIX_PGTABLE_RANGE);
 
+#ifdef CONFIG_PPC_64K_PAGES
+       BUILD_BUG_ON(RADIX_KERN_MAP_SIZE != (1UL << MAX_EA_BITS_PER_CONTEXT));
+#endif
+
        if (unlikely(!slab_is_available()))
                return early_map_kernel_page(ea, pa, flags, map_page_size,
                                                nid, region_start, region_end);
@@ -601,12 +605,11 @@ void __init radix__early_init_mmu(void)
        __pgd_val_bits = RADIX_PGD_VAL_BITS;
 
        __kernel_virt_start = RADIX_KERN_VIRT_START;
-       __kernel_virt_size = RADIX_KERN_VIRT_SIZE;
        __vmalloc_start = RADIX_VMALLOC_START;
        __vmalloc_end = RADIX_VMALLOC_END;
        __kernel_io_start = RADIX_KERN_IO_START;
        __kernel_io_end = RADIX_KERN_IO_END;
-       vmemmap = (struct page *)RADIX_VMEMMAP_BASE;
+       vmemmap = (struct page *)RADIX_VMEMMAP_START;
        ioremap_bot = IOREMAP_BASE;
 
 #ifdef CONFIG_PCI
index 7cea39bdf05f8629aa643bf9f369bc647d4adaad..56068cac2a3cf52035620644bf52650055ffa093 100644 (file)
@@ -90,8 +90,6 @@ unsigned long __pgd_val_bits;
 EXPORT_SYMBOL(__pgd_val_bits);
 unsigned long __kernel_virt_start;
 EXPORT_SYMBOL(__kernel_virt_start);
-unsigned long __kernel_virt_size;
-EXPORT_SYMBOL(__kernel_virt_size);
 unsigned long __vmalloc_start;
 EXPORT_SYMBOL(__vmalloc_start);
 unsigned long __vmalloc_end;
index b430e4e08af69d435f446fadcd2dc2242f51fa8c..b9bda0105841decc74e73629c9a318c092258d7b 100644 (file)
@@ -500,7 +500,7 @@ static void populate_markers(void)
        address_markers[7].start_address = IOREMAP_BASE;
        address_markers[8].start_address = IOREMAP_END;
 #ifdef CONFIG_PPC_BOOK3S_64
-       address_markers[9].start_address =  H_VMEMMAP_BASE;
+       address_markers[9].start_address =  H_VMEMMAP_START;
 #else
        address_markers[9].start_address =  VMEMMAP_BASE;
 #endif
index 37138428ab5585d42a82a2d78e6e74705431619d..63fc56feea15b120b9ee53946c6bb58ba0adc271 100644 (file)
@@ -303,8 +303,9 @@ static void populate_markers(void)
        address_markers[i++].start_address = PHB_IO_END;
        address_markers[i++].start_address = IOREMAP_BASE;
        address_markers[i++].start_address = IOREMAP_END;
+       /* What is the ifdef about? */
 #ifdef CONFIG_PPC_BOOK3S_64
-       address_markers[i++].start_address =  H_VMEMMAP_BASE;
+       address_markers[i++].start_address =  H_VMEMMAP_START;
 #else
        address_markers[i++].start_address =  VMEMMAP_BASE;
 #endif
index 78c0c0a0e3555b930b689914ec8d44773d3996e6..721cb09c9044bb9a2c42fe5d052315de821a5763 100644 (file)
@@ -694,7 +694,7 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id)
        if (id == KERNEL_REGION_ID) {
 
                /* We only support upto MAX_PHYSMEM_BITS */
-               if ((ea & ~REGION_MASK) > (1UL << MAX_PHYSMEM_BITS))
+               if ((ea & EA_MASK) > (1UL << MAX_PHYSMEM_BITS))
                        return -EFAULT;
 
                flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_linear_psize].sllp;
@@ -702,20 +702,25 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id)
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
        } else if (id == VMEMMAP_REGION_ID) {
 
-               if ((ea & ~REGION_MASK) >= (1ULL << MAX_EA_BITS_PER_CONTEXT))
+               if (ea >= H_VMEMMAP_END)
                        return -EFAULT;
 
                flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_vmemmap_psize].sllp;
 #endif
        } else if (id == VMALLOC_REGION_ID) {
 
-               if ((ea & ~REGION_MASK) >= (1ULL << MAX_EA_BITS_PER_CONTEXT))
+               if (ea >= H_VMALLOC_END)
                        return -EFAULT;
 
-               if (ea < H_VMALLOC_END)
-                       flags = local_paca->vmalloc_sllp;
-               else
-                       flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_io_psize].sllp;
+               flags = local_paca->vmalloc_sllp;
+
+       } else if (id == IO_REGION_ID) {
+
+               if (ea >= H_KERN_IO_END)
+                       return -EFAULT;
+
+               flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_io_psize].sllp;
+
        } else {
                return -EFAULT;
        }
@@ -725,6 +730,7 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id)
                ssize = MMU_SEGSIZE_256M;
 
        context = get_kernel_context(ea);
+
        return slb_insert_entry(ea, context, flags, ssize, true);
 }
 
@@ -761,7 +767,7 @@ static long slb_allocate_user(struct mm_struct *mm, unsigned long ea)
 
 long do_slb_fault(struct pt_regs *regs, unsigned long ea)
 {
-       unsigned long id = REGION_ID(ea);
+       unsigned long id = get_region_id(ea);
 
        /* IRQs are not reconciled here, so can't check irqs_disabled */
        VM_WARN_ON(mfmsr() & MSR_EE);
index 7f12c7b78c0f61f0b340e370bc1a79baa563d61b..4770cce1bfe206b275e36330676f72b31f1b0967 100644 (file)
@@ -194,7 +194,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
         * faults need to be deferred to process context.
         */
        if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) &&
-           (REGION_ID(ea) != USER_REGION_ID)) {
+           (get_region_id(ea) != USER_REGION_ID)) {
 
                spin_unlock(&spu->register_lock);
                ret = hash_page(ea,
@@ -224,7 +224,7 @@ static void __spu_kernel_slb(void *addr, struct copro_slb *slb)
        unsigned long ea = (unsigned long)addr;
        u64 llp;
 
-       if (REGION_ID(ea) == KERNEL_REGION_ID)
+       if (get_region_id(ea) == KERNEL_REGION_ID)
                llp = mmu_psize_defs[mmu_linear_psize].sllp;
        else
                llp = mmu_psize_defs[mmu_virtual_psize].sllp;
index dc7b34174f85734bfae9970dffe5f092620018bd..a4d17a5a97635691c3d6c995775aca439fc14cbd 100644 (file)
@@ -168,7 +168,7 @@ int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar)
                if (dsisr & CXL_PSL_DSISR_An_S)
                        access |= _PAGE_WRITE;
 
-               if (!mm && (REGION_ID(dar) != USER_REGION_ID))
+               if (!mm && (get_region_id(dar) != USER_REGION_ID))
                        access |= _PAGE_PRIVILEGED;
 
                if (dsisr & DSISR_NOHPTE)
index d50b861d7e57b9bc14c6a9d3a533244124e0a026..04ec3d74f828c03f22f5458f38630bbe3dcefe02 100644 (file)
@@ -163,7 +163,7 @@ static void xsl_fault_handler_bh(struct work_struct *fault_work)
                if (fault->dsisr & SPA_XSL_S)
                        access |= _PAGE_WRITE;
 
-               if (REGION_ID(fault->dar) != USER_REGION_ID)
+               if (get_region_id(fault->dar) != USER_REGION_ID)
                        access |= _PAGE_PRIVILEGED;
 
                local_irq_save(flags);