summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-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/hypfs/inode.c13
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/entry.S122
-rw-r--r--arch/s390/kernel/entry64.S114
-rw-r--r--arch/s390/kernel/ipl.c147
-rw-r--r--arch/s390/kernel/setup.c10
-rw-r--r--arch/s390/kernel/smp.c56
-rw-r--r--arch/s390/kernel/time.c2
-rw-r--r--arch/s390/kernel/traps.c1
-rw-r--r--arch/s390/mm/cmm.c3
15 files changed, 274 insertions, 274 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 {
int active; /* monitoring status */
/* fill in from here */
- unsigned int ctl_nr; /* sysctl ID */
char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */
unsigned char record_nr; /* Record Nr. for Product ID */
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,
static struct ctl_table_header *appldata_sysctl_header;
static struct ctl_table appldata_table[] = {
{
- .ctl_name = CTL_APPLDATA_TIMER,
.procname = "timer",
.mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_timer_handler,
},
{
- .ctl_name = CTL_APPLDATA_INTERVAL,
.procname = "interval",
.mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_interval_handler,
},
- { .ctl_name = 0 }
+ { },
};
static struct ctl_table appldata_dir_table[] = {
{
- .ctl_name = CTL_APPLDATA,
.procname = appldata_proc_name,
.maxlen = 0,
.mode = S_IRUGO | S_IXUGO,
.child = appldata_table,
},
- { .ctl_name = 0 }
+ { },
};
/*
@@ -441,75 +438,38 @@ out:
*/
int appldata_register_ops(struct appldata_ops *ops)
{
- struct list_head *lh;
- struct appldata_ops *tmp_ops;
- int i;
-
- i = 0;
+ if ((ops->size > APPLDATA_MAX_REC_SIZE) || (ops->size < 0))
+ return -EINVAL;
- if ((ops->size > APPLDATA_MAX_REC_SIZE) ||
- (ops->size < 0)){
- P_ERROR("Invalid size of %s record = %i, maximum = %i!\n",
- ops->name, ops->size, APPLDATA_MAX_REC_SIZE);
- return -ENOMEM;
- }
- if ((ops->ctl_nr == CTL_APPLDATA) ||
- (ops->ctl_nr == CTL_APPLDATA_TIMER) ||
- (ops->ctl_nr == CTL_APPLDATA_INTERVAL)) {
- P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr);
- return -EBUSY;
- }
- ops->ctl_table = kzalloc(4*sizeof(struct ctl_table), GFP_KERNEL);
- if (ops->ctl_table == NULL) {
- P_ERROR("Not enough memory for %s ctl_table!\n", ops->name);
+ ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL);
+ if (!ops->ctl_table)
return -ENOMEM;
- }
spin_lock(&appldata_ops_lock);
- list_for_each(lh, &appldata_ops_list) {
- tmp_ops = list_entry(lh, struct appldata_ops, list);
- P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
- ++i, tmp_ops->name, tmp_ops->ctl_nr);
- P_DEBUG("Comparing %s (ctl %i) with %s (ctl %i)\n",
- tmp_ops->name, tmp_ops->ctl_nr, ops->name,
- ops->ctl_nr);
- if (strncmp(tmp_ops->name, ops->name,
- APPLDATA_PROC_NAME_LENGTH) == 0) {
- P_ERROR("Name \"%s\" already registered!\n", ops->name);
- kfree(ops->ctl_table);
- spin_unlock(&appldata_ops_lock);
- return -EBUSY;
- }
- if (tmp_ops->ctl_nr == ops->ctl_nr) {
- P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
- kfree(ops->ctl_table);
- spin_unlock(&appldata_ops_lock);
- return -EBUSY;
- }
- }
list_add(&ops->list, &appldata_ops_list);
spin_unlock(&appldata_ops_lock);
- ops->ctl_table[0].ctl_name = CTL_APPLDATA;
ops->ctl_table[0].procname = appldata_proc_name;
ops->ctl_table[0].maxlen = 0;
ops->ctl_table[0].mode = S_IRUGO | S_IXUGO;
ops->ctl_table[0].child = &ops->ctl_table[2];
- ops->ctl_table[1].ctl_name = 0;
-
- ops->ctl_table[2].ctl_name = ops->ctl_nr;
ops->ctl_table[2].procname = ops->name;
ops->ctl_table[2].mode = S_IRUGO | S_IWUSR;
ops->ctl_table[2].proc_handler = appldata_generic_handler;
ops->ctl_table[2].data = ops;
- ops->ctl_table[3].ctl_name = 0;
-
ops->sysctl_header = register_sysctl_table(ops->ctl_table);
-
+ if (!ops->sysctl_header)
+ goto out;
P_INFO("%s-ops registered!\n", ops->name);
return 0;
+out:
+ spin_lock(&appldata_ops_lock);
+ list_del(&ops->list);
+ spin_unlock(&appldata_ops_lock);
+ kfree(ops->ctl_table);
+ return -ENOMEM;
}
/*
@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldata_ops *ops)
*/
void appldata_unregister_ops(struct appldata_ops *ops)
{
- void *table;
spin_lock(&appldata_ops_lock);
list_del(&ops->list);
- /* at that point any incoming access will fail */
- table = ops->ctl_table;
- ops->ctl_table = NULL;
spin_unlock(&appldata_ops_lock);
unregister_sysctl_table(ops->sysctl_header);
- kfree(table);
+ kfree(ops->ctl_table);
P_INFO("%s-ops unregistered!\n", ops->name);
}
/********************** 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)
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_MEM,
.name = "mem",
.record_nr = APPLDATA_RECORD_MEM_ID,
.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)
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_NET_SUM,
.name = "net_sum",
.record_nr = APPLDATA_RECORD_NET_SUM_ID,
.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 {
static struct appldata_os_data *appldata_os_data;
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_OS,
.name = "os",
.record_nr = APPLDATA_RECORD_OS_ID,
.owner = THIS_MODULE,
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 5245717295b8..4b010ff814c9 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -490,7 +490,7 @@ static struct super_operations hypfs_s_ops = {
.show_options = hypfs_show_options,
};
-static decl_subsys(s390, NULL, NULL);
+static struct kobject *s390_kobj;
static int __init hypfs_init(void)
{
@@ -506,17 +506,18 @@ static int __init hypfs_init(void)
goto fail_diag;
}
}
- kobj_set_kset_s(&s390_subsys, hypervisor_subsys);
- rc = subsystem_register(&s390_subsys);
- if (rc)
+ s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
+ if (!s390_kobj) {
+ rc = -ENOMEM;;
goto fail_sysfs;
+ }
rc = register_filesystem(&hypfs_type);
if (rc)
goto fail_filesystem;
return 0;
fail_filesystem:
- subsystem_unregister(&s390_subsys);
+ kobject_put(s390_kobj);
fail_sysfs:
if (!MACHINE_IS_VM)
hypfs_diag_exit();
@@ -530,7 +531,7 @@ static void __exit hypfs_exit(void)
if (!MACHINE_IS_VM)
hypfs_diag_exit();
unregister_filesystem(&hypfs_type);
- subsystem_unregister(&s390_subsys);
+ kobject_put(s390_kobj);
}
module_init(hypfs_init)
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)
cc = __tprot(addr);
while (cc == old_cc) {
addr += CHUNK_INCR;
- if (addr >= memsize)
+ if (memsize && addr >= memsize)
break;
#ifndef CONFIG_64BIT
if (addr == ADDR2G)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5cc..1a6dac8df6fb 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
basr %r14,%r1
.endm
- .macro LOCKDEP_SYS_EXIT
- l %r1,BASED(.Llockdep_sys_exit)
+ .macro TRACE_IRQS_CHECK
+ tm SP_PSW(%r15),0x03 # irqs enabled?
+ jz 0f
+ l %r1,BASED(.Ltrace_irq_on)
basr %r14,%r1
+ j 1f
+0: l %r1,BASED(.Ltrace_irq_off)
+ basr %r14,%r1
+1:
.endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define TRACE_IRQS_CHECK
+#endif
+
+#ifdef CONFIG_LOCKDEP
+ .macro LOCKDEP_SYS_EXIT
+ tm SP_PSW+1(%r15),0x01 # returning to user ?
+ jz 0f
+ l %r1,BASED(.Llockdep_sys_exit)
+ basr %r14,%r1
+0:
+ .endm
+#else
#define LOCKDEP_SYS_EXIT
#endif
@@ -234,8 +252,6 @@ sysc_saveall:
lh %r7,0x8a # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_vtime:
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(sysc_do_svc)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -263,19 +279,34 @@ sysc_do_restart:
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
- bno BASED(sysc_leave)
+ bno BASED(sysc_restore)
tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
+sysc_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ la %r1,BASED(sysc_restore_trace_psw)
+ lpsw 0(%r1)
+sysc_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
+sysc_done:
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl sysc_restore_trace_psw
+sysc_restore_trace_psw:
+ .long 0, sysc_restore_trace + 0x80000000
+#endif
#
# recheck if there is more work to do
#
sysc_work_loop:
tm __TI_flags+3(%r9),_TIF_WORK_SVC
- bz BASED(sysc_leave) # there is no work to do
+ bz BASED(sysc_restore) # there is no work to do
#
# One of the work bits is on. Find out which one.
#
@@ -290,8 +321,8 @@ sysc_work:
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
- LOCKDEP_SYS_EXIT
- b BASED(sysc_leave)
+ b BASED(sysc_restore)
+sysc_work_done:
#
# _TIF_NEED_RESCHED is set, call schedule
@@ -458,6 +489,7 @@ pgm_check_handler:
pgm_no_vtime:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
nr %r8,%r3
@@ -497,6 +529,7 @@ pgm_per_std:
pgm_no_vtime2:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -517,15 +550,13 @@ pgm_svcper:
SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(pgm_no_vtime3)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-pgm_no_vtime3:
#endif
lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -542,7 +573,7 @@ kernel_per:
mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
- la %r14,BASED(sysc_leave) # load adr. of system return
+ la %r14,BASED(sysc_restore)# load adr. of system return
br %r1 # branch to do_single_step
/*
@@ -569,26 +600,38 @@ io_no_vtime:
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
- TRACE_IRQS_ON
-
io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifdef CONFIG_PREEMPT
bno BASED(io_preempt) # no -> check for preemptive scheduling
#else
- bno BASED(io_leave) # no-> skip resched & signal
+ bno BASED(io_restore) # no-> skip resched & signal
#endif
tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.)
+io_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ la %r1,BASED(io_restore_trace_psw)
+ lpsw 0(%r1)
+io_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl io_restore_trace_psw
+io_restore_trace_psw:
+ .long 0, io_restore_trace + 0x80000000
+#endif
+
#ifdef CONFIG_PREEMPT
io_preempt:
icm %r0,15,__TI_precount(%r9)
- bnz BASED(io_leave)
+ bnz BASED(io_restore)
l %r1,SP_R15(%r15)
s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -596,14 +639,10 @@ io_preempt:
lr %r15,%r1
io_resume_loop:
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
- bno BASED(io_leave)
- mvc __TI_precount(4,%r9),BASED(.Lc_pactive)
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
- l %r1,BASED(.Lschedule)
- basr %r14,%r1 # call schedule
- stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- xc __TI_precount(4,%r9),__TI_precount(%r9)
- b BASED(io_resume_loop)
+ bno BASED(io_restore)
+ l %r1,BASED(.Lpreempt_schedule_irq)
+ la %r14,BASED(io_resume_loop)
+ br %r1 # call schedule
#endif
#
@@ -627,40 +666,42 @@ io_work_loop:
bo BASED(io_reschedule)
tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
bnz BASED(io_sigpending)
- LOCKDEP_SYS_EXIT
- b BASED(io_leave)
+ b BASED(io_restore)
+io_work_done:
#
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
- TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # TIF bit will be cleared by handler
- TRACE_IRQS_ON
b BASED(io_work_loop)
#
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
+ TRACE_IRQS_ON
l %r1,BASED(.Lschedule)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
basr %r14,%r1 # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
tm __TI_flags+3(%r9),_TIF_WORK_INT
- bz BASED(io_leave) # there is no work to do
+ bz BASED(io_restore) # there is no work to do
b BASED(io_work_loop)
#
# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
#
io_sigpending:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
b BASED(io_work_loop)
/*
@@ -688,7 +729,6 @@ ext_no_vtime:
lh %r3,__LC_EXT_INT_CODE # get interruption code
l %r1,BASED(.Ldo_extint)
basr %r14,%r1
- TRACE_IRQS_ON
b BASED(io_return)
__critical_end:
@@ -853,15 +893,15 @@ cleanup_table_system_call:
cleanup_table_sysc_return:
.long sysc_return + 0x80000000, sysc_leave + 0x80000000
cleanup_table_sysc_leave:
- .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
+ .long sysc_leave + 0x80000000, sysc_done + 0x80000000
cleanup_table_sysc_work_loop:
- .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
+ .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
cleanup_table_io_return:
.long io_return + 0x80000000, io_leave + 0x80000000
cleanup_table_io_leave:
.long io_leave + 0x80000000, io_done + 0x80000000
cleanup_table_io_work_loop:
- .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000
+ .long io_work_loop + 0x80000000, io_work_done + 0x80000000
cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +970,6 @@ cleanup_system_call:
cleanup_vtime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
bhe BASED(cleanup_stime)
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(cleanup_novtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
cleanup_stime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +977,6 @@ cleanup_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
cleanup_update:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-cleanup_novtime:
#endif
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
la %r12,__LC_RETURN_PSW
@@ -978,10 +1015,10 @@ cleanup_sysc_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave_insn:
+ .long sysc_done - 4 + 0x80000000
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .long sysc_leave + 14 + 0x80000000
+ .long sysc_done - 8 + 0x80000000
#endif
- .long sysc_leave + 10 + 0x80000000
cleanup_io_return:
mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1045,10 @@ cleanup_io_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave_insn:
+ .long io_done - 4 + 0x80000000
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .long io_leave + 18 + 0x80000000
+ .long io_done - 8 + 0x80000000
#endif
- .long io_leave + 14 + 0x80000000
/*
* Integer constants
@@ -1019,7 +1056,6 @@ cleanup_io_leave_insn:
.align 4
.Lc_spsize: .long SP_SIZE
.Lc_overhead: .long STACK_FRAME_OVERHEAD
-.Lc_pactive: .long PREEMPT_ACTIVE
.Lnr_syscalls: .long NR_syscalls
.L0x018: .short 0x018
.L0x020: .short 0x020
@@ -1043,6 +1079,10 @@ cleanup_io_leave_insn:
.Lexecve_tail: .long execve_tail
.Ljump_table: .long pgm_check_table
.Lschedule: .long schedule
+#ifdef CONFIG_PREEMPT
+.Lpreempt_schedule_irq:
+ .long preempt_schedule_irq
+#endif
.Ltrace: .long syscall_trace
.Lschedtail: .long schedule_tail
.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 | \
brasl %r14,trace_hardirqs_off
.endm
- .macro LOCKDEP_SYS_EXIT
- brasl %r14,lockdep_sys_exit
+ .macro TRACE_IRQS_CHECK
+ tm SP_PSW(%r15),0x03 # irqs enabled?
+ jz 0f
+ brasl %r14,trace_hardirqs_on
+ j 1f
+0: brasl %r14,trace_hardirqs_off
+1:
.endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define TRACE_IRQS_CHECK
+#endif
+
+#ifdef CONFIG_LOCKDEP
+ .macro LOCKDEP_SYS_EXIT
+ tm SP_PSW+1(%r15),0x01 # returning to user ?
+ jz 0f
+ brasl %r14,lockdep_sys_exit
+0:
+ .endm
+#else
#define LOCKDEP_SYS_EXIT
#endif
@@ -222,8 +238,6 @@ sysc_saveall:
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_vtime:
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz sysc_do_svc
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -257,19 +271,34 @@ sysc_noemu:
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
- jno sysc_leave
+ jno sysc_restore
tm __TI_flags+7(%r9),_TIF_WORK_SVC
jnz sysc_work # there is work to do (signals etc.)
+sysc_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ larl %r1,sysc_restore_trace_psw
+ lpswe 0(%r1)
+sysc_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
+sysc_done:
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl sysc_restore_trace_psw
+sysc_restore_trace_psw:
+ .quad 0, sysc_restore_trace
+#endif
#
# recheck if there is more work to do
#
sysc_work_loop:
tm __TI_flags+7(%r9),_TIF_WORK_SVC
- jz sysc_leave # there is no work to do
+ jz sysc_restore # there is no work to do
#
# One of the work bits is on. Find out which one.
#
@@ -284,8 +313,8 @@ sysc_work:
jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
jo sysc_singlestep
- LOCKDEP_SYS_EXIT
- j sysc_leave
+ j sysc_restore
+sysc_work_done:
#
# _TIF_NEED_RESCHED is set, call schedule
@@ -445,6 +474,7 @@ pgm_check_handler:
pgm_no_vtime:
#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
lgf %r3,__LC_PGM_ILC # load program interruption code
lghi %r8,0x7f
ngr %r8,%r3
@@ -484,6 +514,7 @@ pgm_per_std:
pgm_no_vtime2:
#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
lg %r1,__TI_task(%r9)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
jz kernel_per
@@ -504,12 +535,9 @@ pgm_svcper:
SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz pgm_no_vtime3
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-pgm_no_vtime3:
#endif
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
@@ -529,7 +557,7 @@ kernel_per:
lhi %r0,__LC_PGM_OLD_PSW
sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area
- larl %r14,sysc_leave # load adr. of system ret, no work
+ larl %r14,sysc_restore # load adr. of system ret, no work
jg do_single_step # branch to do_single_step
/*
@@ -554,26 +582,38 @@ io_no_vtime:
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
brasl %r14,do_IRQ # call standard irq handler
- TRACE_IRQS_ON
-
io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifdef CONFIG_PREEMPT
jno io_preempt # no -> check for preemptive scheduling
#else
- jno io_leave # no-> skip resched & signal
+ jno io_restore # no-> skip resched & signal
#endif
tm __TI_flags+7(%r9),_TIF_WORK_INT
jnz io_work # there is work to do (signals etc.)
+io_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ larl %r1,io_restore_trace_psw
+ lpswe 0(%r1)
+io_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl io_restore_trace_psw
+io_restore_trace_psw:
+ .quad 0, io_restore_trace
+#endif
+
#ifdef CONFIG_PREEMPT
io_preempt:
icm %r0,15,__TI_precount(%r9)
- jnz io_leave
+ jnz io_restore
# switch to kernel stack
lg %r1,SP_R15(%r15)
aghi %r1,-SP_SIZE
@@ -582,14 +622,9 @@ io_preempt:
lgr %r15,%r1
io_resume_loop:
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
- jno io_leave
- larl %r1,.Lc_pactive
- mvc __TI_precount(4,%r9),0(%r1)
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
- brasl %r14,schedule # call schedule
- stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- xc __TI_precount(4,%r9),__TI_precount(%r9)
- j io_resume_loop
+ jno io_restore
+ larl %r14,io_resume_loop
+ jg preempt_schedule_irq
#endif
#
@@ -613,37 +648,39 @@ io_work_loop:
jo io_reschedule
tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
jnz io_sigpending
- LOCKDEP_SYS_EXIT
- j io_leave
+ j io_restore
+io_work_done:
#
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
- TRACE_IRQS_OFF
brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
- TRACE_IRQS_ON
j io_work_loop
#
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
brasl %r14,schedule # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
tm __TI_flags+7(%r9),_TIF_WORK_INT
- jz io_leave # there is no work to do
+ jz io_restore # there is no work to do
j io_work_loop
#
# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
#
io_sigpending:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
brasl %r14,do_signal # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
j io_work_loop
/*
@@ -669,7 +706,6 @@ ext_no_vtime:
la %r2,SP_PTREGS(%r15) # address of register-save area
llgh %r3,__LC_EXT_INT_CODE # get interruption code
brasl %r14,do_extint
- TRACE_IRQS_ON
j io_return
__critical_end:
@@ -824,15 +860,15 @@ cleanup_table_system_call:
cleanup_table_sysc_return:
.quad sysc_return, sysc_leave
cleanup_table_sysc_leave:
- .quad sysc_leave, sysc_work_loop
+ .quad sysc_leave, sysc_done
cleanup_table_sysc_work_loop:
- .quad sysc_work_loop, sysc_reschedule
+ .quad sysc_work_loop, sysc_work_done
cleanup_table_io_return:
.quad io_return, io_leave
cleanup_table_io_leave:
.quad io_leave, io_done
cleanup_table_io_work_loop:
- .quad io_work_loop, io_mcck_pending
+ .quad io_work_loop, io_work_done
cleanup_critical:
clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +937,6 @@ cleanup_system_call:
cleanup_vtime:
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
jhe cleanup_stime
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz cleanup_novtime
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
cleanup_stime:
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +944,6 @@ cleanup_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
cleanup_update:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-cleanup_novtime:
#endif
mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
la %r12,__LC_RETURN_PSW
@@ -949,10 +982,10 @@ cleanup_sysc_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave_insn:
+ .quad sysc_done - 4
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .quad sysc_leave + 16
+ .quad sysc_done - 8
#endif
- .quad sysc_leave + 12
cleanup_io_return:
mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,17 +1012,16 @@ cleanup_io_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave_insn:
+ .quad io_done - 4
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .quad io_leave + 20
+ .quad io_done - 8
#endif
- .quad io_leave + 16
/*
* Integer constants
*/
.align 4
.Lconst:
-.Lc_pactive: .long PREEMPT_ACTIVE
.Lnr_syscalls: .long NR_syscalls
.L0x0130: .short 0x130
.L0x0140: .short 0x140
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ce0856d32500..b97694fa62ec 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -162,22 +162,25 @@ EXPORT_SYMBOL_GPL(diag308);
/* SYSFS */
#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \
+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
char *page) \
{ \
return sprintf(page, _format, _value); \
} \
-static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
+static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
__ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \
+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
char *page) \
{ \
return sprintf(page, _fmt_out, \
(unsigned long long) _value); \
} \
-static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \
+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
const char *buf, size_t len) \
{ \
unsigned long long value; \
@@ -186,25 +189,27 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \
_value = value; \
return len; \
} \
-static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
+static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
__ATTR(_name,(S_IRUGO | S_IWUSR), \
sys_##_prefix##_##_name##_show, \
sys_##_prefix##_##_name##_store);
#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \
+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
char *page) \
{ \
return sprintf(page, _fmt_out, _value); \
} \
-static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \
+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
const char *buf, size_t len) \
{ \
if (sscanf(buf, _fmt_in, _value) != 1) \
return -EINVAL; \
return len; \
} \
-static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
+static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
__ATTR(_name,(S_IRUGO | S_IWUSR), \
sys_##_prefix##_##_name##_show, \
sys_##_prefix##_##_name##_store);
@@ -270,14 +275,16 @@ void __init setup_ipl_info(void)
struct ipl_info ipl_info;
EXPORT_SYMBOL_GPL(ipl_info);
-static ssize_t ipl_type_show(struct kset *kset, char *page)
+static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *page)
{
return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
}
-static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
+static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
-static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
+static ssize_t sys_ipl_device_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
@@ -292,7 +299,7 @@ static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
}
}
-static struct subsys_attribute sys_ipl_device_attr =
+static struct kobj_attribute sys_ipl_device_attr =
__ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
@@ -367,7 +374,8 @@ static struct attribute_group ipl_fcp_attr_group = {
/* CCW ipl device attributes */
-static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
+static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
char loadparm[LOADPARM_LEN + 1] = {};
@@ -379,7 +387,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
return sprintf(page, "%s\n", loadparm);
}
-static struct subsys_attribute sys_ipl_ccw_loadparm_attr =
+static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
__ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
static struct attribute *ipl_ccw_attrs[] = {
@@ -418,7 +426,7 @@ static struct attribute_group ipl_unknown_attr_group = {
.attrs = ipl_unknown_attrs,
};
-static decl_subsys(ipl, NULL, NULL);
+static struct kset *ipl_kset;
/*
* reipl section
@@ -465,7 +473,8 @@ static void reipl_get_ascii_loadparm(char *loadparm)
strstrip(loadparm);
}
-static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
+static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
char buf[LOADPARM_LEN + 1];
@@ -473,7 +482,8 @@ static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
return sprintf(page, "%s\n", buf);
}
-static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
+static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
const char *buf, size_t len)
{
int i, lp_len;
@@ -500,7 +510,7 @@ static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
return len;
}
-static struct subsys_attribute sys_reipl_ccw_loadparm_attr =
+static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
__ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
reipl_ccw_loadparm_store);
@@ -568,13 +578,15 @@ static int reipl_set_type(enum ipl_type type)
return 0;
}
-static ssize_t reipl_type_show(struct kset *kset, char *page)
+static ssize_t reipl_type_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
return sprintf(page, "%s\n", ipl_type_str(reipl_type));
}
-static ssize_t reipl_type_store(struct kset *kset, const char *buf,
- size_t len)
+static ssize_t reipl_type_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t len)
{
int rc = -EINVAL;
@@ -587,10 +599,10 @@ static ssize_t reipl_type_store(struct kset *kset, const char *buf,
return (rc != 0) ? rc : len;
}
-static struct subsys_attribute reipl_type_attr =
+static struct kobj_attribute reipl_type_attr =
__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
-static decl_subsys(reipl, NULL, NULL);
+static struct kset *reipl_kset;
/*
* dump section
@@ -663,13 +675,15 @@ static int dump_set_type(enum dump_type type)
return 0;
}
-static ssize_t dump_type_show(struct kset *kset, char *page)
+static ssize_t dump_type_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
return sprintf(page, "%s\n", dump_type_str(dump_type));
}
-static ssize_t dump_type_store(struct kset *kset, const char *buf,
- size_t len)
+static ssize_t dump_type_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t len)
{
int rc = -EINVAL;
@@ -682,26 +696,28 @@ static ssize_t dump_type_store(struct kset *kset, const char *buf,
return (rc != 0) ? rc : len;
}
-static struct subsys_attribute dump_type_attr =
+static struct kobj_attribute dump_type_attr =
__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
-static decl_subsys(dump, NULL, NULL);
+static struct kset *dump_kset;
/*
* Shutdown actions section
*/
-static decl_subsys(shutdown_actions, NULL, NULL);
+static struct kset *shutdown_actions_kset;
/* on panic */
-static ssize_t on_panic_show(struct kset *kset, char *page)
+static ssize_t on_panic_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *page)
{
return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
}
-static ssize_t on_panic_store(struct kset *kset, const char *buf,
- size_t len)
+static ssize_t on_panic_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t len)
{
if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
on_panic_action = SHUTDOWN_REIPL;
@@ -717,7 +733,7 @@ static ssize_t on_panic_store(struct kset *kset, const char *buf,
return len;
}
-static struct subsys_attribute on_panic_attr =
+static struct kobj_attribute on_panic_attr =
__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
void do_reipl(void)
@@ -814,23 +830,23 @@ static int __init ipl_register_fcp_files(void)
{
int rc;
- rc = sysfs_create_group(&ipl_subsys.kobj,
+ rc = sysfs_create_group(&ipl_kset->kobj,
&ipl_fcp_attr_group);
if (rc)
goto out;
- rc = sysfs_create_bin_file(&ipl_subsys.kobj,
+ rc = sysfs_create_bin_file(&ipl_kset->kobj,
&ipl_parameter_attr);
if (rc)
goto out_ipl_parm;
- rc = sysfs_create_bin_file(&ipl_subsys.kobj,
+ rc = sysfs_create_bin_file(&ipl_kset->kobj,
&ipl_scp_data_attr);
if (!rc)
goto out;
- sysfs_remove_bin_file(&ipl_subsys.kobj, &ipl_parameter_attr);
+ sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
out_ipl_parm:
- sysfs_remove_group(&ipl_subsys.kobj, &ipl_fcp_attr_group);
+ sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
out:
return rc;
}
@@ -839,12 +855,12 @@ static int __init ipl_init(void)
{
int rc;
- rc = firmware_register(&ipl_subsys);
- if (rc)
- return rc;
+ ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
+ if (!ipl_kset)
+ return -ENOMEM;
switch (ipl_info.type) {
case IPL_TYPE_CCW:
- rc = sysfs_create_group(&ipl_subsys.kobj,
+ rc = sysfs_create_group(&ipl_kset->kobj,
&ipl_ccw_attr_group);
break;
case IPL_TYPE_FCP:
@@ -852,16 +868,16 @@ static int __init ipl_init(void)
rc = ipl_register_fcp_files();
break;
case IPL_TYPE_NSS:
- rc = sysfs_create_group(&ipl_subsys.kobj,
+ rc = sysfs_create_group(&ipl_kset->kobj,
&ipl_nss_attr_group);
break;
default:
- rc = sysfs_create_group(&ipl_subsys.kobj,
+ rc = sysfs_create_group(&ipl_kset->kobj,
&ipl_unknown_attr_group);
break;
}
if (rc)
- firmware_unregister(&ipl_subsys);
+ kset_unregister(ipl_kset);
return rc;
}
@@ -883,7 +899,7 @@ static int __init reipl_nss_init(void)
if (!MACHINE_IS_VM)
return 0;
- rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_nss_attr_group);
+ rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
if (rc)
return rc;
strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
@@ -898,7 +914,7 @@ static int __init reipl_ccw_init(void)
reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
if (!reipl_block_ccw)
return -ENOMEM;
- rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_ccw_attr_group);
+ rc = sysfs_create_group(&reipl_kset->kobj, &reipl_ccw_attr_group);
if (rc) {
free_page((unsigned long)reipl_block_ccw);
return rc;
@@ -936,7 +952,7 @@ static int __init reipl_fcp_init(void)
reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
if (!reipl_block_fcp)
return -ENOMEM;
- rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_fcp_attr_group);
+ rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group);
if (rc) {
free_page((unsigned long)reipl_block_fcp);
return rc;
@@ -958,12 +974,12 @@ static int __init reipl_init(void)
{
int rc;
- rc = firmware_register(&reipl_subsys);
- if (rc)
- return rc;
- rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
+ reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
+ if (!reipl_kset)
+ return -ENOMEM;
+ rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
if (rc) {
- firmware_unregister(&reipl_subsys);
+ kset_unregister(reipl_kset);
return rc;
}
rc = reipl_ccw_init();
@@ -988,7 +1004,7 @@ static int __init dump_ccw_init(void)
dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
if (!dump_block_ccw)
return -ENOMEM;
- rc = sysfs_create_group(&dump_subsys.kobj, &dump_ccw_attr_group);
+ rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
if (rc) {
free_page((unsigned long)dump_block_ccw);
return rc;
@@ -1012,7 +1028,7 @@ static int __init dump_fcp_init(void)
dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
if (!dump_block_fcp)
return -ENOMEM;
- rc = sysfs_create_group(&dump_subsys.kobj, &dump_fcp_attr_group);
+ rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
if (rc) {
free_page((unsigned long)dump_block_fcp);
return rc;
@@ -1047,12 +1063,12 @@ static int __init dump_init(void)
{
int rc;
- rc = firmware_register(&dump_subsys);
- if (rc)
- return rc;
- rc = subsys_create_file(&dump_subsys, &dump_type_attr);
+ dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
+ if (!dump_kset)
+ return -ENOMEM;
+ rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr);
if (rc) {
- firmware_unregister(&dump_subsys);
+ kset_unregister(dump_kset);
return rc;
}
rc = dump_ccw_init();
@@ -1069,12 +1085,13 @@ static int __init shutdown_actions_init(void)
{
int rc;
- rc = firmware_register(&shutdown_actions_subsys);
- if (rc)
- return rc;
- rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
+ shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
+ firmware_kobj);
+ if (!shutdown_actions_kset)
+ return -ENOMEM;
+ rc = sysfs_create_file(&shutdown_actions_kset->kobj, &on_panic_attr);
if (rc) {
- firmware_unregister(&shutdown_actions_subsys);
+ kset_unregister(shutdown_actions_kset);
return rc;
}
atomic_notifier_chain_register(&panic_notifier_list,
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 7e1bfb984064..577aa7dd660e 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;
void machine_restart(char *command)
{
- if (!in_interrupt() || oops_in_progress)
+ if ((!in_interrupt() && !in_atomic()) || oops_in_progress)
/*
* Only unblank the console if we are called in enabled
* context or a bust_spinlocks cleared the way for us.
@@ -486,12 +486,14 @@ static void setup_addressing_mode(void)
if (s390_noexec) {
printk("S390 execute protection active, ");
set_amode_and_uaccess(PSW_ASC_SECONDARY, PSW32_ASC_SECONDARY);
- return;
- }
- if (switch_amode) {
+ } else if (switch_amode) {
printk("S390 address spaces switched, ");
set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY);
}
+#ifdef CONFIG_TRACE_IRQFLAGS
+ sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+ io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+#endif
}
static 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,
}
EXPORT_SYMBOL(smp_call_function_single);
-static void do_send_stop(void)
+void smp_send_stop(void)
{
int cpu, rc;
- /* stop all processors */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
- do {
- rc = signal_processor(cpu, sigp_stop);
- } while (rc == sigp_busy);
- }
-}
+ /* Disable all interrupts/machine checks */
+ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-static void do_store_status(void)
-{
- int cpu, rc;
+ /* write magic number to zero page (absolute 0) */
+ lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
- /* store status of all processors in their lowcores (real 0) */
+ /* stop all processors */
for_each_online_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
do {
- rc = signal_processor_p(
- (__u32)(unsigned long) lowcore_ptr[cpu], cpu,
- sigp_store_status_at_address);
+ rc = signal_processor(cpu, sigp_stop);
} while (rc == sigp_busy);
- }
-}
-static void do_wait_for_stop(void)
-{
- int cpu;
-
- /* Wait for all other cpus to enter stopped state */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
while (!smp_cpu_not_running(cpu))
cpu_relax();
}
}
/*
- * this function sends a 'stop' sigp to all other CPUs in the system.
- * it goes straight through.
- */
-void smp_send_stop(void)
-{
- /* Disable all interrupts/machine checks */
- __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-
- /* write magic number to zero page (absolute 0) */
- lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
-
- /* stop other processors. */
- do_send_stop();
-
- /* wait until other processors are stopped */
- do_wait_for_stop();
-
- /* store status of other processors. */
- do_store_status();
-}
-
-/*
* Reboot, halt and power_off routines for SMP.
*/
void machine_restart_smp(char *__unused)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 22b800ce2126..3bbac1293be4 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -1145,7 +1145,7 @@ static void etr_work_fn(struct work_struct *work)
* Sysfs interface functions
*/
static struct sysdev_class etr_sysclass = {
- set_kset_name("etr")
+ .name = "etr",
};
static struct sys_device etr_port0_dev = {
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)
bust_spinlocks(1);
printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
print_modules();
+ notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
show_regs(regs);
bust_spinlocks(0);
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,
static struct ctl_table cmm_table[] = {
{
- .ctl_name = VM_CMM_PAGES,
.procname = "cmm_pages",
.mode = 0644,
.proc_handler = &cmm_pages_handler,
},
{
- .ctl_name = VM_CMM_TIMED_PAGES,
.procname = "cmm_timed_pages",
.mode = 0644,
.proc_handler = &cmm_pages_handler,
},
{
- .ctl_name = VM_CMM_TIMEOUT,
.procname = "cmm_timeout",
.mode = 0644,
.proc_handler = &cmm_timeout_handler,