Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7c46c66 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky
Browse files

s390/smp: fix smp_stop_cpu() for !CONFIG_SMP



smp_stop_cpu() should stop the current cpu even for !CONFIG_SMP.
Otherwise machine_halt() will return and and the machine generates a
panic instread of simply stopping the current cpu:

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000

CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 3.14.0-01527-g2b6ef16a6bc5 #10
[...]
Call Trace:
([<0000000000110db0>] show_trace+0xf8/0x158)
 [<0000000000110e7a>] show_stack+0x6a/0xe8
 [<000000000074dba8>] panic+0xe4/0x268
 [<0000000000140570>] do_exit+0xa88/0xb2c
 [<000000000016e12c>] SyS_reboot+0x1f0/0x234
 [<000000000075da70>] sysc_nr_ok+0x22/0x28
 [<000000007d5a09b4>] 0x7d5a09b4

Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent a8a934e4
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
@@ -31,4 +31,23 @@
#define SIGP_STATUS_INCORRECT_STATE	0x00000200UL
#define SIGP_STATUS_INCORRECT_STATE	0x00000200UL
#define SIGP_STATUS_NOT_RUNNING		0x00000400UL
#define SIGP_STATUS_NOT_RUNNING		0x00000400UL


#ifndef __ASSEMBLY__

static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
{
	register unsigned int reg1 asm ("1") = parm;
	int cc;

	asm volatile(
		"	sigp	%1,%2,0(%3)\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
	if (status && cc == 1)
		*status = reg1;
	return cc;
}

#endif /* __ASSEMBLY__ */

#endif /* __S390_ASM_SIGP_H */
#endif /* __S390_ASM_SIGP_H */
+12 −1
Original line number Original line Diff line number Diff line
@@ -7,6 +7,8 @@
#ifndef __ASM_SMP_H
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
#define __ASM_SMP_H


#include <asm/sigp.h>

#ifdef CONFIG_SMP
#ifdef CONFIG_SMP


#include <asm/lowcore.h>
#include <asm/lowcore.h>
@@ -50,9 +52,18 @@ static inline int smp_store_status(int cpu) { return 0; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_yield(void) { }
static inline void smp_yield(void) { }
static inline void smp_stop_cpu(void) { }
static inline void smp_fill_possible_mask(void) { }
static inline void smp_fill_possible_mask(void) { }


static inline void smp_stop_cpu(void)
{
	u16 pcpu = stap();

	for (;;) {
		__pcpu_sigp(pcpu, SIGP_STOP, 0, NULL);
		cpu_relax();
	}
}

#endif /* CONFIG_SMP */
#endif /* CONFIG_SMP */


#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_HOTPLUG_CPU
+0 −15
Original line number Original line Diff line number Diff line
@@ -82,21 +82,6 @@ DEFINE_MUTEX(smp_cpu_state_mutex);
/*
/*
 * Signal processor helper functions.
 * Signal processor helper functions.
 */
 */
static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
{
	register unsigned int reg1 asm ("1") = parm;
	int cc;

	asm volatile(
		"	sigp	%1,%2,0(%3)\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
	if (status && cc == 1)
		*status = reg1;
	return cc;
}

static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
{
{
	int cc;
	int cc;