Module Name:    src
Committed By:   nonaka
Date:           Tue May 23 08:48:35 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: autoconf.c
        src/sys/arch/i386/i386: autoconf.c
        src/sys/arch/x86/include: cpu.h
        src/sys/arch/x86/x86: identcpu.c vmt.c
        src/sys/arch/xen/conf: files.xen
        src/sys/arch/xen/x86: autoconf.c
Added Files:
        src/sys/arch/x86/x86: vmtreg.h vmtvar.h

Log Message:
x86: hypervisor detection from FreeBSD for x2APIC support.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/amd64/amd64/autoconf.c
cvs rdiff -u -r1.102 -r1.103 src/sys/arch/i386/i386/autoconf.c
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/x86/x86/vmt.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/x86/x86/vmtreg.h \
    src/sys/arch/x86/x86/vmtvar.h
cvs rdiff -u -r1.146 -r1.147 src/sys/arch/xen/conf/files.xen
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/xen/x86/autoconf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/autoconf.c
diff -u src/sys/arch/amd64/amd64/autoconf.c:1.25 src/sys/arch/amd64/amd64/autoconf.c:1.26
--- src/sys/arch/amd64/amd64/autoconf.c:1.25	Sun Nov 22 13:41:24 2015
+++ src/sys/arch/amd64/amd64/autoconf.c	Tue May 23 08:48:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.25 2015/11/22 13:41:24 maxv Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.26 2017/05/23 08:48:34 nonaka Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.25 2015/11/22 13:41:24 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.26 2017/05/23 08:48:34 nonaka Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_intrdebug.h"
@@ -91,6 +91,8 @@ cpu_configure(void)
 #if NBIOS32 > 0
 	bios32_init();
 	platform_init();
+	/* identify hypervisor type from SMBIOS */
+	identify_hypervisor();
 #endif
 
 	x86_64_proc0_tss_ldt_init();

Index: src/sys/arch/i386/i386/autoconf.c
diff -u src/sys/arch/i386/i386/autoconf.c:1.102 src/sys/arch/i386/i386/autoconf.c:1.103
--- src/sys/arch/i386/i386/autoconf.c:1.102	Sat Apr 22 04:29:31 2017
+++ src/sys/arch/i386/i386/autoconf.c	Tue May 23 08:48:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.102 2017/04/22 04:29:31 nonaka Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.103 2017/05/23 08:48:34 nonaka Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.102 2017/04/22 04:29:31 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.103 2017/05/23 08:48:34 nonaka Exp $");
 
 #include "opt_compat_oldboot.h"
 #include "opt_intrdebug.h"
@@ -105,6 +105,8 @@ cpu_configure(void)
 #if NBIOS32 > 0
 	bios32_init();
 	platform_init();
+	/* identify hypervisor type from SMBIOS */
+	identify_hypervisor();
 #endif
 #ifdef PCIBIOS
 	pcibios_init();

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.70 src/sys/arch/x86/include/cpu.h:1.71
--- src/sys/arch/x86/include/cpu.h:1.70	Mon May 15 04:02:52 2017
+++ src/sys/arch/x86/include/cpu.h	Tue May 23 08:48:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.70 2017/05/15 04:02:52 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.71 2017/05/23 08:48:34 nonaka Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -422,6 +422,18 @@ void 	tmx86_init_longrun(void);
 /* identcpu.c */
 void 	cpu_probe(struct cpu_info *);
 void	cpu_identify(struct cpu_info *);
+void	identify_hypervisor(void);
+
+typedef enum vm_guest {
+	VM_GUEST_NO = 0,
+	VM_GUEST_VM,
+	VM_GUEST_XEN,
+	VM_GUEST_HV,
+	VM_GUEST_VMWARE,
+	VM_GUEST_KVM,
+	VM_LAST
+} vm_guest_t;
+extern vm_guest_t vm_guest;
 
 /* cpu_topology.c */
 void	x86_cpu_topology(struct cpu_info *);

Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.54 src/sys/arch/x86/x86/identcpu.c:1.55
--- src/sys/arch/x86/x86/identcpu.c:1.54	Wed May 10 08:02:37 2017
+++ src/sys/arch/x86/x86/identcpu.c	Tue May 23 08:48:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: identcpu.c,v 1.54 2017/05/10 08:02:37 msaitoh Exp $	*/
+/*	$NetBSD: identcpu.c,v 1.55 2017/05/23 08:48:34 nonaka Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.54 2017/05/10 08:02:37 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.55 2017/05/23 08:48:34 nonaka Exp $");
 
 #include "opt_xen.h"
 
@@ -50,6 +50,9 @@ __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v
 #include <x86/cpuvar.h>
 #include <x86/cpu_msr.h>
 
+#include <x86/x86/vmtreg.h>	/* for vmt_hvcall() */
+#include <x86/x86/vmtvar.h>	/* for vmt_hvcall() */
+
 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
 
 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] = 
