diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
commit | befddb21c845f8fb49e637997891ef97c6a869dc (patch) | |
tree | 0e7629123184f2dd50291ad6d477b894175f0f26 /arch/sparc | |
parent | e716efde75267eab919cdb2bef5b2cb77f305326 (diff) | |
parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) |
Merge tag 'v3.8-rc4' into irq/core
Merge Linux 3.8-rc4 before pulling in new commits - we were on an old v3.7 base.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/sparc')
87 files changed, 718 insertions, 845 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index b6b442b0d793..9f2edb5c5551 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -20,6 +20,7 @@ config SPARC | |||
20 | select HAVE_ARCH_TRACEHOOK | 20 | select HAVE_ARCH_TRACEHOOK |
21 | select SYSCTL_EXCEPTION_TRACE | 21 | select SYSCTL_EXCEPTION_TRACE |
22 | select ARCH_WANT_OPTIONAL_GPIOLIB | 22 | select ARCH_WANT_OPTIONAL_GPIOLIB |
23 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
23 | select RTC_CLASS | 24 | select RTC_CLASS |
24 | select RTC_DRV_M48T59 | 25 | select RTC_DRV_M48T59 |
25 | select HAVE_IRQ_WORK | 26 | select HAVE_IRQ_WORK |
diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c index c0a798fcf030..bb7c95161d71 100644 --- a/arch/sparc/boot/piggyback.c +++ b/arch/sparc/boot/piggyback.c | |||
@@ -81,18 +81,18 @@ static void usage(void) | |||
81 | 81 | ||
82 | static int start_line(const char *line) | 82 | static int start_line(const char *line) |
83 | { | 83 | { |
84 | if (strcmp(line + 8, " T _start\n") == 0) | 84 | if (strcmp(line + 10, " _start\n") == 0) |
85 | return 1; | 85 | return 1; |
86 | else if (strcmp(line + 16, " T _start\n") == 0) | 86 | else if (strcmp(line + 18, " _start\n") == 0) |
87 | return 1; | 87 | return 1; |
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | 90 | ||
91 | static int end_line(const char *line) | 91 | static int end_line(const char *line) |
92 | { | 92 | { |
93 | if (strcmp(line + 8, " A _end\n") == 0) | 93 | if (strcmp(line + 10, " _end\n") == 0) |
94 | return 1; | 94 | return 1; |
95 | else if (strcmp (line + 16, " A _end\n") == 0) | 95 | else if (strcmp (line + 18, " _end\n") == 0) |
96 | return 1; | 96 | return 1; |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
@@ -100,8 +100,8 @@ static int end_line(const char *line) | |||
100 | /* | 100 | /* |
101 | * Find address for start and end in System.map. | 101 | * Find address for start and end in System.map. |
102 | * The file looks like this: | 102 | * The file looks like this: |
103 | * f0004000 T _start | 103 | * f0004000 ... _start |
104 | * f0379f79 A _end | 104 | * f0379f79 ... _end |
105 | * 1234567890123456 | 105 | * 1234567890123456 |
106 | * ^coloumn 1 | 106 | * ^coloumn 1 |
107 | * There is support for 64 bit addresses too. | 107 | * There is support for 64 bit addresses too. |
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 6ae1ad5e502b..5d469d81761f 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile | |||
@@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o | |||
13 | 13 | ||
14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o | 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
15 | 15 | ||
16 | sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o | 16 | sha1-sparc64-y := sha1_asm.o sha1_glue.o |
17 | sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o | 17 | sha256-sparc64-y := sha256_asm.o sha256_glue.o |
18 | sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o | 18 | sha512-sparc64-y := sha512_asm.o sha512_glue.o |
19 | md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o | 19 | md5-sparc64-y := md5_asm.o md5_glue.o |
20 | 20 | ||
21 | aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o | 21 | aes-sparc64-y := aes_asm.o aes_glue.o |
22 | des-sparc64-y := des_asm.o des_glue.o crop_devid.o | 22 | des-sparc64-y := des_asm.o des_glue.o |
23 | camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o | 23 | camellia-sparc64-y := camellia_asm.o camellia_glue.o |
24 | 24 | ||
25 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o | 25 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o |
diff --git a/arch/sparc/crypto/aes_asm.S b/arch/sparc/crypto/aes_asm.S index 23f6cbb910d3..1cda8aa7cb85 100644 --- a/arch/sparc/crypto/aes_asm.S +++ b/arch/sparc/crypto/aes_asm.S | |||
@@ -1024,7 +1024,11 @@ ENTRY(aes_sparc64_ecb_encrypt_256) | |||
1024 | add %o2, 0x20, %o2 | 1024 | add %o2, 0x20, %o2 |
1025 | brlz,pt %o3, 11f | 1025 | brlz,pt %o3, 11f |
1026 | nop | 1026 | nop |
1027 | 10: ldx [%o1 + 0x00], %g3 | 1027 | 10: ldd [%o0 + 0xd0], %f56 |
1028 | ldd [%o0 + 0xd8], %f58 | ||
1029 | ldd [%o0 + 0xe0], %f60 | ||
1030 | ldd [%o0 + 0xe8], %f62 | ||
1031 | ldx [%o1 + 0x00], %g3 | ||
1028 | ldx [%o1 + 0x08], %g7 | 1032 | ldx [%o1 + 0x08], %g7 |
1029 | xor %g1, %g3, %g3 | 1033 | xor %g1, %g3, %g3 |
1030 | xor %g2, %g7, %g7 | 1034 | xor %g2, %g7, %g7 |
@@ -1128,9 +1132,9 @@ ENTRY(aes_sparc64_ecb_decrypt_256) | |||
1128 | /* %o0=&key[key_len], %o1=input, %o2=output, %o3=len */ | 1132 | /* %o0=&key[key_len], %o1=input, %o2=output, %o3=len */ |
1129 | ldx [%o0 - 0x10], %g1 | 1133 | ldx [%o0 - 0x10], %g1 |
1130 | subcc %o3, 0x10, %o3 | 1134 | subcc %o3, 0x10, %o3 |
1135 | ldx [%o0 - 0x08], %g2 | ||
1131 | be 10f | 1136 | be 10f |
1132 | ldx [%o0 - 0x08], %g2 | 1137 | sub %o0, 0xf0, %o0 |
1133 | sub %o0, 0xf0, %o0 | ||
1134 | 1: ldx [%o1 + 0x00], %g3 | 1138 | 1: ldx [%o1 + 0x00], %g3 |
1135 | ldx [%o1 + 0x08], %g7 | 1139 | ldx [%o1 + 0x08], %g7 |
1136 | ldx [%o1 + 0x10], %o4 | 1140 | ldx [%o1 + 0x10], %o4 |
@@ -1154,7 +1158,11 @@ ENTRY(aes_sparc64_ecb_decrypt_256) | |||
1154 | add %o2, 0x20, %o2 | 1158 | add %o2, 0x20, %o2 |
1155 | brlz,pt %o3, 11f | 1159 | brlz,pt %o3, 11f |
1156 | nop | 1160 | nop |
1157 | 10: ldx [%o1 + 0x00], %g3 | 1161 | 10: ldd [%o0 + 0x18], %f56 |
1162 | ldd [%o0 + 0x10], %f58 | ||
1163 | ldd [%o0 + 0x08], %f60 | ||
1164 | ldd [%o0 + 0x00], %f62 | ||
1165 | ldx [%o1 + 0x00], %g3 | ||
1158 | ldx [%o1 + 0x08], %g7 | 1166 | ldx [%o1 + 0x08], %g7 |
1159 | xor %g1, %g3, %g3 | 1167 | xor %g1, %g3, %g3 |
1160 | xor %g2, %g7, %g7 | 1168 | xor %g2, %g7, %g7 |
@@ -1511,11 +1519,11 @@ ENTRY(aes_sparc64_ctr_crypt_256) | |||
1511 | add %o2, 0x20, %o2 | 1519 | add %o2, 0x20, %o2 |
1512 | brlz,pt %o3, 11f | 1520 | brlz,pt %o3, 11f |
1513 | nop | 1521 | nop |
1514 | ldd [%o0 + 0xd0], %f56 | 1522 | 10: ldd [%o0 + 0xd0], %f56 |
1515 | ldd [%o0 + 0xd8], %f58 | 1523 | ldd [%o0 + 0xd8], %f58 |
1516 | ldd [%o0 + 0xe0], %f60 | 1524 | ldd [%o0 + 0xe0], %f60 |
1517 | ldd [%o0 + 0xe8], %f62 | 1525 | ldd [%o0 + 0xe8], %f62 |
1518 | 10: xor %g1, %g3, %o5 | 1526 | xor %g1, %g3, %o5 |
1519 | MOVXTOD_O5_F0 | 1527 | MOVXTOD_O5_F0 |
1520 | xor %g2, %g7, %o5 | 1528 | xor %g2, %g7, %o5 |
1521 | MOVXTOD_O5_F2 | 1529 | MOVXTOD_O5_F2 |
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index 8f1c9980f637..503e6d96ad4e 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c | |||
@@ -222,6 +222,7 @@ static int ecb_encrypt(struct blkcipher_desc *desc, | |||
222 | 222 | ||
223 | blkcipher_walk_init(&walk, dst, src, nbytes); | 223 | blkcipher_walk_init(&walk, dst, src, nbytes); |
224 | err = blkcipher_walk_virt(desc, &walk); | 224 | err = blkcipher_walk_virt(desc, &walk); |
225 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
225 | 226 | ||
226 | ctx->ops->load_encrypt_keys(&ctx->key[0]); | 227 | ctx->ops->load_encrypt_keys(&ctx->key[0]); |
227 | while ((nbytes = walk.nbytes)) { | 228 | while ((nbytes = walk.nbytes)) { |
@@ -251,6 +252,7 @@ static int ecb_decrypt(struct blkcipher_desc *desc, | |||
251 | 252 | ||
252 | blkcipher_walk_init(&walk, dst, src, nbytes); | 253 | blkcipher_walk_init(&walk, dst, src, nbytes); |
253 | err = blkcipher_walk_virt(desc, &walk); | 254 | err = blkcipher_walk_virt(desc, &walk); |
255 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
254 | 256 | ||
255 | ctx->ops->load_decrypt_keys(&ctx->key[0]); | 257 | ctx->ops->load_decrypt_keys(&ctx->key[0]); |
256 | key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)]; | 258 | key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)]; |
@@ -280,6 +282,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc, | |||
280 | 282 | ||
281 | blkcipher_walk_init(&walk, dst, src, nbytes); | 283 | blkcipher_walk_init(&walk, dst, src, nbytes); |
282 | err = blkcipher_walk_virt(desc, &walk); | 284 | err = blkcipher_walk_virt(desc, &walk); |
285 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
283 | 286 | ||
284 | ctx->ops->load_encrypt_keys(&ctx->key[0]); | 287 | ctx->ops->load_encrypt_keys(&ctx->key[0]); |
285 | while ((nbytes = walk.nbytes)) { | 288 | while ((nbytes = walk.nbytes)) { |
@@ -309,6 +312,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc, | |||
309 | 312 | ||
310 | blkcipher_walk_init(&walk, dst, src, nbytes); | 313 | blkcipher_walk_init(&walk, dst, src, nbytes); |
311 | err = blkcipher_walk_virt(desc, &walk); | 314 | err = blkcipher_walk_virt(desc, &walk); |
315 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
312 | 316 | ||
313 | ctx->ops->load_decrypt_keys(&ctx->key[0]); | 317 | ctx->ops->load_decrypt_keys(&ctx->key[0]); |
314 | key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)]; | 318 | key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)]; |
@@ -329,6 +333,22 @@ static int cbc_decrypt(struct blkcipher_desc *desc, | |||
329 | return err; | 333 | return err; |
330 | } | 334 | } |
331 | 335 | ||
336 | static void ctr_crypt_final(struct crypto_sparc64_aes_ctx *ctx, | ||
337 | struct blkcipher_walk *walk) | ||
338 | { | ||
339 | u8 *ctrblk = walk->iv; | ||
340 | u64 keystream[AES_BLOCK_SIZE / sizeof(u64)]; | ||
341 | u8 *src = walk->src.virt.addr; | ||
342 | u8 *dst = walk->dst.virt.addr; | ||
343 | unsigned int nbytes = walk->nbytes; | ||
344 | |||
345 | ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk, | ||
346 | keystream, AES_BLOCK_SIZE); | ||
347 | crypto_xor((u8 *) keystream, src, nbytes); | ||
348 | memcpy(dst, keystream, nbytes); | ||
349 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | ||
350 | } | ||
351 | |||
332 | static int ctr_crypt(struct blkcipher_desc *desc, | 352 | static int ctr_crypt(struct blkcipher_desc *desc, |
333 | struct scatterlist *dst, struct scatterlist *src, | 353 | struct scatterlist *dst, struct scatterlist *src, |
334 | unsigned int nbytes) | 354 | unsigned int nbytes) |
@@ -338,10 +358,11 @@ static int ctr_crypt(struct blkcipher_desc *desc, | |||
338 | int err; | 358 | int err; |
339 | 359 | ||
340 | blkcipher_walk_init(&walk, dst, src, nbytes); | 360 | blkcipher_walk_init(&walk, dst, src, nbytes); |
341 | err = blkcipher_walk_virt(desc, &walk); | 361 | err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); |
362 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
342 | 363 | ||
343 | ctx->ops->load_encrypt_keys(&ctx->key[0]); | 364 | ctx->ops->load_encrypt_keys(&ctx->key[0]); |
344 | while ((nbytes = walk.nbytes)) { | 365 | while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { |
345 | unsigned int block_len = nbytes & AES_BLOCK_MASK; | 366 | unsigned int block_len = nbytes & AES_BLOCK_MASK; |
346 | 367 | ||
347 | if (likely(block_len)) { | 368 | if (likely(block_len)) { |
@@ -353,6 +374,10 @@ static int ctr_crypt(struct blkcipher_desc *desc, | |||
353 | nbytes &= AES_BLOCK_SIZE - 1; | 374 | nbytes &= AES_BLOCK_SIZE - 1; |
354 | err = blkcipher_walk_done(desc, &walk, nbytes); | 375 | err = blkcipher_walk_done(desc, &walk, nbytes); |
355 | } | 376 | } |
377 | if (walk.nbytes) { | ||
378 | ctr_crypt_final(ctx, &walk); | ||
379 | err = blkcipher_walk_done(desc, &walk, 0); | ||
380 | } | ||
356 | fprs_write(0); | 381 | fprs_write(0); |
357 | return err; | 382 | return err; |
358 | } | 383 | } |
@@ -418,7 +443,7 @@ static struct crypto_alg algs[] = { { | |||
418 | .cra_driver_name = "ctr-aes-sparc64", | 443 | .cra_driver_name = "ctr-aes-sparc64", |
419 | .cra_priority = SPARC_CR_OPCODE_PRIORITY, | 444 | .cra_priority = SPARC_CR_OPCODE_PRIORITY, |
420 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 445 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
421 | .cra_blocksize = AES_BLOCK_SIZE, | 446 | .cra_blocksize = 1, |
422 | .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx), | 447 | .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx), |
423 | .cra_alignmask = 7, | 448 | .cra_alignmask = 7, |
424 | .cra_type = &crypto_blkcipher_type, | 449 | .cra_type = &crypto_blkcipher_type, |
@@ -475,3 +500,5 @@ MODULE_LICENSE("GPL"); | |||
475 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); | 500 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); |
476 | 501 | ||
477 | MODULE_ALIAS("aes"); | 502 | MODULE_ALIAS("aes"); |
503 | |||
504 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c index 42905c084299..888f6260b4ec 100644 --- a/arch/sparc/crypto/camellia_glue.c +++ b/arch/sparc/crypto/camellia_glue.c | |||
@@ -98,6 +98,7 @@ static int __ecb_crypt(struct blkcipher_desc *desc, | |||
98 | 98 | ||
99 | blkcipher_walk_init(&walk, dst, src, nbytes); | 99 | blkcipher_walk_init(&walk, dst, src, nbytes); |
100 | err = blkcipher_walk_virt(desc, &walk); | 100 | err = blkcipher_walk_virt(desc, &walk); |
101 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
101 | 102 | ||
102 | if (encrypt) | 103 | if (encrypt) |
103 | key = &ctx->encrypt_key[0]; | 104 | key = &ctx->encrypt_key[0]; |
@@ -160,6 +161,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc, | |||
160 | 161 | ||
161 | blkcipher_walk_init(&walk, dst, src, nbytes); | 162 | blkcipher_walk_init(&walk, dst, src, nbytes); |
162 | err = blkcipher_walk_virt(desc, &walk); | 163 | err = blkcipher_walk_virt(desc, &walk); |
164 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
163 | 165 | ||
164 | key = &ctx->encrypt_key[0]; | 166 | key = &ctx->encrypt_key[0]; |
165 | camellia_sparc64_load_keys(key, ctx->key_len); | 167 | camellia_sparc64_load_keys(key, ctx->key_len); |
@@ -198,6 +200,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc, | |||
198 | 200 | ||
199 | blkcipher_walk_init(&walk, dst, src, nbytes); | 201 | blkcipher_walk_init(&walk, dst, src, nbytes); |
200 | err = blkcipher_walk_virt(desc, &walk); | 202 | err = blkcipher_walk_virt(desc, &walk); |
203 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
201 | 204 | ||
202 | key = &ctx->decrypt_key[0]; | 205 | key = &ctx->decrypt_key[0]; |
203 | camellia_sparc64_load_keys(key, ctx->key_len); | 206 | camellia_sparc64_load_keys(key, ctx->key_len); |
@@ -320,3 +323,5 @@ MODULE_LICENSE("GPL"); | |||
320 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); | 323 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); |
321 | 324 | ||
322 | MODULE_ALIAS("aes"); | 325 | MODULE_ALIAS("aes"); |
326 | |||
327 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c index 0bd89cea8d8e..5162fad912ce 100644 --- a/arch/sparc/crypto/crc32c_glue.c +++ b/arch/sparc/crypto/crc32c_glue.c | |||
@@ -177,3 +177,5 @@ MODULE_LICENSE("GPL"); | |||
177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); | 177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); |
178 | 178 | ||
179 | MODULE_ALIAS("crc32c"); | 179 | MODULE_ALIAS("crc32c"); |
180 | |||
181 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/des_asm.S b/arch/sparc/crypto/des_asm.S index 30b6e90b28b2..b5c8fc269b5f 100644 --- a/arch/sparc/crypto/des_asm.S +++ b/arch/sparc/crypto/des_asm.S | |||
@@ -376,6 +376,7 @@ ENTRY(des3_ede_sparc64_ecb_crypt) | |||
376 | 1: ldd [%o1 + 0x00], %f60 | 376 | 1: ldd [%o1 + 0x00], %f60 |
377 | DES3_LOOP_BODY(60) | 377 | DES3_LOOP_BODY(60) |
378 | std %f60, [%o2 + 0x00] | 378 | std %f60, [%o2 + 0x00] |
379 | add %o1, 0x08, %o1 | ||
379 | subcc %o3, 0x08, %o3 | 380 | subcc %o3, 0x08, %o3 |
380 | bne,pt %icc, 1b | 381 | bne,pt %icc, 1b |
381 | add %o2, 0x08, %o2 | 382 | add %o2, 0x08, %o2 |
diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c index c4940c2d3073..3065bc61f9d3 100644 --- a/arch/sparc/crypto/des_glue.c +++ b/arch/sparc/crypto/des_glue.c | |||
@@ -100,6 +100,7 @@ static int __ecb_crypt(struct blkcipher_desc *desc, | |||
100 | 100 | ||
101 | blkcipher_walk_init(&walk, dst, src, nbytes); | 101 | blkcipher_walk_init(&walk, dst, src, nbytes); |
102 | err = blkcipher_walk_virt(desc, &walk); | 102 | err = blkcipher_walk_virt(desc, &walk); |
103 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
103 | 104 | ||
104 | if (encrypt) | 105 | if (encrypt) |
105 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); | 106 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); |
@@ -147,6 +148,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc, | |||
147 | 148 | ||
148 | blkcipher_walk_init(&walk, dst, src, nbytes); | 149 | blkcipher_walk_init(&walk, dst, src, nbytes); |
149 | err = blkcipher_walk_virt(desc, &walk); | 150 | err = blkcipher_walk_virt(desc, &walk); |
151 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
150 | 152 | ||
151 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); | 153 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); |
152 | while ((nbytes = walk.nbytes)) { | 154 | while ((nbytes = walk.nbytes)) { |
@@ -177,6 +179,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc, | |||
177 | 179 | ||
178 | blkcipher_walk_init(&walk, dst, src, nbytes); | 180 | blkcipher_walk_init(&walk, dst, src, nbytes); |
179 | err = blkcipher_walk_virt(desc, &walk); | 181 | err = blkcipher_walk_virt(desc, &walk); |
182 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
180 | 183 | ||
181 | des_sparc64_load_keys(&ctx->decrypt_expkey[0]); | 184 | des_sparc64_load_keys(&ctx->decrypt_expkey[0]); |
182 | while ((nbytes = walk.nbytes)) { | 185 | while ((nbytes = walk.nbytes)) { |
@@ -266,6 +269,7 @@ static int __ecb3_crypt(struct blkcipher_desc *desc, | |||
266 | 269 | ||
267 | blkcipher_walk_init(&walk, dst, src, nbytes); | 270 | blkcipher_walk_init(&walk, dst, src, nbytes); |
268 | err = blkcipher_walk_virt(desc, &walk); | 271 | err = blkcipher_walk_virt(desc, &walk); |
272 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
269 | 273 | ||
270 | if (encrypt) | 274 | if (encrypt) |
271 | K = &ctx->encrypt_expkey[0]; | 275 | K = &ctx->encrypt_expkey[0]; |
@@ -317,6 +321,7 @@ static int cbc3_encrypt(struct blkcipher_desc *desc, | |||
317 | 321 | ||
318 | blkcipher_walk_init(&walk, dst, src, nbytes); | 322 | blkcipher_walk_init(&walk, dst, src, nbytes); |
319 | err = blkcipher_walk_virt(desc, &walk); | 323 | err = blkcipher_walk_virt(desc, &walk); |
324 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
320 | 325 | ||
321 | K = &ctx->encrypt_expkey[0]; | 326 | K = &ctx->encrypt_expkey[0]; |
322 | des3_ede_sparc64_load_keys(K); | 327 | des3_ede_sparc64_load_keys(K); |
@@ -352,6 +357,7 @@ static int cbc3_decrypt(struct blkcipher_desc *desc, | |||
352 | 357 | ||
353 | blkcipher_walk_init(&walk, dst, src, nbytes); | 358 | blkcipher_walk_init(&walk, dst, src, nbytes); |
354 | err = blkcipher_walk_virt(desc, &walk); | 359 | err = blkcipher_walk_virt(desc, &walk); |
360 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
355 | 361 | ||
356 | K = &ctx->decrypt_expkey[0]; | 362 | K = &ctx->decrypt_expkey[0]; |
357 | des3_ede_sparc64_load_keys(K); | 363 | des3_ede_sparc64_load_keys(K); |
@@ -527,3 +533,5 @@ MODULE_LICENSE("GPL"); | |||
527 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); | 533 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); |
528 | 534 | ||
529 | MODULE_ALIAS("des"); | 535 | MODULE_ALIAS("des"); |
536 | |||
537 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c index 603d723038ce..09a9ea1dfb69 100644 --- a/arch/sparc/crypto/md5_glue.c +++ b/arch/sparc/crypto/md5_glue.c | |||
@@ -186,3 +186,5 @@ MODULE_LICENSE("GPL"); | |||
186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); | 186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); |
187 | 187 | ||
188 | MODULE_ALIAS("md5"); | 188 | MODULE_ALIAS("md5"); |
189 | |||
190 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c index 2bbb20bee9f1..6cd5f29e1e0d 100644 --- a/arch/sparc/crypto/sha1_glue.c +++ b/arch/sparc/crypto/sha1_glue.c | |||
@@ -181,3 +181,5 @@ MODULE_LICENSE("GPL"); | |||
181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); | 181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); |
182 | 182 | ||
183 | MODULE_ALIAS("sha1"); | 183 | MODULE_ALIAS("sha1"); |
184 | |||
185 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c index 591e656bd891..04f555ab2680 100644 --- a/arch/sparc/crypto/sha256_glue.c +++ b/arch/sparc/crypto/sha256_glue.c | |||
@@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op | |||
239 | 239 | ||
240 | MODULE_ALIAS("sha224"); | 240 | MODULE_ALIAS("sha224"); |
241 | MODULE_ALIAS("sha256"); | 241 | MODULE_ALIAS("sha256"); |
242 | |||
243 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c index 486f0a2b7001..f04d1994d19a 100644 --- a/arch/sparc/crypto/sha512_glue.c +++ b/arch/sparc/crypto/sha512_glue.c | |||
@@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op | |||
224 | 224 | ||
225 | MODULE_ALIAS("sha384"); | 225 | MODULE_ALIAS("sha384"); |
226 | MODULE_ALIAS("sha512"); | 226 | MODULE_ALIAS("sha512"); |
227 | |||
228 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 645a58da0e86..e26d430ce2fd 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
@@ -8,4 +8,5 @@ generic-y += local64.h | |||
8 | generic-y += irq_regs.h | 8 | generic-y += irq_regs.h |
9 | generic-y += local.h | 9 | generic-y += local.h |
10 | generic-y += module.h | 10 | generic-y += module.h |
11 | generic-y += trace_clock.h | ||
11 | generic-y += word-at-a-time.h | 12 | generic-y += word-at-a-time.h |
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index ce35a1cf1a20..be56a244c9cf 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* atomic.h: Thankfully the V9 is at least reasonable for this | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
2 | * stuff. | 2 | * stuff. |
3 | * | 3 | * |
4 | * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __ARCH_SPARC64_ATOMIC__ | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
@@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) | |||
106 | 106 | ||
107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
108 | 108 | ||
109 | extern long atomic64_dec_if_positive(atomic64_t *v); | ||
110 | |||
109 | /* Atomic operations are already serializing */ | 111 | /* Atomic operations are already serializing */ |
110 | #define smp_mb__before_atomic_dec() barrier() | 112 | #define smp_mb__before_atomic_dec() barrier() |
111 | #define smp_mb__after_atomic_dec() barrier() | 113 | #define smp_mb__after_atomic_dec() barrier() |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index db3af0d30fb1..4e02086b839c 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -1,6 +1,46 @@ | |||
1 | #ifndef _SPARC64_BACKOFF_H | 1 | #ifndef _SPARC64_BACKOFF_H |
2 | #define _SPARC64_BACKOFF_H | 2 | #define _SPARC64_BACKOFF_H |
3 | 3 | ||
4 | /* The macros in this file implement an exponential backoff facility | ||
5 | * for atomic operations. | ||
6 | * | ||
7 | * When multiple threads compete on an atomic operation, it is | ||
8 | * possible for one thread to be continually denied a successful | ||
9 | * completion of the compare-and-swap instruction. Heavily | ||
10 | * threaded cpu implementations like Niagara can compound this | ||
11 | * problem even further. | ||
12 | * | ||
13 | * When an atomic operation fails and needs to be retried, we spin a | ||
14 | * certain number of times. At each subsequent failure of the same | ||
15 | * operation we double the spin count, realizing an exponential | ||
16 | * backoff. | ||
17 | * | ||
18 | * When we spin, we try to use an operation that will cause the | ||
19 | * current cpu strand to block, and therefore make the core fully | ||
20 | * available to any other other runnable strands. There are two | ||
21 | * options, based upon cpu capabilities. | ||
22 | * | ||
23 | * On all cpus prior to SPARC-T4 we do three dummy reads of the | ||
24 | * condition code register. Each read blocks the strand for something | ||
25 | * between 40 and 50 cpu cycles. | ||
26 | * | ||
27 | * For SPARC-T4 and later we have a special "pause" instruction | ||
28 | * available. This is implemented using writes to register %asr27. | ||
29 | * The cpu will block the number of cycles written into the register, | ||
30 | * unless a disrupting trap happens first. SPARC-T4 specifically | ||
31 | * implements pause with a granularity of 8 cycles. Each strand has | ||
32 | * an internal pause counter which decrements every 8 cycles. So the | ||
33 | * chip shifts the %asr27 value down by 3 bits, and writes the result | ||
34 | * into the pause counter. If a value smaller than 8 is written, the | ||
35 | * chip blocks for 1 cycle. | ||
36 | * | ||
37 | * To achieve the same amount of backoff as the three %ccr reads give | ||
38 | * on earlier chips, we shift the backoff value up by 7 bits. (Three | ||
39 | * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | ||
40 | * whole amount we want to block into the pause register, rather than | ||
41 | * loop writing 128 each time. | ||
42 | */ | ||
43 | |||
4 | #define BACKOFF_LIMIT (4 * 1024) | 44 | #define BACKOFF_LIMIT (4 * 1024) |
5 | 45 | ||
6 | #ifdef CONFIG_SMP | 46 | #ifdef CONFIG_SMP |
@@ -11,16 +51,25 @@ | |||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
12 | spin_label | 52 | spin_label |
13 | 53 | ||
14 | #define BACKOFF_SPIN(reg, tmp, label) \ | 54 | #define BACKOFF_SPIN(reg, tmp, label) \ |
15 | mov reg, tmp; \ | 55 | mov reg, tmp; \ |
16 | 88: brnz,pt tmp, 88b; \ | 56 | 88: rd %ccr, %g0; \ |
17 | sub tmp, 1, tmp; \ | 57 | rd %ccr, %g0; \ |
18 | set BACKOFF_LIMIT, tmp; \ | 58 | rd %ccr, %g0; \ |
19 | cmp reg, tmp; \ | 59 | .section .pause_3insn_patch,"ax";\ |
20 | bg,pn %xcc, label; \ | 60 | .word 88b; \ |
21 | nop; \ | 61 | sllx tmp, 7, tmp; \ |
22 | ba,pt %xcc, label; \ | 62 | wr tmp, 0, %asr27; \ |
23 | sllx reg, 1, reg; | 63 | clr tmp; \ |
64 | .previous; \ | ||
65 | brnz,pt tmp, 88b; \ | ||
66 | sub tmp, 1, tmp; \ | ||
67 | set BACKOFF_LIMIT, tmp; \ | ||
68 | cmp reg, tmp; \ | ||
69 | bg,pn %xcc, label; \ | ||
70 | nop; \ | ||
71 | ba,pt %xcc, label; \ | ||
72 | sllx reg, 1, reg; | ||
24 | 73 | ||
25 | #else | 74 | #else |
26 | 75 | ||
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index cef99fbc0a21..830502fe62b4 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h | |||
@@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
232 | struct pt_regs *regs = current_thread_info()->kregs; | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
233 | unsigned long usp = regs->u_regs[UREG_I6]; | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
234 | 234 | ||
235 | if (!(test_thread_flag(TIF_32BIT))) | 235 | if (test_thread_64bit_stack(usp)) |
236 | usp += STACK_BIAS; | 236 | usp += STACK_BIAS; |
237 | else | 237 | |
238 | if (test_thread_flag(TIF_32BIT)) | ||
238 | usp &= 0xffffffffUL; | 239 | usp &= 0xffffffffUL; |
239 | 240 | ||
240 | usp -= len; | 241 | usp -= len; |
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 8493fd3c7ba5..05fe53f5346e 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h | |||
@@ -59,6 +59,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, | |||
59 | 59 | ||
60 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 60 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
61 | { | 61 | { |
62 | debug_dma_mapping_error(dev, dma_addr); | ||
62 | return (dma_addr == DMA_ERROR_CODE); | 63 | return (dma_addr == DMA_ERROR_CODE); |
63 | } | 64 | } |
64 | 65 | ||
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index 8c5eed6d267f..9661e9bc7bb6 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h | |||
@@ -61,14 +61,20 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) | |||
61 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | 61 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, |
62 | unsigned long addr, pte_t *ptep) | 62 | unsigned long addr, pte_t *ptep) |
63 | { | 63 | { |
64 | ptep_set_wrprotect(mm, addr, ptep); | 64 | pte_t old_pte = *ptep; |
65 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | ||
65 | } | 66 | } |
66 | 67 | ||
67 | static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, | 68 | static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, |
68 | unsigned long addr, pte_t *ptep, | 69 | unsigned long addr, pte_t *ptep, |
69 | pte_t pte, int dirty) | 70 | pte_t pte, int dirty) |
70 | { | 71 | { |
71 | return ptep_set_access_flags(vma, addr, ptep, pte, dirty); | 72 | int changed = !pte_same(*ptep, pte); |
73 | if (changed) { | ||
74 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | ||
75 | flush_tlb_page(vma, addr); | ||
76 | } | ||
77 | return changed; | ||
72 | } | 78 | } |
73 | 79 | ||
74 | static inline pte_t huge_ptep_get(pte_t *ptep) | 80 | static inline pte_t huge_ptep_get(pte_t *ptep) |
diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index cb33608cc68f..c55291e5b83e 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h | |||
@@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr) | |||
103 | return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); | 103 | return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); |
104 | } | 104 | } |
105 | 105 | ||
106 | static int __devinit ecpp_probe(struct platform_device *op) | 106 | static int ecpp_probe(struct platform_device *op) |
107 | { | 107 | { |
108 | unsigned long base = op->resource[0].start; | 108 | unsigned long base = op->resource[0].start; |
109 | unsigned long config = op->resource[1].start; | 109 | unsigned long config = op->resource[1].start; |
@@ -192,7 +192,7 @@ out_err: | |||
192 | return err; | 192 | return err; |
193 | } | 193 | } |
194 | 194 | ||
195 | static int __devexit ecpp_remove(struct platform_device *op) | 195 | static int ecpp_remove(struct platform_device *op) |
196 | { | 196 | { |
197 | struct parport *p = dev_get_drvdata(&op->dev); | 197 | struct parport *p = dev_get_drvdata(&op->dev); |
198 | int slot = p->dma; | 198 | int slot = p->dma; |
@@ -242,7 +242,7 @@ static struct platform_driver ecpp_driver = { | |||
242 | .of_match_table = ecpp_match, | 242 | .of_match_table = ecpp_match, |
243 | }, | 243 | }, |
244 | .probe = ecpp_probe, | 244 | .probe = ecpp_probe, |
245 | .remove = __devexit_p(ecpp_remove), | 245 | .remove = ecpp_remove, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static int parport_pc_find_nonpci_ports(int autoirq, int autodma) | 248 | static int parport_pc_find_nonpci_ports(int autoirq, int autodma) |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 95515f1e7cef..7870be0f5adc 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -617,6 +617,12 @@ static inline unsigned long pte_present(pte_t pte) | |||
617 | return val; | 617 | return val; |
618 | } | 618 | } |
619 | 619 | ||
620 | #define pte_accessible pte_accessible | ||
621 | static inline unsigned long pte_accessible(pte_t a) | ||
622 | { | ||
623 | return pte_val(a) & _PAGE_VALID; | ||
624 | } | ||
625 | |||
620 | static inline unsigned long pte_special(pte_t pte) | 626 | static inline unsigned long pte_special(pte_t pte) |
621 | { | 627 | { |
622 | return pte_val(pte) & _PAGE_SPECIAL; | 628 | return pte_val(pte) & _PAGE_SPECIAL; |
@@ -802,7 +808,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
802 | * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U | 808 | * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U |
803 | * and SUN4V pte layout, so this inline test is fine. | 809 | * and SUN4V pte layout, so this inline test is fine. |
804 | */ | 810 | */ |
805 | if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID)) | 811 | if (likely(mm != &init_mm) && pte_accessible(orig)) |
806 | tlb_batch_add(mm, addr, ptep, orig, fullmm); | 812 | tlb_batch_add(mm, addr, ptep, orig, fullmm); |
807 | } | 813 | } |
808 | 814 | ||
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index f74ac9ee33a8..c1e01914fd98 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h | |||
@@ -106,7 +106,6 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc, | |||
106 | 106 | ||
107 | /* Free all resources held by a thread. */ | 107 | /* Free all resources held by a thread. */ |
108 | #define release_thread(tsk) do { } while(0) | 108 | #define release_thread(tsk) do { } while(0) |
109 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
110 | 109 | ||
111 | extern unsigned long get_wchan(struct task_struct *); | 110 | extern unsigned long get_wchan(struct task_struct *); |
112 | 111 | ||
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 4e5a483122a0..cce72ce4c334 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h | |||
@@ -94,6 +94,7 @@ struct thread_struct { | |||
94 | #ifndef __ASSEMBLY__ | 94 | #ifndef __ASSEMBLY__ |
95 | 95 | ||
96 | #include <linux/types.h> | 96 | #include <linux/types.h> |
97 | #include <asm/fpumacro.h> | ||
97 | 98 | ||
98 | /* Return saved PC of a blocked thread. */ | 99 | /* Return saved PC of a blocked thread. */ |
99 | struct task_struct; | 100 | struct task_struct; |
@@ -143,6 +144,10 @@ do { \ | |||
143 | : \ | 144 | : \ |
144 | : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ | 145 | : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ |
145 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ | 146 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ |
147 | fprs_write(0); \ | ||
148 | current_thread_info()->xfsr[0] = 0; \ | ||
149 | current_thread_info()->fpsaved[0] = 0; \ | ||
150 | regs->tstate &= ~TSTATE_PEF; \ | ||
146 | } while (0) | 151 | } while (0) |
147 | 152 | ||
148 | #define start_thread32(regs, pc, sp) \ | 153 | #define start_thread32(regs, pc, sp) \ |
@@ -183,20 +188,37 @@ do { \ | |||
183 | : \ | 188 | : \ |
184 | : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ | 189 | : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ |
185 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ | 190 | "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ |
191 | fprs_write(0); \ | ||
192 | current_thread_info()->xfsr[0] = 0; \ | ||
193 | current_thread_info()->fpsaved[0] = 0; \ | ||
194 | regs->tstate &= ~TSTATE_PEF; \ | ||
186 | } while (0) | 195 | } while (0) |
187 | 196 | ||
188 | /* Free all resources held by a thread. */ | 197 | /* Free all resources held by a thread. */ |
189 | #define release_thread(tsk) do { } while (0) | 198 | #define release_thread(tsk) do { } while (0) |
190 | 199 | ||
191 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
192 | |||
193 | extern unsigned long get_wchan(struct task_struct *task); | 200 | extern unsigned long get_wchan(struct task_struct *task); |
194 | 201 | ||
195 | #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs) | 202 | #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs) |
196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) | 203 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) | 204 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
198 | 205 | ||
199 | #define cpu_relax() barrier() | 206 | /* Please see the commentary in asm/backoff.h for a description of |
207 | * what these instructions are doing and how they have been choosen. | ||
208 | * To make a long story short, we are trying to yield the current cpu | ||
209 | * strand during busy loops. | ||
210 | */ | ||
211 | #define cpu_relax() asm volatile("\n99:\n\t" \ | ||
212 | "rd %%ccr, %%g0\n\t" \ | ||
213 | "rd %%ccr, %%g0\n\t" \ | ||
214 | "rd %%ccr, %%g0\n\t" \ | ||
215 | ".section .pause_3insn_patch,\"ax\"\n\t"\ | ||
216 | ".word 99b\n\t" \ | ||
217 | "wr %%g0, 128, %%asr27\n\t" \ | ||
218 | "nop\n\t" \ | ||
219 | "nop\n\t" \ | ||
220 | ".previous" \ | ||
221 | ::: "memory") | ||
200 | 222 | ||
201 | /* Prefetch support. This is tuned for UltraSPARC-III and later. | 223 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
202 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has | 224 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c28765110706..67c62578d170 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
@@ -63,5 +63,13 @@ extern char *of_console_options; | |||
63 | extern void irq_trans_init(struct device_node *dp); | 63 | extern void irq_trans_init(struct device_node *dp); |
64 | extern char *build_path_component(struct device_node *dp); | 64 | extern char *build_path_component(struct device_node *dp); |
65 | 65 | ||
66 | /* SPARC has local implementations */ | ||
67 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
68 | struct resource *r); | ||
69 | #define of_address_to_resource of_address_to_resource | ||
70 | |||
71 | void __iomem *of_iomap(struct device_node *node, int index); | ||
72 | #define of_iomap of_iomap | ||
73 | |||
66 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
67 | #endif /* _SPARC_PROM_H */ | 75 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index da43bdc62294..bdfafd7af46f 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h | |||
@@ -32,6 +32,9 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | |||
32 | #define arch_ptrace_stop(exit_code, info) \ | 32 | #define arch_ptrace_stop(exit_code, info) \ |
33 | synchronize_user_stack() | 33 | synchronize_user_stack() |
34 | 34 | ||
35 | #define current_pt_regs() \ | ||
36 | ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) | ||
37 | |||
35 | struct global_reg_snapshot { | 38 | struct global_reg_snapshot { |
36 | unsigned long tstate; | 39 | unsigned long tstate; |
37 | unsigned long tpc; | 40 | unsigned long tpc; |
@@ -55,9 +58,7 @@ union global_cpu_snapshot { | |||
55 | 58 | ||
56 | extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS]; | 59 | extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS]; |
57 | 60 | ||
58 | #define force_successful_syscall_return() \ | 61 | #define force_successful_syscall_return() set_thread_noerror(1) |
59 | do { current_thread_info()->syscall_noerror = 1; \ | ||
60 | } while (0) | ||
61 | #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) | 62 | #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) |
62 | #define instruction_pointer(regs) ((regs)->tpc) | 63 | #define instruction_pointer(regs) ((regs)->tpc) |
63 | #define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) | 64 | #define instruction_pointer_set(regs, val) ((regs)->tpc = (val)) |
@@ -100,6 +101,9 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs) | |||
100 | #define arch_ptrace_stop(exit_code, info) \ | 101 | #define arch_ptrace_stop(exit_code, info) \ |
101 | synchronize_user_stack() | 102 | synchronize_user_stack() |
102 | 103 | ||
104 | #define current_pt_regs() \ | ||
105 | ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) | ||
106 | |||
103 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) | 107 | #define user_mode(regs) (!((regs)->psr & PSR_PS)) |
104 | #define instruction_pointer(regs) ((regs)->pc) | 108 | #define instruction_pointer(regs) ((regs)->pc) |
105 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) | 109 | #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) |
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h index d243c2ae02d2..77b85850d543 100644 --- a/arch/sparc/include/asm/signal.h +++ b/arch/sparc/include/asm/signal.h | |||
@@ -26,7 +26,5 @@ struct k_sigaction { | |||
26 | void __user *ka_restorer; | 26 | void __user *ka_restorer; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
30 | |||
31 | #endif /* !(__ASSEMBLY__) */ | 29 | #endif /* !(__ASSEMBLY__) */ |
32 | #endif /* !(__SPARC_SIGNAL_H) */ | 30 | #endif /* !(__SPARC_SIGNAL_H) */ |
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index 7923c4a2be38..cad36f56fa03 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h | |||
@@ -23,7 +23,7 @@ do { flush_tlb_pending(); \ | |||
23 | /* If you are tempted to conditionalize the following */ \ | 23 | /* If you are tempted to conditionalize the following */ \ |
24 | /* so that ASI is only written if it changes, think again. */ \ | 24 | /* so that ASI is only written if it changes, think again. */ \ |
25 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ | 25 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ |
26 | : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ | 26 | : : "r" (task_thread_info(next)->current_ds));\ |
27 | trap_block[current_thread_info()->cpu].thread = \ | 27 | trap_block[current_thread_info()->cpu].thread = \ |
28 | task_thread_info(next); \ | 28 | task_thread_info(next); \ |
29 | __asm__ __volatile__( \ | 29 | __asm__ __volatile__( \ |
diff --git a/arch/sparc/include/asm/syscalls.h b/arch/sparc/include/asm/syscalls.h index 45a43f637a14..bf8972adea17 100644 --- a/arch/sparc/include/asm/syscalls.h +++ b/arch/sparc/include/asm/syscalls.h | |||
@@ -8,6 +8,4 @@ extern asmlinkage long sparc_do_fork(unsigned long clone_flags, | |||
8 | struct pt_regs *regs, | 8 | struct pt_regs *regs, |
9 | unsigned long stack_size); | 9 | unsigned long stack_size); |
10 | 10 | ||
11 | extern asmlinkage int sparc_execve(struct pt_regs *regs); | ||
12 | |||
13 | #endif /* _SPARC64_SYSCALLS_H */ | 11 | #endif /* _SPARC64_SYSCALLS_H */ |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 4e2276631081..269bd92313df 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
@@ -14,12 +14,12 @@ | |||
14 | #define TI_FLAG_FAULT_CODE_SHIFT 56 | 14 | #define TI_FLAG_FAULT_CODE_SHIFT 56 |
15 | #define TI_FLAG_BYTE_WSTATE 1 | 15 | #define TI_FLAG_BYTE_WSTATE 1 |
16 | #define TI_FLAG_WSTATE_SHIFT 48 | 16 | #define TI_FLAG_WSTATE_SHIFT 48 |
17 | #define TI_FLAG_BYTE_CWP 2 | 17 | #define TI_FLAG_BYTE_NOERROR 2 |
18 | #define TI_FLAG_CWP_SHIFT 40 | 18 | #define TI_FLAG_BYTE_NOERROR_SHIFT 40 |
19 | #define TI_FLAG_BYTE_CURRENT_DS 3 | 19 | #define TI_FLAG_BYTE_FPDEPTH 3 |
20 | #define TI_FLAG_CURRENT_DS_SHIFT 32 | 20 | #define TI_FLAG_FPDEPTH_SHIFT 32 |
21 | #define TI_FLAG_BYTE_FPDEPTH 4 | 21 | #define TI_FLAG_BYTE_CWP 4 |
22 | #define TI_FLAG_FPDEPTH_SHIFT 24 | 22 | #define TI_FLAG_CWP_SHIFT 24 |
23 | #define TI_FLAG_BYTE_WSAVED 5 | 23 | #define TI_FLAG_BYTE_WSAVED 5 |
24 | #define TI_FLAG_WSAVED_SHIFT 16 | 24 | #define TI_FLAG_WSAVED_SHIFT 16 |
25 | 25 | ||
@@ -47,7 +47,7 @@ struct thread_info { | |||
47 | struct exec_domain *exec_domain; | 47 | struct exec_domain *exec_domain; |
48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 48 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
49 | __u8 new_child; | 49 | __u8 new_child; |
50 | __u8 syscall_noerror; | 50 | __u8 current_ds; |
51 | __u16 cpu; | 51 | __u16 cpu; |
52 | 52 | ||
53 | unsigned long *utraps; | 53 | unsigned long *utraps; |
@@ -74,9 +74,9 @@ struct thread_info { | |||
74 | #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) | 74 | #define TI_FAULT_CODE (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE) |
75 | #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) | 75 | #define TI_WSTATE (TI_FLAGS + TI_FLAG_BYTE_WSTATE) |
76 | #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) | 76 | #define TI_CWP (TI_FLAGS + TI_FLAG_BYTE_CWP) |
77 | #define TI_CURRENT_DS (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS) | ||
78 | #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) | 77 | #define TI_FPDEPTH (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH) |
79 | #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) | 78 | #define TI_WSAVED (TI_FLAGS + TI_FLAG_BYTE_WSAVED) |
79 | #define TI_SYS_NOERROR (TI_FLAGS + TI_FLAG_BYTE_NOERROR) | ||
80 | #define TI_FPSAVED 0x00000010 | 80 | #define TI_FPSAVED 0x00000010 |
81 | #define TI_KSP 0x00000018 | 81 | #define TI_KSP 0x00000018 |
82 | #define TI_FAULT_ADDR 0x00000020 | 82 | #define TI_FAULT_ADDR 0x00000020 |
@@ -84,7 +84,7 @@ struct thread_info { | |||
84 | #define TI_EXEC_DOMAIN 0x00000030 | 84 | #define TI_EXEC_DOMAIN 0x00000030 |
85 | #define TI_PRE_COUNT 0x00000038 | 85 | #define TI_PRE_COUNT 0x00000038 |
86 | #define TI_NEW_CHILD 0x0000003c | 86 | #define TI_NEW_CHILD 0x0000003c |
87 | #define TI_SYS_NOERROR 0x0000003d | 87 | #define TI_CURRENT_DS 0x0000003d |
88 | #define TI_CPU 0x0000003e | 88 | #define TI_CPU 0x0000003e |
89 | #define TI_UTRAPS 0x00000040 | 89 | #define TI_UTRAPS 0x00000040 |
90 | #define TI_REG_WINDOW 0x00000048 | 90 | #define TI_REG_WINDOW 0x00000048 |
@@ -121,7 +121,7 @@ struct thread_info { | |||
121 | #define INIT_THREAD_INFO(tsk) \ | 121 | #define INIT_THREAD_INFO(tsk) \ |
122 | { \ | 122 | { \ |
123 | .task = &tsk, \ | 123 | .task = &tsk, \ |
124 | .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ | 124 | .current_ds = ASI_P, \ |
125 | .exec_domain = &default_exec_domain, \ | 125 | .exec_domain = &default_exec_domain, \ |
126 | .preempt_count = INIT_PREEMPT_COUNT, \ | 126 | .preempt_count = INIT_PREEMPT_COUNT, \ |
127 | .restart_block = { \ | 127 | .restart_block = { \ |
@@ -153,13 +153,12 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
153 | #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) | 153 | #define set_thread_wstate(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val)) |
154 | #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) | 154 | #define get_thread_cwp() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP]) |
155 | #define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) | 155 | #define set_thread_cwp(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val)) |
156 | #define get_thread_current_ds() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS]) | 156 | #define get_thread_noerror() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR]) |
157 | #define set_thread_current_ds(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val)) | 157 | #define set_thread_noerror(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_NOERROR] = (val)) |
158 | #define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) | 158 | #define get_thread_fpdepth() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH]) |
159 | #define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) | 159 | #define set_thread_fpdepth(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val)) |
160 | #define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) | 160 | #define get_thread_wsaved() (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED]) |
161 | #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) | 161 | #define set_thread_wsaved(val) (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val)) |
162 | |||
163 | #endif /* !(__ASSEMBLY__) */ | 162 | #endif /* !(__ASSEMBLY__) */ |
164 | 163 | ||
165 | /* | 164 | /* |
@@ -259,6 +258,11 @@ static inline bool test_and_clear_restore_sigmask(void) | |||
259 | 258 | ||
260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) | 259 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) |
261 | 260 | ||
261 | #define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) | ||
262 | #define test_thread_64bit_stack(__SP) \ | ||
263 | ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ | ||
264 | false : true) | ||
265 | |||
262 | #endif /* !__ASSEMBLY__ */ | 266 | #endif /* !__ASSEMBLY__ */ |
263 | 267 | ||
264 | #endif /* __KERNEL__ */ | 268 | #endif /* __KERNEL__ */ |
diff --git a/arch/sparc/include/asm/timer_64.h b/arch/sparc/include/asm/timer_64.h index ef3c3682debf..01197d8215c4 100644 --- a/arch/sparc/include/asm/timer_64.h +++ b/arch/sparc/include/asm/timer_64.h | |||
@@ -24,7 +24,7 @@ struct sparc64_tick_ops { | |||
24 | extern struct sparc64_tick_ops *tick_ops; | 24 | extern struct sparc64_tick_ops *tick_ops; |
25 | 25 | ||
26 | extern unsigned long sparc64_get_clock_tick(unsigned int cpu); | 26 | extern unsigned long sparc64_get_clock_tick(unsigned int cpu); |
27 | extern void __devinit setup_sparc64_timer(void); | 27 | extern void setup_sparc64_timer(void); |
28 | extern void __init time_init(void); | 28 | extern void __init time_init(void); |
29 | 29 | ||
30 | #endif /* _SPARC64_TIMER_H */ | 30 | #endif /* _SPARC64_TIMER_H */ |
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 48f2807d3265..71b5a67522ab 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h | |||
@@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ | |||
372 | 372 | ||
373 | /* Normal 32bit spill */ | 373 | /* Normal 32bit spill */ |
374 | #define SPILL_2_GENERIC(ASI) \ | 374 | #define SPILL_2_GENERIC(ASI) \ |
375 | srl %sp, 0, %sp; \ | 375 | and %sp, 1, %g3; \ |
376 | brnz,pn %g3, (. - (128 + 4)); \ | ||
377 | srl %sp, 0, %sp; \ | ||
376 | stwa %l0, [%sp + %g0] ASI; \ | 378 | stwa %l0, [%sp + %g0] ASI; \ |
377 | mov 0x04, %g3; \ | 379 | mov 0x04, %g3; \ |
378 | stwa %l1, [%sp + %g3] ASI; \ | 380 | stwa %l1, [%sp + %g3] ASI; \ |
@@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ | |||
398 | stwa %i6, [%g1 + %g0] ASI; \ | 400 | stwa %i6, [%g1 + %g0] ASI; \ |
399 | stwa %i7, [%g1 + %g3] ASI; \ | 401 | stwa %i7, [%g1 + %g3] ASI; \ |
400 | saved; \ | 402 | saved; \ |
401 | retry; nop; nop; \ | 403 | retry; \ |
402 | b,a,pt %xcc, spill_fixup_dax; \ | 404 | b,a,pt %xcc, spill_fixup_dax; \ |
403 | b,a,pt %xcc, spill_fixup_mna; \ | 405 | b,a,pt %xcc, spill_fixup_mna; \ |
404 | b,a,pt %xcc, spill_fixup; | 406 | b,a,pt %xcc, spill_fixup; |
405 | 407 | ||
406 | #define SPILL_2_GENERIC_ETRAP \ | 408 | #define SPILL_2_GENERIC_ETRAP \ |
407 | etrap_user_spill_32bit: \ | 409 | etrap_user_spill_32bit: \ |
408 | srl %sp, 0, %sp; \ | 410 | and %sp, 1, %g3; \ |
411 | brnz,pn %g3, etrap_user_spill_64bit; \ | ||
412 | srl %sp, 0, %sp; \ | ||
409 | stwa %l0, [%sp + 0x00] %asi; \ | 413 | stwa %l0, [%sp + 0x00] %asi; \ |
410 | stwa %l1, [%sp + 0x04] %asi; \ | 414 | stwa %l1, [%sp + 0x04] %asi; \ |
411 | stwa %l2, [%sp + 0x08] %asi; \ | 415 | stwa %l2, [%sp + 0x08] %asi; \ |
@@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ | |||
427 | ba,pt %xcc, etrap_save; \ | 431 | ba,pt %xcc, etrap_save; \ |
428 | wrpr %g1, %cwp; \ | 432 | wrpr %g1, %cwp; \ |
429 | nop; nop; nop; nop; \ | 433 | nop; nop; nop; nop; \ |
430 | nop; nop; nop; nop; \ | 434 | nop; nop; \ |
431 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 435 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
432 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 436 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
433 | ba,a,pt %xcc, etrap_spill_fixup_32bit; | 437 | ba,a,pt %xcc, etrap_spill_fixup_32bit; |
@@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ | |||
592 | 596 | ||
593 | /* Normal 32bit fill */ | 597 | /* Normal 32bit fill */ |
594 | #define FILL_2_GENERIC(ASI) \ | 598 | #define FILL_2_GENERIC(ASI) \ |
595 | srl %sp, 0, %sp; \ | 599 | and %sp, 1, %g3; \ |
600 | brnz,pn %g3, (. - (128 + 4)); \ | ||
601 | srl %sp, 0, %sp; \ | ||
596 | lduwa [%sp + %g0] ASI, %l0; \ | 602 | lduwa [%sp + %g0] ASI, %l0; \ |
597 | mov 0x04, %g2; \ | 603 | mov 0x04, %g2; \ |
598 | mov 0x08, %g3; \ | 604 | mov 0x08, %g3; \ |
@@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ | |||
616 | lduwa [%g1 + %g3] ASI, %i6; \ | 622 | lduwa [%g1 + %g3] ASI, %i6; \ |
617 | lduwa [%g1 + %g5] ASI, %i7; \ | 623 | lduwa [%g1 + %g5] ASI, %i7; \ |
618 | restored; \ | 624 | restored; \ |
619 | retry; nop; nop; nop; nop; \ | 625 | retry; nop; nop; \ |
620 | b,a,pt %xcc, fill_fixup_dax; \ | 626 | b,a,pt %xcc, fill_fixup_dax; \ |
621 | b,a,pt %xcc, fill_fixup_mna; \ | 627 | b,a,pt %xcc, fill_fixup_mna; \ |
622 | b,a,pt %xcc, fill_fixup; | 628 | b,a,pt %xcc, fill_fixup; |
623 | 629 | ||
624 | #define FILL_2_GENERIC_RTRAP \ | 630 | #define FILL_2_GENERIC_RTRAP \ |
625 | user_rtt_fill_32bit: \ | 631 | user_rtt_fill_32bit: \ |
626 | srl %sp, 0, %sp; \ | 632 | and %sp, 1, %g3; \ |
633 | brnz,pn %g3, user_rtt_fill_64bit; \ | ||
634 | srl %sp, 0, %sp; \ | ||
627 | lduwa [%sp + 0x00] %asi, %l0; \ | 635 | lduwa [%sp + 0x00] %asi, %l0; \ |
628 | lduwa [%sp + 0x04] %asi, %l1; \ | 636 | lduwa [%sp + 0x04] %asi, %l1; \ |
629 | lduwa [%sp + 0x08] %asi, %l2; \ | 637 | lduwa [%sp + 0x08] %asi, %l2; \ |
@@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ | |||
643 | ba,pt %xcc, user_rtt_pre_restore; \ | 651 | ba,pt %xcc, user_rtt_pre_restore; \ |
644 | restored; \ | 652 | restored; \ |
645 | nop; nop; nop; nop; nop; \ | 653 | nop; nop; nop; nop; nop; \ |
646 | nop; nop; nop; nop; nop; \ | 654 | nop; nop; nop; \ |
647 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 655 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
648 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 656 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
649 | ba,a,pt %xcc, user_rtt_fill_fixup; | 657 | ba,a,pt %xcc, user_rtt_fill_fixup; |
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 73083e1d38d9..e562d3caee57 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
@@ -38,14 +38,14 @@ | |||
38 | #define VERIFY_READ 0 | 38 | #define VERIFY_READ 0 |
39 | #define VERIFY_WRITE 1 | 39 | #define VERIFY_WRITE 1 |
40 | 40 | ||
41 | #define get_fs() ((mm_segment_t) { get_thread_current_ds() }) | 41 | #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) |
42 | #define get_ds() (KERNEL_DS) | 42 | #define get_ds() (KERNEL_DS) |
43 | 43 | ||
44 | #define segment_eq(a,b) ((a).seg == (b).seg) | 44 | #define segment_eq(a,b) ((a).seg == (b).seg) |
45 | 45 | ||
46 | #define set_fs(val) \ | 46 | #define set_fs(val) \ |
47 | do { \ | 47 | do { \ |
48 | set_thread_current_ds((val).seg); \ | 48 | current_thread_info()->current_ds =(val).seg; \ |
49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ | 49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ |
50 | } while(0) | 50 | } while(0) |
51 | 51 | ||
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 0ecea6ed943e..87ce24c5eb95 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define __ARCH_WANT_COMPAT_SYS_TIME | 45 | #define __ARCH_WANT_COMPAT_SYS_TIME |
46 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | 46 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND |
47 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | 47 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE |
48 | #define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL | ||
48 | #endif | 49 | #endif |
49 | 50 | ||
50 | /* | 51 | /* |
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 9155f7041d44..897d1723fa14 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #define TCSETSF2 _IOW('T', 15, struct termios2) | 21 | #define TCSETSF2 _IOW('T', 15, struct termios2) |
22 | #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ | 22 | #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ |
23 | #define TIOCVHANGUP _IO('T', 0x37) | 23 | #define TIOCVHANGUP _IO('T', 0x37) |
24 | #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ | ||
25 | #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ | ||
26 | #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ | ||
24 | 27 | ||
25 | /* Note that all the ioctls that are not available in Linux have a | 28 | /* Note that all the ioctls that are not available in Linux have a |
26 | * double underscore on the front to: a) avoid some programs to | 29 | * double underscore on the front to: a) avoid some programs to |
diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h index 1a041892538f..c4ffd6c97106 100644 --- a/arch/sparc/include/uapi/asm/signal.h +++ b/arch/sparc/include/uapi/asm/signal.h | |||
@@ -147,12 +147,6 @@ struct sigstack { | |||
147 | #define SIG_UNBLOCK 0x02 /* for unblocking signals */ | 147 | #define SIG_UNBLOCK 0x02 /* for unblocking signals */ |
148 | #define SIG_SETMASK 0x04 /* for setting the signal mask */ | 148 | #define SIG_SETMASK 0x04 /* for setting the signal mask */ |
149 | 149 | ||
150 | /* | ||
151 | * sigaltstack controls | ||
152 | */ | ||
153 | #define SS_ONSTACK 1 | ||
154 | #define SS_DISABLE 2 | ||
155 | |||
156 | #define MINSIGSTKSZ 4096 | 150 | #define MINSIGSTKSZ 4096 |
157 | #define SIGSTKSZ 16384 | 151 | #define SIGSTKSZ 16384 |
158 | 152 | ||
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index bea1568ae4af..c83a937ead00 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | #define SO_ATTACH_FILTER 0x001a | 42 | #define SO_ATTACH_FILTER 0x001a |
43 | #define SO_DETACH_FILTER 0x001b | 43 | #define SO_DETACH_FILTER 0x001b |
44 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
44 | 45 | ||
45 | #define SO_PEERNAME 0x001c | 46 | #define SO_PEERNAME 0x001c |
46 | #define SO_TIMESTAMP 0x001d | 47 | #define SO_TIMESTAMP 0x001d |
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 8974ef7ae920..62ced589bcf7 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h | |||
@@ -405,8 +405,14 @@ | |||
405 | #define __NR_setns 337 | 405 | #define __NR_setns 337 |
406 | #define __NR_process_vm_readv 338 | 406 | #define __NR_process_vm_readv 338 |
407 | #define __NR_process_vm_writev 339 | 407 | #define __NR_process_vm_writev 339 |
408 | #define __NR_kern_features 340 | ||
409 | #define __NR_kcmp 341 | ||
410 | #define __NR_finit_module 342 | ||
408 | 411 | ||
409 | #define NR_syscalls 340 | 412 | #define NR_syscalls 343 |
413 | |||
414 | /* Bitmask values returned from kern_features system call. */ | ||
415 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | ||
410 | 416 | ||
411 | #ifdef __32bit_syscall_numbers__ | 417 | #ifdef __32bit_syscall_numbers__ |
412 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 418 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 812e10bbb0b3..348fa1aeabce 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define APC_DEVNAME "apc" | 31 | #define APC_DEVNAME "apc" |
32 | 32 | ||
33 | static u8 __iomem *regs; | 33 | static u8 __iomem *regs; |
34 | static int apc_no_idle __devinitdata = 0; | 34 | static int apc_no_idle = 0; |
35 | 35 | ||
36 | #define apc_readb(offs) (sbus_readb(regs+offs)) | 36 | #define apc_readb(offs) (sbus_readb(regs+offs)) |
37 | #define apc_writeb(val, offs) (sbus_writeb(val, regs+offs)) | 37 | #define apc_writeb(val, offs) (sbus_writeb(val, regs+offs)) |
@@ -138,7 +138,7 @@ static const struct file_operations apc_fops = { | |||
138 | 138 | ||
139 | static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; | 139 | static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; |
140 | 140 | ||
141 | static int __devinit apc_probe(struct platform_device *op) | 141 | static int apc_probe(struct platform_device *op) |
142 | { | 142 | { |
143 | int err; | 143 | int err; |
144 | 144 | ||
diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 773091ac71a3..86e55778e4af 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c | |||
@@ -102,7 +102,7 @@ static const struct of_device_id auxio_match[] = { | |||
102 | 102 | ||
103 | MODULE_DEVICE_TABLE(of, auxio_match); | 103 | MODULE_DEVICE_TABLE(of, auxio_match); |
104 | 104 | ||
105 | static int __devinit auxio_probe(struct platform_device *dev) | 105 | static int auxio_probe(struct platform_device *dev) |
106 | { | 106 | { |
107 | struct device_node *dp = dev->dev.of_node; | 107 | struct device_node *dp = dev->dev.of_node; |
108 | unsigned long size; | 108 | unsigned long size; |
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 9708851a8b9f..052b5a44318f 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c | |||
@@ -33,7 +33,7 @@ struct fhc { | |||
33 | struct platform_device leds_pdev; | 33 | struct platform_device leds_pdev; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static int __devinit clock_board_calc_nslots(struct clock_board *p) | 36 | static int clock_board_calc_nslots(struct clock_board *p) |
37 | { | 37 | { |
38 | u8 reg = upa_readb(p->clock_regs + CLOCK_STAT1) & 0xc0; | 38 | u8 reg = upa_readb(p->clock_regs + CLOCK_STAT1) & 0xc0; |
39 | 39 | ||
@@ -60,7 +60,7 @@ static int __devinit clock_board_calc_nslots(struct clock_board *p) | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | static int __devinit clock_board_probe(struct platform_device *op) | 63 | static int clock_board_probe(struct platform_device *op) |
64 | { | 64 | { |
65 | struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); | 65 | struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); |
66 | int err = -ENOMEM; | 66 | int err = -ENOMEM; |
@@ -157,7 +157,7 @@ static struct platform_driver clock_board_driver = { | |||
157 | }, | 157 | }, |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static int __devinit fhc_probe(struct platform_device *op) | 160 | static int fhc_probe(struct platform_device *op) |
161 | { | 161 | { |
162 | struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); | 162 | struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); |
163 | int err = -ENOMEM; | 163 | int err = -ENOMEM; |
diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 5f450260981d..dbb210d74e21 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c | |||
@@ -336,9 +336,9 @@ static int jbusmc_print_dimm(int syndrome_code, | |||
336 | return 0; | 336 | return 0; |
337 | } | 337 | } |
338 | 338 | ||
339 | static u64 __devinit jbusmc_dimm_group_size(u64 base, | 339 | static u64 jbusmc_dimm_group_size(u64 base, |
340 | const struct linux_prom64_registers *mem_regs, | 340 | const struct linux_prom64_registers *mem_regs, |
341 | int num_mem_regs) | 341 | int num_mem_regs) |
342 | { | 342 | { |
343 | u64 max = base + (8UL * 1024 * 1024 * 1024); | 343 | u64 max = base + (8UL * 1024 * 1024 * 1024); |
344 | u64 max_seen = base; | 344 | u64 max_seen = base; |
@@ -363,10 +363,10 @@ static u64 __devinit jbusmc_dimm_group_size(u64 base, | |||
363 | return max_seen - base; | 363 | return max_seen - base; |
364 | } | 364 | } |
365 | 365 | ||
366 | static void __devinit jbusmc_construct_one_dimm_group(struct jbusmc *p, | 366 | static void jbusmc_construct_one_dimm_group(struct jbusmc *p, |
367 | unsigned long index, | 367 | unsigned long index, |
368 | const struct linux_prom64_registers *mem_regs, | 368 | const struct linux_prom64_registers *mem_regs, |
369 | int num_mem_regs) | 369 | int num_mem_regs) |
370 | { | 370 | { |
371 | struct jbusmc_dimm_group *dp = &p->dimm_groups[index]; | 371 | struct jbusmc_dimm_group *dp = &p->dimm_groups[index]; |
372 | 372 | ||
@@ -378,9 +378,9 @@ static void __devinit jbusmc_construct_one_dimm_group(struct jbusmc *p, | |||
378 | dp->size = jbusmc_dimm_group_size(dp->base_addr, mem_regs, num_mem_regs); | 378 | dp->size = jbusmc_dimm_group_size(dp->base_addr, mem_regs, num_mem_regs); |
379 | } | 379 | } |
380 | 380 | ||
381 | static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p, | 381 | static void jbusmc_construct_dimm_groups(struct jbusmc *p, |
382 | const struct linux_prom64_registers *mem_regs, | 382 | const struct linux_prom64_registers *mem_regs, |
383 | int num_mem_regs) | 383 | int num_mem_regs) |
384 | { | 384 | { |
385 | if (p->mc_reg_1 & JB_MC_REG1_DIMM1_BANK0) { | 385 | if (p->mc_reg_1 & JB_MC_REG1_DIMM1_BANK0) { |
386 | jbusmc_construct_one_dimm_group(p, 0, mem_regs, num_mem_regs); | 386 | jbusmc_construct_one_dimm_group(p, 0, mem_regs, num_mem_regs); |
@@ -392,7 +392,7 @@ static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p, | |||
392 | } | 392 | } |
393 | } | 393 | } |
394 | 394 | ||
395 | static int __devinit jbusmc_probe(struct platform_device *op) | 395 | static int jbusmc_probe(struct platform_device *op) |
396 | { | 396 | { |
397 | const struct linux_prom64_registers *mem_regs; | 397 | const struct linux_prom64_registers *mem_regs; |
398 | struct device_node *mem_node; | 398 | struct device_node *mem_node; |
@@ -689,7 +689,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) | |||
689 | chmc_read_mcreg(p, CHMCTRL_DECODE4)); | 689 | chmc_read_mcreg(p, CHMCTRL_DECODE4)); |
690 | } | 690 | } |
691 | 691 | ||
692 | static int __devinit chmc_probe(struct platform_device *op) | 692 | static int chmc_probe(struct platform_device *op) |
693 | { | 693 | { |
694 | struct device_node *dp = op->dev.of_node; | 694 | struct device_node *dp = op->dev.of_node; |
695 | unsigned long ver; | 695 | unsigned long ver; |
@@ -763,7 +763,7 @@ out_free: | |||
763 | goto out; | 763 | goto out; |
764 | } | 764 | } |
765 | 765 | ||
766 | static int __devinit us3mc_probe(struct platform_device *op) | 766 | static int us3mc_probe(struct platform_device *op) |
767 | { | 767 | { |
768 | if (mc_type == MC_TYPE_SAFARI) | 768 | if (mc_type == MC_TYPE_SAFARI) |
769 | return chmc_probe(op); | 769 | return chmc_probe(op); |
@@ -772,21 +772,21 @@ static int __devinit us3mc_probe(struct platform_device *op) | |||
772 | return -ENODEV; | 772 | return -ENODEV; |
773 | } | 773 | } |
774 | 774 | ||
775 | static void __devexit chmc_destroy(struct platform_device *op, struct chmc *p) | 775 | static void chmc_destroy(struct platform_device *op, struct chmc *p) |
776 | { | 776 | { |
777 | list_del(&p->list); | 777 | list_del(&p->list); |
778 | of_iounmap(&op->resource[0], p->regs, 0x48); | 778 | of_iounmap(&op->resource[0], p->regs, 0x48); |
779 | kfree(p); | 779 | kfree(p); |
780 | } | 780 | } |
781 | 781 | ||
782 | static void __devexit jbusmc_destroy(struct platform_device *op, struct jbusmc *p) | 782 | static void jbusmc_destroy(struct platform_device *op, struct jbusmc *p) |
783 | { | 783 | { |
784 | mc_list_del(&p->list); | 784 | mc_list_del(&p->list); |
785 | of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE); | 785 | of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE); |
786 | kfree(p); | 786 | kfree(p); |
787 | } | 787 | } |
788 | 788 | ||
789 | static int __devexit us3mc_remove(struct platform_device *op) | 789 | static int us3mc_remove(struct platform_device *op) |
790 | { | 790 | { |
791 | void *p = dev_get_drvdata(&op->dev); | 791 | void *p = dev_get_drvdata(&op->dev); |
792 | 792 | ||
@@ -814,7 +814,7 @@ static struct platform_driver us3mc_driver = { | |||
814 | .of_match_table = us3mc_match, | 814 | .of_match_table = us3mc_match, |
815 | }, | 815 | }, |
816 | .probe = us3mc_probe, | 816 | .probe = us3mc_probe, |
817 | .remove = __devexit_p(us3mc_remove), | 817 | .remove = us3mc_remove, |
818 | }; | 818 | }; |
819 | 819 | ||
820 | static inline bool us3mc_platform(void) | 820 | static inline bool us3mc_platform(void) |
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index f09257c86107..75bb608c423e 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #define DRV_MODULE_VERSION "1.0" | 29 | #define DRV_MODULE_VERSION "1.0" |
30 | #define DRV_MODULE_RELDATE "Jul 11, 2007" | 30 | #define DRV_MODULE_RELDATE "Jul 11, 2007" |
31 | 31 | ||
32 | static char version[] __devinitdata = | 32 | static char version[] = |
33 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 33 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
34 | MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); | 34 | MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); |
35 | MODULE_DESCRIPTION("Sun LDOM domain services driver"); | 35 | MODULE_DESCRIPTION("Sun LDOM domain services driver"); |
@@ -1146,8 +1146,7 @@ static void ds_event(void *arg, int event) | |||
1146 | spin_unlock_irqrestore(&ds_lock, flags); | 1146 | spin_unlock_irqrestore(&ds_lock, flags); |
1147 | } | 1147 | } |
1148 | 1148 | ||
1149 | static int __devinit ds_probe(struct vio_dev *vdev, | 1149 | static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id) |
1150 | const struct vio_device_id *id) | ||
1151 | { | 1150 | { |
1152 | static int ds_version_printed; | 1151 | static int ds_version_printed; |
1153 | struct ldc_channel_config ds_cfg = { | 1152 | struct ldc_channel_config ds_cfg = { |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index dcaa1cf0de40..21fd1a8f47d2 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -806,23 +806,10 @@ sys_nis_syscall: | |||
806 | call c_sys_nis_syscall | 806 | call c_sys_nis_syscall |
807 | mov %l5, %o7 | 807 | mov %l5, %o7 |
808 | 808 | ||
809 | .align 4 | ||
810 | .globl sys_execve | ||
811 | sys_execve: | ||
812 | mov %o7, %l5 | ||
813 | add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg | ||
814 | call sparc_execve | ||
815 | mov %l5, %o7 | ||
816 | |||
817 | .globl sunos_execv | ||
818 | sunos_execv: | 809 | sunos_execv: |
819 | st %g0, [%sp + STACKFRAME_SZ + PT_I2] | 810 | .globl sunos_execv |
820 | 811 | b sys_execve | |
821 | call sparc_execve | 812 | clr %i2 |
822 | add %sp, STACKFRAME_SZ, %o0 | ||
823 | |||
824 | b ret_sys_call | ||
825 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 | ||
826 | 813 | ||
827 | .align 4 | 814 | .align 4 |
828 | .globl sys_sparc_pipe | 815 | .globl sys_sparc_pipe |
@@ -959,17 +946,9 @@ flush_patch_four: | |||
959 | .align 4 | 946 | .align 4 |
960 | linux_sparc_ni_syscall: | 947 | linux_sparc_ni_syscall: |
961 | sethi %hi(sys_ni_syscall), %l7 | 948 | sethi %hi(sys_ni_syscall), %l7 |
962 | b syscall_is_too_hard | 949 | b do_syscall |
963 | or %l7, %lo(sys_ni_syscall), %l7 | 950 | or %l7, %lo(sys_ni_syscall), %l7 |
964 | 951 | ||
965 | linux_fast_syscall: | ||
966 | andn %l7, 3, %l7 | ||
967 | mov %i0, %o0 | ||
968 | mov %i1, %o1 | ||
969 | mov %i2, %o2 | ||
970 | jmpl %l7 + %g0, %g0 | ||
971 | mov %i3, %o3 | ||
972 | |||
973 | linux_syscall_trace: | 952 | linux_syscall_trace: |
974 | add %sp, STACKFRAME_SZ, %o0 | 953 | add %sp, STACKFRAME_SZ, %o0 |
975 | call syscall_trace | 954 | call syscall_trace |
@@ -991,6 +970,23 @@ ret_from_fork: | |||
991 | b ret_sys_call | 970 | b ret_sys_call |
992 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 | 971 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 |
993 | 972 | ||
973 | .globl ret_from_kernel_thread | ||
974 | ret_from_kernel_thread: | ||
975 | call schedule_tail | ||
976 | ld [%g3 + TI_TASK], %o0 | ||
977 | ld [%sp + STACKFRAME_SZ + PT_G1], %l0 | ||
978 | call %l0 | ||
979 | ld [%sp + STACKFRAME_SZ + PT_G2], %o0 | ||
980 | rd %psr, %l1 | ||
981 | ld [%sp + STACKFRAME_SZ + PT_PSR], %l0 | ||
982 | andn %l0, PSR_CWP, %l0 | ||
983 | nop | ||
984 | and %l1, PSR_CWP, %l1 | ||
985 | or %l0, %l1, %l0 | ||
986 | st %l0, [%sp + STACKFRAME_SZ + PT_PSR] | ||
987 | b ret_sys_call | ||
988 | mov 0, %o0 | ||
989 | |||
994 | /* Linux native system calls enter here... */ | 990 | /* Linux native system calls enter here... */ |
995 | .align 4 | 991 | .align 4 |
996 | .globl linux_sparc_syscall | 992 | .globl linux_sparc_syscall |
@@ -1002,11 +998,8 @@ linux_sparc_syscall: | |||
1002 | bgeu linux_sparc_ni_syscall | 998 | bgeu linux_sparc_ni_syscall |
1003 | sll %g1, 2, %l4 | 999 | sll %g1, 2, %l4 |
1004 | ld [%l7 + %l4], %l7 | 1000 | ld [%l7 + %l4], %l7 |
1005 | andcc %l7, 1, %g0 | ||
1006 | bne linux_fast_syscall | ||
1007 | /* Just do first insn from SAVE_ALL in the delay slot */ | ||
1008 | 1001 | ||
1009 | syscall_is_too_hard: | 1002 | do_syscall: |
1010 | SAVE_ALL_HEAD | 1003 | SAVE_ALL_HEAD |
1011 | rd %wim, %l3 | 1004 | rd %wim, %l3 |
1012 | 1005 | ||
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 0c218e4c0881..cc3c5cb47cda 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
@@ -59,6 +59,13 @@ struct popc_6insn_patch_entry { | |||
59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, | 59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, |
60 | __popc_6insn_patch_end; | 60 | __popc_6insn_patch_end; |
61 | 61 | ||
62 | struct pause_patch_entry { | ||
63 | unsigned int addr; | ||
64 | unsigned int insns[3]; | ||
65 | }; | ||
66 | extern struct pause_patch_entry __pause_3insn_patch, | ||
67 | __pause_3insn_patch_end; | ||
68 | |||
62 | extern void __init per_cpu_patch(void); | 69 | extern void __init per_cpu_patch(void); |
63 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, | 70 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, |
64 | struct sun4v_1insn_patch_entry *); | 71 | struct sun4v_1insn_patch_entry *); |
diff --git a/arch/sparc/kernel/etrap_64.S b/arch/sparc/kernel/etrap_64.S index 786b185e6e3f..1276ca2567ba 100644 --- a/arch/sparc/kernel/etrap_64.S +++ b/arch/sparc/kernel/etrap_64.S | |||
@@ -92,8 +92,10 @@ etrap_save: save %g2, -STACK_BIAS, %sp | |||
92 | rdpr %wstate, %g2 | 92 | rdpr %wstate, %g2 |
93 | wrpr %g0, 0, %canrestore | 93 | wrpr %g0, 0, %canrestore |
94 | sll %g2, 3, %g2 | 94 | sll %g2, 3, %g2 |
95 | |||
96 | /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */ | ||
95 | mov 1, %l5 | 97 | mov 1, %l5 |
96 | stb %l5, [%l6 + TI_FPDEPTH] | 98 | sth %l5, [%l6 + TI_SYS_NOERROR] |
97 | 99 | ||
98 | wrpr %g3, 0, %otherwin | 100 | wrpr %g3, 0, %otherwin |
99 | wrpr %g2, 0, %wstate | 101 | wrpr %g2, 0, %wstate |
@@ -152,7 +154,9 @@ etrap_save: save %g2, -STACK_BIAS, %sp | |||
152 | add %l6, TI_FPSAVED + 1, %l4 | 154 | add %l6, TI_FPSAVED + 1, %l4 |
153 | srl %l5, 1, %l3 | 155 | srl %l5, 1, %l3 |
154 | add %l5, 2, %l5 | 156 | add %l5, 2, %l5 |
155 | stb %l5, [%l6 + TI_FPDEPTH] | 157 | |
158 | /* Set TI_SYS_FPDEPTH to %l5 and clear TI_SYS_NOERROR. */ | ||
159 | sth %l5, [%l6 + TI_SYS_NOERROR] | ||
156 | ba,pt %xcc, 2b | 160 | ba,pt %xcc, 2b |
157 | stb %g0, [%l4 + %l3] | 161 | stb %g0, [%l4 + %l3] |
158 | nop | 162 | nop |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 81d92fc9983b..9fcc6b4e93b3 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #define DRV_MODULE_VERSION "1.1" | 27 | #define DRV_MODULE_VERSION "1.1" |
28 | #define DRV_MODULE_RELDATE "July 22, 2008" | 28 | #define DRV_MODULE_RELDATE "July 22, 2008" |
29 | 29 | ||
30 | static char version[] __devinitdata = | 30 | static char version[] = |
31 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 31 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
32 | #define LDC_PACKET_SIZE 64 | 32 | #define LDC_PACKET_SIZE 64 |
33 | 33 | ||
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index f8b6eee40bde..87f60ee65433 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) | |||
56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) | 56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) |
57 | { | 57 | { |
58 | unsigned int eirq; | 58 | unsigned int eirq; |
59 | struct irq_bucket *p; | ||
59 | int cpu = sparc_leon3_cpuid(); | 60 | int cpu = sparc_leon3_cpuid(); |
60 | 61 | ||
61 | eirq = leon_eirq_get(cpu); | 62 | eirq = leon_eirq_get(cpu); |
62 | if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ | 63 | p = irq_map[eirq]; |
63 | generic_handle_irq(irq_map[eirq]->irq); | 64 | if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ |
65 | generic_handle_irq(p->irq); | ||
64 | } | 66 | } |
65 | 67 | ||
66 | /* The extended IRQ controller has been found, this function registers it */ | 68 | /* The extended IRQ controller has been found, this function registers it */ |
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index fc0521161568..852dc8430528 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c | |||
@@ -43,7 +43,7 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) | |||
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 | ||
46 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) | 46 | void pcibios_fixup_bus(struct pci_bus *pbus) |
47 | { | 47 | { |
48 | struct pci_dev *dev; | 48 | struct pci_dev *dev; |
49 | int i, has_io, has_mem; | 49 | int i, has_io, has_mem; |
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index b1bc38853a3d..fc4320886a3a 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c | |||
@@ -668,7 +668,7 @@ static irqreturn_t grpci2_err_interrupt(int irq, void *arg) | |||
668 | return IRQ_HANDLED; | 668 | return IRQ_HANDLED; |
669 | } | 669 | } |
670 | 670 | ||
671 | static int __devinit grpci2_of_probe(struct platform_device *ofdev) | 671 | static int grpci2_of_probe(struct platform_device *ofdev) |
672 | { | 672 | { |
673 | struct grpci2_regs *regs; | 673 | struct grpci2_regs *regs; |
674 | struct grpci2_priv *priv; | 674 | struct grpci2_priv *priv; |
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index f1ddc0d23679..4435488ebe25 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
@@ -43,10 +43,6 @@ void *module_alloc(unsigned long size) | |||
43 | { | 43 | { |
44 | void *ret; | 44 | void *ret; |
45 | 45 | ||
46 | /* We handle the zero case fine, unlike vmalloc */ | ||
47 | if (size == 0) | ||
48 | return NULL; | ||
49 | |||
50 | ret = module_map(size); | 46 | ret = module_map(size); |
51 | if (ret) | 47 | if (ret) |
52 | memset(ret, 0, size); | 48 | memset(ret, 0, size); |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 75b31bcdeadf..baf4366e2d6a 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -356,7 +356,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
356 | return dev; | 356 | return dev; |
357 | } | 357 | } |
358 | 358 | ||
359 | static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) | 359 | static void apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) |
360 | { | 360 | { |
361 | u32 idx, first, last; | 361 | u32 idx, first, last; |
362 | 362 | ||
@@ -378,9 +378,9 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) | |||
378 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 378 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
379 | * a proper 'ranges' property. | 379 | * a proper 'ranges' property. |
380 | */ | 380 | */ |
381 | static void __devinit apb_fake_ranges(struct pci_dev *dev, | 381 | static void apb_fake_ranges(struct pci_dev *dev, |
382 | struct pci_bus *bus, | 382 | struct pci_bus *bus, |
383 | struct pci_pbm_info *pbm) | 383 | struct pci_pbm_info *pbm) |
384 | { | 384 | { |
385 | struct pci_bus_region region; | 385 | struct pci_bus_region region; |
386 | struct resource *res; | 386 | struct resource *res; |
@@ -404,15 +404,15 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, | |||
404 | pcibios_bus_to_resource(dev, res, ®ion); | 404 | pcibios_bus_to_resource(dev, res, ®ion); |
405 | } | 405 | } |
406 | 406 | ||
407 | static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | 407 | static void pci_of_scan_bus(struct pci_pbm_info *pbm, |
408 | struct device_node *node, | 408 | struct device_node *node, |
409 | struct pci_bus *bus); | 409 | struct pci_bus *bus); |
410 | 410 | ||
411 | #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) | 411 | #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) |
412 | 412 | ||
413 | static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | 413 | static void of_scan_pci_bridge(struct pci_pbm_info *pbm, |
414 | struct device_node *node, | 414 | struct device_node *node, |
415 | struct pci_dev *dev) | 415 | struct pci_dev *dev) |
416 | { | 416 | { |
417 | struct pci_bus *bus; | 417 | struct pci_bus *bus; |
418 | const u32 *busrange, *ranges; | 418 | const u32 *busrange, *ranges; |
@@ -503,9 +503,9 @@ after_ranges: | |||
503 | pci_of_scan_bus(pbm, node, bus); | 503 | pci_of_scan_bus(pbm, node, bus); |
504 | } | 504 | } |
505 | 505 | ||
506 | static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | 506 | static void pci_of_scan_bus(struct pci_pbm_info *pbm, |
507 | struct device_node *node, | 507 | struct device_node *node, |
508 | struct pci_bus *bus) | 508 | struct pci_bus *bus) |
509 | { | 509 | { |
510 | struct device_node *child; | 510 | struct device_node *child; |
511 | const u32 *reg; | 511 | const u32 *reg; |
@@ -564,7 +564,7 @@ show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * | |||
564 | 564 | ||
565 | static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, NULL); | 565 | static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, NULL); |
566 | 566 | ||
567 | static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) | 567 | static void pci_bus_register_of_sysfs(struct pci_bus *bus) |
568 | { | 568 | { |
569 | struct pci_dev *dev; | 569 | struct pci_dev *dev; |
570 | struct pci_bus *child_bus; | 570 | struct pci_bus *child_bus; |
@@ -585,8 +585,8 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) | |||
585 | pci_bus_register_of_sysfs(child_bus); | 585 | pci_bus_register_of_sysfs(child_bus); |
586 | } | 586 | } |
587 | 587 | ||
588 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, | 588 | struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, |
589 | struct device *parent) | 589 | struct device *parent) |
590 | { | 590 | { |
591 | LIST_HEAD(resources); | 591 | LIST_HEAD(resources); |
592 | struct device_node *node = pbm->op->dev.of_node; | 592 | struct device_node *node = pbm->op->dev.of_node; |
@@ -618,7 +618,7 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, | |||
618 | return bus; | 618 | return bus; |
619 | } | 619 | } |
620 | 620 | ||
621 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) | 621 | void pcibios_fixup_bus(struct pci_bus *pbus) |
622 | { | 622 | { |
623 | } | 623 | } |
624 | 624 | ||
@@ -949,8 +949,7 @@ static int __init pcibios_init(void) | |||
949 | subsys_initcall(pcibios_init); | 949 | subsys_initcall(pcibios_init); |
950 | 950 | ||
951 | #ifdef CONFIG_SYSFS | 951 | #ifdef CONFIG_SYSFS |
952 | static void __devinit pci_bus_slot_names(struct device_node *node, | 952 | static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) |
953 | struct pci_bus *bus) | ||
954 | { | 953 | { |
955 | const struct pci_slot_names { | 954 | const struct pci_slot_names { |
956 | u32 slot_mask; | 955 | u32 slot_mask; |
diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 188f935276fd..e60fc6a67e9b 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c | |||
@@ -408,8 +408,8 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) | |||
408 | upa_writeq(~(u64)0, pbm->pbm_regs + FIRE_PEC_IENAB); | 408 | upa_writeq(~(u64)0, pbm->pbm_regs + FIRE_PEC_IENAB); |
409 | } | 409 | } |
410 | 410 | ||
411 | static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, | 411 | static int pci_fire_pbm_init(struct pci_pbm_info *pbm, |
412 | struct platform_device *op, u32 portid) | 412 | struct platform_device *op, u32 portid) |
413 | { | 413 | { |
414 | const struct linux_prom64_registers *regs; | 414 | const struct linux_prom64_registers *regs; |
415 | struct device_node *dp = op->dev.of_node; | 415 | struct device_node *dp = op->dev.of_node; |
@@ -454,7 +454,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, | |||
454 | return 0; | 454 | return 0; |
455 | } | 455 | } |
456 | 456 | ||
457 | static int __devinit fire_probe(struct platform_device *op) | 457 | static int fire_probe(struct platform_device *op) |
458 | { | 458 | { |
459 | struct device_node *dp = op->dev.of_node; | 459 | struct device_node *dp = op->dev.of_node; |
460 | struct pci_pbm_info *pbm; | 460 | struct pci_pbm_info *pbm; |
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 918a2031c8bb..5f688531f48c 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h | |||
@@ -88,7 +88,7 @@ struct pci_pbm_info { | |||
88 | int chip_revision; | 88 | int chip_revision; |
89 | 89 | ||
90 | /* Name used for top-level resources. */ | 90 | /* Name used for top-level resources. */ |
91 | char *name; | 91 | const char *name; |
92 | 92 | ||
93 | /* OBP specific information. */ | 93 | /* OBP specific information. */ |
94 | struct platform_device *op; | 94 | struct platform_device *op; |
diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index f4d29e15ce71..c647634ead2b 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c | |||
@@ -366,8 +366,8 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
366 | pci_config_write8(addr, 64); | 366 | pci_config_write8(addr, 64); |
367 | } | 367 | } |
368 | 368 | ||
369 | static void __devinit psycho_scan_bus(struct pci_pbm_info *pbm, | 369 | static void psycho_scan_bus(struct pci_pbm_info *pbm, |
370 | struct device *parent) | 370 | struct device *parent) |
371 | { | 371 | { |
372 | pbm_config_busmastering(pbm); | 372 | pbm_config_busmastering(pbm); |
373 | pbm->is_66mhz_capable = 0; | 373 | pbm->is_66mhz_capable = 0; |
@@ -483,15 +483,15 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, | |||
483 | #define PSYCHO_MEMSPACE_B 0x180000000UL | 483 | #define PSYCHO_MEMSPACE_B 0x180000000UL |
484 | #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL | 484 | #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL |
485 | 485 | ||
486 | static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm, | 486 | static void psycho_pbm_init(struct pci_pbm_info *pbm, |
487 | struct platform_device *op, int is_pbm_a) | 487 | struct platform_device *op, int is_pbm_a) |
488 | { | 488 | { |
489 | psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO); | 489 | psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO); |
490 | psycho_pbm_strbuf_init(pbm, is_pbm_a); | 490 | psycho_pbm_strbuf_init(pbm, is_pbm_a); |
491 | psycho_scan_bus(pbm, &op->dev); | 491 | psycho_scan_bus(pbm, &op->dev); |
492 | } | 492 | } |
493 | 493 | ||
494 | static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) | 494 | static struct pci_pbm_info *psycho_find_sibling(u32 upa_portid) |
495 | { | 495 | { |
496 | struct pci_pbm_info *pbm; | 496 | struct pci_pbm_info *pbm; |
497 | 497 | ||
@@ -504,7 +504,7 @@ static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) | |||
504 | 504 | ||
505 | #define PSYCHO_CONFIGSPACE 0x001000000UL | 505 | #define PSYCHO_CONFIGSPACE 0x001000000UL |
506 | 506 | ||
507 | static int __devinit psycho_probe(struct platform_device *op) | 507 | static int psycho_probe(struct platform_device *op) |
508 | { | 508 | { |
509 | const struct linux_prom64_registers *pr_regs; | 509 | const struct linux_prom64_registers *pr_regs; |
510 | struct device_node *dp = op->dev.of_node; | 510 | struct device_node *dp = op->dev.of_node; |
diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 3efaa4644d60..6f00d27e8dac 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c | |||
@@ -403,8 +403,7 @@ static void apb_init(struct pci_bus *sabre_bus) | |||
403 | } | 403 | } |
404 | } | 404 | } |
405 | 405 | ||
406 | static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm, | 406 | static void sabre_scan_bus(struct pci_pbm_info *pbm, struct device *parent) |
407 | struct device *parent) | ||
408 | { | 407 | { |
409 | static int once; | 408 | static int once; |
410 | 409 | ||
@@ -443,8 +442,8 @@ static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm, | |||
443 | sabre_register_error_handlers(pbm); | 442 | sabre_register_error_handlers(pbm); |
444 | } | 443 | } |
445 | 444 | ||
446 | static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, | 445 | static void sabre_pbm_init(struct pci_pbm_info *pbm, |
447 | struct platform_device *op) | 446 | struct platform_device *op) |
448 | { | 447 | { |
449 | psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); | 448 | psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); |
450 | pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; | 449 | pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; |
@@ -454,7 +453,7 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, | |||
454 | } | 453 | } |
455 | 454 | ||
456 | static const struct of_device_id sabre_match[]; | 455 | static const struct of_device_id sabre_match[]; |
457 | static int __devinit sabre_probe(struct platform_device *op) | 456 | static int sabre_probe(struct platform_device *op) |
458 | { | 457 | { |
459 | const struct of_device_id *match; | 458 | const struct of_device_id *match; |
460 | const struct linux_prom64_registers *pr_regs; | 459 | const struct linux_prom64_registers *pr_regs; |
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 13d4aa20b5a5..8f76f23dac38 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c | |||
@@ -1064,8 +1064,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1064 | pci_config_write8(addr, 64); | 1064 | pci_config_write8(addr, 64); |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, | 1067 | static void schizo_scan_bus(struct pci_pbm_info *pbm, struct device *parent) |
1068 | struct device *parent) | ||
1069 | { | 1068 | { |
1070 | pbm_config_busmastering(pbm); | 1069 | pbm_config_busmastering(pbm); |
1071 | pbm->is_66mhz_capable = | 1070 | pbm->is_66mhz_capable = |
@@ -1307,9 +1306,9 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1307 | } | 1306 | } |
1308 | } | 1307 | } |
1309 | 1308 | ||
1310 | static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, | 1309 | static int schizo_pbm_init(struct pci_pbm_info *pbm, |
1311 | struct platform_device *op, u32 portid, | 1310 | struct platform_device *op, u32 portid, |
1312 | int chip_type) | 1311 | int chip_type) |
1313 | { | 1312 | { |
1314 | const struct linux_prom64_registers *regs; | 1313 | const struct linux_prom64_registers *regs; |
1315 | struct device_node *dp = op->dev.of_node; | 1314 | struct device_node *dp = op->dev.of_node; |
@@ -1400,8 +1399,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1400 | return (x == y); | 1399 | return (x == y); |
1401 | } | 1400 | } |
1402 | 1401 | ||
1403 | static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, | 1402 | static struct pci_pbm_info *schizo_find_sibling(u32 portid, int chip_type) |
1404 | int chip_type) | ||
1405 | { | 1403 | { |
1406 | struct pci_pbm_info *pbm; | 1404 | struct pci_pbm_info *pbm; |
1407 | 1405 | ||
@@ -1412,7 +1410,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, | |||
1412 | return NULL; | 1410 | return NULL; |
1413 | } | 1411 | } |
1414 | 1412 | ||
1415 | static int __devinit __schizo_init(struct platform_device *op, unsigned long chip_type) | 1413 | static int __schizo_init(struct platform_device *op, unsigned long chip_type) |
1416 | { | 1414 | { |
1417 | struct device_node *dp = op->dev.of_node; | 1415 | struct device_node *dp = op->dev.of_node; |
1418 | struct pci_pbm_info *pbm; | 1416 | struct pci_pbm_info *pbm; |
@@ -1460,7 +1458,7 @@ out_err: | |||
1460 | } | 1458 | } |
1461 | 1459 | ||
1462 | static const struct of_device_id schizo_match[]; | 1460 | static const struct of_device_id schizo_match[]; |
1463 | static int __devinit schizo_probe(struct platform_device *op) | 1461 | static int schizo_probe(struct platform_device *op) |
1464 | { | 1462 | { |
1465 | const struct of_device_id *match; | 1463 | const struct of_device_id *match; |
1466 | 1464 | ||
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 051b69caeffd..d07f6b29aed8 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c | |||
@@ -536,8 +536,7 @@ static struct dma_map_ops sun4v_dma_ops = { | |||
536 | .unmap_sg = dma_4v_unmap_sg, | 536 | .unmap_sg = dma_4v_unmap_sg, |
537 | }; | 537 | }; |
538 | 538 | ||
539 | static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, | 539 | static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct device *parent) |
540 | struct device *parent) | ||
541 | { | 540 | { |
542 | struct property *prop; | 541 | struct property *prop; |
543 | struct device_node *dp; | 542 | struct device_node *dp; |
@@ -550,8 +549,8 @@ static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, | |||
550 | /* XXX register error interrupt handlers XXX */ | 549 | /* XXX register error interrupt handlers XXX */ |
551 | } | 550 | } |
552 | 551 | ||
553 | static unsigned long __devinit probe_existing_entries(struct pci_pbm_info *pbm, | 552 | static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, |
554 | struct iommu *iommu) | 553 | struct iommu *iommu) |
555 | { | 554 | { |
556 | struct iommu_arena *arena = &iommu->arena; | 555 | struct iommu_arena *arena = &iommu->arena; |
557 | unsigned long i, cnt = 0; | 556 | unsigned long i, cnt = 0; |
@@ -578,7 +577,7 @@ static unsigned long __devinit probe_existing_entries(struct pci_pbm_info *pbm, | |||
578 | return cnt; | 577 | return cnt; |
579 | } | 578 | } |
580 | 579 | ||
581 | static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | 580 | static int pci_sun4v_iommu_init(struct pci_pbm_info *pbm) |
582 | { | 581 | { |
583 | static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; | 582 | static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; |
584 | struct iommu *iommu = pbm->iommu; | 583 | struct iommu *iommu = pbm->iommu; |
@@ -879,8 +878,8 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | |||
879 | } | 878 | } |
880 | #endif /* !(CONFIG_PCI_MSI) */ | 879 | #endif /* !(CONFIG_PCI_MSI) */ |
881 | 880 | ||
882 | static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, | 881 | static int pci_sun4v_pbm_init(struct pci_pbm_info *pbm, |
883 | struct platform_device *op, u32 devhandle) | 882 | struct platform_device *op, u32 devhandle) |
884 | { | 883 | { |
885 | struct device_node *dp = op->dev.of_node; | 884 | struct device_node *dp = op->dev.of_node; |
886 | int err; | 885 | int err; |
@@ -919,7 +918,7 @@ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, | |||
919 | return 0; | 918 | return 0; |
920 | } | 919 | } |
921 | 920 | ||
922 | static int __devinit pci_sun4v_probe(struct platform_device *op) | 921 | static int pci_sun4v_probe(struct platform_device *op) |
923 | { | 922 | { |
924 | const struct linux_prom64_registers *regs; | 923 | const struct linux_prom64_registers *regs; |
925 | static int hvapi_negotiated = 0; | 924 | static int hvapi_negotiated = 0; |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 521fdf1b20e5..09f4fdd8d808 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -439,8 +439,7 @@ int pcic_present(void) | |||
439 | return pcic0_up; | 439 | return pcic0_up; |
440 | } | 440 | } |
441 | 441 | ||
442 | static int __devinit pdev_to_pnode(struct linux_pbm_info *pbm, | 442 | static int pdev_to_pnode(struct linux_pbm_info *pbm, struct pci_dev *pdev) |
443 | struct pci_dev *pdev) | ||
444 | { | 443 | { |
445 | struct linux_prom_pci_registers regs[PROMREG_MAX]; | 444 | struct linux_prom_pci_registers regs[PROMREG_MAX]; |
446 | int err; | 445 | int err; |
@@ -595,7 +594,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) | |||
595 | /* | 594 | /* |
596 | * Normally called from {do_}pci_scan_bus... | 595 | * Normally called from {do_}pci_scan_bus... |
597 | */ | 596 | */ |
598 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 597 | void pcibios_fixup_bus(struct pci_bus *bus) |
599 | { | 598 | { |
600 | struct pci_dev *dev; | 599 | struct pci_dev *dev; |
601 | int i, has_io, has_mem; | 600 | int i, has_io, has_mem; |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 885a8af74064..b5c38faa4ead 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, | |||
1762 | 1762 | ||
1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; | 1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
1764 | do { | 1764 | do { |
1765 | struct sparc_stackf32 *usf, sf; | ||
1766 | unsigned long pc; | 1765 | unsigned long pc; |
1767 | 1766 | ||
1768 | usf = (struct sparc_stackf32 *) ufp; | 1767 | if (thread32_stack_is_64bit(ufp)) { |
1769 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | 1768 | struct sparc_stackf *usf, sf; |
1770 | break; | ||
1771 | 1769 | ||
1772 | pc = sf.callers_pc; | 1770 | ufp += STACK_BIAS; |
1773 | ufp = (unsigned long)sf.fp; | 1771 | usf = (struct sparc_stackf *) ufp; |
1772 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
1773 | break; | ||
1774 | pc = sf.callers_pc & 0xffffffff; | ||
1775 | ufp = ((unsigned long) sf.fp) & 0xffffffff; | ||
1776 | } else { | ||
1777 | struct sparc_stackf32 *usf, sf; | ||
1778 | usf = (struct sparc_stackf32 *) ufp; | ||
1779 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
1780 | break; | ||
1781 | pc = sf.callers_pc; | ||
1782 | ufp = (unsigned long)sf.fp; | ||
1783 | } | ||
1774 | perf_callchain_store(entry, pc); | 1784 | perf_callchain_store(entry, pc); |
1775 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1785 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
1776 | } | 1786 | } |
diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 0e3202239ff5..dcbb62f63068 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c | |||
@@ -52,7 +52,7 @@ static void pmc_swift_idle(void) | |||
52 | #endif | 52 | #endif |
53 | } | 53 | } |
54 | 54 | ||
55 | static int __devinit pmc_probe(struct platform_device *op) | 55 | static int pmc_probe(struct platform_device *op) |
56 | { | 56 | { |
57 | regs = of_ioremap(&op->resource[0], 0, | 57 | regs = of_ioremap(&op->resource[0], 0, |
58 | resource_size(&op->resource[0]), PMC_OBPNAME); | 58 | resource_size(&op->resource[0]), PMC_OBPNAME); |
diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 0d39075063b2..4cb23c41553f 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c | |||
@@ -23,7 +23,7 @@ static irqreturn_t power_handler(int irq, void *dev_id) | |||
23 | return IRQ_HANDLED; | 23 | return IRQ_HANDLED; |
24 | } | 24 | } |
25 | 25 | ||
26 | static int __devinit has_button_interrupt(unsigned int irq, struct device_node *dp) | 26 | static int has_button_interrupt(unsigned int irq, struct device_node *dp) |
27 | { | 27 | { |
28 | if (irq == 0xffffffff) | 28 | if (irq == 0xffffffff) |
29 | return 0; | 29 | return 0; |
@@ -33,7 +33,7 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node * | |||
33 | return 1; | 33 | return 1; |
34 | } | 34 | } |
35 | 35 | ||
36 | static int __devinit power_probe(struct platform_device *op) | 36 | static int power_probe(struct platform_device *op) |
37 | { | 37 | { |
38 | struct resource *res = &op->resource[0]; | 38 | struct resource *res = &op->resource[0]; |
39 | unsigned int irq = op->archdata.irqs[0]; | 39 | unsigned int irq = op->archdata.irqs[0]; |
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 487bffb36f5e..be8e862badaf 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -286,8 +286,7 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, | |||
286 | parent_tid_ptr = regs->u_regs[UREG_I2]; | 286 | parent_tid_ptr = regs->u_regs[UREG_I2]; |
287 | child_tid_ptr = regs->u_regs[UREG_I4]; | 287 | child_tid_ptr = regs->u_regs[UREG_I4]; |
288 | 288 | ||
289 | ret = do_fork(clone_flags, stack_start, | 289 | ret = do_fork(clone_flags, stack_start, stack_size, |
290 | regs, stack_size, | ||
291 | (int __user *) parent_tid_ptr, | 290 | (int __user *) parent_tid_ptr, |
292 | (int __user *) child_tid_ptr); | 291 | (int __user *) child_tid_ptr); |
293 | 292 | ||
@@ -316,13 +315,13 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, | |||
316 | * XXX See comment above sys_vfork in sparc64. todo. | 315 | * XXX See comment above sys_vfork in sparc64. todo. |
317 | */ | 316 | */ |
318 | extern void ret_from_fork(void); | 317 | extern void ret_from_fork(void); |
318 | extern void ret_from_kernel_thread(void); | ||
319 | 319 | ||
320 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 320 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
321 | unsigned long unused, | 321 | unsigned long arg, struct task_struct *p) |
322 | struct task_struct *p, struct pt_regs *regs) | ||
323 | { | 322 | { |
324 | struct thread_info *ti = task_thread_info(p); | 323 | struct thread_info *ti = task_thread_info(p); |
325 | struct pt_regs *childregs; | 324 | struct pt_regs *childregs, *regs = current_pt_regs(); |
326 | char *new_stack; | 325 | char *new_stack; |
327 | 326 | ||
328 | #ifndef CONFIG_SMP | 327 | #ifndef CONFIG_SMP |
@@ -336,16 +335,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
336 | } | 335 | } |
337 | 336 | ||
338 | /* | 337 | /* |
339 | * p->thread_info new_stack childregs | 338 | * p->thread_info new_stack childregs stack bottom |
340 | * ! ! ! {if(PSR_PS) } | 339 | * ! ! ! ! |
341 | * V V (stk.fr.) V (pt_regs) { (stk.fr.) } | 340 | * V V (stk.fr.) V (pt_regs) V |
342 | * +----- - - - - - ------+===========+============={+==========}+ | 341 | * +----- - - - - - ------+===========+=============+ |
343 | */ | 342 | */ |
344 | new_stack = task_stack_page(p) + THREAD_SIZE; | 343 | new_stack = task_stack_page(p) + THREAD_SIZE; |
345 | if (regs->psr & PSR_PS) | ||
346 | new_stack -= STACKFRAME_SZ; | ||
347 | new_stack -= STACKFRAME_SZ + TRACEREG_SZ; | 344 | new_stack -= STACKFRAME_SZ + TRACEREG_SZ; |
348 | memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ); | ||
349 | childregs = (struct pt_regs *) (new_stack + STACKFRAME_SZ); | 345 | childregs = (struct pt_regs *) (new_stack + STACKFRAME_SZ); |
350 | 346 | ||
351 | /* | 347 | /* |
@@ -356,55 +352,58 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
356 | * Thus, kpsr|=PSR_PIL. | 352 | * Thus, kpsr|=PSR_PIL. |
357 | */ | 353 | */ |
358 | ti->ksp = (unsigned long) new_stack; | 354 | ti->ksp = (unsigned long) new_stack; |
355 | p->thread.kregs = childregs; | ||
356 | |||
357 | if (unlikely(p->flags & PF_KTHREAD)) { | ||
358 | extern int nwindows; | ||
359 | unsigned long psr; | ||
360 | memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ); | ||
361 | p->thread.flags |= SPARC_FLAG_KTHREAD; | ||
362 | p->thread.current_ds = KERNEL_DS; | ||
363 | ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8); | ||
364 | childregs->u_regs[UREG_G1] = sp; /* function */ | ||
365 | childregs->u_regs[UREG_G2] = arg; | ||
366 | psr = childregs->psr = get_psr(); | ||
367 | ti->kpsr = psr | PSR_PIL; | ||
368 | ti->kwim = 1 << (((psr & PSR_CWP) + 1) % nwindows); | ||
369 | return 0; | ||
370 | } | ||
371 | memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ); | ||
372 | childregs->u_regs[UREG_FP] = sp; | ||
373 | p->thread.flags &= ~SPARC_FLAG_KTHREAD; | ||
374 | p->thread.current_ds = USER_DS; | ||
359 | ti->kpc = (((unsigned long) ret_from_fork) - 0x8); | 375 | ti->kpc = (((unsigned long) ret_from_fork) - 0x8); |
360 | ti->kpsr = current->thread.fork_kpsr | PSR_PIL; | 376 | ti->kpsr = current->thread.fork_kpsr | PSR_PIL; |
361 | ti->kwim = current->thread.fork_kwim; | 377 | ti->kwim = current->thread.fork_kwim; |
362 | 378 | ||
363 | if(regs->psr & PSR_PS) { | 379 | if (sp != regs->u_regs[UREG_FP]) { |
364 | extern struct pt_regs fake_swapper_regs; | 380 | struct sparc_stackf __user *childstack; |
381 | struct sparc_stackf __user *parentstack; | ||
365 | 382 | ||
366 | p->thread.kregs = &fake_swapper_regs; | 383 | /* |
367 | new_stack += STACKFRAME_SZ + TRACEREG_SZ; | 384 | * This is a clone() call with supplied user stack. |
368 | childregs->u_regs[UREG_FP] = (unsigned long) new_stack; | 385 | * Set some valid stack frames to give to the child. |
369 | p->thread.flags |= SPARC_FLAG_KTHREAD; | 386 | */ |
370 | p->thread.current_ds = KERNEL_DS; | 387 | childstack = (struct sparc_stackf __user *) |
371 | memcpy(new_stack, (void *)regs->u_regs[UREG_FP], STACKFRAME_SZ); | 388 | (sp & ~0xfUL); |
372 | childregs->u_regs[UREG_G6] = (unsigned long) ti; | 389 | parentstack = (struct sparc_stackf __user *) |
373 | } else { | 390 | regs->u_regs[UREG_FP]; |
374 | p->thread.kregs = childregs; | ||
375 | childregs->u_regs[UREG_FP] = sp; | ||
376 | p->thread.flags &= ~SPARC_FLAG_KTHREAD; | ||
377 | p->thread.current_ds = USER_DS; | ||
378 | |||
379 | if (sp != regs->u_regs[UREG_FP]) { | ||
380 | struct sparc_stackf __user *childstack; | ||
381 | struct sparc_stackf __user *parentstack; | ||
382 | |||
383 | /* | ||
384 | * This is a clone() call with supplied user stack. | ||
385 | * Set some valid stack frames to give to the child. | ||
386 | */ | ||
387 | childstack = (struct sparc_stackf __user *) | ||
388 | (sp & ~0xfUL); | ||
389 | parentstack = (struct sparc_stackf __user *) | ||
390 | regs->u_regs[UREG_FP]; | ||
391 | 391 | ||
392 | #if 0 | 392 | #if 0 |
393 | printk("clone: parent stack:\n"); | 393 | printk("clone: parent stack:\n"); |
394 | show_stackframe(parentstack); | 394 | show_stackframe(parentstack); |
395 | #endif | 395 | #endif |
396 | 396 | ||
397 | childstack = clone_stackframe(childstack, parentstack); | 397 | childstack = clone_stackframe(childstack, parentstack); |
398 | if (!childstack) | 398 | if (!childstack) |
399 | return -EFAULT; | 399 | return -EFAULT; |
400 | 400 | ||
401 | #if 0 | 401 | #if 0 |
402 | printk("clone: child stack:\n"); | 402 | printk("clone: child stack:\n"); |
403 | show_stackframe(childstack); | 403 | show_stackframe(childstack); |
404 | #endif | 404 | #endif |
405 | 405 | ||
406 | childregs->u_regs[UREG_FP] = (unsigned long)childstack; | 406 | childregs->u_regs[UREG_FP] = (unsigned long)childstack; |
407 | } | ||
408 | } | 407 | } |
409 | 408 | ||
410 | #ifdef CONFIG_SMP | 409 | #ifdef CONFIG_SMP |
@@ -475,69 +474,6 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) | |||
475 | return 1; | 474 | return 1; |
476 | } | 475 | } |
477 | 476 | ||
478 | /* | ||
479 | * sparc_execve() executes a new program after the asm stub has set | ||
480 | * things up for us. This should basically do what I want it to. | ||
481 | */ | ||
482 | asmlinkage int sparc_execve(struct pt_regs *regs) | ||
483 | { | ||
484 | int error, base = 0; | ||
485 | struct filename *filename; | ||
486 | |||
487 | /* Check for indirect call. */ | ||
488 | if(regs->u_regs[UREG_G1] == 0) | ||
489 | base = 1; | ||
490 | |||
491 | filename = getname((char __user *)regs->u_regs[base + UREG_I0]); | ||
492 | error = PTR_ERR(filename); | ||
493 | if(IS_ERR(filename)) | ||
494 | goto out; | ||
495 | error = do_execve(filename->name, | ||
496 | (const char __user *const __user *) | ||
497 | regs->u_regs[base + UREG_I1], | ||
498 | (const char __user *const __user *) | ||
499 | regs->u_regs[base + UREG_I2], | ||
500 | regs); | ||
501 | putname(filename); | ||
502 | out: | ||
503 | return error; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * This is the mechanism for creating a new kernel thread. | ||
508 | * | ||
509 | * NOTE! Only a kernel-only process(ie the swapper or direct descendants | ||
510 | * who haven't done an "execve()") should use this: it will work within | ||
511 | * a system call from a "real" process, but the process memory space will | ||
512 | * not be freed until both the parent and the child have exited. | ||
513 | */ | ||
514 | pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
515 | { | ||
516 | long retval; | ||
517 | |||
518 | __asm__ __volatile__("mov %4, %%g2\n\t" /* Set aside fn ptr... */ | ||
519 | "mov %5, %%g3\n\t" /* and arg. */ | ||
520 | "mov %1, %%g1\n\t" | ||
521 | "mov %2, %%o0\n\t" /* Clone flags. */ | ||
522 | "mov 0, %%o1\n\t" /* usp arg == 0 */ | ||
523 | "t 0x10\n\t" /* Linux/Sparc clone(). */ | ||
524 | "cmp %%o1, 0\n\t" | ||
525 | "be 1f\n\t" /* The parent, just return. */ | ||
526 | " nop\n\t" /* Delay slot. */ | ||
527 | "jmpl %%g2, %%o7\n\t" /* Call the function. */ | ||
528 | " mov %%g3, %%o0\n\t" /* Get back the arg in delay. */ | ||
529 | "mov %3, %%g1\n\t" | ||
530 | "t 0x10\n\t" /* Linux/Sparc exit(). */ | ||
531 | /* Notreached by child. */ | ||
532 | "1: mov %%o0, %0\n\t" : | ||
533 | "=r" (retval) : | ||
534 | "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED), | ||
535 | "i" (__NR_exit), "r" (fn), "r" (arg) : | ||
536 | "g1", "g2", "g3", "o0", "o1", "memory", "cc"); | ||
537 | return retval; | ||
538 | } | ||
539 | EXPORT_SYMBOL(kernel_thread); | ||
540 | |||
541 | unsigned long get_wchan(struct task_struct *task) | 477 | unsigned long get_wchan(struct task_struct *task) |
542 | { | 478 | { |
543 | unsigned long pc, fp, bias = 0; | 479 | unsigned long pc, fp, bias = 0; |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index d778248ef3f8..cdb80b2adbe0 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -452,13 +452,16 @@ void flush_thread(void) | |||
452 | /* It's a bit more tricky when 64-bit tasks are involved... */ | 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ |
453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) |
454 | { | 454 | { |
455 | bool stack_64bit = test_thread_64bit_stack(psp); | ||
455 | unsigned long fp, distance, rval; | 456 | unsigned long fp, distance, rval; |
456 | 457 | ||
457 | if (!(test_thread_flag(TIF_32BIT))) { | 458 | if (stack_64bit) { |
458 | csp += STACK_BIAS; | 459 | csp += STACK_BIAS; |
459 | psp += STACK_BIAS; | 460 | psp += STACK_BIAS; |
460 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); | 461 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); |
461 | fp += STACK_BIAS; | 462 | fp += STACK_BIAS; |
463 | if (test_thread_flag(TIF_32BIT)) | ||
464 | fp &= 0xffffffff; | ||
462 | } else | 465 | } else |
463 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); | 466 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
464 | 467 | ||
@@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | |||
472 | rval = (csp - distance); | 475 | rval = (csp - distance); |
473 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) | 476 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) |
474 | rval = 0; | 477 | rval = 0; |
475 | else if (test_thread_flag(TIF_32BIT)) { | 478 | else if (!stack_64bit) { |
476 | if (put_user(((u32)csp), | 479 | if (put_user(((u32)csp), |
477 | &(((struct reg_window32 __user *)rval)->ins[6]))) | 480 | &(((struct reg_window32 __user *)rval)->ins[6]))) |
478 | rval = 0; | 481 | rval = 0; |
@@ -507,18 +510,18 @@ void synchronize_user_stack(void) | |||
507 | 510 | ||
508 | flush_user_windows(); | 511 | flush_user_windows(); |
509 | if ((window = get_thread_wsaved()) != 0) { | 512 | if ((window = get_thread_wsaved()) != 0) { |
510 | int winsize = sizeof(struct reg_window); | ||
511 | int bias = 0; | ||
512 | |||
513 | if (test_thread_flag(TIF_32BIT)) | ||
514 | winsize = sizeof(struct reg_window32); | ||
515 | else | ||
516 | bias = STACK_BIAS; | ||
517 | |||
518 | window -= 1; | 513 | window -= 1; |
519 | do { | 514 | do { |
520 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
521 | struct reg_window *rwin = &t->reg_window[window]; | 515 | struct reg_window *rwin = &t->reg_window[window]; |
516 | int winsize = sizeof(struct reg_window); | ||
517 | unsigned long sp; | ||
518 | |||
519 | sp = t->rwbuf_stkptrs[window]; | ||
520 | |||
521 | if (test_thread_64bit_stack(sp)) | ||
522 | sp += STACK_BIAS; | ||
523 | else | ||
524 | winsize = sizeof(struct reg_window32); | ||
522 | 525 | ||
523 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { | 526 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { |
524 | shift_window_buffer(window, get_thread_wsaved() - 1, t); | 527 | shift_window_buffer(window, get_thread_wsaved() - 1, t); |
@@ -544,13 +547,6 @@ void fault_in_user_windows(void) | |||
544 | { | 547 | { |
545 | struct thread_info *t = current_thread_info(); | 548 | struct thread_info *t = current_thread_info(); |
546 | unsigned long window; | 549 | unsigned long window; |
547 | int winsize = sizeof(struct reg_window); | ||
548 | int bias = 0; | ||
549 | |||
550 | if (test_thread_flag(TIF_32BIT)) | ||
551 | winsize = sizeof(struct reg_window32); | ||
552 | else | ||
553 | bias = STACK_BIAS; | ||
554 | 550 | ||
555 | flush_user_windows(); | 551 | flush_user_windows(); |
556 | window = get_thread_wsaved(); | 552 | window = get_thread_wsaved(); |
@@ -558,8 +554,16 @@ void fault_in_user_windows(void) | |||
558 | if (likely(window != 0)) { | 554 | if (likely(window != 0)) { |
559 | window -= 1; | 555 | window -= 1; |
560 | do { | 556 | do { |
561 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
562 | struct reg_window *rwin = &t->reg_window[window]; | 557 | struct reg_window *rwin = &t->reg_window[window]; |
558 | int winsize = sizeof(struct reg_window); | ||
559 | unsigned long sp; | ||
560 | |||
561 | sp = t->rwbuf_stkptrs[window]; | ||
562 | |||
563 | if (test_thread_64bit_stack(sp)) | ||
564 | sp += STACK_BIAS; | ||
565 | else | ||
566 | winsize = sizeof(struct reg_window32); | ||
563 | 567 | ||
564 | if (unlikely(sp & 0x7UL)) | 568 | if (unlikely(sp & 0x7UL)) |
565 | stack_unaligned(sp); | 569 | stack_unaligned(sp); |
@@ -597,8 +601,7 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, | |||
597 | child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; | 601 | child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; |
598 | } | 602 | } |
599 | 603 | ||
600 | ret = do_fork(clone_flags, stack_start, | 604 | ret = do_fork(clone_flags, stack_start, stack_size, |
601 | regs, stack_size, | ||
602 | parent_tid_ptr, child_tid_ptr); | 605 | parent_tid_ptr, child_tid_ptr); |
603 | 606 | ||
604 | /* If we get an error and potentially restart the system | 607 | /* If we get an error and potentially restart the system |
@@ -618,64 +621,55 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, | |||
618 | * Child --> %o0 == parents pid, %o1 == 1 | 621 | * Child --> %o0 == parents pid, %o1 == 1 |
619 | */ | 622 | */ |
620 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 623 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
621 | unsigned long unused, | 624 | unsigned long arg, struct task_struct *p) |
622 | struct task_struct *p, struct pt_regs *regs) | ||
623 | { | 625 | { |
624 | struct thread_info *t = task_thread_info(p); | 626 | struct thread_info *t = task_thread_info(p); |
627 | struct pt_regs *regs = current_pt_regs(); | ||
625 | struct sparc_stackf *parent_sf; | 628 | struct sparc_stackf *parent_sf; |
626 | unsigned long child_stack_sz; | 629 | unsigned long child_stack_sz; |
627 | char *child_trap_frame; | 630 | char *child_trap_frame; |
628 | int kernel_thread; | ||
629 | |||
630 | kernel_thread = (regs->tstate & TSTATE_PRIV) ? 1 : 0; | ||
631 | parent_sf = ((struct sparc_stackf *) regs) - 1; | ||
632 | 631 | ||
633 | /* Calculate offset to stack_frame & pt_regs */ | 632 | /* Calculate offset to stack_frame & pt_regs */ |
634 | child_stack_sz = ((STACKFRAME_SZ + TRACEREG_SZ) + | 633 | child_stack_sz = (STACKFRAME_SZ + TRACEREG_SZ); |
635 | (kernel_thread ? STACKFRAME_SZ : 0)); | ||
636 | child_trap_frame = (task_stack_page(p) + | 634 | child_trap_frame = (task_stack_page(p) + |
637 | (THREAD_SIZE - child_stack_sz)); | 635 | (THREAD_SIZE - child_stack_sz)); |
638 | memcpy(child_trap_frame, parent_sf, child_stack_sz); | ||
639 | 636 | ||
640 | t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | | ||
641 | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | | ||
642 | (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); | ||
643 | t->new_child = 1; | 637 | t->new_child = 1; |
644 | t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; | 638 | t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; |
645 | t->kregs = (struct pt_regs *) (child_trap_frame + | 639 | t->kregs = (struct pt_regs *) (child_trap_frame + |
646 | sizeof(struct sparc_stackf)); | 640 | sizeof(struct sparc_stackf)); |
647 | t->fpsaved[0] = 0; | 641 | t->fpsaved[0] = 0; |
648 | 642 | ||
649 | if (kernel_thread) { | 643 | if (unlikely(p->flags & PF_KTHREAD)) { |
650 | struct sparc_stackf *child_sf = (struct sparc_stackf *) | 644 | memset(child_trap_frame, 0, child_stack_sz); |
651 | (child_trap_frame + (STACKFRAME_SZ + TRACEREG_SZ)); | 645 | __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = |
652 | 646 | (current_pt_regs()->tstate + 1) & TSTATE_CWP; | |
653 | /* Zero terminate the stack backtrace. */ | 647 | t->current_ds = ASI_P; |
654 | child_sf->fp = NULL; | 648 | t->kregs->u_regs[UREG_G1] = sp; /* function */ |
655 | t->kregs->u_regs[UREG_FP] = | 649 | t->kregs->u_regs[UREG_G2] = arg; |
656 | ((unsigned long) child_sf) - STACK_BIAS; | 650 | return 0; |
651 | } | ||
657 | 652 | ||
658 | t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); | 653 | parent_sf = ((struct sparc_stackf *) regs) - 1; |
659 | t->kregs->u_regs[UREG_G6] = (unsigned long) t; | 654 | memcpy(child_trap_frame, parent_sf, child_stack_sz); |
660 | t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; | 655 | if (t->flags & _TIF_32BIT) { |
661 | } else { | 656 | sp &= 0x00000000ffffffffUL; |
662 | if (t->flags & _TIF_32BIT) { | 657 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; |
663 | sp &= 0x00000000ffffffffUL; | ||
664 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | ||
665 | } | ||
666 | t->kregs->u_regs[UREG_FP] = sp; | ||
667 | t->flags |= ((long)ASI_AIUS << TI_FLAG_CURRENT_DS_SHIFT); | ||
668 | if (sp != regs->u_regs[UREG_FP]) { | ||
669 | unsigned long csp; | ||
670 | |||
671 | csp = clone_stackframe(sp, regs->u_regs[UREG_FP]); | ||
672 | if (!csp) | ||
673 | return -EFAULT; | ||
674 | t->kregs->u_regs[UREG_FP] = csp; | ||
675 | } | ||
676 | if (t->utraps) | ||
677 | t->utraps[0]++; | ||
678 | } | 658 | } |
659 | t->kregs->u_regs[UREG_FP] = sp; | ||
660 | __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = | ||
661 | (regs->tstate + 1) & TSTATE_CWP; | ||
662 | t->current_ds = ASI_AIUS; | ||
663 | if (sp != regs->u_regs[UREG_FP]) { | ||
664 | unsigned long csp; | ||
665 | |||
666 | csp = clone_stackframe(sp, regs->u_regs[UREG_FP]); | ||
667 | if (!csp) | ||
668 | return -EFAULT; | ||
669 | t->kregs->u_regs[UREG_FP] = csp; | ||
670 | } | ||
671 | if (t->utraps) | ||
672 | t->utraps[0]++; | ||
679 | 673 | ||
680 | /* Set the return value for the child. */ | 674 | /* Set the return value for the child. */ |
681 | t->kregs->u_regs[UREG_I0] = current->pid; | 675 | t->kregs->u_regs[UREG_I0] = current->pid; |
@@ -690,45 +684,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
690 | return 0; | 684 | return 0; |
691 | } | 685 | } |
692 | 686 | ||
693 | /* | ||
694 | * This is the mechanism for creating a new kernel thread. | ||
695 | * | ||
696 | * NOTE! Only a kernel-only process(ie the swapper or direct descendants | ||
697 | * who haven't done an "execve()") should use this: it will work within | ||
698 | * a system call from a "real" process, but the process memory space will | ||
699 | * not be freed until both the parent and the child have exited. | ||
700 | */ | ||
701 | pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
702 | { | ||
703 | long retval; | ||
704 | |||
705 | /* If the parent runs before fn(arg) is called by the child, | ||
706 | * the input registers of this function can be clobbered. | ||
707 | * So we stash 'fn' and 'arg' into global registers which | ||
708 | * will not be modified by the parent. | ||
709 | */ | ||
710 | __asm__ __volatile__("mov %4, %%g2\n\t" /* Save FN into global */ | ||
711 | "mov %5, %%g3\n\t" /* Save ARG into global */ | ||
712 | "mov %1, %%g1\n\t" /* Clone syscall nr. */ | ||
713 | "mov %2, %%o0\n\t" /* Clone flags. */ | ||
714 | "mov 0, %%o1\n\t" /* usp arg == 0 */ | ||
715 | "t 0x6d\n\t" /* Linux/Sparc clone(). */ | ||
716 | "brz,a,pn %%o1, 1f\n\t" /* Parent, just return. */ | ||
717 | " mov %%o0, %0\n\t" | ||
718 | "jmpl %%g2, %%o7\n\t" /* Call the function. */ | ||
719 | " mov %%g3, %%o0\n\t" /* Set arg in delay. */ | ||
720 | "mov %3, %%g1\n\t" | ||
721 | "t 0x6d\n\t" /* Linux/Sparc exit(). */ | ||
722 | /* Notreached by child. */ | ||
723 | "1:" : | ||
724 | "=r" (retval) : | ||
725 | "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED), | ||
726 | "i" (__NR_exit), "r" (fn), "r" (arg) : | ||
727 | "g1", "g2", "g3", "o0", "o1", "memory", "cc"); | ||
728 | return retval; | ||
729 | } | ||
730 | EXPORT_SYMBOL(kernel_thread); | ||
731 | |||
732 | typedef struct { | 687 | typedef struct { |
733 | union { | 688 | union { |
734 | unsigned int pr_regs[32]; | 689 | unsigned int pr_regs[32]; |
@@ -795,41 +750,6 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) | |||
795 | } | 750 | } |
796 | EXPORT_SYMBOL(dump_fpu); | 751 | EXPORT_SYMBOL(dump_fpu); |
797 | 752 | ||
798 | /* | ||
799 | * sparc_execve() executes a new program after the asm stub has set | ||
800 | * things up for us. This should basically do what I want it to. | ||
801 | */ | ||
802 | asmlinkage int sparc_execve(struct pt_regs *regs) | ||
803 | { | ||
804 | int error, base = 0; | ||
805 | struct filename *filename; | ||
806 | |||
807 | /* User register window flush is done by entry.S */ | ||
808 | |||
809 | /* Check for indirect call. */ | ||
810 | if (regs->u_regs[UREG_G1] == 0) | ||
811 | base = 1; | ||
812 | |||
813 | filename = getname((char __user *)regs->u_regs[base + UREG_I0]); | ||
814 | error = PTR_ERR(filename); | ||
815 | if (IS_ERR(filename)) | ||
816 | goto out; | ||
817 | error = do_execve(filename->name, | ||
818 | (const char __user *const __user *) | ||
819 | regs->u_regs[base + UREG_I1], | ||
820 | (const char __user *const __user *) | ||
821 | regs->u_regs[base + UREG_I2], regs); | ||
822 | putname(filename); | ||
823 | if (!error) { | ||
824 | fprs_write(0); | ||
825 | current_thread_info()->xfsr[0] = 0; | ||
826 | current_thread_info()->fpsaved[0] = 0; | ||
827 | regs->tstate &= ~TSTATE_PEF; | ||
828 | } | ||
829 | out: | ||
830 | return error; | ||
831 | } | ||
832 | |||
833 | unsigned long get_wchan(struct task_struct *task) | 753 | unsigned long get_wchan(struct task_struct *task) |
834 | { | 754 | { |
835 | unsigned long pc, fp, bias = 0; | 755 | unsigned long pc, fp, bias = 0; |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 484dabac7045..7ff45e4ba681 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
@@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, | |||
151 | { | 151 | { |
152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; | 152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
153 | 153 | ||
154 | if (test_tsk_thread_flag(current, TIF_32BIT)) { | 154 | if (!test_thread_64bit_stack(rw_addr)) { |
155 | struct reg_window32 win32; | 155 | struct reg_window32 win32; |
156 | int i; | 156 | int i; |
157 | 157 | ||
@@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, | |||
176 | { | 176 | { |
177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; | 177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
178 | 178 | ||
179 | if (test_tsk_thread_flag(current, TIF_32BIT)) { | 179 | if (!test_thread_64bit_stack(rw_addr)) { |
180 | struct reg_window32 win32; | 180 | struct reg_window32 win32; |
181 | int i; | 181 | int i; |
182 | 182 | ||
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 0800e71d8a88..0eaf0059aaef 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -316,6 +316,25 @@ static void __init popc_patch(void) | |||
316 | } | 316 | } |
317 | } | 317 | } |
318 | 318 | ||
319 | static void __init pause_patch(void) | ||
320 | { | ||
321 | struct pause_patch_entry *p; | ||
322 | |||
323 | p = &__pause_3insn_patch; | ||
324 | while (p < &__pause_3insn_patch_end) { | ||
325 | unsigned long i, addr = p->addr; | ||
326 | |||
327 | for (i = 0; i < 3; i++) { | ||
328 | *(unsigned int *) (addr + (i * 4)) = p->insns[i]; | ||
329 | wmb(); | ||
330 | __asm__ __volatile__("flush %0" | ||
331 | : : "r" (addr + (i * 4))); | ||
332 | } | ||
333 | |||
334 | p++; | ||
335 | } | ||
336 | } | ||
337 | |||
319 | #ifdef CONFIG_SMP | 338 | #ifdef CONFIG_SMP |
320 | void __init boot_cpu_id_too_large(int cpu) | 339 | void __init boot_cpu_id_too_large(int cpu) |
321 | { | 340 | { |
@@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void) | |||
528 | 547 | ||
529 | if (sparc64_elf_hwcap & AV_SPARC_POPC) | 548 | if (sparc64_elf_hwcap & AV_SPARC_POPC) |
530 | popc_patch(); | 549 | popc_patch(); |
550 | if (sparc64_elf_hwcap & AV_SPARC_PAUSE) | ||
551 | pause_patch(); | ||
531 | } | 552 | } |
532 | 553 | ||
533 | void __init setup_arch(char **cmdline_p) | 554 | void __init setup_arch(char **cmdline_p) |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 867de2f8189c..689e1ba62809 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) | |||
295 | err |= restore_fpu_state(regs, fpu_save); | 295 | err |= restore_fpu_state(regs, fpu_save); |
296 | 296 | ||
297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
298 | err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); | 298 | if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) |
299 | |||
300 | if (err) | ||
301 | goto segv; | 299 | goto segv; |
302 | 300 | ||
303 | err |= __get_user(rwin_save, &sf->rwin_save); | 301 | err |= __get_user(rwin_save, &sf->rwin_save); |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index d94b878577b7..537eb66abd06 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -1180,7 +1180,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1180 | { | 1180 | { |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | void __devinit smp_prepare_boot_cpu(void) | 1183 | void smp_prepare_boot_cpu(void) |
1184 | { | 1184 | { |
1185 | } | 1185 | } |
1186 | 1186 | ||
@@ -1194,7 +1194,7 @@ void __init smp_setup_processor_id(void) | |||
1194 | xcall_deliver_impl = hypervisor_xcall_deliver; | 1194 | xcall_deliver_impl = hypervisor_xcall_deliver; |
1195 | } | 1195 | } |
1196 | 1196 | ||
1197 | void __devinit smp_fill_in_sib_core_maps(void) | 1197 | void smp_fill_in_sib_core_maps(void) |
1198 | { | 1198 | { |
1199 | unsigned int i; | 1199 | unsigned int i; |
1200 | 1200 | ||
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 44025f4ba41f..8475a474273a 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ | |||
47 | sra REG4, 0, REG4 | 47 | sra REG4, 0, REG4 |
48 | 48 | ||
49 | SIGN1(sys32_exit, sparc_exit, %o0) | 49 | SIGN1(sys32_exit, sparc_exit, %o0) |
50 | SIGN1(sys32_exit_group, sys_exit_group, %o0) | 50 | SIGN1(sys32_exit_group, sparc_exit_group, %o0) |
51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) | 51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) |
52 | SIGN1(sys32_creat, sys_creat, %o1) | 52 | SIGN1(sys32_creat, sys_creat, %o1) |
53 | SIGN1(sys32_mknod, sys_mknod, %o1) | 53 | SIGN1(sys32_mknod, sys_mknod, %o1) |
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index c3239811a1b5..4a4cdc633f6b 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -211,20 +211,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) | |||
211 | return sys_sysfs(option, arg1, arg2); | 211 | return sys_sysfs(option, arg1, arg2); |
212 | } | 212 | } |
213 | 213 | ||
214 | asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) | ||
215 | { | ||
216 | struct timespec t; | ||
217 | int ret; | ||
218 | mm_segment_t old_fs = get_fs (); | ||
219 | |||
220 | set_fs (KERNEL_DS); | ||
221 | ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t); | ||
222 | set_fs (old_fs); | ||
223 | if (put_compat_timespec(&t, interval)) | ||
224 | return -EFAULT; | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | asmlinkage long compat_sys_rt_sigprocmask(int how, | 214 | asmlinkage long compat_sys_rt_sigprocmask(int how, |
229 | compat_sigset_t __user *set, | 215 | compat_sigset_t __user *set, |
230 | compat_sigset_t __user *oset, | 216 | compat_sigset_t __user *oset, |
@@ -396,42 +382,6 @@ asmlinkage long compat_sys_rt_sigaction(int sig, | |||
396 | return ret; | 382 | return ret; |
397 | } | 383 | } |
398 | 384 | ||
399 | /* | ||
400 | * sparc32_execve() executes a new program after the asm stub has set | ||
401 | * things up for us. This should basically do what I want it to. | ||
402 | */ | ||
403 | asmlinkage long sparc32_execve(struct pt_regs *regs) | ||
404 | { | ||
405 | int error, base = 0; | ||
406 | struct filename *filename; | ||
407 | |||
408 | /* User register window flush is done by entry.S */ | ||
409 | |||
410 | /* Check for indirect call. */ | ||
411 | if ((u32)regs->u_regs[UREG_G1] == 0) | ||
412 | base = 1; | ||
413 | |||
414 | filename = getname(compat_ptr(regs->u_regs[base + UREG_I0])); | ||
415 | error = PTR_ERR(filename); | ||
416 | if (IS_ERR(filename)) | ||
417 | goto out; | ||
418 | |||
419 | error = compat_do_execve(filename->name, | ||
420 | compat_ptr(regs->u_regs[base + UREG_I1]), | ||
421 | compat_ptr(regs->u_regs[base + UREG_I2]), regs); | ||
422 | |||
423 | putname(filename); | ||
424 | |||
425 | if (!error) { | ||
426 | fprs_write(0); | ||
427 | current_thread_info()->xfsr[0] = 0; | ||
428 | current_thread_info()->fpsaved[0] = 0; | ||
429 | regs->tstate &= ~TSTATE_PEF; | ||
430 | } | ||
431 | out: | ||
432 | return error; | ||
433 | } | ||
434 | |||
435 | #ifdef CONFIG_MODULES | 385 | #ifdef CONFIG_MODULES |
436 | 386 | ||
437 | asmlinkage long sys32_init_module(void __user *umod, u32 len, | 387 | asmlinkage long sys32_init_module(void __user *umod, u32 len, |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 0c9b31b22e07..2da0bdcae52f 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -34,11 +34,9 @@ asmlinkage unsigned long sys_getpagesize(void) | |||
34 | return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ | 34 | return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ |
35 | } | 35 | } |
36 | 36 | ||
37 | #define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) | ||
38 | |||
39 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 37 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
40 | { | 38 | { |
41 | struct vm_area_struct * vmm; | 39 | struct vm_unmapped_area_info info; |
42 | 40 | ||
43 | if (flags & MAP_FIXED) { | 41 | if (flags & MAP_FIXED) { |
44 | /* We do not accept a shared mapping if it would violate | 42 | /* We do not accept a shared mapping if it would violate |
@@ -56,21 +54,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
56 | if (!addr) | 54 | if (!addr) |
57 | addr = TASK_UNMAPPED_BASE; | 55 | addr = TASK_UNMAPPED_BASE; |
58 | 56 | ||
59 | if (flags & MAP_SHARED) | 57 | info.flags = 0; |
60 | addr = COLOUR_ALIGN(addr); | 58 | info.length = len; |
61 | else | 59 | info.low_limit = addr; |
62 | addr = PAGE_ALIGN(addr); | 60 | info.high_limit = TASK_SIZE; |
63 | 61 | info.align_mask = (flags & MAP_SHARED) ? | |
64 | for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { | 62 | (PAGE_MASK & (SHMLBA - 1)) : 0; |
65 | /* At this point: (!vmm || addr < vmm->vm_end). */ | 63 | info.align_offset = pgoff << PAGE_SHIFT; |
66 | if (TASK_SIZE - PAGE_SIZE - len < addr) | 64 | return vm_unmapped_area(&info); |
67 | return -ENOMEM; | ||
68 | if (!vmm || addr + len <= vmm->vm_start) | ||
69 | return addr; | ||
70 | addr = vmm->vm_end; | ||
71 | if (flags & MAP_SHARED) | ||
72 | addr = COLOUR_ALIGN(addr); | ||
73 | } | ||
74 | } | 65 | } |
75 | 66 | ||
76 | /* | 67 | /* |
@@ -258,27 +249,3 @@ out: | |||
258 | up_read(&uts_sem); | 249 | up_read(&uts_sem); |
259 | return err; | 250 | return err; |
260 | } | 251 | } |
261 | |||
262 | /* | ||
263 | * Do a system call from kernel instead of calling sys_execve so we | ||
264 | * end up with proper pt_regs. | ||
265 | */ | ||
266 | int kernel_execve(const char *filename, | ||
267 | const char *const argv[], | ||
268 | const char *const envp[]) | ||
269 | { | ||
270 | long __res; | ||
271 | register long __g1 __asm__ ("g1") = __NR_execve; | ||
272 | register long __o0 __asm__ ("o0") = (long)(filename); | ||
273 | register long __o1 __asm__ ("o1") = (long)(argv); | ||
274 | register long __o2 __asm__ ("o2") = (long)(envp); | ||
275 | asm volatile ("t 0x10\n\t" | ||
276 | "bcc 1f\n\t" | ||
277 | "mov %%o0, %0\n\t" | ||
278 | "sub %%g0, %%o0, %0\n\t" | ||
279 | "1:\n\t" | ||
280 | : "=r" (__res), "=&r" (__o0) | ||
281 | : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) | ||
282 | : "cc"); | ||
283 | return __res; | ||
284 | } | ||
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 11c6c9603e71..708bc29d36a8 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -75,7 +75,7 @@ static inline int invalid_64bit_range(unsigned long addr, unsigned long len) | |||
75 | * the spitfire/niagara VA-hole. | 75 | * the spitfire/niagara VA-hole. |
76 | */ | 76 | */ |
77 | 77 | ||
78 | static inline unsigned long COLOUR_ALIGN(unsigned long addr, | 78 | static inline unsigned long COLOR_ALIGN(unsigned long addr, |
79 | unsigned long pgoff) | 79 | unsigned long pgoff) |
80 | { | 80 | { |
81 | unsigned long base = (addr+SHMLBA-1)&~(SHMLBA-1); | 81 | unsigned long base = (addr+SHMLBA-1)&~(SHMLBA-1); |
@@ -84,24 +84,13 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr, | |||
84 | return base + off; | 84 | return base + off; |
85 | } | 85 | } |
86 | 86 | ||
87 | static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr, | ||
88 | unsigned long pgoff) | ||
89 | { | ||
90 | unsigned long base = addr & ~(SHMLBA-1); | ||
91 | unsigned long off = (pgoff<<PAGE_SHIFT) & (SHMLBA-1); | ||
92 | |||
93 | if (base + off <= addr) | ||
94 | return base + off; | ||
95 | return base - off; | ||
96 | } | ||
97 | |||
98 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 87 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
99 | { | 88 | { |
100 | struct mm_struct *mm = current->mm; | 89 | struct mm_struct *mm = current->mm; |
101 | struct vm_area_struct * vma; | 90 | struct vm_area_struct * vma; |
102 | unsigned long task_size = TASK_SIZE; | 91 | unsigned long task_size = TASK_SIZE; |
103 | unsigned long start_addr; | ||
104 | int do_color_align; | 92 | int do_color_align; |
93 | struct vm_unmapped_area_info info; | ||
105 | 94 | ||
106 | if (flags & MAP_FIXED) { | 95 | if (flags & MAP_FIXED) { |
107 | /* We do not accept a shared mapping if it would violate | 96 | /* We do not accept a shared mapping if it would violate |
@@ -124,7 +113,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
124 | 113 | ||
125 | if (addr) { | 114 | if (addr) { |
126 | if (do_color_align) | 115 | if (do_color_align) |
127 | addr = COLOUR_ALIGN(addr, pgoff); | 116 | addr = COLOR_ALIGN(addr, pgoff); |
128 | else | 117 | else |
129 | addr = PAGE_ALIGN(addr); | 118 | addr = PAGE_ALIGN(addr); |
130 | 119 | ||
@@ -134,50 +123,22 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
134 | return addr; | 123 | return addr; |
135 | } | 124 | } |
136 | 125 | ||
137 | if (len > mm->cached_hole_size) { | 126 | info.flags = 0; |
138 | start_addr = addr = mm->free_area_cache; | 127 | info.length = len; |
139 | } else { | 128 | info.low_limit = TASK_UNMAPPED_BASE; |
140 | start_addr = addr = TASK_UNMAPPED_BASE; | 129 | info.high_limit = min(task_size, VA_EXCLUDE_START); |
141 | mm->cached_hole_size = 0; | 130 | info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; |
131 | info.align_offset = pgoff << PAGE_SHIFT; | ||
132 | addr = vm_unmapped_area(&info); | ||
133 | |||
134 | if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) { | ||
135 | VM_BUG_ON(addr != -ENOMEM); | ||
136 | info.low_limit = VA_EXCLUDE_END; | ||
137 | info.high_limit = task_size; | ||
138 | addr = vm_unmapped_area(&info); | ||
142 | } | 139 | } |
143 | 140 | ||
144 | task_size -= len; | 141 | return addr; |
145 | |||
146 | full_search: | ||
147 | if (do_color_align) | ||
148 | addr = COLOUR_ALIGN(addr, pgoff); | ||
149 | else | ||
150 | addr = PAGE_ALIGN(addr); | ||
151 | |||
152 | for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { | ||
153 | /* At this point: (!vma || addr < vma->vm_end). */ | ||
154 | if (addr < VA_EXCLUDE_START && | ||
155 | (addr + len) >= VA_EXCLUDE_START) { | ||
156 | addr = VA_EXCLUDE_END; | ||
157 | vma = find_vma(mm, VA_EXCLUDE_END); | ||
158 | } | ||
159 | if (unlikely(task_size < addr)) { | ||
160 | if (start_addr != TASK_UNMAPPED_BASE) { | ||
161 | start_addr = addr = TASK_UNMAPPED_BASE; | ||
162 | mm->cached_hole_size = 0; | ||
163 | goto full_search; | ||
164 | } | ||
165 | return -ENOMEM; | ||
166 | } | ||
167 | if (likely(!vma || addr + len <= vma->vm_start)) { | ||
168 | /* | ||
169 | * Remember the place where we stopped the search: | ||
170 | */ | ||
171 | mm->free_area_cache = addr + len; | ||
172 | return addr; | ||
173 | } | ||
174 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
175 | mm->cached_hole_size = vma->vm_start - addr; | ||
176 | |||
177 | addr = vma->vm_end; | ||
178 | if (do_color_align) | ||
179 | addr = COLOUR_ALIGN(addr, pgoff); | ||
180 | } | ||
181 | } | 142 | } |
182 | 143 | ||
183 | unsigned long | 144 | unsigned long |
@@ -190,6 +151,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
190 | unsigned long task_size = STACK_TOP32; | 151 | unsigned long task_size = STACK_TOP32; |
191 | unsigned long addr = addr0; | 152 | unsigned long addr = addr0; |
192 | int do_color_align; | 153 | int do_color_align; |
154 | struct vm_unmapped_area_info info; | ||
193 | 155 | ||
194 | /* This should only ever run for 32-bit processes. */ | 156 | /* This should only ever run for 32-bit processes. */ |
195 | BUG_ON(!test_thread_flag(TIF_32BIT)); | 157 | BUG_ON(!test_thread_flag(TIF_32BIT)); |
@@ -214,7 +176,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
214 | /* requesting a specific address */ | 176 | /* requesting a specific address */ |
215 | if (addr) { | 177 | if (addr) { |
216 | if (do_color_align) | 178 | if (do_color_align) |
217 | addr = COLOUR_ALIGN(addr, pgoff); | 179 | addr = COLOR_ALIGN(addr, pgoff); |
218 | else | 180 | else |
219 | addr = PAGE_ALIGN(addr); | 181 | addr = PAGE_ALIGN(addr); |
220 | 182 | ||
@@ -224,73 +186,27 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
224 | return addr; | 186 | return addr; |
225 | } | 187 | } |
226 | 188 | ||
227 | /* check if free_area_cache is useful for us */ | 189 | info.flags = VM_UNMAPPED_AREA_TOPDOWN; |
228 | if (len <= mm->cached_hole_size) { | 190 | info.length = len; |
229 | mm->cached_hole_size = 0; | 191 | info.low_limit = PAGE_SIZE; |
230 | mm->free_area_cache = mm->mmap_base; | 192 | info.high_limit = mm->mmap_base; |
231 | } | 193 | info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; |
194 | info.align_offset = pgoff << PAGE_SHIFT; | ||
195 | addr = vm_unmapped_area(&info); | ||
232 | 196 | ||
233 | /* either no address requested or can't fit in requested address hole */ | ||
234 | addr = mm->free_area_cache; | ||
235 | if (do_color_align) { | ||
236 | unsigned long base = COLOUR_ALIGN_DOWN(addr-len, pgoff); | ||
237 | |||
238 | addr = base + len; | ||
239 | } | ||
240 | |||
241 | /* make sure it can fit in the remaining address space */ | ||
242 | if (likely(addr > len)) { | ||
243 | vma = find_vma(mm, addr-len); | ||
244 | if (!vma || addr <= vma->vm_start) { | ||
245 | /* remember the address as a hint for next time */ | ||
246 | return (mm->free_area_cache = addr-len); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | if (unlikely(mm->mmap_base < len)) | ||
251 | goto bottomup; | ||
252 | |||
253 | addr = mm->mmap_base-len; | ||
254 | if (do_color_align) | ||
255 | addr = COLOUR_ALIGN_DOWN(addr, pgoff); | ||
256 | |||
257 | do { | ||
258 | /* | ||
259 | * Lookup failure means no vma is above this address, | ||
260 | * else if new region fits below vma->vm_start, | ||
261 | * return with success: | ||
262 | */ | ||
263 | vma = find_vma(mm, addr); | ||
264 | if (likely(!vma || addr+len <= vma->vm_start)) { | ||
265 | /* remember the address as a hint for next time */ | ||
266 | return (mm->free_area_cache = addr); | ||
267 | } | ||
268 | |||
269 | /* remember the largest hole we saw so far */ | ||
270 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
271 | mm->cached_hole_size = vma->vm_start - addr; | ||
272 | |||
273 | /* try just below the current vma->vm_start */ | ||
274 | addr = vma->vm_start-len; | ||
275 | if (do_color_align) | ||
276 | addr = COLOUR_ALIGN_DOWN(addr, pgoff); | ||
277 | } while (likely(len < vma->vm_start)); | ||
278 | |||
279 | bottomup: | ||
280 | /* | 197 | /* |
281 | * A failed mmap() very likely causes application failure, | 198 | * A failed mmap() very likely causes application failure, |
282 | * so fall back to the bottom-up function here. This scenario | 199 | * so fall back to the bottom-up function here. This scenario |
283 | * can happen with large stack limits and large mmap() | 200 | * can happen with large stack limits and large mmap() |
284 | * allocations. | 201 | * allocations. |
285 | */ | 202 | */ |
286 | mm->cached_hole_size = ~0UL; | 203 | if (addr & ~PAGE_MASK) { |
287 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 204 | VM_BUG_ON(addr != -ENOMEM); |
288 | addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); | 205 | info.flags = 0; |
289 | /* | 206 | info.low_limit = TASK_UNMAPPED_BASE; |
290 | * Restore the topdown base: | 207 | info.high_limit = STACK_TOP32; |
291 | */ | 208 | addr = vm_unmapped_area(&info); |
292 | mm->free_area_cache = mm->mmap_base; | 209 | } |
293 | mm->cached_hole_size = ~0UL; | ||
294 | 210 | ||
295 | return addr; | 211 | return addr; |
296 | } | 212 | } |
@@ -730,24 +646,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
730 | return ret; | 646 | return ret; |
731 | } | 647 | } |
732 | 648 | ||
733 | /* | 649 | asmlinkage long sys_kern_features(void) |
734 | * Do a system call from kernel instead of calling sys_execve so we | ||
735 | * end up with proper pt_regs. | ||
736 | */ | ||
737 | int kernel_execve(const char *filename, | ||
738 | const char *const argv[], | ||
739 | const char *const envp[]) | ||
740 | { | 650 | { |
741 | long __res; | 651 | return KERN_FEATURE_MIXED_MODE_STACK; |
742 | register long __g1 __asm__ ("g1") = __NR_execve; | ||
743 | register long __o0 __asm__ ("o0") = (long)(filename); | ||
744 | register long __o1 __asm__ ("o1") = (long)(argv); | ||
745 | register long __o2 __asm__ ("o2") = (long)(envp); | ||
746 | asm volatile ("t 0x6d\n\t" | ||
747 | "sub %%g0, %%o0, %0\n\t" | ||
748 | "movcc %%xcc, %%o0, %0\n\t" | ||
749 | : "=r" (__res), "=&r" (__o0) | ||
750 | : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) | ||
751 | : "cc"); | ||
752 | return __res; | ||
753 | } | 652 | } |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 7f5f65d0b3fd..e0fed7711a94 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
@@ -1,23 +1,19 @@ | |||
1 | /* SunOS's execv() call only specifies the argv argument, the | 1 | /* SunOS's execv() call only specifies the argv argument, the |
2 | * environment settings are the same as the calling processes. | 2 | * environment settings are the same as the calling processes. |
3 | */ | 3 | */ |
4 | sys_execve: | 4 | sys64_execve: |
5 | sethi %hi(sparc_execve), %g1 | 5 | set sys_execve, %g1 |
6 | ba,pt %xcc, execve_merge | 6 | jmpl %g1, %g0 |
7 | or %g1, %lo(sparc_execve), %g1 | 7 | flushw |
8 | 8 | ||
9 | #ifdef CONFIG_COMPAT | 9 | #ifdef CONFIG_COMPAT |
10 | sunos_execv: | 10 | sunos_execv: |
11 | stx %g0, [%sp + PTREGS_OFF + PT_V9_I2] | 11 | mov %g0, %o2 |
12 | sys32_execve: | 12 | sys32_execve: |
13 | sethi %hi(sparc32_execve), %g1 | 13 | set compat_sys_execve, %g1 |
14 | or %g1, %lo(sparc32_execve), %g1 | ||
15 | #endif | ||
16 | |||
17 | execve_merge: | ||
18 | flushw | ||
19 | jmpl %g1, %g0 | 14 | jmpl %g1, %g0 |
20 | add %sp, PTREGS_OFF, %o0 | 15 | flushw |
16 | #endif | ||
21 | 17 | ||
22 | .align 32 | 18 | .align 32 |
23 | sys_sparc_pipe: | 19 | sys_sparc_pipe: |
@@ -112,16 +108,31 @@ sys_clone: | |||
112 | ret_from_syscall: | 108 | ret_from_syscall: |
113 | /* Clear current_thread_info()->new_child. */ | 109 | /* Clear current_thread_info()->new_child. */ |
114 | stb %g0, [%g6 + TI_NEW_CHILD] | 110 | stb %g0, [%g6 + TI_NEW_CHILD] |
115 | ldx [%g6 + TI_FLAGS], %l0 | ||
116 | call schedule_tail | 111 | call schedule_tail |
117 | mov %g7, %o0 | 112 | mov %g7, %o0 |
113 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 | ||
114 | brnz,pt %o0, ret_sys_call | ||
115 | ldx [%g6 + TI_FLAGS], %l0 | ||
116 | ldx [%sp + PTREGS_OFF + PT_V9_G1], %l1 | ||
117 | call %l1 | ||
118 | ldx [%sp + PTREGS_OFF + PT_V9_G2], %o0 | ||
118 | ba,pt %xcc, ret_sys_call | 119 | ba,pt %xcc, ret_sys_call |
119 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 | 120 | mov 0, %o0 |
121 | |||
122 | .globl sparc_exit_group | ||
123 | .type sparc_exit_group,#function | ||
124 | sparc_exit_group: | ||
125 | sethi %hi(sys_exit_group), %g7 | ||
126 | ba,pt %xcc, 1f | ||
127 | or %g7, %lo(sys_exit_group), %g7 | ||
128 | .size sparc_exit_group,.-sparc_exit_group | ||
120 | 129 | ||
121 | .globl sparc_exit | 130 | .globl sparc_exit |
122 | .type sparc_exit,#function | 131 | .type sparc_exit,#function |
123 | sparc_exit: | 132 | sparc_exit: |
124 | rdpr %pstate, %g2 | 133 | sethi %hi(sys_exit), %g7 |
134 | or %g7, %lo(sys_exit), %g7 | ||
135 | 1: rdpr %pstate, %g2 | ||
125 | wrpr %g2, PSTATE_IE, %pstate | 136 | wrpr %g2, PSTATE_IE, %pstate |
126 | rdpr %otherwin, %g1 | 137 | rdpr %otherwin, %g1 |
127 | rdpr %cansave, %g3 | 138 | rdpr %cansave, %g3 |
@@ -129,7 +140,7 @@ sparc_exit: | |||
129 | wrpr %g3, 0x0, %cansave | 140 | wrpr %g3, 0x0, %cansave |
130 | wrpr %g0, 0x0, %otherwin | 141 | wrpr %g0, 0x0, %otherwin |
131 | wrpr %g2, 0x0, %pstate | 142 | wrpr %g2, 0x0, %pstate |
132 | ba,pt %xcc, sys_exit | 143 | jmpl %g7, %g0 |
133 | stb %g0, [%g6 + TI_WSAVED] | 144 | stb %g0, [%g6 + TI_WSAVED] |
134 | .size sparc_exit,.-sparc_exit | 145 | .size sparc_exit,.-sparc_exit |
135 | 146 | ||
@@ -222,7 +233,6 @@ ret_sys_call: | |||
222 | ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc | 233 | ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc |
223 | 234 | ||
224 | 2: | 235 | 2: |
225 | stb %g0, [%g6 + TI_SYS_NOERROR] | ||
226 | /* System call success, clear Carry condition code. */ | 236 | /* System call success, clear Carry condition code. */ |
227 | andn %g3, %g2, %g3 | 237 | andn %g3, %g2, %g3 |
228 | 3: | 238 | 3: |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 63402f9e9f51..6ac43c36bbbf 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
@@ -85,3 +85,4 @@ sys_call_table: | |||
85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev | 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
88 | /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 3a58e0d66f51..1009ecb92678 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -86,6 +86,7 @@ sys_call_table32: | |||
86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime | 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime |
88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev | 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev |
89 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module | ||
89 | 90 | ||
90 | #endif /* CONFIG_COMPAT */ | 91 | #endif /* CONFIG_COMPAT */ |
91 | 92 | ||
@@ -106,7 +107,7 @@ sys_call_table: | |||
106 | /*40*/ .word sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_nis_syscall | 107 | /*40*/ .word sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_nis_syscall |
107 | .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid | 108 | .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid |
108 | /*50*/ .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl | 109 | /*50*/ .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl |
109 | .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve | 110 | .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys64_execve |
110 | /*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize | 111 | /*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize |
111 | .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall | 112 | .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall |
112 | /*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect | 113 | /*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect |
@@ -132,7 +133,7 @@ sys_call_table: | |||
132 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents | 133 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents |
133 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr | 134 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr |
134 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall | 135 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall |
135 | .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname | 136 | .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname |
136 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl | 137 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl |
137 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask | 138 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask |
138 | /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall | 139 | /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall |
@@ -163,3 +164,4 @@ sys_call_table: | |||
163 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 164 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
164 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 165 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
165 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev | 166 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
167 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module | ||
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 953641549e82..c4c27b0f9063 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c | |||
@@ -278,7 +278,7 @@ static struct platform_device m48t59_rtc = { | |||
278 | }, | 278 | }, |
279 | }; | 279 | }; |
280 | 280 | ||
281 | static int __devinit clock_probe(struct platform_device *op) | 281 | static int clock_probe(struct platform_device *op) |
282 | { | 282 | { |
283 | struct device_node *dp = op->dev.of_node; | 283 | struct device_node *dp = op->dev.of_node; |
284 | const char *model = of_get_property(dp, "model", NULL); | 284 | const char *model = of_get_property(dp, "model", NULL); |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index e861072b9c52..c3d82b5f54ca 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
@@ -419,7 +419,7 @@ static struct platform_device rtc_cmos_device = { | |||
419 | .num_resources = 1, | 419 | .num_resources = 1, |
420 | }; | 420 | }; |
421 | 421 | ||
422 | static int __devinit rtc_probe(struct platform_device *op) | 422 | static int rtc_probe(struct platform_device *op) |
423 | { | 423 | { |
424 | struct resource *r; | 424 | struct resource *r; |
425 | 425 | ||
@@ -477,7 +477,7 @@ static struct platform_device rtc_bq4802_device = { | |||
477 | .num_resources = 1, | 477 | .num_resources = 1, |
478 | }; | 478 | }; |
479 | 479 | ||
480 | static int __devinit bq4802_probe(struct platform_device *op) | 480 | static int bq4802_probe(struct platform_device *op) |
481 | { | 481 | { |
482 | 482 | ||
483 | printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", | 483 | printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", |
@@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { | |||
534 | }, | 534 | }, |
535 | }; | 535 | }; |
536 | 536 | ||
537 | static int __devinit mostek_probe(struct platform_device *op) | 537 | static int mostek_probe(struct platform_device *op) |
538 | { | 538 | { |
539 | struct device_node *dp = op->dev.of_node; | 539 | struct device_node *dp = op->dev.of_node; |
540 | 540 | ||
@@ -746,7 +746,7 @@ void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) | |||
746 | set_irq_regs(old_regs); | 746 | set_irq_regs(old_regs); |
747 | } | 747 | } |
748 | 748 | ||
749 | void __devinit setup_sparc64_timer(void) | 749 | void setup_sparc64_timer(void) |
750 | { | 750 | { |
751 | struct clock_event_device *sevt; | 751 | struct clock_event_device *sevt; |
752 | unsigned long pstate; | 752 | unsigned long pstate; |
@@ -844,7 +844,7 @@ unsigned long long sched_clock(void) | |||
844 | >> SPARC64_NSEC_PER_CYC_SHIFT; | 844 | >> SPARC64_NSEC_PER_CYC_SHIFT; |
845 | } | 845 | } |
846 | 846 | ||
847 | int __devinit read_current_timer(unsigned long *timer_val) | 847 | int read_current_timer(unsigned long *timer_val) |
848 | { | 848 | { |
849 | *timer_val = tick_ops->get_tick(); | 849 | *timer_val = tick_ops->get_tick(); |
850 | return 0; | 850 | return 0; |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index b66a77968f35..e7ecf1507d90 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -2688,8 +2688,8 @@ void __init trap_init(void) | |||
2688 | TI_PRE_COUNT != offsetof(struct thread_info, | 2688 | TI_PRE_COUNT != offsetof(struct thread_info, |
2689 | preempt_count) || | 2689 | preempt_count) || |
2690 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || | 2690 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || |
2691 | TI_SYS_NOERROR != offsetof(struct thread_info, | 2691 | TI_CURRENT_DS != offsetof(struct thread_info, |
2692 | syscall_noerror) || | 2692 | current_ds) || |
2693 | TI_RESTART_BLOCK != offsetof(struct thread_info, | 2693 | TI_RESTART_BLOCK != offsetof(struct thread_info, |
2694 | restart_block) || | 2694 | restart_block) || |
2695 | TI_KUNA_REGS != offsetof(struct thread_info, | 2695 | TI_KUNA_REGS != offsetof(struct thread_info, |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index f81d038f7340..8201c25e7669 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm) | |||
113 | 113 | ||
114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | 114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
115 | { | 115 | { |
116 | unsigned long value; | 116 | unsigned long value, fp; |
117 | 117 | ||
118 | if (reg < 16) | 118 | if (reg < 16) |
119 | return (!reg ? 0 : regs->u_regs[reg]); | 119 | return (!reg ? 0 : regs->u_regs[reg]); |
120 | |||
121 | fp = regs->u_regs[UREG_FP]; | ||
122 | |||
120 | if (regs->tstate & TSTATE_PRIV) { | 123 | if (regs->tstate & TSTATE_PRIV) { |
121 | struct reg_window *win; | 124 | struct reg_window *win; |
122 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 125 | win = (struct reg_window *)(fp + STACK_BIAS); |
123 | value = win->locals[reg - 16]; | 126 | value = win->locals[reg - 16]; |
124 | } else if (test_thread_flag(TIF_32BIT)) { | 127 | } else if (!test_thread_64bit_stack(fp)) { |
125 | struct reg_window32 __user *win32; | 128 | struct reg_window32 __user *win32; |
126 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 129 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
127 | get_user(value, &win32->locals[reg - 16]); | 130 | get_user(value, &win32->locals[reg - 16]); |
128 | } else { | 131 | } else { |
129 | struct reg_window __user *win; | 132 | struct reg_window __user *win; |
130 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 133 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
131 | get_user(value, &win->locals[reg - 16]); | 134 | get_user(value, &win->locals[reg - 16]); |
132 | } | 135 | } |
133 | return value; | 136 | return value; |
@@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | |||
135 | 138 | ||
136 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) | 139 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) |
137 | { | 140 | { |
141 | unsigned long fp; | ||
142 | |||
138 | if (reg < 16) | 143 | if (reg < 16) |
139 | return ®s->u_regs[reg]; | 144 | return ®s->u_regs[reg]; |
145 | |||
146 | fp = regs->u_regs[UREG_FP]; | ||
147 | |||
140 | if (regs->tstate & TSTATE_PRIV) { | 148 | if (regs->tstate & TSTATE_PRIV) { |
141 | struct reg_window *win; | 149 | struct reg_window *win; |
142 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 150 | win = (struct reg_window *)(fp + STACK_BIAS); |
143 | return &win->locals[reg - 16]; | 151 | return &win->locals[reg - 16]; |
144 | } else if (test_thread_flag(TIF_32BIT)) { | 152 | } else if (!test_thread_64bit_stack(fp)) { |
145 | struct reg_window32 *win32; | 153 | struct reg_window32 *win32; |
146 | win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 154 | win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); |
147 | return (unsigned long *)&win32->locals[reg - 16]; | 155 | return (unsigned long *)&win32->locals[reg - 16]; |
148 | } else { | 156 | } else { |
149 | struct reg_window *win; | 157 | struct reg_window *win; |
150 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 158 | win = (struct reg_window *)(fp + STACK_BIAS); |
151 | return &win->locals[reg - 16]; | 159 | return &win->locals[reg - 16]; |
152 | } | 160 | } |
153 | } | 161 | } |
@@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs) | |||
392 | if (rd) | 400 | if (rd) |
393 | regs->u_regs[rd] = ret; | 401 | regs->u_regs[rd] = ret; |
394 | } else { | 402 | } else { |
395 | if (test_thread_flag(TIF_32BIT)) { | 403 | unsigned long fp = regs->u_regs[UREG_FP]; |
404 | |||
405 | if (!test_thread_64bit_stack(fp)) { | ||
396 | struct reg_window32 __user *win32; | 406 | struct reg_window32 __user *win32; |
397 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 407 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
398 | put_user(ret, &win32->locals[rd - 16]); | 408 | put_user(ret, &win32->locals[rd - 16]); |
399 | } else { | 409 | } else { |
400 | struct reg_window __user *win; | 410 | struct reg_window __user *win; |
401 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 411 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
402 | put_user(ret, &win->locals[rd - 16]); | 412 | put_user(ret, &win->locals[rd - 16]); |
403 | } | 413 | } |
404 | } | 414 | } |
@@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) | |||
554 | reg[0] = 0; | 564 | reg[0] = 0; |
555 | if ((insn & 0x780000) == 0x180000) | 565 | if ((insn & 0x780000) == 0x180000) |
556 | reg[1] = 0; | 566 | reg[1] = 0; |
557 | } else if (test_thread_flag(TIF_32BIT)) { | 567 | } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { |
558 | put_user(0, (int __user *) reg); | 568 | put_user(0, (int __user *) reg); |
559 | if ((insn & 0x780000) == 0x180000) | 569 | if ((insn & 0x780000) == 0x180000) |
560 | put_user(0, ((int __user *) reg) + 1); | 570 | put_user(0, ((int __user *) reg) + 1); |
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index 08e074b7eb6a..c096c624ac4d 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c | |||
@@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, | |||
149 | 149 | ||
150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | 150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
151 | { | 151 | { |
152 | unsigned long value; | 152 | unsigned long value, fp; |
153 | 153 | ||
154 | if (reg < 16) | 154 | if (reg < 16) |
155 | return (!reg ? 0 : regs->u_regs[reg]); | 155 | return (!reg ? 0 : regs->u_regs[reg]); |
156 | |||
157 | fp = regs->u_regs[UREG_FP]; | ||
158 | |||
156 | if (regs->tstate & TSTATE_PRIV) { | 159 | if (regs->tstate & TSTATE_PRIV) { |
157 | struct reg_window *win; | 160 | struct reg_window *win; |
158 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 161 | win = (struct reg_window *)(fp + STACK_BIAS); |
159 | value = win->locals[reg - 16]; | 162 | value = win->locals[reg - 16]; |
160 | } else if (test_thread_flag(TIF_32BIT)) { | 163 | } else if (!test_thread_64bit_stack(fp)) { |
161 | struct reg_window32 __user *win32; | 164 | struct reg_window32 __user *win32; |
162 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 165 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
163 | get_user(value, &win32->locals[reg - 16]); | 166 | get_user(value, &win32->locals[reg - 16]); |
164 | } else { | 167 | } else { |
165 | struct reg_window __user *win; | 168 | struct reg_window __user *win; |
166 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 169 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
167 | get_user(value, &win->locals[reg - 16]); | 170 | get_user(value, &win->locals[reg - 16]); |
168 | } | 171 | } |
169 | return value; | 172 | return value; |
@@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | |||
172 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, | 175 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, |
173 | struct pt_regs *regs) | 176 | struct pt_regs *regs) |
174 | { | 177 | { |
178 | unsigned long fp = regs->u_regs[UREG_FP]; | ||
179 | |||
175 | BUG_ON(reg < 16); | 180 | BUG_ON(reg < 16); |
176 | BUG_ON(regs->tstate & TSTATE_PRIV); | 181 | BUG_ON(regs->tstate & TSTATE_PRIV); |
177 | 182 | ||
178 | if (test_thread_flag(TIF_32BIT)) { | 183 | if (!test_thread_64bit_stack(fp)) { |
179 | struct reg_window32 __user *win32; | 184 | struct reg_window32 __user *win32; |
180 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 185 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
181 | return (unsigned long __user *)&win32->locals[reg - 16]; | 186 | return (unsigned long __user *)&win32->locals[reg - 16]; |
182 | } else { | 187 | } else { |
183 | struct reg_window __user *win; | 188 | struct reg_window __user *win; |
184 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 189 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
185 | return &win->locals[reg - 16]; | 190 | return &win->locals[reg - 16]; |
186 | } | 191 | } |
187 | } | 192 | } |
@@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) | |||
204 | } else { | 209 | } else { |
205 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); | 210 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); |
206 | 211 | ||
207 | if (test_thread_flag(TIF_32BIT)) | 212 | if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) |
208 | __put_user((u32)val, (u32 __user *)rd_user); | 213 | __put_user((u32)val, (u32 __user *)rd_user); |
209 | else | 214 | else |
210 | __put_user(val, rd_user); | 215 | __put_user(val, rd_user); |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 89c2c29f154b..0bacceb19150 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -132,6 +132,11 @@ SECTIONS | |||
132 | *(.popc_6insn_patch) | 132 | *(.popc_6insn_patch) |
133 | __popc_6insn_patch_end = .; | 133 | __popc_6insn_patch_end = .; |
134 | } | 134 | } |
135 | .pause_3insn_patch : { | ||
136 | __pause_3insn_patch = .; | ||
137 | *(.pause_3insn_patch) | ||
138 | __pause_3insn_patch_end = .; | ||
139 | } | ||
135 | PERCPU_SECTION(SMP_CACHE_BYTES) | 140 | PERCPU_SECTION(SMP_CACHE_BYTES) |
136 | 141 | ||
137 | . = ALIGN(PAGE_SIZE); | 142 | . = ALIGN(PAGE_SIZE); |
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index a6b0863c27df..1e67ce958369 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S | |||
@@ -43,6 +43,8 @@ spill_fixup_mna: | |||
43 | spill_fixup_dax: | 43 | spill_fixup_dax: |
44 | TRAP_LOAD_THREAD_REG(%g6, %g1) | 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
45 | ldx [%g6 + TI_FLAGS], %g1 | 45 | ldx [%g6 + TI_FLAGS], %g1 |
46 | andcc %sp, 0x1, %g0 | ||
47 | movne %icc, 0, %g1 | ||
46 | andcc %g1, _TIF_32BIT, %g0 | 48 | andcc %g1, _TIF_32BIT, %g0 |
47 | ldub [%g6 + TI_WSAVED], %g1 | 49 | ldub [%g6 + TI_WSAVED], %g1 |
48 | sll %g1, 3, %g3 | 50 | sll %g1, 3, %g3 |
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 4d502da3de78..85c233d0a340 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S | |||
@@ -1,6 +1,6 @@ | |||
1 | /* atomic.S: These things are too big to do inline. | 1 | /* atomic.S: These things are too big to do inline. |
2 | * | 2 | * |
3 | * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
@@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ | |||
117 | sub %g1, %o0, %o0 | 117 | sub %g1, %o0, %o0 |
118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
119 | ENDPROC(atomic64_sub_ret) | 119 | ENDPROC(atomic64_sub_ret) |
120 | |||
121 | ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ | ||
122 | BACKOFF_SETUP(%o2) | ||
123 | 1: ldx [%o0], %g1 | ||
124 | brlez,pn %g1, 3f | ||
125 | sub %g1, 1, %g7 | ||
126 | casx [%o0], %g1, %g7 | ||
127 | cmp %g1, %g7 | ||
128 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) | ||
129 | nop | ||
130 | 3: retl | ||
131 | sub %g1, 1, %o0 | ||
132 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
133 | ENDPROC(atomic64_dec_if_positive) | ||
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index ee31b884c61b..0c4e35e522fa 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c | |||
@@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add); | |||
116 | EXPORT_SYMBOL(atomic64_add_ret); | 116 | EXPORT_SYMBOL(atomic64_add_ret); |
117 | EXPORT_SYMBOL(atomic64_sub); | 117 | EXPORT_SYMBOL(atomic64_sub); |
118 | EXPORT_SYMBOL(atomic64_sub_ret); | 118 | EXPORT_SYMBOL(atomic64_sub_ret); |
119 | EXPORT_SYMBOL(atomic64_dec_if_positive); | ||
119 | 120 | ||
120 | /* Atomic bit operations. */ | 121 | /* Atomic bit operations. */ |
121 | EXPORT_SYMBOL(test_and_set_bit); | 122 | EXPORT_SYMBOL(test_and_set_bit); |
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 1704068da928..034aadbff036 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c | |||
@@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) | |||
320 | XR = 0; | 320 | XR = 0; |
321 | else if (freg < 16) | 321 | else if (freg < 16) |
322 | XR = regs->u_regs[freg]; | 322 | XR = regs->u_regs[freg]; |
323 | else if (test_thread_flag(TIF_32BIT)) { | 323 | else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { |
324 | struct reg_window32 __user *win32; | 324 | struct reg_window32 __user *win32; |
325 | flushw_user (); | 325 | flushw_user (); |
326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); |
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index f76f83d5ac63..d2b59441ebdd 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c | |||
@@ -30,55 +30,28 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp, | |||
30 | unsigned long pgoff, | 30 | unsigned long pgoff, |
31 | unsigned long flags) | 31 | unsigned long flags) |
32 | { | 32 | { |
33 | struct mm_struct *mm = current->mm; | ||
34 | struct vm_area_struct * vma; | ||
35 | unsigned long task_size = TASK_SIZE; | 33 | unsigned long task_size = TASK_SIZE; |
36 | unsigned long start_addr; | 34 | struct vm_unmapped_area_info info; |
37 | 35 | ||
38 | if (test_thread_flag(TIF_32BIT)) | 36 | if (test_thread_flag(TIF_32BIT)) |
39 | task_size = STACK_TOP32; | 37 | task_size = STACK_TOP32; |
40 | if (unlikely(len >= VA_EXCLUDE_START)) | ||
41 | return -ENOMEM; | ||
42 | 38 | ||
43 | if (len > mm->cached_hole_size) { | 39 | info.flags = 0; |
44 | start_addr = addr = mm->free_area_cache; | 40 | info.length = len; |
45 | } else { | 41 | info.low_limit = TASK_UNMAPPED_BASE; |
46 | start_addr = addr = TASK_UNMAPPED_BASE; | 42 | info.high_limit = min(task_size, VA_EXCLUDE_START); |
47 | mm->cached_hole_size = 0; | 43 | info.align_mask = PAGE_MASK & ~HPAGE_MASK; |
44 | info.align_offset = 0; | ||
45 | addr = vm_unmapped_area(&info); | ||
46 | |||
47 | if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) { | ||
48 | VM_BUG_ON(addr != -ENOMEM); | ||
49 | info.low_limit = VA_EXCLUDE_END; | ||
50 | info.high_limit = task_size; | ||
51 | addr = vm_unmapped_area(&info); | ||
48 | } | 52 | } |
49 | 53 | ||
50 | task_size -= len; | 54 | return addr; |
51 | |||
52 | full_search: | ||
53 | addr = ALIGN(addr, HPAGE_SIZE); | ||
54 | |||
55 | for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { | ||
56 | /* At this point: (!vma || addr < vma->vm_end). */ | ||
57 | if (addr < VA_EXCLUDE_START && | ||
58 | (addr + len) >= VA_EXCLUDE_START) { | ||
59 | addr = VA_EXCLUDE_END; | ||
60 | vma = find_vma(mm, VA_EXCLUDE_END); | ||
61 | } | ||
62 | if (unlikely(task_size < addr)) { | ||
63 | if (start_addr != TASK_UNMAPPED_BASE) { | ||
64 | start_addr = addr = TASK_UNMAPPED_BASE; | ||
65 | mm->cached_hole_size = 0; | ||
66 | goto full_search; | ||
67 | } | ||
68 | return -ENOMEM; | ||
69 | } | ||
70 | if (likely(!vma || addr + len <= vma->vm_start)) { | ||
71 | /* | ||
72 | * Remember the place where we stopped the search: | ||
73 | */ | ||
74 | mm->free_area_cache = addr + len; | ||
75 | return addr; | ||
76 | } | ||
77 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
78 | mm->cached_hole_size = vma->vm_start - addr; | ||
79 | |||
80 | addr = ALIGN(vma->vm_end, HPAGE_SIZE); | ||
81 | } | ||
82 | } | 55 | } |
83 | 56 | ||
84 | static unsigned long | 57 | static unsigned long |
@@ -87,71 +60,34 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
87 | const unsigned long pgoff, | 60 | const unsigned long pgoff, |
88 | const unsigned long flags) | 61 | const unsigned long flags) |
89 | { | 62 | { |
90 | struct vm_area_struct *vma; | ||
91 | struct mm_struct *mm = current->mm; | 63 | struct mm_struct *mm = current->mm; |
92 | unsigned long addr = addr0; | 64 | unsigned long addr = addr0; |
65 | struct vm_unmapped_area_info info; | ||
93 | 66 | ||
94 | /* This should only ever run for 32-bit processes. */ | 67 | /* This should only ever run for 32-bit processes. */ |
95 | BUG_ON(!test_thread_flag(TIF_32BIT)); | 68 | BUG_ON(!test_thread_flag(TIF_32BIT)); |
96 | 69 | ||
97 | /* check if free_area_cache is useful for us */ | 70 | info.flags = VM_UNMAPPED_AREA_TOPDOWN; |
98 | if (len <= mm->cached_hole_size) { | 71 | info.length = len; |
99 | mm->cached_hole_size = 0; | 72 | info.low_limit = PAGE_SIZE; |
100 | mm->free_area_cache = mm->mmap_base; | 73 | info.high_limit = mm->mmap_base; |
101 | } | 74 | info.align_mask = PAGE_MASK & ~HPAGE_MASK; |
102 | 75 | info.align_offset = 0; | |
103 | /* either no address requested or can't fit in requested address hole */ | 76 | addr = vm_unmapped_area(&info); |
104 | addr = mm->free_area_cache & HPAGE_MASK; | ||
105 | |||
106 | /* make sure it can fit in the remaining address space */ | ||
107 | if (likely(addr > len)) { | ||
108 | vma = find_vma(mm, addr-len); | ||
109 | if (!vma || addr <= vma->vm_start) { | ||
110 | /* remember the address as a hint for next time */ | ||
111 | return (mm->free_area_cache = addr-len); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (unlikely(mm->mmap_base < len)) | ||
116 | goto bottomup; | ||
117 | |||
118 | addr = (mm->mmap_base-len) & HPAGE_MASK; | ||
119 | |||
120 | do { | ||
121 | /* | ||
122 | * Lookup failure means no vma is above this address, | ||
123 | * else if new region fits below vma->vm_start, | ||
124 | * return with success: | ||
125 | */ | ||
126 | vma = find_vma(mm, addr); | ||
127 | if (likely(!vma || addr+len <= vma->vm_start)) { | ||
128 | /* remember the address as a hint for next time */ | ||
129 | return (mm->free_area_cache = addr); | ||
130 | } | ||
131 | |||
132 | /* remember the largest hole we saw so far */ | ||
133 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
134 | mm->cached_hole_size = vma->vm_start - addr; | ||
135 | |||
136 | /* try just below the current vma->vm_start */ | ||
137 | addr = (vma->vm_start-len) & HPAGE_MASK; | ||
138 | } while (likely(len < vma->vm_start)); | ||
139 | 77 | ||
140 | bottomup: | ||
141 | /* | 78 | /* |
142 | * A failed mmap() very likely causes application failure, | 79 | * A failed mmap() very likely causes application failure, |
143 | * so fall back to the bottom-up function here. This scenario | 80 | * so fall back to the bottom-up function here. This scenario |
144 | * can happen with large stack limits and large mmap() | 81 | * can happen with large stack limits and large mmap() |
145 | * allocations. | 82 | * allocations. |
146 | */ | 83 | */ |
147 | mm->cached_hole_size = ~0UL; | 84 | if (addr & ~PAGE_MASK) { |
148 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 85 | VM_BUG_ON(addr != -ENOMEM); |
149 | addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); | 86 | info.flags = 0; |
150 | /* | 87 | info.low_limit = TASK_UNMAPPED_BASE; |
151 | * Restore the topdown base: | 88 | info.high_limit = STACK_TOP32; |
152 | */ | 89 | addr = vm_unmapped_area(&info); |
153 | mm->free_area_cache = mm->mmap_base; | 90 | } |
154 | mm->cached_hole_size = ~0UL; | ||
155 | 91 | ||
156 | return addr; | 92 | return addr; |
157 | } | 93 | } |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 9e28a118e6a4..c3b72423c846 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -87,8 +87,8 @@ static unsigned long cpu_pgsz_mask; | |||
87 | 87 | ||
88 | #define MAX_BANKS 32 | 88 | #define MAX_BANKS 32 |
89 | 89 | ||
90 | static struct linux_prom64_registers pavail[MAX_BANKS] __devinitdata; | 90 | static struct linux_prom64_registers pavail[MAX_BANKS]; |
91 | static int pavail_ents __devinitdata; | 91 | static int pavail_ents; |
92 | 92 | ||
93 | static int cmp_p64(const void *a, const void *b) | 93 | static int cmp_p64(const void *a, const void *b) |
94 | { | 94 | { |
@@ -624,7 +624,7 @@ static void __init inherit_prom_mappings(void) | |||
624 | void prom_world(int enter) | 624 | void prom_world(int enter) |
625 | { | 625 | { |
626 | if (!enter) | 626 | if (!enter) |
627 | set_fs((mm_segment_t) { get_thread_current_ds() }); | 627 | set_fs(get_fs()); |
628 | 628 | ||
629 | __asm__ __volatile__("flushw"); | 629 | __asm__ __volatile__("flushw"); |
630 | } | 630 | } |
@@ -1931,7 +1931,7 @@ void __init paging_init(void) | |||
1931 | printk("Booting Linux...\n"); | 1931 | printk("Booting Linux...\n"); |
1932 | } | 1932 | } |
1933 | 1933 | ||
1934 | int __devinit page_in_phys_avail(unsigned long paddr) | 1934 | int page_in_phys_avail(unsigned long paddr) |
1935 | { | 1935 | { |
1936 | int i; | 1936 | int i; |
1937 | 1937 | ||
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 28368701ef79..3109ca684a99 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/netdevice.h> | 3 | #include <linux/netdevice.h> |
4 | #include <linux/filter.h> | 4 | #include <linux/filter.h> |
5 | #include <linux/cache.h> | 5 | #include <linux/cache.h> |
6 | #include <linux/if_vlan.h> | ||
6 | 7 | ||
7 | #include <asm/cacheflush.h> | 8 | #include <asm/cacheflush.h> |
8 | #include <asm/ptrace.h> | 9 | #include <asm/ptrace.h> |
@@ -312,6 +313,12 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \ | |||
312 | #define emit_addi(R1, IMM, R3) \ | 313 | #define emit_addi(R1, IMM, R3) \ |
313 | *prog++ = (ADD | IMMED | RS1(R1) | S13(IMM) | RD(R3)) | 314 | *prog++ = (ADD | IMMED | RS1(R1) | S13(IMM) | RD(R3)) |
314 | 315 | ||
316 | #define emit_and(R1, R2, R3) \ | ||
317 | *prog++ = (AND | RS1(R1) | RS2(R2) | RD(R3)) | ||
318 | |||
319 | #define emit_andi(R1, IMM, R3) \ | ||
320 | *prog++ = (AND | IMMED | RS1(R1) | S13(IMM) | RD(R3)) | ||
321 | |||
315 | #define emit_alloc_stack(SZ) \ | 322 | #define emit_alloc_stack(SZ) \ |
316 | *prog++ = (SUB | IMMED | RS1(SP) | S13(SZ) | RD(SP)) | 323 | *prog++ = (SUB | IMMED | RS1(SP) | S13(SZ) | RD(SP)) |
317 | 324 | ||
@@ -415,6 +422,8 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
415 | case BPF_S_ANC_IFINDEX: | 422 | case BPF_S_ANC_IFINDEX: |
416 | case BPF_S_ANC_MARK: | 423 | case BPF_S_ANC_MARK: |
417 | case BPF_S_ANC_RXHASH: | 424 | case BPF_S_ANC_RXHASH: |
425 | case BPF_S_ANC_VLAN_TAG: | ||
426 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
418 | case BPF_S_ANC_CPU: | 427 | case BPF_S_ANC_CPU: |
419 | case BPF_S_ANC_QUEUE: | 428 | case BPF_S_ANC_QUEUE: |
420 | case BPF_S_LD_W_ABS: | 429 | case BPF_S_LD_W_ABS: |
@@ -600,6 +609,16 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
600 | case BPF_S_ANC_RXHASH: | 609 | case BPF_S_ANC_RXHASH: |
601 | emit_skb_load32(rxhash, r_A); | 610 | emit_skb_load32(rxhash, r_A); |
602 | break; | 611 | break; |
612 | case BPF_S_ANC_VLAN_TAG: | ||
613 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
614 | emit_skb_load16(vlan_tci, r_A); | ||
615 | if (filter[i].code == BPF_S_ANC_VLAN_TAG) { | ||
616 | emit_andi(r_A, VLAN_VID_MASK, r_A); | ||
617 | } else { | ||
618 | emit_loadimm(VLAN_TAG_PRESENT, r_TMP); | ||
619 | emit_and(r_A, r_TMP, r_A); | ||
620 | } | ||
621 | break; | ||
603 | 622 | ||
604 | case BPF_S_LD_IMM: | 623 | case BPF_S_LD_IMM: |
605 | emit_loadimm(K, r_A); | 624 | emit_loadimm(K, r_A); |