aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/appldata/appldata.h1
-rw-r--r--arch/s390/appldata/appldata_base.c74
-rw-r--r--arch/s390/appldata/appldata_mem.c1
-rw-r--r--arch/s390/appldata/appldata_net_sum.c1
-rw-r--r--arch/s390/appldata/appldata_os.c1
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/entry.S120
-rw-r--r--arch/s390/kernel/entry64.S114
-rw-r--r--arch/s390/kernel/setup.c6
-rw-r--r--arch/s390/kernel/smp.c56
-rw-r--r--arch/s390/kernel/traps.c1
-rw-r--r--arch/s390/mm/cmm.c3
-rw-r--r--drivers/s390/cio/css.c2
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/device_id.c45
-rw-r--r--include/asm-s390/system.h5
-rw-r--r--include/linux/sysctl.h6
-rw-r--r--kernel/sysctl_check.c14
-rw-r--r--mm/rmap.c9
-rw-r--r--net/iucv/iucv.c107
20 files changed, 263 insertions, 307 deletions
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h
index 4069b81f7f1d..db3ae8505103 100644
--- a/arch/s390/appldata/appldata.h
+++ b/arch/s390/appldata/appldata.h
@@ -45,7 +45,6 @@ struct appldata_ops {
45 int active; /* monitoring status */ 45 int active; /* monitoring status */
46 46
47 /* fill in from here */ 47 /* fill in from here */
48 unsigned int ctl_nr; /* sysctl ID */
49 char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */ 48 char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */
50 unsigned char record_nr; /* Record Nr. for Product ID */ 49 unsigned char record_nr; /* Record Nr. for Product ID */
51 void (*callback)(void *data); /* callback function */ 50 void (*callback)(void *data); /* callback function */
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index ac61cf43a7d9..655d52543e2d 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -53,29 +53,26 @@ static int appldata_interval_handler(ctl_table *ctl, int write,
53static struct ctl_table_header *appldata_sysctl_header; 53static struct ctl_table_header *appldata_sysctl_header;
54static struct ctl_table appldata_table[] = { 54static struct ctl_table appldata_table[] = {
55 { 55 {
56 .ctl_name = CTL_APPLDATA_TIMER,
57 .procname = "timer", 56 .procname = "timer",
58 .mode = S_IRUGO | S_IWUSR, 57 .mode = S_IRUGO | S_IWUSR,
59 .proc_handler = &appldata_timer_handler, 58 .proc_handler = &appldata_timer_handler,
60 }, 59 },
61 { 60 {
62 .ctl_name = CTL_APPLDATA_INTERVAL,
63 .procname = "interval", 61 .procname = "interval",
64 .mode = S_IRUGO | S_IWUSR, 62 .mode = S_IRUGO | S_IWUSR,
65 .proc_handler = &appldata_interval_handler, 63 .proc_handler = &appldata_interval_handler,
66 }, 64 },
67 { .ctl_name = 0 } 65 { },
68}; 66};
69 67
70static struct ctl_table appldata_dir_table[] = { 68static struct ctl_table appldata_dir_table[] = {
71 { 69 {
72 .ctl_name = CTL_APPLDATA,
73 .procname = appldata_proc_name, 70 .procname = appldata_proc_name,
74 .maxlen = 0, 71 .maxlen = 0,
75 .mode = S_IRUGO | S_IXUGO, 72 .mode = S_IRUGO | S_IXUGO,
76 .child = appldata_table, 73 .child = appldata_table,
77 }, 74 },
78 { .ctl_name = 0 } 75 { },
79}; 76};
80 77
81/* 78/*
@@ -441,75 +438,38 @@ out:
441 */ 438 */
442int appldata_register_ops(struct appldata_ops *ops) 439int appldata_register_ops(struct appldata_ops *ops)
443{ 440{
444 struct list_head *lh; 441 if ((ops->size > APPLDATA_MAX_REC_SIZE) || (ops->size < 0))
445 struct appldata_ops *tmp_ops; 442 return -EINVAL;
446 int i;
447
448 i = 0;
449 443
450 if ((ops->size > APPLDATA_MAX_REC_SIZE) || 444 ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL);
451 (ops->size < 0)){ 445 if (!ops->ctl_table)
452 P_ERROR("Invalid size of %s record = %i, maximum = %i!\n",
453 ops->name, ops->size, APPLDATA_MAX_REC_SIZE);
454 return -ENOMEM;
455 }
456 if ((ops->ctl_nr == CTL_APPLDATA) ||
457 (ops->ctl_nr == CTL_APPLDATA_TIMER) ||
458 (ops->ctl_nr == CTL_APPLDATA_INTERVAL)) {
459 P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr);
460 return -EBUSY;
461 }
462 ops->ctl_table = kzalloc(4*sizeof(struct ctl_table), GFP_KERNEL);
463 if (ops->ctl_table == NULL) {
464 P_ERROR("Not enough memory for %s ctl_table!\n", ops->name);
465 return -ENOMEM; 446 return -ENOMEM;
466 }
467 447
468 spin_lock(&appldata_ops_lock); 448 spin_lock(&appldata_ops_lock);
469 list_for_each(lh, &appldata_ops_list) {
470 tmp_ops = list_entry(lh, struct appldata_ops, list);
471 P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
472 ++i, tmp_ops->name, tmp_ops->ctl_nr);
473 P_DEBUG("Comparing %s (ctl %i) with %s (ctl %i)\n",
474 tmp_ops->name, tmp_ops->ctl_nr, ops->name,
475 ops->ctl_nr);
476 if (strncmp(tmp_ops->name, ops->name,
477 APPLDATA_PROC_NAME_LENGTH) == 0) {
478 P_ERROR("Name \"%s\" already registered!\n", ops->name);
479 kfree(ops->ctl_table);
480 spin_unlock(&appldata_ops_lock);
481 return -EBUSY;
482 }
483 if (tmp_ops->ctl_nr == ops->ctl_nr) {
484 P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
485 kfree(ops->ctl_table);
486 spin_unlock(&appldata_ops_lock);
487 return -EBUSY;
488 }
489 }
490 list_add(&ops->list, &appldata_ops_list); 449 list_add(&ops->list, &appldata_ops_list);
491 spin_unlock(&appldata_ops_lock); 450 spin_unlock(&appldata_ops_lock);
492 451
493 ops->ctl_table[0].ctl_name = CTL_APPLDATA;
494 ops->ctl_table[0].procname = appldata_proc_name; 452 ops->ctl_table[0].procname = appldata_proc_name;
495 ops->ctl_table[0].maxlen = 0; 453 ops->ctl_table[0].maxlen = 0;
496 ops->ctl_table[0].mode = S_IRUGO | S_IXUGO; 454 ops->ctl_table[0].mode = S_IRUGO | S_IXUGO;
497 ops->ctl_table[0].child = &ops->ctl_table[2]; 455 ops->ctl_table[0].child = &ops->ctl_table[2];
498 456
499 ops->ctl_table[1].ctl_name = 0;
500
501 ops->ctl_table[2].ctl_name = ops->ctl_nr;
502 ops->ctl_table[2].procname = ops->name; 457 ops->ctl_table[2].procname = ops->name;
503 ops->ctl_table[2].mode = S_IRUGO | S_IWUSR; 458 ops->ctl_table[2].mode = S_IRUGO | S_IWUSR;
504 ops->ctl_table[2].proc_handler = appldata_generic_handler; 459 ops->ctl_table[2].proc_handler = appldata_generic_handler;
505 ops->ctl_table[2].data = ops; 460 ops->ctl_table[2].data = ops;
506 461
507 ops->ctl_table[3].ctl_name = 0;
508
509 ops->sysctl_header = register_sysctl_table(ops->ctl_table); 462 ops->sysctl_header = register_sysctl_table(ops->ctl_table);
510 463 if (!ops->sysctl_header)
464 goto out;
511 P_INFO("%s-ops registered!\n", ops->name); 465 P_INFO("%s-ops registered!\n", ops->name);
512 return 0; 466 return 0;
467out:
468 spin_lock(&appldata_ops_lock);
469 list_del(&ops->list);
470 spin_unlock(&appldata_ops_lock);
471 kfree(ops->ctl_table);
472 return -ENOMEM;
513} 473}
514 474
515/* 475/*
@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldata_ops *ops)
519 */ 479 */
520void appldata_unregister_ops(struct appldata_ops *ops) 480void appldata_unregister_ops(struct appldata_ops *ops)
521{ 481{
522 void *table;
523 spin_lock(&appldata_ops_lock); 482 spin_lock(&appldata_ops_lock);
524 list_del(&ops->list); 483 list_del(&ops->list);
525 /* at that point any incoming access will fail */
526 table = ops->ctl_table;
527 ops->ctl_table = NULL;
528 spin_unlock(&appldata_ops_lock); 484 spin_unlock(&appldata_ops_lock);
529 unregister_sysctl_table(ops->sysctl_header); 485 unregister_sysctl_table(ops->sysctl_header);
530 kfree(table); 486 kfree(ops->ctl_table);
531 P_INFO("%s-ops unregistered!\n", ops->name); 487 P_INFO("%s-ops unregistered!\n", ops->name);
532} 488}
533/********************** module-ops management <END> **************************/ 489/********************** module-ops management <END> **************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 697eb30a68a3..51181ccdb87b 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -147,7 +147,6 @@ static void appldata_get_mem_data(void *data)
147 147
148 148
149static struct appldata_ops ops = { 149static struct appldata_ops ops = {
150 .ctl_nr = CTL_APPLDATA_MEM,
151 .name = "mem", 150 .name = "mem",
152 .record_nr = APPLDATA_RECORD_MEM_ID, 151 .record_nr = APPLDATA_RECORD_MEM_ID,
153 .size = sizeof(struct appldata_mem_data), 152 .size = sizeof(struct appldata_mem_data),
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index 6c1815a47714..4d8344336001 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -142,7 +142,6 @@ static void appldata_get_net_sum_data(void *data)
142 142
143 143
144static struct appldata_ops ops = { 144static struct appldata_ops ops = {
145 .ctl_nr = CTL_APPLDATA_NET_SUM,
146 .name = "net_sum", 145 .name = "net_sum",
147 .record_nr = APPLDATA_RECORD_NET_SUM_ID, 146 .record_nr = APPLDATA_RECORD_NET_SUM_ID,
148 .size = sizeof(struct appldata_net_sum_data), 147 .size = sizeof(struct appldata_net_sum_data),
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 76a15523ae9e..6b3eafe10453 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -82,7 +82,6 @@ struct appldata_os_data {
82static struct appldata_os_data *appldata_os_data; 82static struct appldata_os_data *appldata_os_data;
83 83
84static struct appldata_ops ops = { 84static struct appldata_ops ops = {
85 .ctl_nr = CTL_APPLDATA_OS,
86 .name = "os", 85 .name = "os",
87 .record_nr = APPLDATA_RECORD_OS_ID, 86 .record_nr = APPLDATA_RECORD_OS_ID,
88 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 8bf4ae1150be..1b3af7dab816 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -200,7 +200,7 @@ static noinline __init void find_memory_chunks(unsigned long memsize)
200 cc = __tprot(addr); 200 cc = __tprot(addr);
201 while (cc == old_cc) { 201 while (cc == old_cc) {
202 addr += CHUNK_INCR; 202 addr += CHUNK_INCR;
203 if (addr >= memsize) 203 if (memsize && addr >= memsize)
204 break; 204 break;
205#ifndef CONFIG_64BIT 205#ifndef CONFIG_64BIT
206 if (addr == ADDR2G) 206 if (addr == ADDR2G)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5cc..b2b2edc40eb1 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
69 basr %r14,%r1 69 basr %r14,%r1
70 .endm 70 .endm
71 71
72 .macro LOCKDEP_SYS_EXIT 72 .macro TRACE_IRQS_CHECK
73 l %r1,BASED(.Llockdep_sys_exit) 73 tm SP_PSW(%r15),0x03 # irqs enabled?
74 jz 0f
75 l %r1,BASED(.Ltrace_irq_on)
74 basr %r14,%r1 76 basr %r14,%r1
77 j 1f
780: l %r1,BASED(.Ltrace_irq_off)
79 basr %r14,%r1
801:
75 .endm 81 .endm
76#else 82#else
77#define TRACE_IRQS_ON 83#define TRACE_IRQS_ON
78#define TRACE_IRQS_OFF 84#define TRACE_IRQS_OFF
85#define TRACE_IRQS_CHECK
86#endif
87
88#ifdef CONFIG_LOCKDEP
89 .macro LOCKDEP_SYS_EXIT
90 tm SP_PSW+1(%r15),0x01 # returning to user ?
91 jz 0f
92 l %r1,BASED(.Llockdep_sys_exit)
93 basr %r14,%r1
940:
95 .endm
96#else
79#define LOCKDEP_SYS_EXIT 97#define LOCKDEP_SYS_EXIT
80#endif 98#endif
81 99
@@ -234,8 +252,6 @@ sysc_saveall:
234 lh %r7,0x8a # get svc number from lowcore 252 lh %r7,0x8a # get svc number from lowcore
235#ifdef CONFIG_VIRT_CPU_ACCOUNTING 253#ifdef CONFIG_VIRT_CPU_ACCOUNTING
236sysc_vtime: 254sysc_vtime:
237 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
238 bz BASED(sysc_do_svc)
239 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 255 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
240sysc_stime: 256sysc_stime:
241 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 257 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -263,19 +279,34 @@ sysc_do_restart:
263 279
264sysc_return: 280sysc_return:
265 tm SP_PSW+1(%r15),0x01 # returning to user ? 281 tm SP_PSW+1(%r15),0x01 # returning to user ?
266 bno BASED(sysc_leave) 282 bno BASED(sysc_restore)
267 tm __TI_flags+3(%r9),_TIF_WORK_SVC 283 tm __TI_flags+3(%r9),_TIF_WORK_SVC
268 bnz BASED(sysc_work) # there is work to do (signals etc.) 284 bnz BASED(sysc_work) # there is work to do (signals etc.)
285sysc_restore:
286#ifdef CONFIG_TRACE_IRQFLAGS
287 la %r1,BASED(sysc_restore_trace_psw)
288 lpsw 0(%r1)
289sysc_restore_trace:
290 TRACE_IRQS_CHECK
269 LOCKDEP_SYS_EXIT 291 LOCKDEP_SYS_EXIT
292#endif
270sysc_leave: 293sysc_leave:
271 RESTORE_ALL __LC_RETURN_PSW,1 294 RESTORE_ALL __LC_RETURN_PSW,1
295sysc_done:
296
297#ifdef CONFIG_TRACE_IRQFLAGS
298 .align 8
299 .globl sysc_restore_trace_psw
300sysc_restore_trace_psw:
301 .long 0, sysc_restore_trace + 0x80000000
302#endif
272 303
273# 304#
274# recheck if there is more work to do 305# recheck if there is more work to do
275# 306#
276sysc_work_loop: 307sysc_work_loop:
277 tm __TI_flags+3(%r9),_TIF_WORK_SVC 308 tm __TI_flags+3(%r9),_TIF_WORK_SVC
278 bz BASED(sysc_leave) # there is no work to do 309 bz BASED(sysc_restore) # there is no work to do
279# 310#
280# One of the work bits is on. Find out which one. 311# One of the work bits is on. Find out which one.
281# 312#
@@ -290,8 +321,8 @@ sysc_work:
290 bo BASED(sysc_restart) 321 bo BASED(sysc_restart)
291 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 322 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
292 bo BASED(sysc_singlestep) 323 bo BASED(sysc_singlestep)
293 LOCKDEP_SYS_EXIT 324 b BASED(sysc_restore)
294 b BASED(sysc_leave) 325sysc_work_done:
295 326
296# 327#
297# _TIF_NEED_RESCHED is set, call schedule 328# _TIF_NEED_RESCHED is set, call schedule
@@ -458,6 +489,7 @@ pgm_check_handler:
458pgm_no_vtime: 489pgm_no_vtime:
459#endif 490#endif
460 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 491 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
492 TRACE_IRQS_OFF
461 l %r3,__LC_PGM_ILC # load program interruption code 493 l %r3,__LC_PGM_ILC # load program interruption code
462 la %r8,0x7f 494 la %r8,0x7f
463 nr %r8,%r3 495 nr %r8,%r3
@@ -497,6 +529,7 @@ pgm_per_std:
497pgm_no_vtime2: 529pgm_no_vtime2:
498#endif 530#endif
499 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 531 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
532 TRACE_IRQS_OFF
500 l %r1,__TI_task(%r9) 533 l %r1,__TI_task(%r9)
501 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 534 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
502 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 535 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -517,15 +550,13 @@ pgm_svcper:
517 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 550 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
518 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 551 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
519#ifdef CONFIG_VIRT_CPU_ACCOUNTING 552#ifdef CONFIG_VIRT_CPU_ACCOUNTING
520 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
521 bz BASED(pgm_no_vtime3)
522 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 553 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
523 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 554 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
524 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 555 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
525pgm_no_vtime3:
526#endif 556#endif
527 lh %r7,0x8a # get svc number from lowcore 557 lh %r7,0x8a # get svc number from lowcore
528 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 558 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
559 TRACE_IRQS_OFF
529 l %r1,__TI_task(%r9) 560 l %r1,__TI_task(%r9)
530 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 561 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
531 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 562 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -542,7 +573,7 @@ kernel_per:
542 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check 573 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
543 la %r2,SP_PTREGS(%r15) # address of register-save area 574 la %r2,SP_PTREGS(%r15) # address of register-save area
544 l %r1,BASED(.Lhandle_per) # load adr. of per handler 575 l %r1,BASED(.Lhandle_per) # load adr. of per handler
545 la %r14,BASED(sysc_leave) # load adr. of system return 576 la %r14,BASED(sysc_restore)# load adr. of system return
546 br %r1 # branch to do_single_step 577 br %r1 # branch to do_single_step
547 578
548/* 579/*
@@ -569,26 +600,38 @@ io_no_vtime:
569 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 600 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
570 la %r2,SP_PTREGS(%r15) # address of register-save area 601 la %r2,SP_PTREGS(%r15) # address of register-save area
571 basr %r14,%r1 # branch to standard irq handler 602 basr %r14,%r1 # branch to standard irq handler
572 TRACE_IRQS_ON
573
574io_return: 603io_return:
575 tm SP_PSW+1(%r15),0x01 # returning to user ? 604 tm SP_PSW+1(%r15),0x01 # returning to user ?
576#ifdef CONFIG_PREEMPT 605#ifdef CONFIG_PREEMPT
577 bno BASED(io_preempt) # no -> check for preemptive scheduling 606 bno BASED(io_preempt) # no -> check for preemptive scheduling
578#else 607#else
579 bno BASED(io_leave) # no-> skip resched & signal 608 bno BASED(io_restore) # no-> skip resched & signal
580#endif 609#endif
581 tm __TI_flags+3(%r9),_TIF_WORK_INT 610 tm __TI_flags+3(%r9),_TIF_WORK_INT
582 bnz BASED(io_work) # there is work to do (signals etc.) 611 bnz BASED(io_work) # there is work to do (signals etc.)
612io_restore:
613#ifdef CONFIG_TRACE_IRQFLAGS
614 la %r1,BASED(io_restore_trace_psw)
615 lpsw 0(%r1)
616io_restore_trace:
617 TRACE_IRQS_CHECK
583 LOCKDEP_SYS_EXIT 618 LOCKDEP_SYS_EXIT
619#endif
584io_leave: 620io_leave:
585 RESTORE_ALL __LC_RETURN_PSW,0 621 RESTORE_ALL __LC_RETURN_PSW,0
586io_done: 622io_done:
587 623
624#ifdef CONFIG_TRACE_IRQFLAGS
625 .align 8
626 .globl io_restore_trace_psw
627io_restore_trace_psw:
628 .long 0, io_restore_trace + 0x80000000
629#endif
630
588#ifdef CONFIG_PREEMPT 631#ifdef CONFIG_PREEMPT
589io_preempt: 632io_preempt:
590 icm %r0,15,__TI_precount(%r9) 633 icm %r0,15,__TI_precount(%r9)
591 bnz BASED(io_leave) 634 bnz BASED(io_restore)
592 l %r1,SP_R15(%r15) 635 l %r1,SP_R15(%r15)
593 s %r1,BASED(.Lc_spsize) 636 s %r1,BASED(.Lc_spsize)
594 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 637 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -596,14 +639,10 @@ io_preempt:
596 lr %r15,%r1 639 lr %r15,%r1
597io_resume_loop: 640io_resume_loop:
598 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 641 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
599 bno BASED(io_leave) 642 bno BASED(io_restore)
600 mvc __TI_precount(4,%r9),BASED(.Lc_pactive) 643 l %r1,BASED(.Lpreempt_schedule_irq)
601 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 644 la %r14,BASED(io_resume_loop)
602 l %r1,BASED(.Lschedule) 645 br %r1 # call schedule
603 basr %r14,%r1 # call schedule
604 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
605 xc __TI_precount(4,%r9),__TI_precount(%r9)
606 b BASED(io_resume_loop)
607#endif 646#endif
608 647
609# 648#
@@ -627,40 +666,42 @@ io_work_loop:
627 bo BASED(io_reschedule) 666 bo BASED(io_reschedule)
628 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 667 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
629 bnz BASED(io_sigpending) 668 bnz BASED(io_sigpending)
630 LOCKDEP_SYS_EXIT 669 b BASED(io_restore)
631 b BASED(io_leave) 670io_work_done:
632 671
633# 672#
634# _TIF_MCCK_PENDING is set, call handler 673# _TIF_MCCK_PENDING is set, call handler
635# 674#
636io_mcck_pending: 675io_mcck_pending:
637 TRACE_IRQS_OFF
638 l %r1,BASED(.Ls390_handle_mcck) 676 l %r1,BASED(.Ls390_handle_mcck)
639 basr %r14,%r1 # TIF bit will be cleared by handler 677 basr %r14,%r1 # TIF bit will be cleared by handler
640 TRACE_IRQS_ON
641 b BASED(io_work_loop) 678 b BASED(io_work_loop)
642 679
643# 680#
644# _TIF_NEED_RESCHED is set, call schedule 681# _TIF_NEED_RESCHED is set, call schedule
645# 682#
646io_reschedule: 683io_reschedule:
684 TRACE_IRQS_ON
647 l %r1,BASED(.Lschedule) 685 l %r1,BASED(.Lschedule)
648 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 686 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
649 basr %r14,%r1 # call scheduler 687 basr %r14,%r1 # call scheduler
650 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 688 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
689 TRACE_IRQS_OFF
651 tm __TI_flags+3(%r9),_TIF_WORK_INT 690 tm __TI_flags+3(%r9),_TIF_WORK_INT
652 bz BASED(io_leave) # there is no work to do 691 bz BASED(io_restore) # there is no work to do
653 b BASED(io_work_loop) 692 b BASED(io_work_loop)
654 693
655# 694#
656# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 695# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
657# 696#
658io_sigpending: 697io_sigpending:
698 TRACE_IRQS_ON
659 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 699 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
660 la %r2,SP_PTREGS(%r15) # load pt_regs 700 la %r2,SP_PTREGS(%r15) # load pt_regs
661 l %r1,BASED(.Ldo_signal) 701 l %r1,BASED(.Ldo_signal)
662 basr %r14,%r1 # call do_signal 702 basr %r14,%r1 # call do_signal
663 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 703 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
704 TRACE_IRQS_OFF
664 b BASED(io_work_loop) 705 b BASED(io_work_loop)
665 706
666/* 707/*
@@ -688,7 +729,6 @@ ext_no_vtime:
688 lh %r3,__LC_EXT_INT_CODE # get interruption code 729 lh %r3,__LC_EXT_INT_CODE # get interruption code
689 l %r1,BASED(.Ldo_extint) 730 l %r1,BASED(.Ldo_extint)
690 basr %r14,%r1 731 basr %r14,%r1
691 TRACE_IRQS_ON
692 b BASED(io_return) 732 b BASED(io_return)
693 733
694__critical_end: 734__critical_end:
@@ -853,15 +893,15 @@ cleanup_table_system_call:
853cleanup_table_sysc_return: 893cleanup_table_sysc_return:
854 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 894 .long sysc_return + 0x80000000, sysc_leave + 0x80000000
855cleanup_table_sysc_leave: 895cleanup_table_sysc_leave:
856 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 896 .long sysc_leave + 0x80000000, sysc_done + 0x80000000
857cleanup_table_sysc_work_loop: 897cleanup_table_sysc_work_loop:
858 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 898 .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
859cleanup_table_io_return: 899cleanup_table_io_return:
860 .long io_return + 0x80000000, io_leave + 0x80000000 900 .long io_return + 0x80000000, io_leave + 0x80000000
861cleanup_table_io_leave: 901cleanup_table_io_leave:
862 .long io_leave + 0x80000000, io_done + 0x80000000 902 .long io_leave + 0x80000000, io_done + 0x80000000
863cleanup_table_io_work_loop: 903cleanup_table_io_work_loop:
864 .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000 904 .long io_work_loop + 0x80000000, io_work_done + 0x80000000
865 905
866cleanup_critical: 906cleanup_critical:
867 clc 4(4,%r12),BASED(cleanup_table_system_call) 907 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +970,6 @@ cleanup_system_call:
930cleanup_vtime: 970cleanup_vtime:
931 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 971 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
932 bhe BASED(cleanup_stime) 972 bhe BASED(cleanup_stime)
933 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
934 bz BASED(cleanup_novtime)
935 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 973 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
936cleanup_stime: 974cleanup_stime:
937 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 975 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +977,6 @@ cleanup_stime:
939 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 977 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
940cleanup_update: 978cleanup_update:
941 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 979 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
942cleanup_novtime:
943#endif 980#endif
944 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 981 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
945 la %r12,__LC_RETURN_PSW 982 la %r12,__LC_RETURN_PSW
@@ -978,10 +1015,10 @@ cleanup_sysc_leave:
9782: la %r12,__LC_RETURN_PSW 10152: la %r12,__LC_RETURN_PSW
979 br %r14 1016 br %r14
980cleanup_sysc_leave_insn: 1017cleanup_sysc_leave_insn:
1018 .long sysc_done - 4 + 0x80000000
981#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1019#ifdef CONFIG_VIRT_CPU_ACCOUNTING
982 .long sysc_leave + 14 + 0x80000000 1020 .long sysc_done - 8 + 0x80000000
983#endif 1021#endif
984 .long sysc_leave + 10 + 0x80000000
985 1022
986cleanup_io_return: 1023cleanup_io_return:
987 mvc __LC_RETURN_PSW(4),0(%r12) 1024 mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1045,10 @@ cleanup_io_leave:
10082: la %r12,__LC_RETURN_PSW 10452: la %r12,__LC_RETURN_PSW
1009 br %r14 1046 br %r14
1010cleanup_io_leave_insn: 1047cleanup_io_leave_insn:
1048 .long io_done - 4 + 0x80000000
1011#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1049#ifdef CONFIG_VIRT_CPU_ACCOUNTING
1012 .long io_leave + 18 + 0x80000000 1050 .long io_done - 8 + 0x80000000
1013#endif 1051#endif
1014 .long io_leave + 14 + 0x80000000
1015 1052
1016/* 1053/*
1017 * Integer constants 1054 * Integer constants
@@ -1019,7 +1056,6 @@ cleanup_io_leave_insn:
1019 .align 4 1056 .align 4
1020.Lc_spsize: .long SP_SIZE 1057.Lc_spsize: .long SP_SIZE
1021.Lc_overhead: .long STACK_FRAME_OVERHEAD 1058.Lc_overhead: .long STACK_FRAME_OVERHEAD
1022.Lc_pactive: .long PREEMPT_ACTIVE
1023.Lnr_syscalls: .long NR_syscalls 1059.Lnr_syscalls: .long NR_syscalls
1024.L0x018: .short 0x018 1060.L0x018: .short 0x018
1025.L0x020: .short 0x020 1061.L0x020: .short 0x020
@@ -1043,6 +1079,8 @@ cleanup_io_leave_insn:
1043.Lexecve_tail: .long execve_tail 1079.Lexecve_tail: .long execve_tail
1044.Ljump_table: .long pgm_check_table 1080.Ljump_table: .long pgm_check_table
1045.Lschedule: .long schedule 1081.Lschedule: .long schedule
1082.Lpreempt_schedule_irq:
1083 .long preempt_schedule_irq
1046.Ltrace: .long syscall_trace 1084.Ltrace: .long syscall_trace
1047.Lschedtail: .long schedule_tail 1085.Lschedtail: .long schedule_tail
1048.Lsysc_table: .long sys_call_table 1086.Lsysc_table: .long sys_call_table
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 05e26d1fdf40..a3e47b893f07 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -67,12 +67,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
67 brasl %r14,trace_hardirqs_off 67 brasl %r14,trace_hardirqs_off
68 .endm 68 .endm
69 69
70 .macro LOCKDEP_SYS_EXIT 70 .macro TRACE_IRQS_CHECK
71 brasl %r14,lockdep_sys_exit 71 tm SP_PSW(%r15),0x03 # irqs enabled?
72 jz 0f
73 brasl %r14,trace_hardirqs_on
74 j 1f
750: brasl %r14,trace_hardirqs_off
761:
72 .endm 77 .endm
73#else 78#else
74#define TRACE_IRQS_ON 79#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF 80#define TRACE_IRQS_OFF
81#define TRACE_IRQS_CHECK
82#endif
83
84#ifdef CONFIG_LOCKDEP
85 .macro LOCKDEP_SYS_EXIT
86 tm SP_PSW+1(%r15),0x01 # returning to user ?
87 jz 0f
88 brasl %r14,lockdep_sys_exit
890:
90 .endm
91#else
76#define LOCKDEP_SYS_EXIT 92#define LOCKDEP_SYS_EXIT
77#endif 93#endif
78 94
@@ -222,8 +238,6 @@ sysc_saveall:
222 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 238 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
223#ifdef CONFIG_VIRT_CPU_ACCOUNTING 239#ifdef CONFIG_VIRT_CPU_ACCOUNTING
224sysc_vtime: 240sysc_vtime:
225 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
226 jz sysc_do_svc
227 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 241 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
228sysc_stime: 242sysc_stime:
229 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 243 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -257,19 +271,34 @@ sysc_noemu:
257 271
258sysc_return: 272sysc_return:
259 tm SP_PSW+1(%r15),0x01 # returning to user ? 273 tm SP_PSW+1(%r15),0x01 # returning to user ?
260 jno sysc_leave 274 jno sysc_restore
261 tm __TI_flags+7(%r9),_TIF_WORK_SVC 275 tm __TI_flags+7(%r9),_TIF_WORK_SVC
262 jnz sysc_work # there is work to do (signals etc.) 276 jnz sysc_work # there is work to do (signals etc.)
277sysc_restore:
278#ifdef CONFIG_TRACE_IRQFLAGS
279 larl %r1,sysc_restore_trace_psw
280 lpswe 0(%r1)
281sysc_restore_trace:
282 TRACE_IRQS_CHECK
263 LOCKDEP_SYS_EXIT 283 LOCKDEP_SYS_EXIT
284#endif
264sysc_leave: 285sysc_leave:
265 RESTORE_ALL __LC_RETURN_PSW,1 286 RESTORE_ALL __LC_RETURN_PSW,1
287sysc_done:
288
289#ifdef CONFIG_TRACE_IRQFLAGS
290 .align 8
291 .globl sysc_restore_trace_psw
292sysc_restore_trace_psw:
293 .quad 0, sysc_restore_trace
294#endif
266 295
267# 296#
268# recheck if there is more work to do 297# recheck if there is more work to do
269# 298#
270sysc_work_loop: 299sysc_work_loop:
271 tm __TI_flags+7(%r9),_TIF_WORK_SVC 300 tm __TI_flags+7(%r9),_TIF_WORK_SVC
272 jz sysc_leave # there is no work to do 301 jz sysc_restore # there is no work to do
273# 302#
274# One of the work bits is on. Find out which one. 303# One of the work bits is on. Find out which one.
275# 304#
@@ -284,8 +313,8 @@ sysc_work:
284 jo sysc_restart 313 jo sysc_restart
285 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP 314 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
286 jo sysc_singlestep 315 jo sysc_singlestep
287 LOCKDEP_SYS_EXIT 316 j sysc_restore
288 j sysc_leave 317sysc_work_done:
289 318
290# 319#
291# _TIF_NEED_RESCHED is set, call schedule 320# _TIF_NEED_RESCHED is set, call schedule
@@ -445,6 +474,7 @@ pgm_check_handler:
445pgm_no_vtime: 474pgm_no_vtime:
446#endif 475#endif
447 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 476 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
477 TRACE_IRQS_OFF
448 lgf %r3,__LC_PGM_ILC # load program interruption code 478 lgf %r3,__LC_PGM_ILC # load program interruption code
449 lghi %r8,0x7f 479 lghi %r8,0x7f
450 ngr %r8,%r3 480 ngr %r8,%r3
@@ -484,6 +514,7 @@ pgm_per_std:
484pgm_no_vtime2: 514pgm_no_vtime2:
485#endif 515#endif
486 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 516 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
517 TRACE_IRQS_OFF
487 lg %r1,__TI_task(%r9) 518 lg %r1,__TI_task(%r9)
488 tm SP_PSW+1(%r15),0x01 # kernel per event ? 519 tm SP_PSW+1(%r15),0x01 # kernel per event ?
489 jz kernel_per 520 jz kernel_per
@@ -504,12 +535,9 @@ pgm_svcper:
504 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 535 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
505 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 536 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
506#ifdef CONFIG_VIRT_CPU_ACCOUNTING 537#ifdef CONFIG_VIRT_CPU_ACCOUNTING
507 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
508 jz pgm_no_vtime3
509 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 538 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
510 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 539 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
511 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 540 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
512pgm_no_vtime3:
513#endif 541#endif
514 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 542 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
515 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 543 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
@@ -529,7 +557,7 @@ kernel_per:
529 lhi %r0,__LC_PGM_OLD_PSW 557 lhi %r0,__LC_PGM_OLD_PSW
530 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check 558 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
531 la %r2,SP_PTREGS(%r15) # address of register-save area 559 la %r2,SP_PTREGS(%r15) # address of register-save area
532 larl %r14,sysc_leave # load adr. of system ret, no work 560 larl %r14,sysc_restore # load adr. of system ret, no work
533 jg do_single_step # branch to do_single_step 561 jg do_single_step # branch to do_single_step
534 562
535/* 563/*
@@ -554,26 +582,38 @@ io_no_vtime:
554 TRACE_IRQS_OFF 582 TRACE_IRQS_OFF
555 la %r2,SP_PTREGS(%r15) # address of register-save area 583 la %r2,SP_PTREGS(%r15) # address of register-save area
556 brasl %r14,do_IRQ # call standard irq handler 584 brasl %r14,do_IRQ # call standard irq handler
557 TRACE_IRQS_ON
558
559io_return: 585io_return:
560 tm SP_PSW+1(%r15),0x01 # returning to user ? 586 tm SP_PSW+1(%r15),0x01 # returning to user ?
561#ifdef CONFIG_PREEMPT 587#ifdef CONFIG_PREEMPT
562 jno io_preempt # no -> check for preemptive scheduling 588 jno io_preempt # no -> check for preemptive scheduling
563#else 589#else
564 jno io_leave # no-> skip resched & signal 590 jno io_restore # no-> skip resched & signal
565#endif 591#endif
566 tm __TI_flags+7(%r9),_TIF_WORK_INT 592 tm __TI_flags+7(%r9),_TIF_WORK_INT
567 jnz io_work # there is work to do (signals etc.) 593 jnz io_work # there is work to do (signals etc.)
594io_restore:
595#ifdef CONFIG_TRACE_IRQFLAGS
596 larl %r1,io_restore_trace_psw
597 lpswe 0(%r1)
598io_restore_trace:
599 TRACE_IRQS_CHECK
568 LOCKDEP_SYS_EXIT 600 LOCKDEP_SYS_EXIT
601#endif
569io_leave: 602io_leave:
570 RESTORE_ALL __LC_RETURN_PSW,0 603 RESTORE_ALL __LC_RETURN_PSW,0
571io_done: 604io_done:
572 605
606#ifdef CONFIG_TRACE_IRQFLAGS
607 .align 8
608 .globl io_restore_trace_psw
609io_restore_trace_psw:
610 .quad 0, io_restore_trace
611#endif
612
573#ifdef CONFIG_PREEMPT 613#ifdef CONFIG_PREEMPT
574io_preempt: 614io_preempt:
575 icm %r0,15,__TI_precount(%r9) 615 icm %r0,15,__TI_precount(%r9)
576 jnz io_leave 616 jnz io_restore
577 # switch to kernel stack 617 # switch to kernel stack
578 lg %r1,SP_R15(%r15) 618 lg %r1,SP_R15(%r15)
579 aghi %r1,-SP_SIZE 619 aghi %r1,-SP_SIZE
@@ -582,14 +622,9 @@ io_preempt:
582 lgr %r15,%r1 622 lgr %r15,%r1
583io_resume_loop: 623io_resume_loop:
584 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 624 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
585 jno io_leave 625 jno io_restore
586 larl %r1,.Lc_pactive 626 larl %r14,io_resume_loop
587 mvc __TI_precount(4,%r9),0(%r1) 627 jg preempt_schedule_irq
588 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
589 brasl %r14,schedule # call schedule
590 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
591 xc __TI_precount(4,%r9),__TI_precount(%r9)
592 j io_resume_loop
593#endif 628#endif
594 629
595# 630#
@@ -613,37 +648,39 @@ io_work_loop:
613 jo io_reschedule 648 jo io_reschedule
614 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 649 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
615 jnz io_sigpending 650 jnz io_sigpending
616 LOCKDEP_SYS_EXIT 651 j io_restore
617 j io_leave 652io_work_done:
618 653
619# 654#
620# _TIF_MCCK_PENDING is set, call handler 655# _TIF_MCCK_PENDING is set, call handler
621# 656#
622io_mcck_pending: 657io_mcck_pending:
623 TRACE_IRQS_OFF
624 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler 658 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
625 TRACE_IRQS_ON
626 j io_work_loop 659 j io_work_loop
627 660
628# 661#
629# _TIF_NEED_RESCHED is set, call schedule 662# _TIF_NEED_RESCHED is set, call schedule
630# 663#
631io_reschedule: 664io_reschedule:
665 TRACE_IRQS_ON
632 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
633 brasl %r14,schedule # call scheduler 667 brasl %r14,schedule # call scheduler
634 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF
635 tm __TI_flags+7(%r9),_TIF_WORK_INT 670 tm __TI_flags+7(%r9),_TIF_WORK_INT
636 jz io_leave # there is no work to do 671 jz io_restore # there is no work to do
637 j io_work_loop 672 j io_work_loop
638 673
639# 674#
640# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 675# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
641# 676#
642io_sigpending: 677io_sigpending:
678 TRACE_IRQS_ON
643 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 679 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
644 la %r2,SP_PTREGS(%r15) # load pt_regs 680 la %r2,SP_PTREGS(%r15) # load pt_regs
645 brasl %r14,do_signal # call do_signal 681 brasl %r14,do_signal # call do_signal
646 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 682 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
683 TRACE_IRQS_OFF
647 j io_work_loop 684 j io_work_loop
648 685
649/* 686/*
@@ -669,7 +706,6 @@ ext_no_vtime:
669 la %r2,SP_PTREGS(%r15) # address of register-save area 706 la %r2,SP_PTREGS(%r15) # address of register-save area
670 llgh %r3,__LC_EXT_INT_CODE # get interruption code 707 llgh %r3,__LC_EXT_INT_CODE # get interruption code
671 brasl %r14,do_extint 708 brasl %r14,do_extint
672 TRACE_IRQS_ON
673 j io_return 709 j io_return
674 710
675__critical_end: 711__critical_end:
@@ -824,15 +860,15 @@ cleanup_table_system_call:
824cleanup_table_sysc_return: 860cleanup_table_sysc_return:
825 .quad sysc_return, sysc_leave 861 .quad sysc_return, sysc_leave
826cleanup_table_sysc_leave: 862cleanup_table_sysc_leave:
827 .quad sysc_leave, sysc_work_loop 863 .quad sysc_leave, sysc_done
828cleanup_table_sysc_work_loop: 864cleanup_table_sysc_work_loop:
829 .quad sysc_work_loop, sysc_reschedule 865 .quad sysc_work_loop, sysc_work_done
830cleanup_table_io_return: 866cleanup_table_io_return:
831 .quad io_return, io_leave 867 .quad io_return, io_leave
832cleanup_table_io_leave: 868cleanup_table_io_leave:
833 .quad io_leave, io_done 869 .quad io_leave, io_done
834cleanup_table_io_work_loop: 870cleanup_table_io_work_loop:
835 .quad io_work_loop, io_mcck_pending 871 .quad io_work_loop, io_work_done
836 872
837cleanup_critical: 873cleanup_critical:
838 clc 8(8,%r12),BASED(cleanup_table_system_call) 874 clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +937,6 @@ cleanup_system_call:
901cleanup_vtime: 937cleanup_vtime:
902 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
903 jhe cleanup_stime 939 jhe cleanup_stime
904 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
905 jz cleanup_novtime
906 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 940 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
907cleanup_stime: 941cleanup_stime:
908 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 942 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +944,6 @@ cleanup_stime:
910 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 944 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
911cleanup_update: 945cleanup_update:
912 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 946 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
913cleanup_novtime:
914#endif 947#endif
915 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 948 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
916 la %r12,__LC_RETURN_PSW 949 la %r12,__LC_RETURN_PSW
@@ -949,10 +982,10 @@ cleanup_sysc_leave:
9492: la %r12,__LC_RETURN_PSW 9822: la %r12,__LC_RETURN_PSW
950 br %r14 983 br %r14
951cleanup_sysc_leave_insn: 984cleanup_sysc_leave_insn:
985 .quad sysc_done - 4
952#ifdef CONFIG_VIRT_CPU_ACCOUNTING 986#ifdef CONFIG_VIRT_CPU_ACCOUNTING
953 .quad sysc_leave + 16 987 .quad sysc_done - 8
954#endif 988#endif
955 .quad sysc_leave + 12
956 989
957cleanup_io_return: 990cleanup_io_return:
958 mvc __LC_RETURN_PSW(8),0(%r12) 991 mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,17 +1012,16 @@ cleanup_io_leave:
9792: la %r12,__LC_RETURN_PSW 10122: la %r12,__LC_RETURN_PSW
980 br %r14 1013 br %r14
981cleanup_io_leave_insn: 1014cleanup_io_leave_insn:
1015 .quad io_done - 4
982#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1016#ifdef CONFIG_VIRT_CPU_ACCOUNTING
983 .quad io_leave + 20 1017 .quad io_done - 8
984#endif 1018#endif
985 .quad io_leave + 16
986 1019
987/* 1020/*
988 * Integer constants 1021 * Integer constants
989 */ 1022 */
990 .align 4 1023 .align 4
991.Lconst: 1024.Lconst:
992.Lc_pactive: .long PREEMPT_ACTIVE
993.Lnr_syscalls: .long NR_syscalls 1025.Lnr_syscalls: .long NR_syscalls
994.L0x0130: .short 0x130 1026.L0x0130: .short 0x130
995.L0x0140: .short 0x140 1027.L0x0140: .short 0x140
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 7e1bfb984064..50f8f1e3760e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -347,7 +347,7 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
347 347
348void machine_restart(char *command) 348void machine_restart(char *command)
349{ 349{
350 if (!in_interrupt() || oops_in_progress) 350 if ((!in_interrupt() && !in_atomic()) || oops_in_progress)
351 /* 351 /*
352 * Only unblank the console if we are called in enabled 352 * Only unblank the console if we are called in enabled
353 * context or a bust_spinlocks cleared the way for us. 353 * context or a bust_spinlocks cleared the way for us.
@@ -492,6 +492,10 @@ static void setup_addressing_mode(void)
492 printk("S390 address spaces switched, "); 492 printk("S390 address spaces switched, ");
493 set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY); 493 set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY);
494 } 494 }
495#ifdef CONFIG_TRACE_IRQFLAGS
496 sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
497 io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
498#endif
495} 499}
496 500
497static void __init 501static void __init
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b05ae8584258..264ea906db4c 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -193,72 +193,30 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
193} 193}
194EXPORT_SYMBOL(smp_call_function_single); 194EXPORT_SYMBOL(smp_call_function_single);
195 195
196static void do_send_stop(void) 196void smp_send_stop(void)
197{ 197{
198 int cpu, rc; 198 int cpu, rc;
199 199
200 /* stop all processors */ 200 /* Disable all interrupts/machine checks */
201 for_each_online_cpu(cpu) { 201 __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
202 if (cpu == smp_processor_id())
203 continue;
204 do {
205 rc = signal_processor(cpu, sigp_stop);
206 } while (rc == sigp_busy);
207 }
208}
209 202
210static void do_store_status(void) 203 /* write magic number to zero page (absolute 0) */
211{ 204 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
212 int cpu, rc;
213 205
214 /* store status of all processors in their lowcores (real 0) */ 206 /* stop all processors */
215 for_each_online_cpu(cpu) { 207 for_each_online_cpu(cpu) {
216 if (cpu == smp_processor_id()) 208 if (cpu == smp_processor_id())
217 continue; 209 continue;
218 do { 210 do {
219 rc = signal_processor_p( 211 rc = signal_processor(cpu, sigp_stop);
220 (__u32)(unsigned long) lowcore_ptr[cpu], cpu,
221 sigp_store_status_at_address);
222 } while (rc == sigp_busy); 212 } while (rc == sigp_busy);
223 }
224}
225 213
226static void do_wait_for_stop(void)
227{
228 int cpu;
229
230 /* Wait for all other cpus to enter stopped state */
231 for_each_online_cpu(cpu) {
232 if (cpu == smp_processor_id())
233 continue;
234 while (!smp_cpu_not_running(cpu)) 214 while (!smp_cpu_not_running(cpu))
235 cpu_relax(); 215 cpu_relax();
236 } 216 }
237} 217}
238 218
239/* 219/*
240 * this function sends a 'stop' sigp to all other CPUs in the system.
241 * it goes straight through.
242 */
243void smp_send_stop(void)
244{
245 /* Disable all interrupts/machine checks */
246 __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
247
248 /* write magic number to zero page (absolute 0) */
249 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
250
251 /* stop other processors. */
252 do_send_stop();
253
254 /* wait until other processors are stopped */
255 do_wait_for_stop();
256
257 /* store status of other processors. */
258 do_store_status();
259}
260
261/*
262 * Reboot, halt and power_off routines for SMP. 220 * Reboot, halt and power_off routines for SMP.
263 */ 221 */
264void machine_restart_smp(char *__unused) 222void machine_restart_smp(char *__unused)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 8ec9def83ccb..8ed16a83fba7 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -260,6 +260,7 @@ void die(const char * str, struct pt_regs * regs, long err)
260 bust_spinlocks(1); 260 bust_spinlocks(1);
261 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 261 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
262 print_modules(); 262 print_modules();
263 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
263 show_regs(regs); 264 show_regs(regs);
264 bust_spinlocks(0); 265 bust_spinlocks(0);
265 add_taint(TAINT_DIE); 266 add_taint(TAINT_DIE);
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index d4ed93dfb9c7..413c240cbca7 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -341,19 +341,16 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
341 341
342static struct ctl_table cmm_table[] = { 342static struct ctl_table cmm_table[] = {
343 { 343 {
344 .ctl_name = VM_CMM_PAGES,
345 .procname = "cmm_pages", 344 .procname = "cmm_pages",
346 .mode = 0644, 345 .mode = 0644,
347 .proc_handler = &cmm_pages_handler, 346 .proc_handler = &cmm_pages_handler,
348 }, 347 },
349 { 348 {
350 .ctl_name = VM_CMM_TIMED_PAGES,
351 .procname = "cmm_timed_pages", 349 .procname = "cmm_timed_pages",
352 .mode = 0644, 350 .mode = 0644,
353 .proc_handler = &cmm_pages_handler, 351 .proc_handler = &cmm_pages_handler,
354 }, 352 },
355 { 353 {
356 .ctl_name = VM_CMM_TIMEOUT,
357 .procname = "cmm_timeout", 354 .procname = "cmm_timeout",
358 .mode = 0644, 355 .mode = 0644,
359 .proc_handler = &cmm_timeout_handler, 356 .proc_handler = &cmm_timeout_handler,
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 838f7ac0dc32..6db31089d2d7 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -483,7 +483,7 @@ static DECLARE_WORK(css_reprobe_work, reprobe_all);
483void css_schedule_reprobe(void) 483void css_schedule_reprobe(void)
484{ 484{
485 need_reprobe = 1; 485 need_reprobe = 1;
486 queue_work(ccw_device_work, &css_reprobe_work); 486 queue_work(slow_path_wq, &css_reprobe_work);
487} 487}
488 488
489EXPORT_SYMBOL_GPL(css_schedule_reprobe); 489EXPORT_SYMBOL_GPL(css_schedule_reprobe);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8867443b8060..bfad421cda66 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -1034,7 +1034,7 @@ device_trigger_reprobe(struct subchannel *sch)
1034 if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { 1034 if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
1035 PREPARE_WORK(&cdev->private->kick_work, 1035 PREPARE_WORK(&cdev->private->kick_work,
1036 ccw_device_move_to_orphanage); 1036 ccw_device_move_to_orphanage);
1037 queue_work(ccw_device_work, &cdev->private->kick_work); 1037 queue_work(slow_path_wq, &cdev->private->kick_work);
1038 } else 1038 } else
1039 ccw_device_start_id(cdev, 0); 1039 ccw_device_start_id(cdev, 0);
1040} 1040}
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index f232832f2b22..2f6bf462425e 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -113,19 +113,10 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
113{ 113{
114 struct subchannel *sch; 114 struct subchannel *sch;
115 struct ccw1 *ccw; 115 struct ccw1 *ccw;
116 int ret;
117 116
118 sch = to_subchannel(cdev->dev.parent); 117 sch = to_subchannel(cdev->dev.parent);
119 /* Setup sense channel program. */ 118 /* Setup sense channel program. */
120 ccw = cdev->private->iccws; 119 ccw = cdev->private->iccws;
121 if (sch->schib.pmcw.pim != 0x80) {
122 /* more than one path installed. */
123 ccw->cmd_code = CCW_CMD_SUSPEND_RECONN;
124 ccw->cda = 0;
125 ccw->count = 0;
126 ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC;
127 ccw++;
128 }
129 ccw->cmd_code = CCW_CMD_SENSE_ID; 120 ccw->cmd_code = CCW_CMD_SENSE_ID;
130 ccw->cda = (__u32) __pa (&cdev->private->senseid); 121 ccw->cda = (__u32) __pa (&cdev->private->senseid);
131 ccw->count = sizeof (struct senseid); 122 ccw->count = sizeof (struct senseid);
@@ -133,25 +124,9 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
133 124
134 /* Reset device status. */ 125 /* Reset device status. */
135 memset(&cdev->private->irb, 0, sizeof(struct irb)); 126 memset(&cdev->private->irb, 0, sizeof(struct irb));
127 cdev->private->flags.intretry = 0;
136 128
137 /* Try on every path. */ 129 return cio_start(sch, ccw, LPM_ANYPATH);
138 ret = -ENODEV;
139 while (cdev->private->imask != 0) {
140 if ((sch->opm & cdev->private->imask) != 0 &&
141 cdev->private->iretry > 0) {
142 cdev->private->iretry--;
143 /* Reset internal retry indication. */
144 cdev->private->flags.intretry = 0;
145 ret = cio_start (sch, cdev->private->iccws,
146 cdev->private->imask);
147 /* ret is 0, -EBUSY, -EACCES or -ENODEV */
148 if (ret != -EACCES)
149 return ret;
150 }
151 cdev->private->imask >>= 1;
152 cdev->private->iretry = 5;
153 }
154 return ret;
155} 130}
156 131
157void 132void
@@ -161,8 +136,7 @@ ccw_device_sense_id_start(struct ccw_device *cdev)
161 136
162 memset (&cdev->private->senseid, 0, sizeof (struct senseid)); 137 memset (&cdev->private->senseid, 0, sizeof (struct senseid));
163 cdev->private->senseid.cu_type = 0xFFFF; 138 cdev->private->senseid.cu_type = 0xFFFF;
164 cdev->private->imask = 0x80; 139 cdev->private->iretry = 3;
165 cdev->private->iretry = 5;
166 ret = __ccw_device_sense_id_start(cdev); 140 ret = __ccw_device_sense_id_start(cdev);
167 if (ret && ret != -EBUSY) 141 if (ret && ret != -EBUSY)
168 ccw_device_sense_id_done(cdev, ret); 142 ccw_device_sense_id_done(cdev, ret);
@@ -278,14 +252,13 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
278 ccw_device_sense_id_done(cdev, ret); 252 ccw_device_sense_id_done(cdev, ret);
279 break; 253 break;
280 case -EACCES: /* channel is not operational. */ 254 case -EACCES: /* channel is not operational. */
281 sch->lpm &= ~cdev->private->imask;
282 cdev->private->imask >>= 1;
283 cdev->private->iretry = 5;
284 /* fall through. */
285 case -EAGAIN: /* try again. */ 255 case -EAGAIN: /* try again. */
286 ret = __ccw_device_sense_id_start(cdev); 256 cdev->private->iretry--;
287 if (ret == 0 || ret == -EBUSY) 257 if (cdev->private->iretry > 0) {
288 break; 258 ret = __ccw_device_sense_id_start(cdev);
259 if (ret == 0 || ret == -EBUSY)
260 break;
261 }
289 /* fall through. */ 262 /* fall through. */
290 default: /* Sense ID failed. Try asking VM. */ 263 default: /* Sense ID failed. Try asking VM. */
291 if (MACHINE_IS_VM) { 264 if (MACHINE_IS_VM) {
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index d866d3385556..44bda786eef7 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -388,6 +388,11 @@ extern void (*_machine_power_off)(void);
388 388
389#define arch_align_stack(x) (x) 389#define arch_align_stack(x) (x)
390 390
391#ifdef CONFIG_TRACE_IRQFLAGS
392extern psw_t sysc_restore_trace_psw;
393extern psw_t io_restore_trace_psw;
394#endif
395
391#endif /* __KERNEL__ */ 396#endif /* __KERNEL__ */
392 397
393#endif 398#endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e99171f01b4c..4f5047df8a9e 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -70,7 +70,6 @@ enum
70 CTL_ABI=9, /* Binary emulation */ 70 CTL_ABI=9, /* Binary emulation */
71 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */ 71 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
72 CTL_ARLAN=254, /* arlan wireless driver */ 72 CTL_ARLAN=254, /* arlan wireless driver */
73 CTL_APPLDATA=2120, /* s390 appldata */
74 CTL_S390DBF=5677, /* s390 debug */ 73 CTL_S390DBF=5677, /* s390 debug */
75 CTL_SUNRPC=7249, /* sunrpc debug */ 74 CTL_SUNRPC=7249, /* sunrpc debug */
76 CTL_PM=9899, /* frv power management */ 75 CTL_PM=9899, /* frv power management */
@@ -207,11 +206,6 @@ enum
207 VM_PANIC_ON_OOM=33, /* panic at out-of-memory */ 206 VM_PANIC_ON_OOM=33, /* panic at out-of-memory */
208 VM_VDSO_ENABLED=34, /* map VDSO into new processes? */ 207 VM_VDSO_ENABLED=34, /* map VDSO into new processes? */
209 VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */ 208 VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */
210
211 /* s390 vm cmm sysctls */
212 VM_CMM_PAGES=1111,
213 VM_CMM_TIMED_PAGES=1112,
214 VM_CMM_TIMEOUT=1113,
215}; 209};
216 210
217 211
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index 4abc6d2306f4..8f5baac1eb08 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -140,9 +140,6 @@ static struct trans_ctl_table trans_vm_table[] = {
140 { VM_PANIC_ON_OOM, "panic_on_oom" }, 140 { VM_PANIC_ON_OOM, "panic_on_oom" },
141 { VM_VDSO_ENABLED, "vdso_enabled" }, 141 { VM_VDSO_ENABLED, "vdso_enabled" },
142 { VM_MIN_SLAB, "min_slab_ratio" }, 142 { VM_MIN_SLAB, "min_slab_ratio" },
143 { VM_CMM_PAGES, "cmm_pages" },
144 { VM_CMM_TIMED_PAGES, "cmm_timed_pages" },
145 { VM_CMM_TIMEOUT, "cmm_timeout" },
146 143
147 {} 144 {}
148}; 145};
@@ -1219,16 +1216,6 @@ static struct trans_ctl_table trans_arlan_table[] = {
1219 {} 1216 {}
1220}; 1217};
1221 1218
1222static struct trans_ctl_table trans_appldata_table[] = {
1223 { CTL_APPLDATA_TIMER, "timer" },
1224 { CTL_APPLDATA_INTERVAL, "interval" },
1225 { CTL_APPLDATA_OS, "os" },
1226 { CTL_APPLDATA_NET_SUM, "net_sum" },
1227 { CTL_APPLDATA_MEM, "mem" },
1228 {}
1229
1230};
1231
1232static struct trans_ctl_table trans_s390dbf_table[] = { 1219static struct trans_ctl_table trans_s390dbf_table[] = {
1233 { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" }, 1220 { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" },
1234 { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" }, 1221 { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" },
@@ -1273,7 +1260,6 @@ static struct trans_ctl_table trans_root_table[] = {
1273 { CTL_ABI, "abi" }, 1260 { CTL_ABI, "abi" },
1274 /* CTL_CPU not used */ 1261 /* CTL_CPU not used */
1275 { CTL_ARLAN, "arlan", trans_arlan_table }, 1262 { CTL_ARLAN, "arlan", trans_arlan_table },
1276 { CTL_APPLDATA, "appldata", trans_appldata_table },
1277 { CTL_S390DBF, "s390dbf", trans_s390dbf_table }, 1263 { CTL_S390DBF, "s390dbf", trans_s390dbf_table },
1278 { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, 1264 { CTL_SUNRPC, "sunrpc", trans_sunrpc_table },
1279 { CTL_PM, "pm", trans_pm_table }, 1265 { CTL_PM, "pm", trans_pm_table },
diff --git a/mm/rmap.c b/mm/rmap.c
index dc3be5f5b0da..dbc2ca2057a5 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -471,11 +471,12 @@ int page_mkclean(struct page *page)
471 471
472 if (page_mapped(page)) { 472 if (page_mapped(page)) {
473 struct address_space *mapping = page_mapping(page); 473 struct address_space *mapping = page_mapping(page);
474 if (mapping) 474 if (mapping) {
475 ret = page_mkclean_file(mapping, page); 475 ret = page_mkclean_file(mapping, page);
476 if (page_test_dirty(page)) { 476 if (page_test_dirty(page)) {
477 page_clear_dirty(page); 477 page_clear_dirty(page);
478 ret = 1; 478 ret = 1;
479 }
479 } 480 }
480 } 481 }
481 482
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index a2f5a6ea3895..7698f6c459d6 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -97,7 +97,7 @@ struct iucv_irq_list {
97 struct iucv_irq_data data; 97 struct iucv_irq_data data;
98}; 98};
99 99
100static struct iucv_irq_data *iucv_irq_data; 100static struct iucv_irq_data *iucv_irq_data[NR_CPUS];
101static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE; 101static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE;
102static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE; 102static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE;
103 103
@@ -277,7 +277,7 @@ union iucv_param {
277/* 277/*
278 * Anchor for per-cpu IUCV command parameter block. 278 * Anchor for per-cpu IUCV command parameter block.
279 */ 279 */
280static union iucv_param *iucv_param; 280static union iucv_param *iucv_param[NR_CPUS];
281 281
282/** 282/**
283 * iucv_call_b2f0 283 * iucv_call_b2f0
@@ -356,7 +356,7 @@ static void iucv_allow_cpu(void *data)
356 * 0x10 - Flag to allow priority message completion interrupts 356 * 0x10 - Flag to allow priority message completion interrupts
357 * 0x08 - Flag to allow IUCV control interrupts 357 * 0x08 - Flag to allow IUCV control interrupts
358 */ 358 */
359 parm = percpu_ptr(iucv_param, smp_processor_id()); 359 parm = iucv_param[cpu];
360 memset(parm, 0, sizeof(union iucv_param)); 360 memset(parm, 0, sizeof(union iucv_param));
361 parm->set_mask.ipmask = 0xf8; 361 parm->set_mask.ipmask = 0xf8;
362 iucv_call_b2f0(IUCV_SETMASK, parm); 362 iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -377,7 +377,7 @@ static void iucv_block_cpu(void *data)
377 union iucv_param *parm; 377 union iucv_param *parm;
378 378
379 /* Disable all iucv interrupts. */ 379 /* Disable all iucv interrupts. */
380 parm = percpu_ptr(iucv_param, smp_processor_id()); 380 parm = iucv_param[cpu];
381 memset(parm, 0, sizeof(union iucv_param)); 381 memset(parm, 0, sizeof(union iucv_param));
382 iucv_call_b2f0(IUCV_SETMASK, parm); 382 iucv_call_b2f0(IUCV_SETMASK, parm);
383 383
@@ -401,9 +401,9 @@ static void iucv_declare_cpu(void *data)
401 return; 401 return;
402 402
403 /* Declare interrupt buffer. */ 403 /* Declare interrupt buffer. */
404 parm = percpu_ptr(iucv_param, cpu); 404 parm = iucv_param[cpu];
405 memset(parm, 0, sizeof(union iucv_param)); 405 memset(parm, 0, sizeof(union iucv_param));
406 parm->db.ipbfadr1 = virt_to_phys(percpu_ptr(iucv_irq_data, cpu)); 406 parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
407 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); 407 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
408 if (rc) { 408 if (rc) {
409 char *err = "Unknown"; 409 char *err = "Unknown";
@@ -458,7 +458,7 @@ static void iucv_retrieve_cpu(void *data)
458 iucv_block_cpu(NULL); 458 iucv_block_cpu(NULL);
459 459
460 /* Retrieve interrupt buffer. */ 460 /* Retrieve interrupt buffer. */
461 parm = percpu_ptr(iucv_param, cpu); 461 parm = iucv_param[cpu];
462 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); 462 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
463 463
464 /* Clear indication that an iucv buffer exists for this cpu. */ 464 /* Clear indication that an iucv buffer exists for this cpu. */
@@ -558,22 +558,23 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
558 switch (action) { 558 switch (action) {
559 case CPU_UP_PREPARE: 559 case CPU_UP_PREPARE:
560 case CPU_UP_PREPARE_FROZEN: 560 case CPU_UP_PREPARE_FROZEN:
561 if (!percpu_populate(iucv_irq_data, 561 iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
562 sizeof(struct iucv_irq_data), 562 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
563 GFP_KERNEL|GFP_DMA, cpu)) 563 if (!iucv_irq_data[cpu])
564 return NOTIFY_BAD; 564 return NOTIFY_BAD;
565 if (!percpu_populate(iucv_param, sizeof(union iucv_param), 565 iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
566 GFP_KERNEL|GFP_DMA, cpu)) { 566 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
567 percpu_depopulate(iucv_irq_data, cpu); 567 if (!iucv_param[cpu])
568 return NOTIFY_BAD; 568 return NOTIFY_BAD;
569 }
570 break; 569 break;
571 case CPU_UP_CANCELED: 570 case CPU_UP_CANCELED:
572 case CPU_UP_CANCELED_FROZEN: 571 case CPU_UP_CANCELED_FROZEN:
573 case CPU_DEAD: 572 case CPU_DEAD:
574 case CPU_DEAD_FROZEN: 573 case CPU_DEAD_FROZEN:
575 percpu_depopulate(iucv_param, cpu); 574 kfree(iucv_param[cpu]);
576 percpu_depopulate(iucv_irq_data, cpu); 575 iucv_param[cpu] = NULL;
576 kfree(iucv_irq_data[cpu]);
577 iucv_irq_data[cpu] = NULL;
577 break; 578 break;
578 case CPU_ONLINE: 579 case CPU_ONLINE:
579 case CPU_ONLINE_FROZEN: 580 case CPU_ONLINE_FROZEN:
@@ -612,7 +613,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
612{ 613{
613 union iucv_param *parm; 614 union iucv_param *parm;
614 615
615 parm = percpu_ptr(iucv_param, smp_processor_id()); 616 parm = iucv_param[smp_processor_id()];
616 memset(parm, 0, sizeof(union iucv_param)); 617 memset(parm, 0, sizeof(union iucv_param));
617 if (userdata) 618 if (userdata)
618 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); 619 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -755,7 +756,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
755 756
756 local_bh_disable(); 757 local_bh_disable();
757 /* Prepare parameter block. */ 758 /* Prepare parameter block. */
758 parm = percpu_ptr(iucv_param, smp_processor_id()); 759 parm = iucv_param[smp_processor_id()];
759 memset(parm, 0, sizeof(union iucv_param)); 760 memset(parm, 0, sizeof(union iucv_param));
760 parm->ctrl.ippathid = path->pathid; 761 parm->ctrl.ippathid = path->pathid;
761 parm->ctrl.ipmsglim = path->msglim; 762 parm->ctrl.ipmsglim = path->msglim;
@@ -799,7 +800,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
799 BUG_ON(in_atomic()); 800 BUG_ON(in_atomic());
800 spin_lock_bh(&iucv_table_lock); 801 spin_lock_bh(&iucv_table_lock);
801 iucv_cleanup_queue(); 802 iucv_cleanup_queue();
802 parm = percpu_ptr(iucv_param, smp_processor_id()); 803 parm = iucv_param[smp_processor_id()];
803 memset(parm, 0, sizeof(union iucv_param)); 804 memset(parm, 0, sizeof(union iucv_param));
804 parm->ctrl.ipmsglim = path->msglim; 805 parm->ctrl.ipmsglim = path->msglim;
805 parm->ctrl.ipflags1 = path->flags; 806 parm->ctrl.ipflags1 = path->flags;
@@ -854,7 +855,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
854 int rc; 855 int rc;
855 856
856 local_bh_disable(); 857 local_bh_disable();
857 parm = percpu_ptr(iucv_param, smp_processor_id()); 858 parm = iucv_param[smp_processor_id()];
858 memset(parm, 0, sizeof(union iucv_param)); 859 memset(parm, 0, sizeof(union iucv_param));
859 if (userdata) 860 if (userdata)
860 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); 861 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -881,7 +882,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
881 int rc; 882 int rc;
882 883
883 local_bh_disable(); 884 local_bh_disable();
884 parm = percpu_ptr(iucv_param, smp_processor_id()); 885 parm = iucv_param[smp_processor_id()];
885 memset(parm, 0, sizeof(union iucv_param)); 886 memset(parm, 0, sizeof(union iucv_param));
886 if (userdata) 887 if (userdata)
887 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); 888 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -936,7 +937,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
936 int rc; 937 int rc;
937 938
938 local_bh_disable(); 939 local_bh_disable();
939 parm = percpu_ptr(iucv_param, smp_processor_id()); 940 parm = iucv_param[smp_processor_id()];
940 memset(parm, 0, sizeof(union iucv_param)); 941 memset(parm, 0, sizeof(union iucv_param));
941 parm->purge.ippathid = path->pathid; 942 parm->purge.ippathid = path->pathid;
942 parm->purge.ipmsgid = msg->id; 943 parm->purge.ipmsgid = msg->id;
@@ -1003,7 +1004,7 @@ int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
1003 } 1004 }
1004 1005
1005 local_bh_disable(); 1006 local_bh_disable();
1006 parm = percpu_ptr(iucv_param, smp_processor_id()); 1007 parm = iucv_param[smp_processor_id()];
1007 memset(parm, 0, sizeof(union iucv_param)); 1008 memset(parm, 0, sizeof(union iucv_param));
1008 parm->db.ipbfadr1 = (u32)(addr_t) buffer; 1009 parm->db.ipbfadr1 = (u32)(addr_t) buffer;
1009 parm->db.ipbfln1f = (u32) size; 1010 parm->db.ipbfln1f = (u32) size;
@@ -1040,7 +1041,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
1040 int rc; 1041 int rc;
1041 1042
1042 local_bh_disable(); 1043 local_bh_disable();
1043 parm = percpu_ptr(iucv_param, smp_processor_id()); 1044 parm = iucv_param[smp_processor_id()];
1044 memset(parm, 0, sizeof(union iucv_param)); 1045 memset(parm, 0, sizeof(union iucv_param));
1045 parm->db.ippathid = path->pathid; 1046 parm->db.ippathid = path->pathid;
1046 parm->db.ipmsgid = msg->id; 1047 parm->db.ipmsgid = msg->id;
@@ -1074,7 +1075,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
1074 int rc; 1075 int rc;
1075 1076
1076 local_bh_disable(); 1077 local_bh_disable();
1077 parm = percpu_ptr(iucv_param, smp_processor_id()); 1078 parm = iucv_param[smp_processor_id()];
1078 memset(parm, 0, sizeof(union iucv_param)); 1079 memset(parm, 0, sizeof(union iucv_param));
1079 if (flags & IUCV_IPRMDATA) { 1080 if (flags & IUCV_IPRMDATA) {
1080 parm->dpl.ippathid = path->pathid; 1081 parm->dpl.ippathid = path->pathid;
@@ -1118,7 +1119,7 @@ int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
1118 int rc; 1119 int rc;
1119 1120
1120 local_bh_disable(); 1121 local_bh_disable();
1121 parm = percpu_ptr(iucv_param, smp_processor_id()); 1122 parm = iucv_param[smp_processor_id()];
1122 memset(parm, 0, sizeof(union iucv_param)); 1123 memset(parm, 0, sizeof(union iucv_param));
1123 if (flags & IUCV_IPRMDATA) { 1124 if (flags & IUCV_IPRMDATA) {
1124 /* Message of 8 bytes can be placed into the parameter list. */ 1125 /* Message of 8 bytes can be placed into the parameter list. */
@@ -1172,7 +1173,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
1172 int rc; 1173 int rc;
1173 1174
1174 local_bh_disable(); 1175 local_bh_disable();
1175 parm = percpu_ptr(iucv_param, smp_processor_id()); 1176 parm = iucv_param[smp_processor_id()];
1176 memset(parm, 0, sizeof(union iucv_param)); 1177 memset(parm, 0, sizeof(union iucv_param));
1177 if (flags & IUCV_IPRMDATA) { 1178 if (flags & IUCV_IPRMDATA) {
1178 parm->dpl.ippathid = path->pathid; 1179 parm->dpl.ippathid = path->pathid;
@@ -1559,7 +1560,7 @@ static void iucv_external_interrupt(u16 code)
1559 struct iucv_irq_data *p; 1560 struct iucv_irq_data *p;
1560 struct iucv_irq_list *work; 1561 struct iucv_irq_list *work;
1561 1562
1562 p = percpu_ptr(iucv_irq_data, smp_processor_id()); 1563 p = iucv_irq_data[smp_processor_id()];
1563 if (p->ippathid >= iucv_max_pathid) { 1564 if (p->ippathid >= iucv_max_pathid) {
1564 printk(KERN_WARNING "iucv_do_int: Got interrupt with " 1565 printk(KERN_WARNING "iucv_do_int: Got interrupt with "
1565 "pathid %d > max_connections (%ld)\n", 1566 "pathid %d > max_connections (%ld)\n",
@@ -1598,6 +1599,7 @@ static void iucv_external_interrupt(u16 code)
1598static int __init iucv_init(void) 1599static int __init iucv_init(void)
1599{ 1600{
1600 int rc; 1601 int rc;
1602 int cpu;
1601 1603
1602 if (!MACHINE_IS_VM) { 1604 if (!MACHINE_IS_VM) {
1603 rc = -EPROTONOSUPPORT; 1605 rc = -EPROTONOSUPPORT;
@@ -1617,19 +1619,23 @@ static int __init iucv_init(void)
1617 rc = PTR_ERR(iucv_root); 1619 rc = PTR_ERR(iucv_root);
1618 goto out_bus; 1620 goto out_bus;
1619 } 1621 }
1620 /* Note: GFP_DMA used to get memory below 2G */ 1622
1621 iucv_irq_data = percpu_alloc(sizeof(struct iucv_irq_data), 1623 for_each_online_cpu(cpu) {
1622 GFP_KERNEL|GFP_DMA); 1624 /* Note: GFP_DMA used to get memory below 2G */
1623 if (!iucv_irq_data) { 1625 iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
1624 rc = -ENOMEM; 1626 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
1625 goto out_root; 1627 if (!iucv_irq_data[cpu]) {
1626 } 1628 rc = -ENOMEM;
1627 /* Allocate parameter blocks. */ 1629 goto out_free;
1628 iucv_param = percpu_alloc(sizeof(union iucv_param), 1630 }
1629 GFP_KERNEL|GFP_DMA); 1631
1630 if (!iucv_param) { 1632 /* Allocate parameter blocks. */
1631 rc = -ENOMEM; 1633 iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
1632 goto out_extint; 1634 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
1635 if (!iucv_param[cpu]) {
1636 rc = -ENOMEM;
1637 goto out_free;
1638 }
1633 } 1639 }
1634 register_hotcpu_notifier(&iucv_cpu_notifier); 1640 register_hotcpu_notifier(&iucv_cpu_notifier);
1635 ASCEBC(iucv_error_no_listener, 16); 1641 ASCEBC(iucv_error_no_listener, 16);
@@ -1638,9 +1644,13 @@ static int __init iucv_init(void)
1638 iucv_available = 1; 1644 iucv_available = 1;
1639 return 0; 1645 return 0;
1640 1646
1641out_extint: 1647out_free:
1642 percpu_free(iucv_irq_data); 1648 for_each_possible_cpu(cpu) {
1643out_root: 1649 kfree(iucv_param[cpu]);
1650 iucv_param[cpu] = NULL;
1651 kfree(iucv_irq_data[cpu]);
1652 iucv_irq_data[cpu] = NULL;
1653 }
1644 s390_root_dev_unregister(iucv_root); 1654 s390_root_dev_unregister(iucv_root);
1645out_bus: 1655out_bus:
1646 bus_unregister(&iucv_bus); 1656 bus_unregister(&iucv_bus);
@@ -1658,6 +1668,7 @@ out:
1658static void __exit iucv_exit(void) 1668static void __exit iucv_exit(void)
1659{ 1669{
1660 struct iucv_irq_list *p, *n; 1670 struct iucv_irq_list *p, *n;
1671 int cpu;
1661 1672
1662 spin_lock_irq(&iucv_queue_lock); 1673 spin_lock_irq(&iucv_queue_lock);
1663 list_for_each_entry_safe(p, n, &iucv_task_queue, list) 1674 list_for_each_entry_safe(p, n, &iucv_task_queue, list)
@@ -1666,8 +1677,12 @@ static void __exit iucv_exit(void)
1666 kfree(p); 1677 kfree(p);
1667 spin_unlock_irq(&iucv_queue_lock); 1678 spin_unlock_irq(&iucv_queue_lock);
1668 unregister_hotcpu_notifier(&iucv_cpu_notifier); 1679 unregister_hotcpu_notifier(&iucv_cpu_notifier);
1669 percpu_free(iucv_param); 1680 for_each_possible_cpu(cpu) {
1670 percpu_free(iucv_irq_data); 1681 kfree(iucv_param[cpu]);
1682 iucv_param[cpu] = NULL;
1683 kfree(iucv_irq_data[cpu]);
1684 iucv_irq_data[cpu] = NULL;
1685 }
1671 s390_root_dev_unregister(iucv_root); 1686 s390_root_dev_unregister(iucv_root);
1672 bus_unregister(&iucv_bus); 1687 bus_unregister(&iucv_bus);
1673 unregister_external_interrupt(0x4000, iucv_external_interrupt); 1688 unregister_external_interrupt(0x4000, iucv_external_interrupt);