@@ -912,6 +915,7 @@ cpu_probe(struct cpu_info *ci)
 		for (i = 0; i < __arraycount(cpu_feature); i++) {
 			cpu_feature[i] = ci->ci_feat_val[i];
 		}
+		identify_hypervisor();
 #ifndef XEN
 		/* Early patch of text segment. */
 		x86_patch(true);
@@ -995,3 +999,96 @@ cpu_identify(struct cpu_info *ci)
 #endif	/* i386 */
 
 }
+
+/*
+ * Hypervisor
+ */
+vm_guest_t vm_guest = VM_GUEST_NO;
+
+static const char * const vm_bios_vendors[] = {
+	"QEMU",				/* QEMU */
+	"Plex86",			/* Plex86 */
+	"Bochs",			/* Bochs */
+	"Xen",				/* Xen */
+	"BHYVE",			/* bhyve */
+	"Seabios",			/* KVM */
+};
+
+static const char * const vm_system_products[] = {
+	"VMware Virtual Platform",	/* VMWare VM */
+	"Virtual Machine",		/* Microsoft VirtualPC */
+	"VirtualBox",			/* Sun xVM VirtualBox */
+	"Parallels Virtual Platform",	/* Parallels VM */
+	"KVM",				/* KVM */
+};
+
+void
+identify_hypervisor(void)
+{
+	u_int regs[6];
+	char hv_vendor[12];
+	const char *p;
+	int i;
+
+	if (vm_guest != VM_GUEST_NO)
+		return;
+
+	/*
+	 * [RFC] CPUID usage for interaction between Hypervisors and Linux.
+	 * http://lkml.org/lkml/2008/10/1/246
+	 *
+	 * KB1009458: Mechanisms to determine if software is running in
+	 * a VMware virtual machine
+	 * http://kb.vmware.com/kb/1009458
+	 */
+	if (ISSET(cpu_feature[1], CPUID2_RAZ)) {
+		vm_guest = VM_GUEST_VM;
+		x86_cpuid(0x40000000, regs);
+		if (regs[0] >= 0x40000000) {
+			memcpy(&hv_vendor[0], &regs[1], sizeof(*regs));
+			memcpy(&hv_vendor[4], &regs[2], sizeof(*regs));
+			memcpy(&hv_vendor[8], &regs[3], sizeof(*regs));
+			if (memcmp(hv_vendor, "VMwareVMware", 12) == 0)
+				vm_guest = VM_GUEST_VMWARE;
+			else if (memcmp(hv_vendor, "Microsoft Hv", 12) == 0)
+				vm_guest = VM_GUEST_HV;
+			else if (memcmp(hv_vendor, "KVMKVMKVM\0\0\0", 12) == 0)
+				vm_guest = VM_GUEST_KVM;
+			/* FreeBSD bhyve: "bhyve bhyve " */
+			/* OpenBSD vmm:   "OpenBSDVMM58" */
+		}
+		return;
+	}
+
+	/*
+	 * Examine SMBIOS strings for older hypervisors.
+	 */
+	p = pmf_get_platform("system-serial");
+	if (p != NULL) {
+		if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) {
+			vmt_hvcall(VM_CMD_GET_VERSION, regs);
+			if (regs[1] == VM_MAGIC) {
+				vm_guest = VM_GUEST_VMWARE;
+				return;
+			}
+		}
+	}
+	p = pmf_get_platform("bios-vendor");
+	if (p != NULL) {
+		for (i = 0; i < __arraycount(vm_bios_vendors); i++) {
+			if (strcmp(p, vm_bios_vendors[i]) == 0) {
+				vm_guest = VM_GUEST_VM;
+				return;
+			}
+		}
+	}
+	p = pmf_get_platform("system-product");
+	if (p != NULL) {
+		for (i = 0; i < __arraycount(vm_system_products); i++) {
+			if (strcmp(p, vm_system_products[i]) == 0) {
+				vm_guest = VM_GUEST_VM;
+				return;
+			}
+		}
+	}
+}

