summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/early.c9
-rw-r--r--arch/s390/kernel/entry.S8
-rw-r--r--arch/s390/kernel/entry64.S8
-rw-r--r--arch/s390/kernel/ipl.c7
-rw-r--r--arch/s390/kernel/smp.c7
-rw-r--r--arch/s390/kernel/swsusp_asm64.S2
6 files changed, 26 insertions, 15 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index bf8b4ae7ff2..e49e9e0c69f 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -55,6 +55,7 @@ static void __init reset_tod_clock(void)
disabled_wait(0);
sched_clock_base_cc = TOD_UNIX_EPOCH;
+ S390_lowcore.last_update_clock = sched_clock_base_cc;
}
#ifdef CONFIG_SHARED_KERNEL
@@ -167,6 +168,14 @@ static noinline __init void create_kernel_nss(void)
return;
}
+ /* re-initialize cputime accounting. */
+ sched_clock_base_cc = get_clock();
+ S390_lowcore.last_update_clock = sched_clock_base_cc;
+ S390_lowcore.last_update_timer = 0x7fffffffffffffffULL;
+ S390_lowcore.user_timer = 0;
+ S390_lowcore.system_timer = 0;
+ asm volatile("SPT 0(%0)" : : "a" (&S390_lowcore.last_update_timer));
+
/* re-setup boot command line with new ipl vm parms */
ipl_update_parameters();
setup_boot_command_line();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index f43d2ee5446..48215d15762 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -565,10 +565,10 @@ pgm_svcper:
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
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+ l %r8,__TI_task(%r9)
+ mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+ mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index a6f7b20df61..9aff1d449b6 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -543,10 +543,10 @@ pgm_svcper:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- lg %r1,__TI_task(%r9)
- mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
- mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
- mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+ lg %r8,__TI_task(%r9)
+ mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+ mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ee57a42e6e9..4890ac6d7fa 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1595,10 +1595,9 @@ static void stop_run(struct shutdown_trigger *trigger)
{
if (strcmp(trigger->name, ON_PANIC_STR) == 0)
disabled_wait((unsigned long) __builtin_return_address(0));
- else {
- signal_processor(smp_processor_id(), sigp_stop);
- for (;;);
- }
+ while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+ cpu_relax();
+ for (;;);
}
static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index c932caa5e85..93e52039321 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -76,7 +76,6 @@ static int cpu_stopped(int cpu)
__u32 status;
switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
- case sigp_order_code_accepted:
case sigp_status_stored:
/* Check for stopped and check stop state */
if (status & 0x50)
@@ -638,6 +637,8 @@ void __cpu_die(unsigned int cpu)
/* Wait until target cpu is down */
while (!cpu_stopped(cpu))
cpu_relax();
+ while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy)
+ udelay(10);
smp_free_lowcore(cpu);
pr_info("Processor %d stopped\n", cpu);
}
@@ -645,8 +646,8 @@ void __cpu_die(unsigned int cpu)
void cpu_die(void)
{
idle_task_exit();
- signal_processor(smp_processor_id(), sigp_stop);
- BUG();
+ while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+ cpu_relax();
for (;;);
}
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index 7c8653e27db..0c26cc1898e 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -199,6 +199,7 @@ pgm_check_entry:
brc 2,4b /* busy, try again */
5:
sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */
+ brc 2,5b /* busy, try again */
6: j 6b
restart_suspend:
@@ -206,6 +207,7 @@ restart_suspend:
llgh %r2,0(%r1)
7:
sigp %r9,%r2,__SIGP_SENSE /* Wait for resume CPU */
+ brc 8,7b /* accepted, status 0, still running */
brc 2,7b /* busy, try again */
tmll %r9,0x40 /* Test if resume CPU is stopped */
jz 7b