[S390] Automatic IPL after dump
Provide new shutdown action "dump_reipl" for automatic ipl after dump. Signed-off-by: Frank Munzert <munzert@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
这个提交包含在:
@@ -56,13 +56,14 @@ struct shutdown_trigger {
|
||||
};
|
||||
|
||||
/*
|
||||
* Five shutdown action types are supported:
|
||||
* The following shutdown action types are supported:
|
||||
*/
|
||||
#define SHUTDOWN_ACTION_IPL_STR "ipl"
|
||||
#define SHUTDOWN_ACTION_REIPL_STR "reipl"
|
||||
#define SHUTDOWN_ACTION_DUMP_STR "dump"
|
||||
#define SHUTDOWN_ACTION_VMCMD_STR "vmcmd"
|
||||
#define SHUTDOWN_ACTION_STOP_STR "stop"
|
||||
#define SHUTDOWN_ACTION_DUMP_REIPL_STR "dump_reipl"
|
||||
|
||||
struct shutdown_action {
|
||||
char *name;
|
||||
@@ -146,6 +147,7 @@ static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
|
||||
static struct ipl_parameter_block *reipl_block_fcp;
|
||||
static struct ipl_parameter_block *reipl_block_ccw;
|
||||
static struct ipl_parameter_block *reipl_block_nss;
|
||||
static struct ipl_parameter_block *reipl_block_actual;
|
||||
|
||||
static int dump_capabilities = DUMP_TYPE_NONE;
|
||||
static enum dump_type dump_type = DUMP_TYPE_NONE;
|
||||
@@ -835,6 +837,7 @@ static int reipl_set_type(enum ipl_type type)
|
||||
reipl_method = REIPL_METHOD_CCW_VM;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_CCW_CIO;
|
||||
reipl_block_actual = reipl_block_ccw;
|
||||
break;
|
||||
case IPL_TYPE_FCP:
|
||||
if (diag308_set_works)
|
||||
@@ -843,6 +846,7 @@ static int reipl_set_type(enum ipl_type type)
|
||||
reipl_method = REIPL_METHOD_FCP_RO_VM;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_FCP_RO_DIAG;
|
||||
reipl_block_actual = reipl_block_fcp;
|
||||
break;
|
||||
case IPL_TYPE_FCP_DUMP:
|
||||
reipl_method = REIPL_METHOD_FCP_DUMP;
|
||||
@@ -852,6 +856,7 @@ static int reipl_set_type(enum ipl_type type)
|
||||
reipl_method = REIPL_METHOD_NSS_DIAG;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_NSS;
|
||||
reipl_block_actual = reipl_block_nss;
|
||||
break;
|
||||
case IPL_TYPE_UNKNOWN:
|
||||
reipl_method = REIPL_METHOD_DEFAULT;
|
||||
@@ -1332,6 +1337,48 @@ static struct shutdown_action __refdata dump_action = {
|
||||
.init = dump_init,
|
||||
};
|
||||
|
||||
static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||
{
|
||||
preempt_disable();
|
||||
/*
|
||||
* Bypass dynamic address translation (DAT) when storing IPL parameter
|
||||
* information block address and checksum into the prefix area
|
||||
* (corresponding to absolute addresses 0-8191).
|
||||
* When enhanced DAT applies and the STE format control in one,
|
||||
* the absolute address is formed without prefixing. In this case a
|
||||
* normal store (stg/st) into the prefix area would no more match to
|
||||
* absolute addresses 0-8191.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
asm volatile("sturg %0,%1"
|
||||
:: "a" ((unsigned long) reipl_block_actual),
|
||||
"a" (&lowcore_ptr[smp_processor_id()]->ipib));
|
||||
#else
|
||||
asm volatile("stura %0,%1"
|
||||
:: "a" ((unsigned long) reipl_block_actual),
|
||||
"a" (&lowcore_ptr[smp_processor_id()]->ipib));
|
||||
#endif
|
||||
asm volatile("stura %0,%1"
|
||||
:: "a" (cksm(reipl_block_actual, reipl_block_actual->hdr.len)),
|
||||
"a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum));
|
||||
preempt_enable();
|
||||
dump_run(trigger);
|
||||
}
|
||||
|
||||
static int __init dump_reipl_init(void)
|
||||
{
|
||||
if (!diag308_set_works)
|
||||
return -EOPNOTSUPP;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shutdown_action __refdata dump_reipl_action = {
|
||||
.name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
|
||||
.fn = dump_reipl_run,
|
||||
.init = dump_reipl_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* vmcmd shutdown action: Trigger vm command on shutdown.
|
||||
*/
|
||||
@@ -1421,7 +1468,8 @@ static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
|
||||
/* action list */
|
||||
|
||||
static struct shutdown_action *shutdown_actions_list[] = {
|
||||
&ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
|
||||
&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
|
||||
&vmcmd_action, &stop_action};
|
||||
#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
|
||||
|
||||
/*
|
||||
@@ -1434,11 +1482,11 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
|
||||
size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
|
||||
if (!shutdown_actions_list[i])
|
||||
continue;
|
||||
if (strncmp(buf, shutdown_actions_list[i]->name,
|
||||
strlen(shutdown_actions_list[i]->name)) == 0) {
|
||||
if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
|
||||
trigger->action = shutdown_actions_list[i];
|
||||
return len;
|
||||
}
|
||||
|
@@ -86,6 +86,10 @@ volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
|
||||
int __initdata memory_end_set;
|
||||
unsigned long __initdata memory_end;
|
||||
|
||||
/* An array with a pointer to the lowcore of every CPU. */
|
||||
struct _lowcore *lowcore_ptr[NR_CPUS];
|
||||
EXPORT_SYMBOL(lowcore_ptr);
|
||||
|
||||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
* for S390 need to find out, what we have to setup
|
||||
@@ -434,6 +438,7 @@ setup_lowcore(void)
|
||||
lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
|
||||
#endif
|
||||
set_prefix((u32)(unsigned long) lc);
|
||||
lowcore_ptr[0] = lc;
|
||||
}
|
||||
|
||||
static void __init
|
||||
|
@@ -50,12 +50,6 @@
|
||||
#include <asm/vdso.h>
|
||||
#include "entry.h"
|
||||
|
||||
/*
|
||||
* An array with a pointer the lowcore of every CPU.
|
||||
*/
|
||||
struct _lowcore *lowcore_ptr[NR_CPUS];
|
||||
EXPORT_SYMBOL(lowcore_ptr);
|
||||
|
||||
static struct task_struct *current_set[NR_CPUS];
|
||||
|
||||
static u8 smp_cpu_type;
|
||||
@@ -82,9 +76,6 @@ 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 all processors */
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == smp_processor_id())
|
||||
|
在新工单中引用
屏蔽一个用户