Index: src/sys/arch/x86/x86/vmt.c
diff -u src/sys/arch/x86/x86/vmt.c:1.15 src/sys/arch/x86/x86/vmt.c:1.16
--- src/sys/arch/x86/x86/vmt.c:1.15	Thu Nov 10 03:32:04 2016
+++ src/sys/arch/x86/x86/vmt.c	Tue May 23 08:48:34 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: vmt.c,v 1.15 2016/11/10 03:32:04 ozaki-r Exp $ */
+/* $NetBSD: vmt.c,v 1.16 2017/05/23 08:48:34 nonaka Exp $ */
 /* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */
 
 /*
@@ -46,130 +46,10 @@
 #include <dev/sysmon/sysmonvar.h>
 #include <dev/sysmon/sysmon_taskq.h>
 
-/* #define VMT_DEBUG */
-
-/* OS name to report to host */
-#ifdef __i386__
-#define VM_OS_NAME	"other"
-#else
-#define VM_OS_NAME	"other-64"
-#endif
-
-/* "The" magic number, always occupies the EAX register. */
-#define VM_MAGIC			0x564D5868
-
-/* Port numbers, passed on EDX.LOW . */
-#define VM_PORT_CMD			0x5658
-#define VM_PORT_RPC			0x5659
-
-/* Commands, passed on ECX.LOW. */
-#define VM_CMD_GET_SPEED		0x01
-#define VM_CMD_APM			0x02
-#define VM_CMD_GET_MOUSEPOS		0x04
-#define VM_CMD_SET_MOUSEPOS		0x05
-#define VM_CMD_GET_CLIPBOARD_LEN	0x06
-#define VM_CMD_GET_CLIPBOARD		0x07
-#define VM_CMD_SET_CLIPBOARD_LEN	0x08
-#define VM_CMD_SET_CLIPBOARD		0x09
-#define VM_CMD_GET_VERSION		0x0a
-#define  VM_VERSION_UNMANAGED			0x7fffffff
-#define VM_CMD_GET_DEVINFO		0x0b
-#define VM_CMD_DEV_ADDREMOVE		0x0c
-#define VM_CMD_GET_GUI_OPTIONS		0x0d
-#define VM_CMD_SET_GUI_OPTIONS		0x0e
-#define VM_CMD_GET_SCREEN_SIZE		0x0f
-#define VM_CMD_GET_HWVER		0x11
-#define VM_CMD_POPUP_OSNOTFOUND		0x12
-#define VM_CMD_GET_BIOS_UUID		0x13
-#define VM_CMD_GET_MEM_SIZE		0x14
-/*#define VM_CMD_GET_TIME		0x17 */	/* deprecated */
-#define VM_CMD_RPC			0x1e
-#define VM_CMD_GET_TIME_FULL		0x2e
-
-/* RPC sub-commands, passed on ECX.HIGH. */
-#define VM_RPC_OPEN			0x00
-#define VM_RPC_SET_LENGTH		0x01
-#define VM_RPC_SET_DATA			0x02
-#define VM_RPC_GET_LENGTH		0x03
-#define VM_RPC_GET_DATA			0x04
-#define VM_RPC_GET_END			0x05
-#define VM_RPC_CLOSE			0x06
-
-/* RPC magic numbers, passed on EBX. */
-#define VM_RPC_OPEN_RPCI	0x49435052UL /* with VM_RPC_OPEN. */
-#define VM_RPC_OPEN_TCLO	0x4F4C4354UL /* with VP_RPC_OPEN. */
-#define VM_RPC_ENH_DATA		0x00010000UL /* with enhanced RPC data calls. */
-
-#define VM_RPC_FLAG_COOKIE	0x80000000UL
-
-/* RPC reply flags */
-#define VM_RPC_REPLY_SUCCESS	0x0001
-#define VM_RPC_REPLY_DORECV	0x0002		/* incoming message available */
-#define VM_RPC_REPLY_CLOSED	0x0004		/* RPC channel is closed */
-#define VM_RPC_REPLY_UNSENT	0x0008		/* incoming message was removed? */
-#define VM_RPC_REPLY_CHECKPOINT	0x0010		/* checkpoint occurred -> retry */
-#define VM_RPC_REPLY_POWEROFF	0x0020		/* underlying device is powering off */
-#define VM_RPC_REPLY_TIMEOUT	0x0040
-#define VM_RPC_REPLY_HB		0x0080		/* high-bandwidth tx/rx available */
-
-/* VM state change IDs */
-#define VM_STATE_CHANGE_HALT	1
-#define VM_STATE_CHANGE_REBOOT	2
-#define VM_STATE_CHANGE_POWERON 3
-#define VM_STATE_CHANGE_RESUME  4
-#define VM_STATE_CHANGE_SUSPEND 5
-
-/* VM guest info keys */
-#define VM_GUEST_INFO_DNS_NAME		1
-#define VM_GUEST_INFO_IP_ADDRESS	2
-#define VM_GUEST_INFO_DISK_FREE_SPACE	3
-#define VM_GUEST_INFO_BUILD_NUMBER	4
-#define VM_GUEST_INFO_OS_NAME_FULL	5
-#define VM_GUEST_INFO_OS_NAME		6
-#define VM_GUEST_INFO_UPTIME		7
-#define VM_GUEST_INFO_MEMORY		8
-#define VM_GUEST_INFO_IP_ADDRESS_V2	9
-
-/* RPC responses */
-#define VM_RPC_REPLY_OK			"OK "
-#define VM_RPC_RESET_REPLY		"OK ATR toolbox"
-#define VM_RPC_REPLY_ERROR		"ERROR Unknown command"
-#define VM_RPC_REPLY_ERROR_IP_ADDR	"ERROR Unable to find guest IP address"
-
-/* A register. */
-union vm_reg {
-	struct {
-		uint16_t low;
-		uint16_t high;
-	} part;
-	uint32_t word;
-#ifdef __amd64__
-	struct {
-		uint32_t low;
-		uint32_t high;
-	} words;
-	uint64_t quad;
-#endif
-} __packed;
+#include <x86/x86/vmtreg.h>
+#include <x86/x86/vmtvar.h>
 
