diff options
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/include/asm/mman.h | 5 | ||||
| -rw-r--r-- | arch/s390/include/asm/processor.h | 5 | ||||
| -rw-r--r-- | arch/s390/include/asm/topology.h | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/mcount.S | 6 | ||||
| -rw-r--r-- | arch/s390/lib/div64.c | 2 | ||||
| -rw-r--r-- | arch/s390/lib/uaccess_pt.c | 18 | ||||
| -rw-r--r-- | arch/s390/mm/mmap.c | 48 | ||||
| -rw-r--r-- | arch/s390/mm/pgtable.c | 2 |
8 files changed, 48 insertions, 40 deletions
diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h index 7839767d837..da01432e8f4 100644 --- a/arch/s390/include/asm/mman.h +++ b/arch/s390/include/asm/mman.h | |||
| @@ -22,4 +22,9 @@ | |||
| 22 | #define MCL_CURRENT 1 /* lock all current mappings */ | 22 | #define MCL_CURRENT 1 /* lock all current mappings */ |
| 23 | #define MCL_FUTURE 2 /* lock all future mappings */ | 23 | #define MCL_FUTURE 2 /* lock all future mappings */ |
| 24 | 24 | ||
| 25 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT) | ||
| 26 | int s390_mmap_check(unsigned long addr, unsigned long len); | ||
| 27 | #define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len) | ||
| 28 | #endif | ||
| 29 | |||
| 25 | #endif /* __S390_MMAN_H__ */ | 30 | #endif /* __S390_MMAN_H__ */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 066b99502e0..db4523fe38a 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -61,7 +61,7 @@ extern void print_cpu_info(struct cpuinfo_S390 *); | |||
| 61 | extern int get_cpu_capability(unsigned int *); | 61 | extern int get_cpu_capability(unsigned int *); |
| 62 | 62 | ||
| 63 | /* | 63 | /* |
| 64 | * User space process size: 2GB for 31 bit, 4TB for 64 bit. | 64 | * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. |
| 65 | */ | 65 | */ |
| 66 | #ifndef __s390x__ | 66 | #ifndef __s390x__ |
| 67 | 67 | ||
| @@ -70,8 +70,7 @@ extern int get_cpu_capability(unsigned int *); | |||
| 70 | 70 | ||
| 71 | #else /* __s390x__ */ | 71 | #else /* __s390x__ */ |
| 72 | 72 | ||
| 73 | #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ | 73 | #define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) |
| 74 | (1UL << 31) : (1UL << 53)) | ||
| 75 | #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ | 74 | #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ |
| 76 | (1UL << 30) : (1UL << 41)) | 75 | (1UL << 30) : (1UL << 41)) |
| 77 | #define TASK_SIZE TASK_SIZE_OF(current) | 76 | #define TASK_SIZE TASK_SIZE_OF(current) |
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index c93eb50e1d0..c979c3b56ab 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
| @@ -30,6 +30,8 @@ static inline void s390_init_cpu_topology(void) | |||
| 30 | }; | 30 | }; |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #define SD_MC_INIT SD_CPU_INIT | ||
| 34 | |||
| 33 | #include <asm-generic/topology.h> | 35 | #include <asm-generic/topology.h> |
| 34 | 36 | ||
| 35 | #endif /* _ASM_S390_TOPOLOGY_H */ | 37 | #endif /* _ASM_S390_TOPOLOGY_H */ |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 397d131a345..80641224a09 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <asm/asm-offsets.h> | ||
| 9 | |||
| 8 | #ifndef CONFIG_64BIT | 10 | #ifndef CONFIG_64BIT |
| 9 | .globl _mcount | 11 | .globl _mcount |
| 10 | _mcount: | 12 | _mcount: |
| @@ -14,7 +16,7 @@ _mcount: | |||
| 14 | ahi %r15,-96 | 16 | ahi %r15,-96 |
| 15 | l %r3,100(%r15) | 17 | l %r3,100(%r15) |
| 16 | la %r2,0(%r14) | 18 | la %r2,0(%r14) |
| 17 | st %r1,0(%r15) | 19 | st %r1,__SF_BACKCHAIN(%r15) |
| 18 | la %r3,0(%r3) | 20 | la %r3,0(%r3) |
| 19 | bras %r14,0f | 21 | bras %r14,0f |
| 20 | .long ftrace_trace_function | 22 | .long ftrace_trace_function |
| @@ -38,7 +40,7 @@ _mcount: | |||
| 38 | stg %r14,112(%r15) | 40 | stg %r14,112(%r15) |
| 39 | lgr %r1,%r15 | 41 | lgr %r1,%r15 |
| 40 | aghi %r15,-160 | 42 | aghi %r15,-160 |
| 41 | stg %r1,0(%r15) | 43 | stg %r1,__SF_BACKCHAIN(%r15) |
| 42 | lgr %r2,%r14 | 44 | lgr %r2,%r14 |
| 43 | lg %r3,168(%r15) | 45 | lg %r3,168(%r15) |
| 44 | larl %r14,ftrace_trace_function | 46 | larl %r14,ftrace_trace_function |
diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c index a5f8300bf3e..d9e62c0b576 100644 --- a/arch/s390/lib/div64.c +++ b/arch/s390/lib/div64.c | |||
| @@ -61,7 +61,7 @@ static uint32_t __div64_31(uint64_t *n, uint32_t base) | |||
| 61 | " clr %0,%3\n" | 61 | " clr %0,%3\n" |
| 62 | " jl 0f\n" | 62 | " jl 0f\n" |
| 63 | " slr %0,%3\n" | 63 | " slr %0,%3\n" |
| 64 | " alr %1,%2\n" | 64 | " ahi %1,1\n" |
| 65 | "0:\n" | 65 | "0:\n" |
| 66 | : "+d" (reg2), "+d" (reg3), "=d" (tmp) | 66 | : "+d" (reg2), "+d" (reg3), "=d" (tmp) |
| 67 | : "d" (base), "2" (1UL) : "cc" ); | 67 | : "d" (base), "2" (1UL) : "cc" ); |
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index d66215b0fde..b0b84c35b0a 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
| @@ -119,8 +119,6 @@ retry: | |||
| 119 | goto fault; | 119 | goto fault; |
| 120 | 120 | ||
| 121 | pfn = pte_pfn(*pte); | 121 | pfn = pte_pfn(*pte); |
| 122 | if (!pfn_valid(pfn)) | ||
| 123 | goto out; | ||
| 124 | 122 | ||
| 125 | offset = uaddr & (PAGE_SIZE - 1); | 123 | offset = uaddr & (PAGE_SIZE - 1); |
| 126 | size = min(n - done, PAGE_SIZE - offset); | 124 | size = min(n - done, PAGE_SIZE - offset); |
| @@ -135,7 +133,6 @@ retry: | |||
| 135 | done += size; | 133 | done += size; |
| 136 | uaddr += size; | 134 | uaddr += size; |
| 137 | } while (done < n); | 135 | } while (done < n); |
| 138 | out: | ||
| 139 | spin_unlock(&mm->page_table_lock); | 136 | spin_unlock(&mm->page_table_lock); |
| 140 | return n - done; | 137 | return n - done; |
| 141 | fault: | 138 | fault: |
| @@ -163,9 +160,6 @@ retry: | |||
| 163 | goto fault; | 160 | goto fault; |
| 164 | 161 | ||
| 165 | pfn = pte_pfn(*pte); | 162 | pfn = pte_pfn(*pte); |
| 166 | if (!pfn_valid(pfn)) | ||
| 167 | goto out; | ||
| 168 | |||
| 169 | ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); | 163 | ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); |
| 170 | out: | 164 | out: |
| 171 | return ret; | 165 | return ret; |
| @@ -244,11 +238,6 @@ retry: | |||
| 244 | goto fault; | 238 | goto fault; |
| 245 | 239 | ||
| 246 | pfn = pte_pfn(*pte); | 240 | pfn = pte_pfn(*pte); |
| 247 | if (!pfn_valid(pfn)) { | ||
| 248 | done = -1; | ||
| 249 | goto out; | ||
| 250 | } | ||
| 251 | |||
| 252 | offset = uaddr & (PAGE_SIZE-1); | 241 | offset = uaddr & (PAGE_SIZE-1); |
| 253 | addr = (char *)(pfn << PAGE_SHIFT) + offset; | 242 | addr = (char *)(pfn << PAGE_SHIFT) + offset; |
| 254 | len = min(count - done, PAGE_SIZE - offset); | 243 | len = min(count - done, PAGE_SIZE - offset); |
| @@ -256,7 +245,6 @@ retry: | |||
| 256 | done += len_str; | 245 | done += len_str; |
| 257 | uaddr += len_str; | 246 | uaddr += len_str; |
| 258 | } while ((len_str == len) && (done < count)); | 247 | } while ((len_str == len) && (done < count)); |
| 259 | out: | ||
| 260 | spin_unlock(&mm->page_table_lock); | 248 | spin_unlock(&mm->page_table_lock); |
| 261 | return done + 1; | 249 | return done + 1; |
| 262 | fault: | 250 | fault: |
| @@ -325,12 +313,7 @@ retry: | |||
| 325 | } | 313 | } |
| 326 | 314 | ||
| 327 | pfn_from = pte_pfn(*pte_from); | 315 | pfn_from = pte_pfn(*pte_from); |
| 328 | if (!pfn_valid(pfn_from)) | ||
| 329 | goto out; | ||
| 330 | pfn_to = pte_pfn(*pte_to); | 316 | pfn_to = pte_pfn(*pte_to); |
| 331 | if (!pfn_valid(pfn_to)) | ||
| 332 | goto out; | ||
| 333 | |||
| 334 | offset_from = uaddr_from & (PAGE_SIZE-1); | 317 | offset_from = uaddr_from & (PAGE_SIZE-1); |
| 335 | offset_to = uaddr_from & (PAGE_SIZE-1); | 318 | offset_to = uaddr_from & (PAGE_SIZE-1); |
| 336 | offset_max = max(offset_from, offset_to); | 319 | offset_max = max(offset_from, offset_to); |
| @@ -342,7 +325,6 @@ retry: | |||
| 342 | uaddr_from += size; | 325 | uaddr_from += size; |
| 343 | uaddr_to += size; | 326 | uaddr_to += size; |
| 344 | } while (done < n); | 327 | } while (done < n); |
| 345 | out: | ||
| 346 | spin_unlock(&mm->page_table_lock); | 328 | spin_unlock(&mm->page_table_lock); |
| 347 | return n - done; | 329 | return n - done; |
| 348 | fault: | 330 | fault: |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 5932a824547..e008d236cc1 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | * Leave an at least ~128 MB hole. | 35 | * Leave an at least ~128 MB hole. |
| 36 | */ | 36 | */ |
| 37 | #define MIN_GAP (128*1024*1024) | 37 | #define MIN_GAP (128*1024*1024) |
| 38 | #define MAX_GAP (TASK_SIZE/6*5) | 38 | #define MAX_GAP (STACK_TOP/6*5) |
| 39 | 39 | ||
| 40 | static inline unsigned long mmap_base(void) | 40 | static inline unsigned long mmap_base(void) |
| 41 | { | 41 | { |
| @@ -46,7 +46,7 @@ static inline unsigned long mmap_base(void) | |||
| 46 | else if (gap > MAX_GAP) | 46 | else if (gap > MAX_GAP) |
| 47 | gap = MAX_GAP; | 47 | gap = MAX_GAP; |
| 48 | 48 | ||
| 49 | return TASK_SIZE - (gap & PAGE_MASK); | 49 | return STACK_TOP - (gap & PAGE_MASK); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static inline int mmap_is_legacy(void) | 52 | static inline int mmap_is_legacy(void) |
| @@ -89,42 +89,58 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); | |||
| 89 | 89 | ||
| 90 | #else | 90 | #else |
| 91 | 91 | ||
| 92 | int s390_mmap_check(unsigned long addr, unsigned long len) | ||
| 93 | { | ||
| 94 | if (!test_thread_flag(TIF_31BIT) && | ||
| 95 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) | ||
| 96 | return crst_table_upgrade(current->mm, 1UL << 53); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 92 | static unsigned long | 100 | static unsigned long |
| 93 | s390_get_unmapped_area(struct file *filp, unsigned long addr, | 101 | s390_get_unmapped_area(struct file *filp, unsigned long addr, |
| 94 | unsigned long len, unsigned long pgoff, unsigned long flags) | 102 | unsigned long len, unsigned long pgoff, unsigned long flags) |
| 95 | { | 103 | { |
| 96 | struct mm_struct *mm = current->mm; | 104 | struct mm_struct *mm = current->mm; |
| 105 | unsigned long area; | ||
| 97 | int rc; | 106 | int rc; |
| 98 | 107 | ||
| 99 | addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags); | 108 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
| 100 | if (addr & ~PAGE_MASK) | 109 | if (!(area & ~PAGE_MASK)) |
| 101 | return addr; | 110 | return area; |
| 102 | if (unlikely(mm->context.asce_limit < addr + len)) { | 111 | if (area == -ENOMEM && |
| 103 | rc = crst_table_upgrade(mm, addr + len); | 112 | !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { |
| 113 | /* Upgrade the page table to 4 levels and retry. */ | ||
| 114 | rc = crst_table_upgrade(mm, 1UL << 53); | ||
| 104 | if (rc) | 115 | if (rc) |
| 105 | return (unsigned long) rc; | 116 | return (unsigned long) rc; |
| 117 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); | ||
| 106 | } | 118 | } |
| 107 | return addr; | 119 | return area; |
| 108 | } | 120 | } |
| 109 | 121 | ||
| 110 | static unsigned long | 122 | static unsigned long |
| 111 | s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | 123 | s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, |
| 112 | const unsigned long len, const unsigned long pgoff, | 124 | const unsigned long len, const unsigned long pgoff, |
| 113 | const unsigned long flags) | 125 | const unsigned long flags) |
| 114 | { | 126 | { |
| 115 | struct mm_struct *mm = current->mm; | 127 | struct mm_struct *mm = current->mm; |
| 116 | unsigned long addr = addr0; | 128 | unsigned long area; |
| 117 | int rc; | 129 | int rc; |
| 118 | 130 | ||
| 119 | addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); | 131 | area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); |
| 120 | if (addr & ~PAGE_MASK) | 132 | if (!(area & ~PAGE_MASK)) |
| 121 | return addr; | 133 | return area; |
| 122 | if (unlikely(mm->context.asce_limit < addr + len)) { | 134 | if (area == -ENOMEM && |
| 123 | rc = crst_table_upgrade(mm, addr + len); | 135 | !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { |
| 136 | /* Upgrade the page table to 4 levels and retry. */ | ||
| 137 | rc = crst_table_upgrade(mm, 1UL << 53); | ||
| 124 | if (rc) | 138 | if (rc) |
| 125 | return (unsigned long) rc; | 139 | return (unsigned long) rc; |
| 140 | area = arch_get_unmapped_area_topdown(filp, addr, len, | ||
| 141 | pgoff, flags); | ||
| 126 | } | 142 | } |
| 127 | return addr; | 143 | return area; |
| 128 | } | 144 | } |
| 129 | /* | 145 | /* |
| 130 | * This function, called very early during the creation of a new | 146 | * This function, called very early during the creation of a new |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0767827540b..6b6ddc4ea02 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -117,6 +117,7 @@ repeat: | |||
| 117 | crst_table_init(table, entry); | 117 | crst_table_init(table, entry); |
| 118 | pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); | 118 | pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); |
| 119 | mm->pgd = (pgd_t *) table; | 119 | mm->pgd = (pgd_t *) table; |
| 120 | mm->task_size = mm->context.asce_limit; | ||
| 120 | table = NULL; | 121 | table = NULL; |
| 121 | } | 122 | } |
| 122 | spin_unlock(&mm->page_table_lock); | 123 | spin_unlock(&mm->page_table_lock); |
| @@ -154,6 +155,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |||
| 154 | BUG(); | 155 | BUG(); |
| 155 | } | 156 | } |
| 156 | mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); | 157 | mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); |
| 158 | mm->task_size = mm->context.asce_limit; | ||
| 157 | crst_table_free(mm, (unsigned long *) pgd); | 159 | crst_table_free(mm, (unsigned long *) pgd); |
| 158 | } | 160 | } |
| 159 | update_mm(mm, current); | 161 | update_mm(mm, current); |
