Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Merge jym-xensuspend branch in -current. ok bouyer@.
details: https://anonhg.NetBSD.org/src/rev/6e897acb8f62
branches: trunk
changeset: 769710:6e897acb8f62
user: jym <jym%NetBSD.org@localhost>
date: Tue Sep 20 00:12:23 2011 +0000
description:
Merge jym-xensuspend branch in -current. ok bouyer@.
Goal: save/restore support in NetBSD domUs, for i386, i386 PAE and amd64.
Executive summary:
- split all Xen drivers (xenbus(4), grant tables, xbd(4), xennet(4))
in two parts: suspend and resume, and hook them to pmf(9).
- modify pmap so that Xen hypervisor does not cry out loud in case
it finds "unexpected" recursive memory mappings
- provide a sysctl(7), machdep.xen.suspend, to command suspend from
userland via powerd(8). Note: a suspend can only be handled correctly
when dom0 requested it, so provide a mechanism that will prevent
kernel to blindly validate user's commands
The code is still in experimental state, use at your own risk: restore
can corrupt backend communications rings; this can completely thrash
dom0 as it will loop at a high interrupt level trying to honor
all domU requests.
XXX PAE suspend does not work in amd64 currently, due to (yet again!)
page validation issues with hypervisor. Will fix.
XXX secondary CPUs are not suspended, I will write the handlers
in sync with cherry's Xen MP work.
Tested under i386 and amd64, bear in mind ring corruption though.
No build break expected, GENERICs and XEN* kernels should be fine.
./build.sh distribution still running. In any case: sorry if it does
break for you, contact me directly for reports.
diffstat:
sys/arch/x86/include/cpu.h | 4 +-
sys/arch/x86/include/pmap.h | 8 +-
sys/arch/x86/x86/pmap.c | 120 +++++++++++++++++++-
sys/arch/xen/include/evtchn.h | 5 +-
sys/arch/xen/include/granttables.h | 6 +-
sys/arch/xen/include/hypervisor.h | 3 +-
sys/arch/xen/include/shutdown_xenbus.h | 5 +-
sys/arch/xen/include/xen.h | 5 +-
sys/arch/xen/include/xenbus.h | 4 +-
sys/arch/xen/x86/cpu.c | 7 +-
sys/arch/xen/x86/hypervisor_machdep.c | 15 +-
sys/arch/xen/x86/mainbus.c | 9 +-
sys/arch/xen/x86/x86_xpmap.c | 6 +-
sys/arch/xen/x86/xen_pmap.c | 22 ++-
sys/arch/xen/xen/balloon.c | 7 +-
sys/arch/xen/xen/clock.c | 42 +++++-
sys/arch/xen/xen/evtchn.c | 44 ++++++-
sys/arch/xen/xen/hypervisor.c | 32 ++++-
sys/arch/xen/xen/if_xennet_xenbus.c | 142 ++++++++++++++++++----
sys/arch/xen/xen/shutdown_xenbus.c | 16 +-
sys/arch/xen/xen/xbd_xenbus.c | 149 ++++++++++++++++++-----
sys/arch/xen/xen/xen_machdep.c | 203 ++++++++++++++++++++++++++++++++-
sys/arch/xen/xen/xencons.c | 76 +++++++++--
sys/arch/xen/xen/xengnt.c | 35 ++++-
sys/arch/xen/xenbus/xenbus_comms.c | 33 +++-
sys/arch/xen/xenbus/xenbus_comms.h | 4 +-
sys/arch/xen/xenbus/xenbus_probe.c | 52 ++++++++-
27 files changed, 904 insertions(+), 150 deletions(-)
diffs (truncated from 1972 to 300 lines):
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/x86/include/cpu.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.37 2011/08/11 18:11:17 cherry Exp $ */
+/* $NetBSD: cpu.h,v 1.38 2011/09/20 00:12:23 jym Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -409,6 +409,8 @@
void startrtclock(void);
void xen_delay(unsigned int);
void xen_initclocks(void);
+void xen_suspendclocks(void);
+void xen_resumeclocks(void);
#else
/* clock.c */
void initrtclock(u_long);
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/x86/include/pmap.h
--- a/sys/arch/x86/include/pmap.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/x86/include/pmap.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.41 2011/08/13 12:09:38 cherry Exp $ */
+/* $NetBSD: pmap.h,v 1.42 2011/09/20 00:12:23 jym Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -396,6 +396,12 @@
#ifdef XEN
+void pmap_unmap_all_apdp_pdes(void);
+#ifdef PAE
+void pmap_map_recursive_entries(void);
+void pmap_unmap_recursive_entries(void);
+#endif /* PAE */
+
#include <sys/bitops.h>
#define XPTE_MASK L1_FRAME
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/x86/x86/pmap.c Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.129 2011/08/28 00:51:21 dyoung Exp $ */
+/* $NetBSD: pmap.c,v 1.130 2011/09/20 00:12:23 jym Exp $ */
/*-
* Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
@@ -171,7 +171,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.129 2011/08/28 00:51:21 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.130 2011/09/20 00:12:23 jym Exp $");
#include "opt_user_ldt.h"
#include "opt_lockdebug.h"
@@ -4387,3 +4387,119 @@
return pflag;
}
+
+#ifdef XEN
+/*
+ * Flush all APDP entries found in pmaps
+ * Required during Xen save/restore operations, as it does not
+ * handle alternative recursive mappings properly
+ */
+void
+pmap_unmap_all_apdp_pdes(void)
+{
+
+ int i;
+ int s;
+ struct pmap *pm;
+
+ s = splvm();
+
+ pmap_unmap_apdp();
+
+ mutex_enter(&pmaps_lock);
+ /*
+ * Set APDP entries to 0 in all pmaps.
+ * Note that for PAE kernels, this only clears the APDP entries
+ * found in the L2 shadow pages, as pmap_pdirpa() is used to obtain
+ * the PA of the pmap->pm_pdir[] pages (forming the 4 contiguous
+ * pages of PAE PD: 3 for user space, 1 for the L2 kernel shadow page)
+ */
+ LIST_FOREACH(pm, &pmaps, pm_list) {
+ for (i = 0; i < PDP_SIZE; i++) {
+ xpq_queue_pte_update(
+ xpmap_ptom(pmap_pdirpa(pm, PDIR_SLOT_APTE + i)), 0);
+ }
+ }
+ mutex_exit(&pmaps_lock);
+
+ xpq_flush_queue();
+
+ splx(s);
+
+}
+
+#ifdef PAE
+/*
+ * NetBSD uses L2 shadow pages to support PAE with Xen. However, Xen does not
+ * handle them correctly during save/restore, leading to incorrect page
+ * tracking and pinning during restore.
+ * For save/restore to succeed, two functions are introduced:
+ * - pmap_map_recursive_entries(), used by resume code to set the recursive
+ * mapping entries to their correct value
+ * - pmap_unmap_recursive_entries(), used by suspend code to clear all
+ * PDIR_SLOT_PTE entries
+ */
+void
+pmap_map_recursive_entries(void)
+{
+
+ int i;
+ struct pmap *pm;
+
+ mutex_enter(&pmaps_lock);
+
+ LIST_FOREACH(pm, &pmaps, pm_list) {
+ for (i = 0; i < PDP_SIZE; i++) {
+ xpq_queue_pte_update(
+ xpmap_ptom(pmap_pdirpa(pm, PDIR_SLOT_PTE + i)),
+ xpmap_ptom((pm)->pm_pdirpa[i]) | PG_V);
+ }
+ }
+
+ mutex_exit(&pmaps_lock);
+
+ for (i = 0; i < PDP_SIZE; i++) {
+ xpq_queue_pte_update(
+ xpmap_ptom(pmap_pdirpa(pmap_kernel(), PDIR_SLOT_PTE + i)),
+ xpmap_ptom(pmap_kernel()->pm_pdirpa[i]) | PG_V);
+ }
+
+ xpq_flush_queue();
+}
+
+void
+pmap_unmap_recursive_entries(void)
+{
+
+ int i;
+ struct pmap *pm;
+
+ /*
+ * We must invalidate all shadow pages found inside the pmap_pdp_cache.
+ * They are technically considered by Xen as L2 pages, although they
+ * are not currently found inside pmaps list.
+ */
+ pool_cache_invalidate(&pmap_pdp_cache);
+
+ mutex_enter(&pmaps_lock);
+
+ LIST_FOREACH(pm, &pmaps, pm_list) {
+ for (i = 0; i < PDP_SIZE; i++) {
+ xpq_queue_pte_update(
+ xpmap_ptom(pmap_pdirpa(pm, PDIR_SLOT_PTE + i)), 0);
+ }
+ }
+
+ mutex_exit(&pmaps_lock);
+
+ /* do it for pmap_kernel() too! */
+ for (i = 0; i < PDP_SIZE; i++)
+ xpq_queue_pte_update(
+ xpmap_ptom(pmap_pdirpa(pmap_kernel(), PDIR_SLOT_PTE + i)),
+ 0);
+
+ xpq_flush_queue();
+
+}
+#endif /* PAE */
+#endif /* XEN */
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/evtchn.h
--- a/sys/arch/xen/include/evtchn.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/evtchn.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: evtchn.h,v 1.19 2011/08/11 17:58:59 cherry Exp $ */
+/* $NetBSD: evtchn.h,v 1.20 2011/09/20 00:12:23 jym Exp $ */
/*
*
@@ -35,6 +35,9 @@
void events_default_setup(void);
void events_init(void);
+bool events_suspend(void);
+bool events_resume(void);
+
unsigned int evtchn_do_event(int, struct intrframe *);
void call_evtchn_do_event(int, struct intrframe *);
void call_xenevt_event(int);
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/granttables.h
--- a/sys/arch/xen/include/granttables.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/granttables.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: granttables.h,v 1.7 2009/10/19 18:41:10 bouyer Exp $ */
+/* $NetBSD: granttables.h,v 1.8 2011/09/20 00:12:23 jym Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
*
@@ -30,6 +30,10 @@
void xengnt_init(void);
+/* suspend/resume grant table, for save/restore operations */
+bool xengnt_suspend(void);
+bool xengnt_resume(void);
+
/*
* grant access to a remote domain. Returns a handle on the allocated grant
* entry in table in grant_ref_t *.
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/hypervisor.h
--- a/sys/arch/xen/include/hypervisor.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/hypervisor.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.h,v 1.32 2011/08/10 21:46:02 cherry Exp $ */
+/* $NetBSD: hypervisor.h,v 1.33 2011/09/20 00:12:23 jym Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -140,6 +140,7 @@
void hypervisor_set_ipending(struct cpu_info *,
uint32_t, int, int);
void hypervisor_machdep_attach(void);
+void hypervisor_machdep_resume(void);
/*
* Force a proper event-channel callback from Xen after clearing the
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/shutdown_xenbus.h
--- a/sys/arch/xen/include/shutdown_xenbus.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/shutdown_xenbus.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: shutdown_xenbus.h,v 1.3 2007/10/17 19:58:29 garbled Exp $ */
+/* $NetBSD: shutdown_xenbus.h,v 1.4 2011/09/20 00:12:24 jym Exp $ */
/*-
* Copyright (c)2006 YAMAMOTO Takashi,
@@ -29,6 +29,9 @@
#ifndef _XEN_SHUTDOWN_XENBUS_H_
#define _XEN_SHUTDOWN_XENBUS_H_
+/* Whether dom0 ordered a suspend (true) or not (false) */
+bool xen_suspend_allow;
+
void shutdown_xenbus_setup(void);
#endif /* _XEN_SHUTDOWN_XENBUS_H_ */
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/xen.h
--- a/sys/arch/xen/include/xen.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/xen.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xen.h,v 1.34 2011/07/17 20:54:49 joerg Exp $ */
+/* $NetBSD: xen.h,v 1.35 2011/09/20 00:12:24 jym Exp $ */
/*
*
@@ -72,6 +72,9 @@
void idle_block(void);
+/* xen_machdep.c */
+void sysctl_xen_suspend_setup(void);
+
#if defined(XENDEBUG) || 1 /* XXX */
#include <sys/stdarg.h>
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/include/xenbus.h
--- a/sys/arch/xen/include/xenbus.h Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/include/xenbus.h Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xenbus.h,v 1.11 2008/10/29 13:35:35 cegger Exp $ */
+/* $NetBSD: xenbus.h,v 1.12 2011/09/20 00:12:24 jym Exp $ */
/******************************************************************************
* xenbus.h
*
@@ -257,6 +257,8 @@
void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
...);
+bool xenbus_device_suspend(struct xenbus_device *);
+bool xenbus_device_resume(struct xenbus_device *);
#endif /* _ASM_XEN_XENBUS_H */
diff -r 46aa68692302 -r 6e897acb8f62 sys/arch/xen/x86/cpu.c
--- a/sys/arch/xen/x86/cpu.c Mon Sep 19 23:54:29 2011 +0000
+++ b/sys/arch/xen/x86/cpu.c Tue Sep 20 00:12:23 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.64 2011/08/16 02:59:16 dholland Exp $ */
+/* $NetBSD: cpu.c,v 1.65 2011/09/20 00:12:24 jym Exp $ */
/* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp */
/*-
@@ -66,7 +66,7 @@
Home |
Main Index |
Thread Index |
Old Index