diff options
author | David S. Miller <davem@davemloft.net> | 2009-03-26 15:23:24 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-26 15:23:24 -0700 |
commit | 08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6 (patch) | |
tree | 2be39bf8942edca1bcec735145e144a682ca9cd3 /arch/s390 | |
parent | f0de70f8bb56952f6e016a65a8a8d006918f5bf6 (diff) | |
parent | 0384e2959127a56d0640505d004d8dd92f9c29f5 (diff) | |
download | linux-3.10-08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6.tar.gz linux-3.10-08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6.tar.bz2 linux-3.10-08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6.zip |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts:
drivers/net/wimax/i2400m/usb-notif.c
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/crypto/sha.h | 6 | ||||
-rw-r--r-- | arch/s390/crypto/sha1_s390.c | 40 | ||||
-rw-r--r-- | arch/s390/crypto/sha256_s390.c | 40 | ||||
-rw-r--r-- | arch/s390/crypto/sha512_s390.c | 81 | ||||
-rw-r--r-- | arch/s390/crypto/sha_common.c | 20 | ||||
-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 |
13 files changed, 149 insertions, 126 deletions
diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h index 1ceafa571ea..f4e9dc71675 100644 --- a/arch/s390/crypto/sha.h +++ b/arch/s390/crypto/sha.h @@ -29,7 +29,9 @@ struct s390_sha_ctx { int func; /* KIMD function to use */ }; -void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len); -void s390_sha_final(struct crypto_tfm *tfm, u8 *out); +struct shash_desc; + +int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len); +int s390_sha_final(struct shash_desc *desc, u8 *out); #endif diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index b3cb5a89b00..e85ba348722 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c @@ -23,17 +23,17 @@ * any later version. * */ +#include <crypto/internal/hash.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/crypto.h> #include <crypto/sha.h> #include "crypt_s390.h" #include "sha.h" -static void sha1_init(struct crypto_tfm *tfm) +static int sha1_init(struct shash_desc *desc) { - struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_sha_ctx *sctx = shash_desc_ctx(desc); sctx->state[0] = SHA1_H0; sctx->state[1] = SHA1_H1; @@ -42,34 +42,36 @@ static void sha1_init(struct crypto_tfm *tfm) sctx->state[4] = SHA1_H4; sctx->count = 0; sctx->func = KIMD_SHA_1; + + return 0; } -static struct crypto_alg alg = { - .cra_name = "sha1", - .cra_driver_name= "sha1-s390", - .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_DIGEST, - .cra_blocksize = SHA1_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct s390_sha_ctx), - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(alg.cra_list), - .cra_u = { .digest = { - .dia_digestsize = SHA1_DIGEST_SIZE, - .dia_init = sha1_init, - .dia_update = s390_sha_update, - .dia_final = s390_sha_final } } +static struct shash_alg alg = { + .digestsize = SHA1_DIGEST_SIZE, + .init = sha1_init, + .update = s390_sha_update, + .final = s390_sha_final, + .descsize = sizeof(struct s390_sha_ctx), + .base = { + .cra_name = "sha1", + .cra_driver_name= "sha1-s390", + .cra_priority = CRYPT_S390_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } }; static int __init sha1_s390_init(void) { if (!crypt_s390_func_available(KIMD_SHA_1)) return -EOPNOTSUPP; - return crypto_register_alg(&alg); + return crypto_register_shash(&alg); } static void __exit sha1_s390_fini(void) { - crypto_unregister_alg(&alg); + crypto_unregister_shash(&alg); } module_init(sha1_s390_init); diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index 19c03fb6ba7..f9fefc56963 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c @@ -16,17 +16,17 @@ * any later version. * */ +#include <crypto/internal/hash.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/crypto.h> #include <crypto/sha.h> #include "crypt_s390.h" #include "sha.h" -static void sha256_init(struct crypto_tfm *tfm) +static int sha256_init(struct shash_desc *desc) { - struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_sha_ctx *sctx = shash_desc_ctx(desc); sctx->state[0] = SHA256_H0; sctx->state[1] = SHA256_H1; @@ -38,22 +38,24 @@ static void sha256_init(struct crypto_tfm *tfm) sctx->state[7] = SHA256_H7; sctx->count = 0; sctx->func = KIMD_SHA_256; + + return 0; } -static struct crypto_alg alg = { - .cra_name = "sha256", - .cra_driver_name = "sha256-s390", - .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_DIGEST, - .cra_blocksize = SHA256_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct s390_sha_ctx), - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(alg.cra_list), - .cra_u = { .digest = { - .dia_digestsize = SHA256_DIGEST_SIZE, - .dia_init = sha256_init, - .dia_update = s390_sha_update, - .dia_final = s390_sha_final } } +static struct shash_alg alg = { + .digestsize = SHA256_DIGEST_SIZE, + .init = sha256_init, + .update = s390_sha_update, + .final = s390_sha_final, + .descsize = sizeof(struct s390_sha_ctx), + .base = { + .cra_name = "sha256", + .cra_driver_name= "sha256-s390", + .cra_priority = CRYPT_S390_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } }; static int sha256_s390_init(void) @@ -61,12 +63,12 @@ static int sha256_s390_init(void) if (!crypt_s390_func_available(KIMD_SHA_256)) return -EOPNOTSUPP; - return crypto_register_alg(&alg); + return crypto_register_shash(&alg); } static void __exit sha256_s390_fini(void) { - crypto_unregister_alg(&alg); + crypto_unregister_shash(&alg); } module_init(sha256_s390_init); diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c index 23c7861f6ae..83192bfc804 100644 --- a/arch/s390/crypto/sha512_s390.c +++ b/arch/s390/crypto/sha512_s390.c @@ -12,16 +12,16 @@ * any later version. * */ +#include <crypto/internal/hash.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/crypto.h> #include "sha.h" #include "crypt_s390.h" -static void sha512_init(struct crypto_tfm *tfm) +static int sha512_init(struct shash_desc *desc) { - struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); + struct s390_sha_ctx *ctx = shash_desc_ctx(desc); *(__u64 *)&ctx->state[0] = 0x6a09e667f3bcc908ULL; *(__u64 *)&ctx->state[2] = 0xbb67ae8584caa73bULL; @@ -33,29 +33,31 @@ static void sha512_init(struct crypto_tfm *tfm) *(__u64 *)&ctx->state[14] = 0x5be0cd19137e2179ULL; ctx->count = 0; ctx->func = KIMD_SHA_512; + + return 0; } -static struct crypto_alg sha512_alg = { - .cra_name = "sha512", - .cra_driver_name = "sha512-s390", - .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_DIGEST, - .cra_blocksize = SHA512_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct s390_sha_ctx), - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(sha512_alg.cra_list), - .cra_u = { .digest = { - .dia_digestsize = SHA512_DIGEST_SIZE, - .dia_init = sha512_init, - .dia_update = s390_sha_update, - .dia_final = s390_sha_final } } +static struct shash_alg sha512_alg = { + .digestsize = SHA512_DIGEST_SIZE, + .init = sha512_init, + .update = s390_sha_update, + .final = s390_sha_final, + .descsize = sizeof(struct s390_sha_ctx), + .base = { + .cra_name = "sha512", + .cra_driver_name= "sha512-s390", + .cra_priority = CRYPT_S390_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } }; MODULE_ALIAS("sha512"); -static void sha384_init(struct crypto_tfm *tfm) +static int sha384_init(struct shash_desc *desc) { - struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); + struct s390_sha_ctx *ctx = shash_desc_ctx(desc); *(__u64 *)&ctx->state[0] = 0xcbbb9d5dc1059ed8ULL; *(__u64 *)&ctx->state[2] = 0x629a292a367cd507ULL; @@ -67,22 +69,25 @@ static void sha384_init(struct crypto_tfm *tfm) *(__u64 *)&ctx->state[14] = 0x47b5481dbefa4fa4ULL; ctx->count = 0; ctx->func = KIMD_SHA_512; + + return 0; } -static struct crypto_alg sha384_alg = { - .cra_name = "sha384", - .cra_driver_name = "sha384-s390", - .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_DIGEST, - .cra_blocksize = SHA384_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct s390_sha_ctx), - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(sha384_alg.cra_list), - .cra_u = { .digest = { - .dia_digestsize = SHA384_DIGEST_SIZE, - .dia_init = sha384_init, - .dia_update = s390_sha_update, - .dia_final = s390_sha_final } } +static struct shash_alg sha384_alg = { + .digestsize = SHA384_DIGEST_SIZE, + .init = sha384_init, + .update = s390_sha_update, + .final = s390_sha_final, + .descsize = sizeof(struct s390_sha_ctx), + .base = { + .cra_name = "sha384", + .cra_driver_name= "sha384-s390", + .cra_priority = CRYPT_S390_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct s390_sha_ctx), + .cra_module = THIS_MODULE, + } }; MODULE_ALIAS("sha384"); @@ -93,18 +98,18 @@ static int __init init(void) if (!crypt_s390_func_available(KIMD_SHA_512)) return -EOPNOTSUPP; - if ((ret = crypto_register_alg(&sha512_alg)) < 0) + if ((ret = crypto_register_shash(&sha512_alg)) < 0) goto out; - if ((ret = crypto_register_alg(&sha384_alg)) < 0) - crypto_unregister_alg(&sha512_alg); + if ((ret = crypto_register_shash(&sha384_alg)) < 0) + crypto_unregister_shash(&sha512_alg); out: return ret; } static void __exit fini(void) { - crypto_unregister_alg(&sha512_alg); - crypto_unregister_alg(&sha384_alg); + crypto_unregister_shash(&sha512_alg); + crypto_unregister_shash(&sha384_alg); } module_init(init); diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c index 9d6eb8c3d37..7903ec47e6b 100644 --- a/arch/s390/crypto/sha_common.c +++ b/arch/s390/crypto/sha_common.c @@ -13,14 +13,14 @@ * */ -#include <linux/crypto.h> +#include <crypto/internal/hash.h> #include "sha.h" #include "crypt_s390.h" -void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) +int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) { - struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + struct s390_sha_ctx *ctx = shash_desc_ctx(desc); + unsigned int bsize = crypto_shash_blocksize(desc->tfm); unsigned int index; int ret; @@ -51,13 +51,15 @@ void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) store: if (len) memcpy(ctx->buf + index , data, len); + + return 0; } EXPORT_SYMBOL_GPL(s390_sha_update); -void s390_sha_final(struct crypto_tfm *tfm, u8 *out) +int s390_sha_final(struct shash_desc *desc, u8 *out) { - struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + struct s390_sha_ctx *ctx = shash_desc_ctx(desc); + unsigned int bsize = crypto_shash_blocksize(desc->tfm); u64 bits; unsigned int index, end, plen; int ret; @@ -87,9 +89,11 @@ void s390_sha_final(struct crypto_tfm *tfm, u8 *out) BUG_ON(ret != end); /* copy digest to out */ - memcpy(out, ctx->state, crypto_hash_digestsize(crypto_hash_cast(tfm))); + memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); /* wipe context */ memset(ctx, 0, sizeof *ctx); + + return 0; } EXPORT_SYMBOL_GPL(s390_sha_final); 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 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ +#if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT) +int s390_mmap_check(unsigned long addr, unsigned long len); +#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len) +#endif + #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 *); extern int get_cpu_capability(unsigned int *); /* - * User space process size: 2GB for 31 bit, 4TB for 64 bit. + * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. */ #ifndef __s390x__ @@ -70,8 +70,7 @@ extern int get_cpu_capability(unsigned int *); #else /* __s390x__ */ -#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ - (1UL << 31) : (1UL << 53)) +#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #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) }; #endif +#define SD_MC_INIT SD_CPU_INIT + #include <asm-generic/topology.h> #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 @@ * */ +#include <asm/asm-offsets.h> + #ifndef CONFIG_64BIT .globl _mcount _mcount: @@ -14,7 +16,7 @@ _mcount: ahi %r15,-96 l %r3,100(%r15) la %r2,0(%r14) - st %r1,0(%r15) + st %r1,__SF_BACKCHAIN(%r15) la %r3,0(%r3) bras %r14,0f .long ftrace_trace_function @@ -38,7 +40,7 @@ _mcount: stg %r14,112(%r15) lgr %r1,%r15 aghi %r15,-160 - stg %r1,0(%r15) + stg %r1,__SF_BACKCHAIN(%r15) lgr %r2,%r14 lg %r3,168(%r15) 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) " clr %0,%3\n" " jl 0f\n" " slr %0,%3\n" - " alr %1,%2\n" + " ahi %1,1\n" "0:\n" : "+d" (reg2), "+d" (reg3), "=d" (tmp) : "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: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out; offset = uaddr & (PAGE_SIZE - 1); size = min(n - done, PAGE_SIZE - offset); @@ -135,7 +133,6 @@ retry: done += size; uaddr += size; } while (done < n); -out: spin_unlock(&mm->page_table_lock); return n - done; fault: @@ -163,9 +160,6 @@ retry: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out; - ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); out: return ret; @@ -244,11 +238,6 @@ retry: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) { - done = -1; - goto out; - } - offset = uaddr & (PAGE_SIZE-1); addr = (char *)(pfn << PAGE_SHIFT) + offset; len = min(count - done, PAGE_SIZE - offset); @@ -256,7 +245,6 @@ retry: done += len_str; uaddr += len_str; } while ((len_str == len) && (done < count)); -out: spin_unlock(&mm->page_table_lock); return done + 1; fault: @@ -325,12 +313,7 @@ retry: } pfn_from = pte_pfn(*pte_from); - if (!pfn_valid(pfn_from)) - goto out; pfn_to = pte_pfn(*pte_to); - if (!pfn_valid(pfn_to)) - goto out; - offset_from = uaddr_from & (PAGE_SIZE-1); offset_to = uaddr_from & (PAGE_SIZE-1); offset_max = max(offset_from, offset_to); @@ -342,7 +325,6 @@ retry: uaddr_from += size; uaddr_to += size; } while (done < n); -out: spin_unlock(&mm->page_table_lock); return n - done; 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 @@ * Leave an at least ~128 MB hole. */ #define MIN_GAP (128*1024*1024) -#define MAX_GAP (TASK_SIZE/6*5) +#define MAX_GAP (STACK_TOP/6*5) static inline unsigned long mmap_base(void) { @@ -46,7 +46,7 @@ static inline unsigned long mmap_base(void) else if (gap > MAX_GAP) gap = MAX_GAP; - return TASK_SIZE - (gap & PAGE_MASK); + return STACK_TOP - (gap & PAGE_MASK); } static inline int mmap_is_legacy(void) @@ -89,42 +89,58 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); #else +int s390_mmap_check(unsigned long addr, unsigned long len) +{ + if (!test_thread_flag(TIF_31BIT) && + len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) + return crst_table_upgrade(current->mm, 1UL << 53); + return 0; +} + static unsigned long s390_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; + unsigned long area; int rc; - addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags); - if (addr & ~PAGE_MASK) - return addr; - if (unlikely(mm->context.asce_limit < addr + len)) { - rc = crst_table_upgrade(mm, addr + len); + area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); + if (!(area & ~PAGE_MASK)) + return area; + if (area == -ENOMEM && + !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { + /* Upgrade the page table to 4 levels and retry. */ + rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; + area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); } - return addr; + return area; } static unsigned long -s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, const unsigned long len, const unsigned long pgoff, const unsigned long flags) { struct mm_struct *mm = current->mm; - unsigned long addr = addr0; + unsigned long area; int rc; - addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); - if (addr & ~PAGE_MASK) - return addr; - if (unlikely(mm->context.asce_limit < addr + len)) { - rc = crst_table_upgrade(mm, addr + len); + area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); + if (!(area & ~PAGE_MASK)) + return area; + if (area == -ENOMEM && + !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { + /* Upgrade the page table to 4 levels and retry. */ + rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; + area = arch_get_unmapped_area_topdown(filp, addr, len, + pgoff, flags); } - return addr; + return area; } /* * 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: crst_table_init(table, entry); pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); mm->pgd = (pgd_t *) table; + mm->task_size = mm->context.asce_limit; table = NULL; } spin_unlock(&mm->page_table_lock); @@ -154,6 +155,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) BUG(); } mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); + mm->task_size = mm->context.asce_limit; crst_table_free(mm, (unsigned long *) pgd); } update_mm(mm, current); |