]> Zhao Yanbai Git Server - minix.git/commitdiff
VMWare poweroff magic cli;hlt sequence 27/727/3
authorAntoine Leca <Antoine.Leca.1@gmail.com>
Fri, 1 Mar 2013 18:59:18 +0000 (18:59 +0000)
committerGerrit Code Review <gerrit@gerrit>
Sun, 11 Aug 2013 21:55:43 +0000 (23:55 +0200)
Change-Id: I9d8f96cc2e6423b89eb743e27550225d8759ee1d

kernel/arch/i386/arch_reset.c
kernel/arch/i386/include/arch_proto.h
kernel/arch/i386/klib.S

index 89b43a4a15cf98c19e4af11847b7d55debaa5dc1..0fd32770dbbbbe305314ee56559b4e9cb49790f9 100644 (file)
@@ -84,7 +84,14 @@ reset(void)
        }
 }
 
-void
+static __dead void
+halt(void)
+{
+       for ( ; ; )
+               halt_cpu();
+}
+
+static __dead void
 poweroff(void)
 {
        const char *shutdown_str;
@@ -96,8 +103,11 @@ poweroff(void)
        shutdown_str = "Shutdown";
         while (*shutdown_str) outb(0x8900, *(shutdown_str++));
 
+       /* VMware magic power off; likely to halt CPU */
+       poweroff_vmware_clihlt();
+
        /* fallback option: hang */
-       for (; ; ) halt_cpu();
+       halt();
 }
 
 __dead void arch_shutdown(int how)
index 9748b6c52014bcd75fec3e50f7ab13ceb4202f1c..3aa879096bc526877b81472676b9654035296c7d 100644 (file)
@@ -81,9 +81,10 @@ struct exception_frame {
 
 void exception(struct exception_frame * frame);
 
-/* klib386.s */
+/* klib.S */
 __dead void monitor(void);
 __dead void reset(void);
+__dead void poweroff_vmware_clihlt(void);
 __dead void x86_triplefault(void);
 reg_t read_cr0(void);
 reg_t read_cr2(void);
index abd43faa8f7accbfe80a46be5cfbc7cb2d553876..83663a759b21d8ff9dea784b658109c8ec623a38 100644 (file)
@@ -382,6 +382,35 @@ ENTRY(halt_cpu)
         */
        ret
 
+/*===========================================================================*/
+/*                     poweroff_vmware_clihlt                               */
+/*===========================================================================*/
+/*
+ * PUBLIC void poweroff_vmware_clihlt(void);
+ * VMware detects this peculiar sequence and forces the virtual machine off
+ * when the parameter gui.exitOnCLIHLT is set to TRUE.
+ * Otherwise this sequence just hangs the CPU, requiring a power down action.
+ */
+ENTRY(poweroff_vmware_clihlt)
+#ifndef NO_VMWARE_DETECTION
+       mov     $1, %eax
+       cpuid
+       test    $[1<<31], %ecx /* "virtualized" */
+       jz      1f      /* always 0 on real hardware */
+       mov     $0x40000000, %eax /* select hypervisor-use leaf */
+       cpuid
+       cmp     $0x61774D56, %ebx /* ASCII "VMwa" */
+       jne     1f
+       cmp     $0x4D566572, %ecx /* ASCII "reVM" */
+       jne     1f
+       cmp     $0x65726177, %edx /* ASCII "ware" */
+       jne     1f
+       /* we are virtualized by some VMware product! */
+#endif
+       cli
+       hlt
+1:     ret
+
 /*===========================================================================*/
 /*                           read_flags                                     */
 /*===========================================================================*/