-/* A register frame. */
-/* XXX 'volatile' as a workaround because BACKDOOR_OP is likely broken */
-struct vm_backdoor {
-	volatile union vm_reg eax;
-	volatile union vm_reg ebx;
-	volatile union vm_reg ecx;
-	volatile union vm_reg edx;
-	volatile union vm_reg esi;
-	volatile union vm_reg edi;
-	volatile union vm_reg ebp;
-} __packed;
-
-/* RPC context. */
-struct vm_rpc {
-	uint16_t channel;
-	uint32_t cookie1;
-	uint32_t cookie2;
-};
+/* #define VMT_DEBUG */
 
 static int	vmt_match(device_t, cfdata_t, void *);
 static void	vmt_attach(device_t, device_t, void *);
@@ -861,64 +741,6 @@ out:
 	callout_schedule(&sc->sc_tclo_tick, sc->sc_tclo_ping ? hz : 1);
 }
 
-#define BACKDOOR_OP_I386(op, frame)		\
-	__asm__ __volatile__ (			\
-		"pushal;"			\
-		"pushl %%eax;"			\
-		"movl 0x18(%%eax), %%ebp;"	\
-		"movl 0x14(%%eax), %%edi;"	\
-		"movl 0x10(%%eax), %%esi;"	\
-		"movl 0x0c(%%eax), %%edx;"	\
-		"movl 0x08(%%eax), %%ecx;"	\
-		"movl 0x04(%%eax), %%ebx;"	\
-		"movl 0x00(%%eax), %%eax;"	\
-		op				\
-		"xchgl %%eax, 0x00(%%esp);"	\
-		"movl %%ebp, 0x18(%%eax);"	\
-		"movl %%edi, 0x14(%%eax);"	\
-		"movl %%esi, 0x10(%%eax);"	\
-		"movl %%edx, 0x0c(%%eax);"	\
-		"movl %%ecx, 0x08(%%eax);"	\
-		"movl %%ebx, 0x04(%%eax);"	\
-		"popl 0x00(%%eax);"		\
-		"popal;"			\
-		:				\
-		:"a"(frame)			\
-	)
-
-#define BACKDOOR_OP_AMD64(op, frame)		\
-	__asm__ __volatile__ (			\
-		"pushq %%rbp;			\n\t" \
-		"pushq %%rax;			\n\t" \
-		"movq 0x30(%%rax), %%rbp;	\n\t" \
-		"movq 0x28(%%rax), %%rdi;	\n\t" \
-		"movq 0x20(%%rax), %%rsi;	\n\t" \
-		"movq 0x18(%%rax), %%rdx;	\n\t" \
-		"movq 0x10(%%rax), %%rcx;	\n\t" \
-		"movq 0x08(%%rax), %%rbx;	\n\t" \
-		"movq 0x00(%%rax), %%rax;	\n\t" \
-		op				"\n\t" \
-		"xchgq %%rax, 0x00(%%rsp);	\n\t" \
-		"movq %%rbp, 0x30(%%rax);	\n\t" \
-		"movq %%rdi, 0x28(%%rax);	\n\t" \
-		"movq %%rsi, 0x20(%%rax);	\n\t" \
-		"movq %%rdx, 0x18(%%rax);	\n\t" \
-		"movq %%rcx, 0x10(%%rax);	\n\t" \
-		"movq %%rbx, 0x08(%%rax);	\n\t" \
-		"popq 0x00(%%rax);		\n\t" \
-		"popq %%rbp;			\n\t" \
-		: /* No outputs. */ : "a" (frame) \
-		  /* No pushal on amd64 so warn gcc about the clobbered registers. */ \
-		: "rbx", "rcx", "rdx", "rdi", "rsi", "cc", "memory" \
-	)
-
-
-#ifdef __i386__
-#define BACKDOOR_OP(op, frame) BACKDOOR_OP_I386(op, frame)
-#else
-#define BACKDOOR_OP(op, frame) BACKDOOR_OP_AMD64(op, frame)
-#endif
-
 static void
 vm_cmd(struct vm_backdoor *frame)
 {

Index: src/sys/arch/xen/conf/files.xen
diff -u src/sys/arch/xen/conf/files.xen:1.146 src/sys/arch/xen/conf/files.xen:1.147
--- src/sys/arch/xen/conf/files.xen:1.146	Fri Mar 24 17:09:37 2017
+++ src/sys/arch/xen/conf/files.xen	Tue May 23 08:48:35 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: files.xen,v 1.146 2017/03/24 17:09:37 maxv Exp $
+#	$NetBSD: files.xen,v 1.147 2017/05/23 08:48:35 nonaka Exp $
 #	NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp 
 #	NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp 
 
@@ -146,6 +146,7 @@ file	arch/x86/x86/tsc.c		machdep
 file	arch/x86/x86/vm_machdep.c	machdep
 file	arch/x86/x86/x86_machdep.c	machdep
 file	arch/x86/x86/cpu_topology.c	machdep
+file	arch/x86/x86/platform.c		machdep
 
 include	"arch/xen/conf/files.compat"
 

Index: src/sys/arch/xen/x86/autoconf.c
diff -u src/sys/arch/xen/x86/autoconf.c:1.17 src/sys/arch/xen/x86/autoconf.c:1.18
--- src/sys/arch/xen/x86/autoconf.c:1.17	Thu Apr  3 15:53:05 2014
+++ src/sys/arch/xen/x86/autoconf.c	Tue May 23 08:48:35 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.17 2014/04/03 15:53:05 christos Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.18 2017/05/23 08:48:35 nonaka Exp $	*/
 /*	NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp 	*/
 
 /*-
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.17 2014/04/03 15:53:05 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.18 2017/05/23 08:48:35 nonaka Exp $");
 
 #include "opt_xen.h"
 #include "opt_compat_oldboot.h"
@@ -94,6 +94,8 @@ int x86_ndisks;
 #include "bios32.h"
 #if NBIOS32 > 0
 #include <machine/bios32.h>
+/* XXX */
+extern void platform_init(void);
 #endif
 
 #include "opt_pcibios.h"
@@ -113,10 +115,17 @@ cpu_configure(void)
 
 	startrtclock();
 
-#if NBIOS32 > 0 && defined(DOM0OPS)
-	if (xendomain_is_dom0())
+#if defined(DOM0OPS)
+	if (xendomain_is_dom0()) {
+#if NBIOS32 > 0
 		bios32_init();
-#endif /* NBIOS32 > 0 && DOM0OPS */
+		platform_init();
+		/* identify hypervisor type from SMBIOS */
+		identify_hypervisor();
+#endif /* NBIOS32 > 0 */
+	} else
+#endif /* DOM0OPS */
+		vm_guest = VM_GUEST_XEN;
 #ifdef PCIBIOS
 	pcibios_init();
 #endif

Added files:

Index: src/sys/arch/x86/x86/vmtreg.h
diff -u /dev/null src/sys/arch/x86/x86/vmtreg.h:1.1
--- /dev/null	Tue May 23 08:48:35 2017
+++ src/sys/arch/x86/x86/vmtreg.h	Tue May 23 08:48:34 2017
@@ -0,0 +1,117 @@
+/* $NetBSD: vmtreg.h,v 1.1 2017/05/23 08:48:34 nonaka Exp $ */
+/* NetBSD: vmt.c,v 1.15 2016/11/10 03:32:04 ozaki-r Exp */
+/* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */
+
+/*
+ * Copyright (c) 2007 David Crawshaw <da...@zentus.com>
+ * Copyright (c) 2008 David Gwynne <d...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Protocol reverse engineered by Ken Kato:
+ * http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
+ */
+
+/* OS name to report to host */
+#ifdef __i386__
+#define VM_OS_NAME	"other"
+#else
+#define VM_OS_NAME	"other-64"
+#endif
+
+/* "The" magic number, always occupies the EAX register. */
+#define VM_MAGIC			0x564D5868
+
+/* Port numbers, passed on EDX.LOW . */
+#define VM_PORT_CMD			0x5658
+#define VM_PORT_RPC			0x5659
+
+/* Commands, passed on ECX.LOW. */
+#define VM_CMD_GET_SPEED		0x01
+#define VM_CMD_APM			0x02
+#define VM_CMD_GET_MOUSEPOS		0x04
+#define VM_CMD_SET_MOUSEPOS		0x05
+#define VM_CMD_GET_CLIPBOARD_LEN	0x06
+#define VM_CMD_GET_CLIPBOARD		0x07
+#define VM_CMD_SET_CLIPBOARD_LEN	0x08
+#define VM_CMD_SET_CLIPBOARD		0x09
+#define VM_CMD_GET_VERSION		0x0a
+#define  VM_VERSION_UNMANAGED			0x7fffffff
+#define VM_CMD_GET_DEVINFO		0x0b
+#define VM_CMD_DEV_ADDREMOVE		0x0c
+#define VM_CMD_GET_GUI_OPTIONS		0x0d
+#define VM_CMD_SET_GUI_OPTIONS		0x0e
+#define VM_CMD_GET_SCREEN_SIZE		0x0f
+#define VM_CMD_GET_HWVER		0x11
+#define VM_CMD_POPUP_OSNOTFOUND		0x12
+#define VM_CMD_GET_BIOS_UUID		0x13
+#define VM_CMD_GET_MEM_SIZE		0x14
+/*#define VM_CMD_GET_TIME		0x17 */	/* deprecated */
+#define VM_CMD_RPC			0x1e
+#define VM_CMD_GET_HZ			0x2d
+#define VM_CMD_GET_TIME_FULL		0x2e
+#define VM_CMD_GET_VCPU_INFO		0x44
+#define  VCPUINFO_LEGACY_X2APIC			__BIT(3)
+#define  VCPUINFO_VCPU_RESERVED			__BIT(31)
+
+/* RPC sub-commands, passed on ECX.HIGH. */
+#define VM_RPC_OPEN			0x00
+#define VM_RPC_SET_LENGTH		0x01
+#define VM_RPC_SET_DATA			0x02
+#define VM_RPC_GET_LENGTH		0x03
+#define VM_RPC_GET_DATA			0x04
+#define VM_RPC_GET_END			0x05
+#define VM_RPC_CLOSE			0x06
+
+/* RPC magic numbers, passed on EBX. */
+#define VM_RPC_OPEN_RPCI	0x49435052UL /* with VM_RPC_OPEN. */
+#define VM_RPC_OPEN_TCLO	0x4F4C4354UL /* with VP_RPC_OPEN. */
+#define VM_RPC_ENH_DATA		0x00010000UL /* with enhanced RPC data calls. */
+
+#define VM_RPC_FLAG_COOKIE	0x80000000UL
+
+/* RPC reply flags */
+#define VM_RPC_REPLY_SUCCESS	0x0001
+#define VM_RPC_REPLY_DORECV	0x0002		/* incoming message available */
+#define VM_RPC_REPLY_CLOSED	0x0004		/* RPC channel is closed */
+#define VM_RPC_REPLY_UNSENT	0x0008		/* incoming message was removed? */
+#define VM_RPC_REPLY_CHECKPOINT	0x0010		/* checkpoint occurred -> retry */
+#define VM_RPC_REPLY_POWEROFF	0x0020		/* underlying device is powering off */
+#define VM_RPC_REPLY_TIMEOUT	0x0040
+#define VM_RPC_REPLY_HB		0x0080		/* high-bandwidth tx/rx available */
+
+/* VM state change IDs */
+#define VM_STATE_CHANGE_HALT	1
+#define VM_STATE_CHANGE_REBOOT	2
+#define VM_STATE_CHANGE_POWERON 3
+#define VM_STATE_CHANGE_RESUME  4
+#define VM_STATE_CHANGE_SUSPEND 5
+
+/* VM guest info keys */
+#define VM_GUEST_INFO_DNS_NAME		1
+#define VM_GUEST_INFO_IP_ADDRESS	2
+#define VM_GUEST_INFO_DISK_FREE_SPACE	3
+#define VM_GUEST_INFO_BUILD_NUMBER	4
+#define VM_GUEST_INFO_OS_NAME_FULL	5
+#define VM_GUEST_INFO_OS_NAME		6
+#define VM_GUEST_INFO_UPTIME		7
+#define VM_GUEST_INFO_MEMORY		8
+#define VM_GUEST_INFO_IP_ADDRESS_V2	9
+
+/* RPC responses */
+#define VM_RPC_REPLY_OK			"OK "
+#define VM_RPC_RESET_REPLY		"OK ATR toolbox"
+#define VM_RPC_REPLY_ERROR		"ERROR Unknown command"
+#define VM_RPC_REPLY_ERROR_IP_ADDR	"ERROR Unable to find guest IP address"
Index: src/sys/arch/x86/x86/vmtvar.h
diff -u /dev/null src/sys/arch/x86/x86/vmtvar.h:1.1
--- /dev/null	Tue May 23 08:48:35 2017
+++ src/sys/arch/x86/x86/vmtvar.h	Tue May 23 08:48:34 2017
@@ -0,0 +1,134 @@
+/* $NetBSD: vmtvar.h,v 1.1 2017/05/23 08:48:34 nonaka Exp $ */
+/* NetBSD: vmt.c,v 1.15 2016/11/10 03:32:04 ozaki-r Exp */
+/* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */
+
+/*
+ * Copyright (c) 2007 David Crawshaw <da...@zentus.com>
+ * Copyright (c) 2008 David Gwynne <d...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* A register. */
+union vm_reg {
+	struct {
+		uint16_t low;
+		uint16_t high;
+	} part;
+	uint32_t word;
+#ifdef __amd64__
+	struct {
+		uint32_t low;
+		uint32_t high;
+	} words;
+	uint64_t quad;
+#endif
+} __packed;
+
+/* A register frame. */
+/* XXX 'volatile' as a workaround because BACKDOOR_OP is likely broken */
+struct vm_backdoor {
+	volatile union vm_reg eax;
+	volatile union vm_reg ebx;
+	volatile union vm_reg ecx;
+	volatile union vm_reg edx;
+	volatile union vm_reg esi;
+	volatile union vm_reg edi;
+	volatile union vm_reg ebp;
+} __packed;
+
+/* RPC context. */
+struct vm_rpc {
+	uint16_t channel;
+	uint32_t cookie1;
+	uint32_t cookie2;
+};
+
+#define BACKDOOR_OP_I386(op, frame)		\
+	__asm__ __volatile__ (			\
+		"pushal;"			\
+		"pushl %%eax;"			\
+		"movl 0x18(%%eax), %%ebp;"	\
+		"movl 0x14(%%eax), %%edi;"	\
+		"movl 0x10(%%eax), %%esi;"	\
+		"movl 0x0c(%%eax), %%edx;"	\
+		"movl 0x08(%%eax), %%ecx;"	\
+		"movl 0x04(%%eax), %%ebx;"	\
+		"movl 0x00(%%eax), %%eax;"	\
+		op				\
+		"xchgl %%eax, 0x00(%%esp);"	\
+		"movl %%ebp, 0x18(%%eax);"	\
+		"movl %%edi, 0x14(%%eax);"	\
+		"movl %%esi, 0x10(%%eax);"	\
+		"movl %%edx, 0x0c(%%eax);"	\
+		"movl %%ecx, 0x08(%%eax);"	\
+		"movl %%ebx, 0x04(%%eax);"	\
+		"popl 0x00(%%eax);"		\
+		"popal;"			\
+		:				\
+		:"a"(frame)			\
+	)
+
+#define BACKDOOR_OP_AMD64(op, frame)		\
+	__asm__ __volatile__ (			\
+		"pushq %%rbp;			\n\t" \
+		"pushq %%rax;			\n\t" \
+		"movq 0x30(%%rax), %%rbp;	\n\t" \
+		"movq 0x28(%%rax), %%rdi;	\n\t" \
+		"movq 0x20(%%rax), %%rsi;	\n\t" \
+		"movq 0x18(%%rax), %%rdx;	\n\t" \
+		"movq 0x10(%%rax), %%rcx;	\n\t" \
+		"movq 0x08(%%rax), %%rbx;	\n\t" \
+		"movq 0x00(%%rax), %%rax;	\n\t" \
+		op				"\n\t" \
+		"xchgq %%rax, 0x00(%%rsp);	\n\t" \
+		"movq %%rbp, 0x30(%%rax);	\n\t" \
+		"movq %%rdi, 0x28(%%rax);	\n\t" \
+		"movq %%rsi, 0x20(%%rax);	\n\t" \
+		"movq %%rdx, 0x18(%%rax);	\n\t" \
+		"movq %%rcx, 0x10(%%rax);	\n\t" \
+		"movq %%rbx, 0x08(%%rax);	\n\t" \
+		"popq 0x00(%%rax);		\n\t" \
+		"popq %%rbp;			\n\t" \
+		: /* No outputs. */ \
+		: "a" (frame) \
+		  /* No pushal on amd64 so warn gcc about the clobbered registers. */\
+		: "rbx", "rcx", "rdx", "rdi", "rsi", "cc", "memory" \
+	)
+
+#ifdef __i386__
+#define BACKDOOR_OP(op, frame) BACKDOOR_OP_I386(op, frame)
+#else
+#define BACKDOOR_OP(op, frame) BACKDOOR_OP_AMD64(op, frame)
+#endif
+
+static __inline void
+vmt_hvcall(uint8_t cmd, u_int regs[6])
+{
+	struct vm_backdoor frame;
+
+	memset(&frame, 0, sizeof(frame));
+	frame.eax.word = VM_MAGIC;
+	frame.ebx.word = UINT_MAX;
+	frame.ecx.part.low = cmd;
+	frame.edx.part.low = VM_PORT_CMD;
+
+	BACKDOOR_OP("inl %%dx, %%eax;", &frame);
+
+	regs[0] = frame.eax.word;
+	regs[1] = frame.ebx.word;
+	regs[2] = frame.ecx.word;
+	regs[3] = frame.edx.word;
+	regs[4] = frame.esi.word;
+	regs[5] = frame.edi.word;
+}

Reply via email to