diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-16 10:39:30 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-16 10:39:30 -0500 |
| commit | 62735e5231e2de4c491c7cd52f83ce0fe64b4c36 (patch) | |
| tree | 6bd255649afb17d97b5ce549b15869150be8ef13 | |
| parent | 7279d7cb529b083d26d59b0ef9e369e5fd1e2332 (diff) | |
| parent | ae289dc1f474ff380e9d7601f02e4d766cbba408 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 patches from Martin Schwidefsky:
"Some more bug fixes and a config change.
The signal bug is nasty, if the clock_gettime vdso function is
interrupted by a signal while in access-register-mode we end up with
an endless signal loop until the signal stack is full. The config
change is for aligned struct pages, gives us 8% improvement with
hackbench."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/3215: fix tty close handling
s390/mm: have 16 byte aligned struct pages
s390/gup: fix access_ok() usage in __get_user_pages_fast()
s390/gup: add missing TASK_SIZE check to get_user_pages_fast()
s390/topology: fix core id vs physical package id mix-up
s390/signal: set correct address space control
| -rw-r--r-- | arch/s390/Kconfig | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/compat.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/topology.h | 3 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/ptrace.h | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_signal.c | 14 | ||||
| -rw-r--r-- | arch/s390/kernel/signal.c | 14 | ||||
| -rw-r--r-- | arch/s390/kernel/topology.c | 6 | ||||
| -rw-r--r-- | arch/s390/mm/gup.c | 5 | ||||
| -rw-r--r-- | drivers/s390/char/con3215.c | 12 |
9 files changed, 42 insertions, 19 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dba755a43e6..d385f396dfee 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -96,6 +96,7 @@ config S390 | |||
| 96 | select HAVE_MEMBLOCK_NODE_MAP | 96 | select HAVE_MEMBLOCK_NODE_MAP |
| 97 | select HAVE_CMPXCHG_LOCAL | 97 | select HAVE_CMPXCHG_LOCAL |
| 98 | select HAVE_CMPXCHG_DOUBLE | 98 | select HAVE_CMPXCHG_DOUBLE |
| 99 | select HAVE_ALIGNED_STRUCT_PAGE if SLUB | ||
| 99 | select HAVE_VIRT_CPU_ACCOUNTING | 100 | select HAVE_VIRT_CPU_ACCOUNTING |
| 100 | select VIRT_CPU_ACCOUNTING | 101 | select VIRT_CPU_ACCOUNTING |
| 101 | select ARCH_DISCARD_MEMBLOCK | 102 | select ARCH_DISCARD_MEMBLOCK |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a34a9d612fc0..18cd6b592650 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #define PSW32_MASK_CC 0x00003000UL | 20 | #define PSW32_MASK_CC 0x00003000UL |
| 21 | #define PSW32_MASK_PM 0x00000f00UL | 21 | #define PSW32_MASK_PM 0x00000f00UL |
| 22 | 22 | ||
| 23 | #define PSW32_MASK_USER 0x00003F00UL | 23 | #define PSW32_MASK_USER 0x0000FF00UL |
| 24 | 24 | ||
| 25 | #define PSW32_ADDR_AMODE 0x80000000UL | 25 | #define PSW32_ADDR_AMODE 0x80000000UL |
| 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL | 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL |
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 9ca305383760..9935cbd6a46f 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
| @@ -8,6 +8,9 @@ struct cpu; | |||
| 8 | 8 | ||
| 9 | #ifdef CONFIG_SCHED_BOOK | 9 | #ifdef CONFIG_SCHED_BOOK |
| 10 | 10 | ||
| 11 | extern unsigned char cpu_socket_id[NR_CPUS]; | ||
| 12 | #define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) | ||
| 13 | |||
| 11 | extern unsigned char cpu_core_id[NR_CPUS]; | 14 | extern unsigned char cpu_core_id[NR_CPUS]; |
| 12 | extern cpumask_t cpu_core_map[NR_CPUS]; | 15 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| 13 | 16 | ||
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 705588a16d70..a5ca214b34fd 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h | |||
| @@ -239,7 +239,7 @@ typedef struct | |||
| 239 | #define PSW_MASK_EA 0x00000000UL | 239 | #define PSW_MASK_EA 0x00000000UL |
| 240 | #define PSW_MASK_BA 0x00000000UL | 240 | #define PSW_MASK_BA 0x00000000UL |
| 241 | 241 | ||
| 242 | #define PSW_MASK_USER 0x00003F00UL | 242 | #define PSW_MASK_USER 0x0000FF00UL |
| 243 | 243 | ||
| 244 | #define PSW_ADDR_AMODE 0x80000000UL | 244 | #define PSW_ADDR_AMODE 0x80000000UL |
| 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL | 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL |
| @@ -269,7 +269,7 @@ typedef struct | |||
| 269 | #define PSW_MASK_EA 0x0000000100000000UL | 269 | #define PSW_MASK_EA 0x0000000100000000UL |
| 270 | #define PSW_MASK_BA 0x0000000080000000UL | 270 | #define PSW_MASK_BA 0x0000000080000000UL |
| 271 | 271 | ||
| 272 | #define PSW_MASK_USER 0x00003F8180000000UL | 272 | #define PSW_MASK_USER 0x0000FF8180000000UL |
| 273 | 273 | ||
| 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL | 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL |
| 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL | 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a1e8a8694bb7..593fcc9253fc 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
| @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) | |||
| 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | | 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | | 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | |
| 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); | 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); |
| 312 | /* Check for invalid user address space control. */ | ||
| 313 | if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | ||
| 314 | regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | ||
| 315 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 312 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); | 316 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); |
| 313 | for (i = 0; i < NUM_GPRS; i++) | 317 | for (i = 0; i < NUM_GPRS; i++) |
| 314 | regs->gprs[i] = (__u64) regs32.gprs[i]; | 318 | regs->gprs[i] = (__u64) regs32.gprs[i]; |
| @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
| 481 | 485 | ||
| 482 | /* Set up registers for signal handler */ | 486 | /* Set up registers for signal handler */ |
| 483 | regs->gprs[15] = (__force __u64) frame; | 487 | regs->gprs[15] = (__force __u64) frame; |
| 484 | regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | 488 | /* Force 31 bit amode and default user address space control. */ |
| 489 | regs->psw.mask = PSW_MASK_BA | | ||
| 490 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 491 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 485 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; | 492 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; |
| 486 | 493 | ||
| 487 | regs->gprs[2] = map_signal(sig); | 494 | regs->gprs[2] = map_signal(sig); |
| @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 549 | 556 | ||
| 550 | /* Set up registers for signal handler */ | 557 | /* Set up registers for signal handler */ |
| 551 | regs->gprs[15] = (__force __u64) frame; | 558 | regs->gprs[15] = (__force __u64) frame; |
| 552 | regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | 559 | /* Force 31 bit amode and default user address space control. */ |
| 560 | regs->psw.mask = PSW_MASK_BA | | ||
| 561 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 562 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 553 | regs->psw.addr = (__u64) ka->sa.sa_handler; | 563 | regs->psw.addr = (__u64) ka->sa.sa_handler; |
| 554 | 564 | ||
| 555 | regs->gprs[2] = map_signal(sig); | 565 | regs->gprs[2] = map_signal(sig); |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a37ef00..d1259d875074 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
| @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) | |||
| 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ | 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ |
| 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | | 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); | 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); |
| 139 | /* Check for invalid user address space control. */ | ||
| 140 | if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | ||
| 141 | regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | ||
| 142 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 139 | /* Check for invalid amode */ | 143 | /* Check for invalid amode */ |
| 140 | if (regs->psw.mask & PSW_MASK_EA) | 144 | if (regs->psw.mask & PSW_MASK_EA) |
| 141 | regs->psw.mask |= PSW_MASK_BA; | 145 | regs->psw.mask |= PSW_MASK_BA; |
| @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
| 273 | 277 | ||
| 274 | /* Set up registers for signal handler */ | 278 | /* Set up registers for signal handler */ |
| 275 | regs->gprs[15] = (unsigned long) frame; | 279 | regs->gprs[15] = (unsigned long) frame; |
| 276 | regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | 280 | /* Force default amode and default user address space control. */ |
| 281 | regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | ||
| 282 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 283 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 277 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; | 284 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 278 | 285 | ||
| 279 | regs->gprs[2] = map_signal(sig); | 286 | regs->gprs[2] = map_signal(sig); |
| @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 346 | 353 | ||
| 347 | /* Set up registers for signal handler */ | 354 | /* Set up registers for signal handler */ |
| 348 | regs->gprs[15] = (unsigned long) frame; | 355 | regs->gprs[15] = (unsigned long) frame; |
| 349 | regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | 356 | /* Force default amode and default user address space control. */ |
| 357 | regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | ||
| 358 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 359 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 350 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; | 360 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 351 | 361 | ||
| 352 | regs->gprs[2] = map_signal(sig); | 362 | regs->gprs[2] = map_signal(sig); |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 54d93f4b6818..dd55f7c20104 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
| @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); | |||
| 40 | static struct mask_info core_info; | 40 | static struct mask_info core_info; |
| 41 | cpumask_t cpu_core_map[NR_CPUS]; | 41 | cpumask_t cpu_core_map[NR_CPUS]; |
| 42 | unsigned char cpu_core_id[NR_CPUS]; | 42 | unsigned char cpu_core_id[NR_CPUS]; |
| 43 | unsigned char cpu_socket_id[NR_CPUS]; | ||
| 43 | 44 | ||
| 44 | static struct mask_info book_info; | 45 | static struct mask_info book_info; |
| 45 | cpumask_t cpu_book_map[NR_CPUS]; | 46 | cpumask_t cpu_book_map[NR_CPUS]; |
| @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, | |||
| 83 | cpumask_set_cpu(lcpu, &book->mask); | 84 | cpumask_set_cpu(lcpu, &book->mask); |
| 84 | cpu_book_id[lcpu] = book->id; | 85 | cpu_book_id[lcpu] = book->id; |
| 85 | cpumask_set_cpu(lcpu, &core->mask); | 86 | cpumask_set_cpu(lcpu, &core->mask); |
| 87 | cpu_core_id[lcpu] = rcpu; | ||
| 86 | if (one_core_per_cpu) { | 88 | if (one_core_per_cpu) { |
| 87 | cpu_core_id[lcpu] = rcpu; | 89 | cpu_socket_id[lcpu] = rcpu; |
| 88 | core = core->next; | 90 | core = core->next; |
| 89 | } else { | 91 | } else { |
| 90 | cpu_core_id[lcpu] = core->id; | 92 | cpu_socket_id[lcpu] = core->id; |
| 91 | } | 93 | } |
| 92 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); | 94 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); |
| 93 | } | 95 | } |
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8b8285310b5a..1f5315d1215c 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
| @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
| 180 | addr = start; | 180 | addr = start; |
| 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 182 | end = start + len; | 182 | end = start + len; |
| 183 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | 183 | if ((end < start) || (end > TASK_SIZE)) |
| 184 | (void __user *)start, len))) | ||
| 185 | return 0; | 184 | return 0; |
| 186 | 185 | ||
| 187 | local_irq_save(flags); | 186 | local_irq_save(flags); |
| @@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
| 229 | addr = start; | 228 | addr = start; |
| 230 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 229 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 231 | end = start + len; | 230 | end = start + len; |
| 232 | if (end < start) | 231 | if ((end < start) || (end > TASK_SIZE)) |
| 233 | goto slow_irqon; | 232 | goto slow_irqon; |
| 234 | 233 | ||
| 235 | /* | 234 | /* |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5f17aa..4ed343e4eb41 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #define RAW3215_NR_CCWS 3 | 44 | #define RAW3215_NR_CCWS 3 |
| 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ | 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ |
| 46 | 46 | ||
| 47 | #define RAW3215_FIXED 1 /* 3215 console device is not be freed */ | ||
| 48 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ | 47 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ |
| 49 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ | 48 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ |
| 50 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ | 49 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ |
| @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) | |||
| 339 | struct tty_struct *tty; | 338 | struct tty_struct *tty; |
| 340 | 339 | ||
| 341 | tty = tty_port_tty_get(&raw->port); | 340 | tty = tty_port_tty_get(&raw->port); |
| 342 | tty_wakeup(tty); | 341 | if (tty) { |
| 343 | tty_kref_put(tty); | 342 | tty_wakeup(tty); |
| 343 | tty_kref_put(tty); | ||
| 344 | } | ||
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | /* | 347 | /* |
| @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
| 629 | DECLARE_WAITQUEUE(wait, current); | 630 | DECLARE_WAITQUEUE(wait, current); |
| 630 | unsigned long flags; | 631 | unsigned long flags; |
| 631 | 632 | ||
| 632 | if (!(raw->port.flags & ASYNC_INITIALIZED) || | 633 | if (!(raw->port.flags & ASYNC_INITIALIZED)) |
| 633 | (raw->flags & RAW3215_FIXED)) | ||
| 634 | return; | 634 | return; |
| 635 | /* Wait for outstanding requests, then free irq */ | 635 | /* Wait for outstanding requests, then free irq */ |
| 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
| @@ -926,8 +926,6 @@ static int __init con3215_init(void) | |||
| 926 | dev_set_drvdata(&cdev->dev, raw); | 926 | dev_set_drvdata(&cdev->dev, raw); |
| 927 | cdev->handler = raw3215_irq; | 927 | cdev->handler = raw3215_irq; |
| 928 | 928 | ||
| 929 | raw->flags |= RAW3215_FIXED; | ||
| 930 | |||
| 931 | /* Request the console irq */ | 929 | /* Request the console irq */ |
| 932 | if (raw3215_startup(raw) != 0) { | 930 | if (raw3215_startup(raw) != 0) { |
| 933 | raw3215_free_info(raw); | 931 | raw3215_free_info(raw); |
