[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC v1 25/74] 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>
---
 docs/misc/xen-command-line.markdown   |  3 +++
 xen/arch/x86/shutdown.c               | 34 ++++++++++++++++++++++++++++++----
 xen/include/asm-x86/guest/hypercall.h | 29 +++++++++++++++++++++++++++++
 3 files changed, 62 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 c460f59c54..38791088fb 100644
--- a/xen/include/asm-x86/guest/hypercall.h
+++ b/xen/include/asm-x86/guest/hypercall.h
@@ -19,6 +19,11 @@
 #ifndef __X86_XEN_HYPERCALL_H__
 #define __X86_XEN_HYPERCALL_H__
 
+#include <xen/types.h>
+
+#include <public/xen.h>
+#include <public/sched.h>
+
 #ifdef CONFIG_XEN_GUEST
 
 /*
@@ -78,6 +83,30 @@
         (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)
+{
+    return xen_hypercall_sched_op(SCHEDOP_shutdown, &reason);
+}
+
+#else /* CONFIG_XEN_GUEST */
+
+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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.