[PATCH] (2.6) os-term call upon kernel panic

Mike Strosaker strosake at austin.ibm.com
Fri Feb 27 11:02:55 EST 2004


This patch will cause the os-term RTAS call to be invoked after a
kernel panic.  The call notifies the platform that the OS is terminating
normal operation, which causes the service processor (on systems so
equipped) to perform some pre-defined actions (like a call home).  The
os-term routine is given the lowest priority on panic_notifier_list so
that it will be the last routine invoked, since it may not return.

Comments welcome.

Thanks,
Mike

diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c	Thu Feb 26 16:54:18 2004
+++ b/arch/ppc64/kernel/chrp_setup.c	Thu Feb 26 16:54:18 2004
@@ -268,6 +268,7 @@
  	ppc_md.restart        = rtas_restart;
  	ppc_md.power_off      = rtas_power_off;
  	ppc_md.halt           = rtas_halt;
+	ppc_md.panic          = rtas_os_term;

  	ppc_md.get_boot_time  = pSeries_get_boot_time;
  	ppc_md.get_rtc_time   = pSeries_get_rtc_time;
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c	Thu Feb 26 16:54:18 2004
+++ b/arch/ppc64/kernel/iSeries_setup.c	Thu Feb 26 16:54:18 2004
@@ -323,6 +323,7 @@
  	ppc_md.restart = iSeries_restart;
  	ppc_md.power_off = iSeries_power_off;
  	ppc_md.halt = iSeries_halt;
+	ppc_md.panic = iSeries_panic;

  	ppc_md.get_boot_time = iSeries_get_boot_time;
  	ppc_md.set_rtc_time = iSeries_set_rtc_time;
@@ -790,6 +791,14 @@
  void iSeries_halt(void)
  {
  	mf_powerOff();
+}
+
+/*
+ * Document me.
+ */
+void iSeries_panic(void)
+{
+	mf_reboot();
  }

  /* JDH Hack */
diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
--- a/arch/ppc64/kernel/rtas.c	Thu Feb 26 16:54:18 2004
+++ b/arch/ppc64/kernel/rtas.c	Thu Feb 26 16:54:18 2004
@@ -420,6 +420,17 @@
          rtas_power_off();
  }

+void
+rtas_os_term(void)
+{
+	long status;
+	char *str = "OS panic";
+
+	status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL, __pa(str));
+	if (status != 0)
+		printk(KERN_EMERG "ibm,os-term call failed %ld\n", status);
+}
+
  unsigned long rtas_rmo_buf = 0;

  asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c	Thu Feb 26 16:54:18 2004
+++ b/arch/ppc64/kernel/setup.c	Thu Feb 26 16:54:18 2004
@@ -25,6 +25,7 @@
  #include <linux/version.h>
  #include <linux/tty.h>
  #include <linux/root_dev.h>
+#include <linux/notifier.h>
  #include <asm/io.h>
  #include <asm/prom.h>
  #include <asm/processor.h>
@@ -93,6 +94,12 @@

  struct machdep_calls ppc_md;

+static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
+static struct notifier_block ppc64_panic_block = {
+	notifier_call: ppc64_panic_event,
+	priority: INT_MIN /* may not return; must be done last */
+};
+
  /*
   * Perhaps we can put the pmac screen_info[] here
   * on pmac as well so we don't need the ifdef's.
@@ -316,6 +323,13 @@

  EXPORT_SYMBOL(machine_halt);

+static int ppc64_panic_event(struct notifier_block *this,
+			     unsigned long event, void *ptr)
+{
+	ppc_md.panic();		/* May not return */
+	return NOTIFY_DONE;
+}
+
  unsigned long ppc_proc_freq;
  unsigned long ppc_tb_freq;

@@ -610,8 +624,9 @@
  	dcache_bsize = systemcfg->dCacheL1LineSize;
  	icache_bsize = systemcfg->iCacheL1LineSize;

-	/* reboot on panic */
-	panic_timeout = 180;
+	/* do not reboot on panic */
+	panic_timeout = 0;
+	notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);

  	init_mm.start_code = PAGE_OFFSET;
  	init_mm.end_code = (unsigned long) _etext;
diff -Nru a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
--- a/include/asm-ppc64/machdep.h	Thu Feb 26 16:54:18 2004
+++ b/include/asm-ppc64/machdep.h	Thu Feb 26 16:54:18 2004
@@ -82,6 +82,7 @@
  	void		(*restart)(char *cmd);
  	void		(*power_off)(void);
  	void		(*halt)(void);
+	void		(*panic)(void);

  	int		(*set_rtc_time)(struct rtc_time *);
  	void		(*get_rtc_time)(struct rtc_time *);
diff -Nru a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
--- a/include/asm-ppc64/rtas.h	Thu Feb 26 16:54:18 2004
+++ b/include/asm-ppc64/rtas.h	Thu Feb 26 16:54:18 2004
@@ -175,6 +175,7 @@
  extern void rtas_restart(char *cmd);
  extern void rtas_power_off(void);
  extern void rtas_halt(void);
+extern void rtas_os_term(void);
  extern int rtas_get_sensor(int sensor, int index, int *state);
  extern int rtas_get_power_level(int powerdomain, int *level);
  extern int rtas_set_indicator(int indicator, int index, int new_value);

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list