aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-04-09 09:48:08 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-04-09 09:48:08 +0000
commit0b00b6397904a181f46925672309f5d6887e4020 (patch)
tree685c45c23034136ff376c0b0a062508f98f8a7dc
parent5aa9e2fcf576425ea9f903150a6caf7ddc51b436 (diff)
downloadxen-0b00b6397904a181f46925672309f5d6887e4020.tar.gz
xen-0b00b6397904a181f46925672309f5d6887e4020.tar.bz2
xen-0b00b6397904a181f46925672309f5d6887e4020.zip
bitkeeper revision 1.860 (40767158VSrp08a0j4zL0drGEP4xNg)
Synchronously flush console data when a domain dies.
-rw-r--r--.rootkeys1
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c47
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c17
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/kernel/process.c9
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c5
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h16
-rw-r--r--xenolinux-2.4.25-sparse/kernel/panic.c157
7 files changed, 87 insertions, 165 deletions
diff --git a/.rootkeys b/.rootkeys
index 1ca38ee6f8..1938f8edbb 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -738,7 +738,6 @@
3e5a4e686V0nioX2ZpFf056sgvdiQw xenolinux-2.4.25-sparse/include/linux/sunrpc/debug.h
401c0592pLrp_aCbQRo9GXiYQQaVVA xenolinux-2.4.25-sparse/include/linux/timer.h
3e5a4e68W_hpMlM3u_-QOKMp3gzcwQ xenolinux-2.4.25-sparse/init/do_mounts.c
-3e5a4e68TJJavrunYwTAnLRSBxSYqQ xenolinux-2.4.25-sparse/kernel/panic.c
3f9d4b44247udoqWEgFkaHiWv6Uvyg xenolinux-2.4.25-sparse/kernel/time.c
401c059bjLBFYHRD4Py2uM3eA1D4zQ xenolinux-2.4.25-sparse/kernel/timer.c
3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.25-sparse/mkbuildtree
diff --git a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c
index 3287790162..a6ee346857 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c
@@ -50,6 +50,7 @@ static struct tq_struct xencons_tx_flush_task = {
routine: xencons_tx_flush_task_routine
};
+
/******************** Kernel console driver ********************************/
static void kcons_write(
@@ -112,7 +113,7 @@ void xen_console_init(void)
}
-/*** Useful function for console debugging -- goes straight to Xen ****/
+/*** Useful function for console debugging -- goes straight to Xen. ***/
asmlinkage int xprintk(const char *fmt, ...)
{
va_list args;
@@ -133,6 +134,45 @@ asmlinkage int xprintk(const char *fmt, ...)
return 0;
}
+/*** Forcibly flush console data before dying. ***/
+void xencons_force_flush(void)
+{
+ ctrl_msg_t msg;
+ int sz;
+
+ /* Emergency console is synchronous, so there's nothing to flush. */
+ if ( start_info.flags & SIF_INITDOMAIN )
+ return;
+
+ /*
+ * We use dangerous control-interface functions that require a quiescent
+ * system and no interrupts. Try to ensure this with a global cli().
+ */
+ cli();
+
+ /* Spin until console data is flushed through to the domain controller. */
+ while ( (wc != wp) && !ctrl_if_transmitter_empty() )
+ {
+ /* Interrupts are disabled -- we must manually reap responses. */
+ ctrl_if_discard_responses();
+
+ if ( (sz = wp - wc) == 0 )
+ continue;
+ if ( sz > sizeof(msg.msg) )
+ sz = sizeof(msg.msg);
+ if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) )
+ sz = WBUF_SIZE - WBUF_MASK(wc);
+
+ msg.type = CMSG_CONSOLE;
+ msg.subtype = CMSG_CONSOLE_DATA;
+ msg.length = sz;
+ memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
+
+ if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
+ wc += sz;
+ }
+}
+
/******************** User-space console driver (/dev/console) ************/
@@ -431,7 +471,7 @@ static void xencons_close(struct tty_struct *tty, struct file *filp)
MOD_DEC_USE_COUNT;
}
-int __init xencons_init(void)
+static int __init xencons_init(void)
{
memset(&xencons_driver, 0, sizeof(struct tty_driver));
xencons_driver.magic = TTY_DRIVER_MAGIC;
@@ -481,7 +521,7 @@ int __init xencons_init(void)
return 0;
}
-void __exit xencons_fini(void)
+static void __exit xencons_fini(void)
{
int ret;
@@ -501,4 +541,3 @@ void __exit xencons_fini(void)
module_init(xencons_init);
module_exit(xencons_fini);
-
diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c
index 4c43d091e7..4002ae4c61 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c
@@ -315,3 +315,20 @@ void __init ctrl_if_init(void)
ctrl_if_resume();
}
+
+
+/*
+ * !! The following are DANGEROUS FUNCTIONS !!
+ * Use with care [for example, see xencons_force_flush()].
+ */
+
+int ctrl_if_transmitter_empty(void)
+{
+ return (get_ctrl_if()->tx_req_prod == ctrl_if_tx_resp_cons);
+}
+
+void ctrl_if_discard_responses(void)
+{
+ ctrl_if_tx_resp_cons = get_ctrl_if()->tx_resp_prod;
+}
+
diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c
index 640179661b..1ef8521fcb 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c
@@ -117,17 +117,20 @@ void cpu_idle (void)
void machine_restart(char * __unused)
{
+ /* We really want to get pending console data out before we die. */
+ extern void xencons_force_flush(void);
+ xencons_force_flush();
HYPERVISOR_exit();
}
void machine_halt(void)
{
- HYPERVISOR_exit();
+ machine_restart(NULL);
}
void machine_power_off(void)
{
- HYPERVISOR_exit();
+ machine_restart(NULL);
}
extern void show_trace(unsigned long* esp);
@@ -207,7 +210,7 @@ void release_thread(struct task_struct *dead_task)
if (dead_task->mm) {
// temporary debugging check
if (dead_task->mm->context.size) {
- printk("WARNING: dead process %8s still has LDT? <%p/%p>\n",
+ printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n",
dead_task->comm,
dead_task->mm->context.ldt,
dead_task->mm->context.size);
diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
index be7cc61efe..6be85db7f1 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
@@ -169,6 +169,11 @@ void __init setup_arch(char **cmdline_p)
extern unsigned long cpu0_pte_quicklist[];
extern unsigned long cpu0_pgd_quicklist[];
+ /* Force a quick death if the kernel panics. */
+ extern int panic_timeout;
+ if ( panic_timeout == 0 )
+ panic_timeout = 1;
+
#ifndef CONFIG_HIGHIO
blk_nohighio = 1;
#endif
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h b/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h
index c9e874bb0d..9d12487144 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h
@@ -95,4 +95,20 @@ void ctrl_if_resume(void);
/* Start-of-day setup. */
void ctrl_if_init(void);
+/*
+ * Returns TRUE if there are no outstanding message requests at the domain
+ * controller. This can be used to ensure that messages have really flushed
+ * through when it is not possible to use the response-callback interface.
+ * WARNING: If other subsystems are using the control interface then this
+ * function might never return TRUE!
+ */
+int ctrl_if_transmitter_empty(void); /* !! DANGEROUS FUNCTION !! */
+
+/*
+ * Manually discard response messages from the domain controller.
+ * WARNING: This is usually done automatically -- this function should only
+ * be called when normal interrupt mechanisms are disabled!
+ */
+void ctrl_if_discard_responses(void); /* !! DANGEROUS FUNCTION !! */
+
#endif /* __ASM_XEN__CONTROL_IF_H__ */
diff --git a/xenolinux-2.4.25-sparse/kernel/panic.c b/xenolinux-2.4.25-sparse/kernel/panic.c
deleted file mode 100644
index 9c96d92e40..0000000000
--- a/xenolinux-2.4.25-sparse/kernel/panic.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * linux/kernel/panic.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/*
- * This function is used through-out the kernel (including mm and fs)
- * to indicate a major problem.
- */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/notifier.h>
-#include <linux/init.h>
-#include <linux/sysrq.h>
-#include <linux/interrupt.h>
-#include <linux/console.h>
-
-asmlinkage void sys_sync(void); /* it's really int */
-
-int panic_timeout;
-
-struct notifier_block *panic_notifier_list;
-
-static int __init panic_setup(char *str)
-{
- panic_timeout = simple_strtoul(str, NULL, 0);
- return 1;
-}
-
-__setup("panic=", panic_setup);
-
-int machine_paniced;
-
-/**
- * panic - halt the system
- * @fmt: The text string to print
- *
- * Display a message, then perform cleanups. Functions in the panic
- * notifier list are called after the filesystem cache is flushed (when possible).
- *
- * This function never returns.
- */
-
-NORET_TYPE void panic(const char * fmt, ...)
-{
- static char buf[1024];
- va_list args;
-#if defined(CONFIG_ARCH_S390)
- unsigned long caller = (unsigned long) __builtin_return_address(0);
-#endif
-
-#ifdef CONFIG_VT
- disable_console_blank();
-#endif
- machine_paniced = 1;
-
- bust_spinlocks(1);
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
- printk(KERN_EMERG "Kernel panic: %s\n",buf);
- if (in_interrupt())
- printk(KERN_EMERG "In interrupt handler - not syncing\n");
- else if (!current->pid)
- printk(KERN_EMERG "In idle task - not syncing\n");
- else
- sys_sync();
- bust_spinlocks(0);
-
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
-
- notifier_call_chain(&panic_notifier_list, 0, NULL);
-
- if (panic_timeout > 0)
- {
- /*
- * Delay timeout seconds before rebooting the machine.
- * We can't use the "normal" timers since we just panicked..
- */
- printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
- mdelay(panic_timeout*1000);
- /*
- * Should we run the reboot notifier. For the moment Im
- * choosing not too. It might crash, be corrupt or do
- * more harm than good for other reasons.
- */
- machine_restart(NULL);
- }
-#ifdef __sparc__
- {
- extern int stop_a_enabled;
- /* Make sure the user can actually press L1-A */
- stop_a_enabled = 1;
- printk("Press L1-A to return to the boot prom\n");
- }
-#endif
-#if defined(CONFIG_ARCH_S390)
- disabled_wait(caller);
-#endif
- sti();
- for(;;) {
-#if defined(CONFIG_X86) && defined(CONFIG_VT)
- extern void panic_blink(void);
- panic_blink();
-#endif
- CHECK_EMERGENCY_SYNC
-#if defined(CONFIG_XEN)
- HYPERVISOR_exit();
-#endif
- }
-}
-
-/**
- * print_tainted - return a string to represent the kernel taint state.
- *
- * The string is overwritten by the next call to print_taint().
- */
-
-const char *print_tainted()
-{
- static char buf[20];
- if (tainted) {
- snprintf(buf, sizeof(buf), "Tainted: %c%c",
- tainted & 1 ? 'P' : 'G',
- tainted & 2 ? 'F' : ' ');
- }
- else
- snprintf(buf, sizeof(buf), "Not tainted");
- return(buf);
-}
-
-int tainted = 0;
-
-/*
- * A BUG() call in an inline function in a header should be avoided,
- * because it can seriously bloat the kernel. So here we have
- * helper functions.
- * We lose the BUG()-time file-and-line info this way, but it's
- * usually not very useful from an inline anyway. The backtrace
- * tells us what we want to know.
- */
-
-void __out_of_line_bug(int line)
-{
- printk("kernel BUG in header file at line %d\n", line);
-
- BUG();
-
- /* Satisfy __attribute__((noreturn)) */
- for ( ; ; )
- ;
-}