[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 23/62] x86/shutdown: Support for using SCHEDOP_{shutdown, reboot}
From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- v2: 1. Use sched_shutdown 2. Move header inclusion --- docs/misc/xen-command-line.markdown | 3 +++ xen/arch/x86/shutdown.c | 34 ++++++++++++++++++++++++++++++---- xen/include/asm-x86/guest/hypercall.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index 781110d4b2..e5979bceee 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -1478,6 +1478,9 @@ Specify the host reboot method. 'efi' instructs Xen to reboot using the EFI reboot call (in EFI mode by default it will use that method first). +`xen` instructs Xen to reboot using Xen's SCHEDOP hypercall (this is the default +when running nested Xen) + ### rmrr > '= > start<-end>=[s1]bdf1[,[s1]bdf2[,...]];start<-end>=[s2]bdf1[,[s2]bdf2[,...]] diff --git a/xen/arch/x86/shutdown.c b/xen/arch/x86/shutdown.c index a87aa60add..689f6f137d 100644 --- a/xen/arch/x86/shutdown.c +++ b/xen/arch/x86/shutdown.c @@ -25,6 +25,7 @@ #include <asm/mpspec.h> #include <asm/tboot.h> #include <asm/apic.h> +#include <asm/guest.h> enum reboot_type { BOOT_INVALID, @@ -34,6 +35,7 @@ enum reboot_type { BOOT_CF9 = 'p', BOOT_CF9_PWR = 'P', BOOT_EFI = 'e', + BOOT_XEN = 'x', }; static int reboot_mode; @@ -49,6 +51,7 @@ static int reboot_mode; * pci Use the so-called "PCI reset register", CF9 * Power Like 'pci' but for a full power-cyle reset * efi Use the EFI reboot (if running under EFI) + * xen Use Xen SCHEDOP hypercall (if running under Xen as a guest) */ static enum reboot_type reboot_type = BOOT_INVALID; @@ -75,6 +78,7 @@ static int __init set_reboot_type(const char *str) case 'P': case 'p': case 't': + case 'x': reboot_type = *str; break; default: @@ -93,6 +97,13 @@ static int __init set_reboot_type(const char *str) reboot_type = BOOT_INVALID; } + if ( reboot_type == BOOT_XEN && !xen_guest ) + { + printk("Xen reboot selected, but Xen hypervisor not detected\n" + "Falling back to default\n"); + reboot_type = BOOT_INVALID; + } + return rc; } custom_param("reboot", set_reboot_type); @@ -109,6 +120,10 @@ static inline void kb_wait(void) static void noreturn __machine_halt(void *unused) { local_irq_disable(); + + if ( reboot_type == BOOT_XEN ) + xen_hypercall_shutdown(SHUTDOWN_poweroff); + for ( ; ; ) halt(); } @@ -129,10 +144,17 @@ void machine_halt(void) static void default_reboot_type(void) { - if ( reboot_type == BOOT_INVALID ) - reboot_type = efi_enabled(EFI_RS) ? BOOT_EFI - : acpi_disabled ? BOOT_KBD - : BOOT_ACPI; + if ( reboot_type != BOOT_INVALID ) + return; + + if ( xen_guest ) + reboot_type = BOOT_XEN; + else if ( efi_enabled(EFI_RS) ) + reboot_type = BOOT_EFI; + else if ( acpi_disabled ) + reboot_type = BOOT_KBD; + else + reboot_type = BOOT_ACPI; } static int __init override_reboot(struct dmi_system_id *d) @@ -618,6 +640,10 @@ void machine_restart(unsigned int delay_millisecs) } reboot_type = BOOT_ACPI; break; + + case BOOT_XEN: + xen_hypercall_shutdown(SHUTDOWN_reboot); + break; } } } diff --git a/xen/include/asm-x86/guest/hypercall.h b/xen/include/asm-x86/guest/hypercall.h index d959c3dd8a..a05041d30b 100644 --- a/xen/include/asm-x86/guest/hypercall.h +++ b/xen/include/asm-x86/guest/hypercall.h @@ -21,6 +21,11 @@ #ifdef CONFIG_XEN_GUEST +#include <xen/types.h> + +#include <public/xen.h> +#include <public/sched.h> + /* * Hypercall primatives for 64bit * @@ -78,6 +83,33 @@ (type)res; \ }) +/* + * Primitive Hypercall wrappers + */ +static inline long xen_hypercall_sched_op(unsigned int cmd, void *arg) +{ + return _hypercall64_2(long, __HYPERVISOR_sched_op, cmd, arg); +} + +/* + * Higher level hypercall helpers + */ +static inline long xen_hypercall_shutdown(unsigned int reason) +{ + struct sched_shutdown s = { .reason = reason }; + return xen_hypercall_sched_op(SCHEDOP_shutdown, &s); +} + +#else /* CONFIG_XEN_GUEST */ + +#include <public/sched.h> + +static inline long xen_hypercall_shutdown(unsigned int reason) +{ + ASSERT_UNREACHABLE(); + return 0; +} + #endif /* CONFIG_XEN_GUEST */ #endif /* __X86_XEN_HYPERCALL_H__ */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |