# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID dd0958aa23228c7210162d1a728ba5fb5b6965b6
# Parent 7680b29c03a6dbc15a1394ebe1467c46bdab9a39
[POWERPC] DomU shutdown and reboot
This patch allows for DomUs to shutdown and reboot.
Along the way we:
- updated def and use HYPERVISOR_sched_op() to use the xencomm when needed.
- consolodated externs in arch/powerpc/platforms/xen/*.c into "setup.h"
Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
arch/powerpc/platforms/xen/Makefile | 2 -
arch/powerpc/platforms/xen/evtchn.c | 3 -
arch/powerpc/platforms/xen/hcall.c | 50 ++++++++++++++++++++++++++++++++
arch/powerpc/platforms/xen/reboot.c | 33 +++++++++++++++++++++
arch/powerpc/platforms/xen/setup.c | 13 ++++----
arch/powerpc/platforms/xen/setup.h | 6 +++
include/asm-powerpc/xen/asm/hypercall.h | 11 +++++--
7 files changed, 107 insertions(+), 11 deletions(-)
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/Makefile
--- a/arch/powerpc/platforms/xen/Makefile Sat Aug 05 11:33:24 2006 -0400
+++ b/arch/powerpc/platforms/xen/Makefile Mon Aug 07 17:37:23 2006 -0400
@@ -1,4 +1,4 @@ obj-y += setup.o evtchn.o hcall.o udbg_x
-obj-y += setup.o evtchn.o hcall.o udbg_xen.o xen_guest.o
+obj-y += setup.o evtchn.o hcall.o udbg_xen.o xen_guest.o reboot.o
ifndef CONFIG_XEN_BALLOON
obj-y += balloon.o
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/evtchn.c
--- a/arch/powerpc/platforms/xen/evtchn.c Sat Aug 05 11:33:24 2006 -0400
+++ b/arch/powerpc/platforms/xen/evtchn.c Mon Aug 07 17:37:23 2006 -0400
@@ -7,6 +7,7 @@
#include <asm/machdep.h>
#include <asm/of_device.h>
#include <asm/udbg.h>
+#include "setup.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -31,7 +32,6 @@ struct hw_interrupt_type *xen_pirq;
struct hw_interrupt_type *xen_pirq;
static struct hw_interrupt_type hc_irq;
extern struct machdep_calls mach_maple_md;
-extern void evtchn_init_IRQ(void);
int xen_get_irq(struct pt_regs *regs)
{
@@ -80,7 +80,6 @@ static inline struct mpic *mpic_from_irq
return container_of(irq_desc[irq].handler, struct mpic, hc_irq);
}
-extern void xen_init_IRQ(void);
void xen_maple_init_IRQ(void)
{
struct mpic *mpic;
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c Sat Aug 05 11:33:24 2006 -0400
+++ b/arch/powerpc/platforms/xen/hcall.c Mon Aug 07 17:37:23 2006 -0400
@@ -183,6 +183,55 @@ int HYPERVISOR_grant_table_op(unsigned i
return rc;
}
EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
+
+int HYPERVISOR_sched_op(int cmd, void *arg)
+{
+ int rc;
+ struct xencomm_desc *desc;
+ ulong argsize;
+
+ switch (cmd) {
+ case SCHEDOP_yield:
+ case SCHEDOP_block:
+ return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
+ cmd, 0);
+ break;
+
+ case SCHEDOP_shutdown: {
+ /* we use a minicom area cuz we could be called from panic() */
+ char xc_area[XENCOMM_MINI_AREA];
+
+ rc = xencomm_create_mini(xc_area, XENCOMM_MINI_AREA,
+ arg, sizeof(sched_shutdown_t), &desc);
+ if (rc)
+ return rc;
+
+ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
+ cmd, __pa(desc));
+ return rc;
+ }
+ case SCHEDOP_poll:
+ argsize = sizeof(sched_poll_t);
+ break;
+ case SCHEDOP_remote_shutdown:
+ argsize = sizeof(sched_remote_shutdown_t);
+ break;
+ default:
+ printk("%s: unknown sched op %d\n", __func__, cmd);
+ return -ENOSYS;
+ }
+
+ rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL);
+ if (rc)
+ return rc;
+
+ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
+ cmd, __pa(desc));
+ xencomm_free(desc);
+
+ return rc;
+}
+EXPORT_SYMBOL(HYPERVISOR_sched_op);
int HYPERVISOR_multicall(void *call_list, int nr_calls)
{
@@ -463,3 +512,4 @@ int arch_privcmd_hypercall(privcmd_hyper
hypercall->arg[4]);
}
}
+
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/setup.c
--- a/arch/powerpc/platforms/xen/setup.c Sat Aug 05 11:33:24 2006 -0400
+++ b/arch/powerpc/platforms/xen/setup.c Mon Aug 07 17:37:23 2006 -0400
@@ -16,6 +16,7 @@
#include <asm/machdep.h>
#include <asm/hypervisor.h>
#include <asm/time.h>
+#include "setup.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -110,17 +111,19 @@ static void __init xen_init_early(void)
DBG(" console_evtchn %x\n", xen_start_info->store_evtchn);
is_dom0 = !!(xen_start_info->flags & SIF_INITDOMAIN);
+
if (is_dom0) {
+ xen_reboot_init(&mach_maple_md);
+
ppc_md.pcibios_fixup = mach_maple_md.pcibios_fixup;
ppc_md.pci_get_legacy_ide_irq =
mach_maple_md.pci_get_legacy_ide_irq;
- ppc_md.restart = mach_maple_md.restart;
- ppc_md.power_off = mach_maple_md.power_off;
- ppc_md.halt = mach_maple_md.halt;
ppc_md.get_boot_time = mach_maple_md.get_boot_time;
ppc_md.set_rtc_time = mach_maple_md.set_rtc_time;
ppc_md.get_rtc_time = mach_maple_md.get_rtc_time;
add_preferred_console("ttyS", 0, NULL);
+ } else {
+ xen_reboot_init(NULL);
}
DBG("Hello World I'm Maple Xen-LPAR!\n");
@@ -174,7 +177,7 @@ static void xen_idle(void)
rc = HYPERVISOR_set_timer_op(now_ns + offset_ns);
BUG_ON(rc != 0);
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
+ HYPERVISOR_sched_op(SCHEDOP_block, NULL);
}
local_irq_enable();
@@ -298,8 +301,6 @@ void xen_machine_crash_shutdown(struct p
}
#endif
-extern void xen_maple_init_IRQ(void);
-extern int xen_get_irq(struct pt_regs *regs);
define_machine(xen) {
.name = "Xen-Maple",
.probe = xen_probe,
diff -r 7680b29c03a6 -r dd0958aa2322 include/asm-powerpc/xen/asm/hypercall.h
--- a/include/asm-powerpc/xen/asm/hypercall.h Sat Aug 05 11:33:24 2006 -0400
+++ b/include/asm-powerpc/xen/asm/hypercall.h Mon Aug 07 17:37:23 2006 -0400
@@ -34,6 +34,7 @@
#include <asm/page.h>
#include <xen/xencomm.h>
#include <xen/interface/xen.h>
+#include <xen/interface/sched.h>
#define XEN_MARK(a)((a) | (~0UL << 16))
@@ -46,9 +47,14 @@ extern int HYPERVISOR_memory_op(unsigned
extern int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
extern int HYPERVISOR_multicall(void *call_list, int nr_calls);
-static inline int HYPERVISOR_sched_op(int cmd, unsigned long arg)
+extern int HYPERVISOR_sched_op(int cmd, void *arg);
+static inline int HYPERVISOR_shutdown(unsigned int reason)
{
- return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op), cmd, arg);
+ struct sched_shutdown sched_shutdown = {
+ .reason = reason
+ };
+
+ return HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
}
static inline int HYPERVISOR_set_timer_op(unsigned long arg)
@@ -56,4 +62,5 @@ static inline int HYPERVISOR_set_timer_o
return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_set_timer_op), arg);
}
+
#endif /* __HYPERCALL_H__ */
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/reboot.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/powerpc/platforms/xen/reboot.c Mon Aug 07 17:37:23 2006 -0400
@@ -0,0 +1,33 @@
+#include <linux/module.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/io/console.h>
+#include <xen/xencons.h>
+#include <asm/hypervisor.h>
+#include <asm/machdep.h>
+
+static void domain_machine_restart(char * __unused)
+{
+ /* We really want to get pending console data out before we die. */
+ xencons_force_flush();
+ HYPERVISOR_shutdown(SHUTDOWN_reboot);
+}
+
+static void domain_machine_power_off(void)
+{
+ /* We really want to get pending console data out before we die. */
+ xencons_force_flush();
+ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+}
+
+void xen_reboot_init(struct machdep_calls *md)
+{
+ if (md != NULL) {
+ ppc_md.restart = md->restart;
+ ppc_md.power_off = md->power_off;
+ ppc_md.halt = md->halt;
+ } else {
+ ppc_md.restart = domain_machine_restart;
+ ppc_md.power_off = domain_machine_power_off;
+ ppc_md.halt = domain_machine_power_off;
+ }
+}
diff -r 7680b29c03a6 -r dd0958aa2322 arch/powerpc/platforms/xen/setup.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/powerpc/platforms/xen/setup.h Mon Aug 07 17:37:23 2006 -0400
@@ -0,0 +1,6 @@
+
+extern void evtchn_init_IRQ(void);
+extern void xen_init_IRQ(void);
+extern void xen_reboot_init(struct machdep_calls *);
+extern void xen_maple_init_IRQ(void);
+extern int xen_get_irq(struct pt_regs *regs);
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|