summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-05-27 02:31:25 +0400
committerThomas Gleixner <tglx@linutronix.de>2008-05-27 12:11:37 +0400
commit6b9b732d0e396a3f1a95977162a8624aafce38a1 (patch)
tree920798feaef2e92dfccd37e8f7af5acdf9a34941
parent0f2287ad7c61f10b2a22a06e2a66cdbbbfc44ad0 (diff)
downloadlinux-6b9b732d0e396a3f1a95977162a8624aafce38a1.tar.xz
xen-console: add save/restore
Add code to: 1. Deal with the console page being canonicalized. During save, the console's mfn in the start_info structure is canonicalized to a pfn. In order to deal with that, we always use a copy of the pfn and indirect off that all the time. However, we fall back to using the mfn if the pfn hasn't been initialized yet. 2. Restore the console event channel, and rebind it to the existing irq. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/char/hvc_xen.c25
-rw-r--r--include/xen/hvc-console.h2
2 files changed, 23 insertions, 4 deletions
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index d5fe0a8952fa..db2ae4216279 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -39,9 +39,14 @@ static int xencons_irq;
/* ------------------------------------------------------------------ */
+static unsigned long console_pfn = ~0ul;
+
static inline struct xencons_interface *xencons_interface(void)
{
- return mfn_to_virt(xen_start_info->console.domU.mfn);
+ if (console_pfn == ~0ul)
+ return mfn_to_virt(xen_start_info->console.domU.mfn);
+ else
+ return __va(console_pfn << PAGE_SHIFT);
}
static inline void notify_daemon(void)
@@ -101,20 +106,32 @@ static int __init xen_init(void)
{
struct hvc_struct *hp;
- if (!is_running_on_xen())
- return 0;
+ if (!is_running_on_xen() ||
+ is_initial_xendomain() ||
+ !xen_start_info->console.domU.evtchn)
+ return -ENODEV;
xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
if (xencons_irq < 0)
- xencons_irq = 0 /* NO_IRQ */;
+ xencons_irq = 0; /* NO_IRQ */
+
hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
if (IS_ERR(hp))
return PTR_ERR(hp);
hvc = hp;
+
+ console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn);
+
return 0;
}
+void xen_console_resume(void)
+{
+ if (xencons_irq)
+ rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
+}
+
static void __exit xen_fini(void)
{
if (hvc)
diff --git a/include/xen/hvc-console.h b/include/xen/hvc-console.h
index efc3237ab990..fd5483a059bb 100644
--- a/include/xen/hvc-console.h
+++ b/include/xen/hvc-console.h
@@ -3,6 +3,8 @@
extern struct console xenboot_console;
+void xen_console_resume(void);
+
void xen_raw_console_write(const char *str);
void xen_raw_printk(const char *fmt, ...);