Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Aug 2013 19:17:06 +0000 (UTC)
From:      Takuya ASADA <syuu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r253935 - user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload
Message-ID:  <201308041917.r74JH6BZ063779@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: syuu
Date: Sun Aug  4 19:17:06 2013
New Revision: 253935
URL: http://svnweb.freebsd.org/changeset/base/253935

Log:
  support '-S' option for standalone guest program

Added:
  user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/standalone.c
Modified:
  user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/Makefile
  user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.8
  user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c

Modified: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/Makefile
==============================================================================
--- user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/Makefile	Sun Aug  4 18:20:53 2013	(r253934)
+++ user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/Makefile	Sun Aug  4 19:17:06 2013	(r253935)
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PROG=	bhyveload
-SRCS=	bhyveload.c
+SRCS=	bhyveload.c standalone.c
 MAN=	bhyveload.8
 
 DPADD+=	${LIBVMMAPI}

Modified: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.8
==============================================================================
--- user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.8	Sun Aug  4 18:20:53 2013	(r253934)
+++ user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.8	Sun Aug  4 19:17:06 2013	(r253935)
@@ -38,6 +38,7 @@ guest inside a bhyve virtual machine
 .Op Fl m Ar mem-size
 .Op Fl d Ar disk-path
 .Op Fl h Ar host-path
+.Op Fl S Ar stand-binary:stand-addr
 .Ar vmname
 .Sh DESCRIPTION
 .Nm
@@ -75,6 +76,13 @@ is the pathname of the guest's boot disk
 The
 .Ar host-path
 is the directory at the top of the guest's boot filesystem.
+.It Fl S Ar stand-binary:stand-addr
+The
+.Ar stand-binary
+is the pathname of the standalone guest program.
+The
+.Ar stand-addr
+is the entrypoint address of the standalone guest program.
 .El
 .Sh EXAMPLES
 To create a virtual machine named

Modified: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c
==============================================================================
--- user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c	Sun Aug  4 18:20:53 2013	(r253934)
+++ user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c	Sun Aug  4 19:17:06 2013	(r253935)
@@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/disk.h>
-#include <sys/param.h>
 
 #include <machine/specialreg.h>
 #include <machine/vmm.h>
@@ -76,8 +75,6 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include <vmmapi.h>
 
@@ -98,6 +95,9 @@ static uint64_t gdtbase, cr3, rsp;
 
 static void cb_exit(void *arg, int v);
 
+extern int stand_load(struct loader_callbacks *cb, char *image, 
+    uint64_t addr);
+
 /*
  * Console i/o callbacks
  */
@@ -555,152 +555,16 @@ usage(void)
 
 	fprintf(stderr,
 		"usage: %s [-m mem-size][-d <disk-path>] [-h <host-path>] "
+		"[-S stand-binary:stand-addr] "
 		"<vmname>\n", progname);
 	exit(1);
 }
 
-#define MSR_EFER        0xc0000080
-#define CR4_PAE         0x00000020
-#define CR4_PSE         0x00000010
-#define CR0_PG          0x80000000
-#define	CR0_PE		0x00000001	/* Protected mode Enable */
-#define	CR0_NE		0x00000020	/* Numeric Error enable (EX16 vs IRQ13) */
-
-#define PG_V	0x001
-#define PG_RW	0x002
-#define PG_U	0x004
-#define PG_PS	0x080
-
-typedef u_int64_t p4_entry_t;
-typedef u_int64_t p3_entry_t;
-typedef u_int64_t p2_entry_t;
-
-#define	GUEST_NULL_SEL		0
-#define	GUEST_CODE_SEL		1
-#define	GUEST_DATA_SEL		2
-#define	GUEST_GDTR_LIMIT	(3 * 8 - 1)
-
-static void
-setup_stand_gdt(uint64_t *gdtr)
-{
-	gdtr[GUEST_NULL_SEL] = 0;
-	gdtr[GUEST_CODE_SEL] = 0x0020980000000000;
-	gdtr[GUEST_DATA_SEL] = 0x0000900000000000;
-}
-
-static int
-stand_load(char *image, uint64_t addr)
-{
-	int i;
-	int fd;
-	struct stat sb;
-	char *buf;
-	uint32_t		stack[1024];
-	p4_entry_t		PT4[512];
-	p3_entry_t		PT3[512];
-	p2_entry_t		PT2[512];
-	uint64_t		gdtr[3];
-
-	if ((fd = open(image, O_RDONLY)) < 0) {
-		perror("open");
-		return (1);
-	}
-	if (fstat(fd, &sb)) {
-		perror("fstat");
-		return (1);
-	}
-	buf = alloca(sb.st_size);
-	if (read(fd, buf, sb.st_size) != sb.st_size) {
-		perror("read");
-		return (1);
-	}
-	if (close(fd) < 0) {
-		perror("close");
-		return (1);
-	}
-	if (cb_copyin(NULL, buf, addr, sb.st_size)) {
-		perror("copyin");
-		return (1);
-	}
-
-	bzero(PT4, PAGE_SIZE);
-	bzero(PT3, PAGE_SIZE);
-	bzero(PT2, PAGE_SIZE);
-
-	/*
-	 * Build a scratch stack at physical 0x1000, page tables:
-	 *	PT4 at 0x2000,
-	 *	PT3 at 0x3000,
-	 *	PT2 at 0x4000,
-	 *      gdtr at 0x5000,
-	 */
-
-	/*
-	 * This is kinda brutal, but every single 1GB VM memory segment
-	 * points to the same first 1GB of physical memory.  But it is
-	 * more than adequate.
-	 */
-	for (i = 0; i < 512; i++) {
-		/* Each slot of the level 4 pages points to the same level 3 page */
-		PT4[i] = (p4_entry_t) 0x3000;
-		PT4[i] |= PG_V | PG_RW | PG_U;
-
-		/* Each slot of the level 3 pages points to the same level 2 page */
-		PT3[i] = (p3_entry_t) 0x4000;
-		PT3[i] |= PG_V | PG_RW | PG_U;
-
-		/* The level 2 page slots are mapped with 2MB pages for 1GB. */
-		PT2[i] = i * (2 * 1024 * 1024);
-		PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
-	}
-
-#ifdef DEBUG
-	printf("Start @ %#llx ...\n", addr);
-#endif
-
-	cb_copyin(NULL, stack, 0x1000, sizeof(stack));
-	cb_copyin(NULL, PT4, 0x2000, sizeof(PT4));
-	cb_copyin(NULL, PT3, 0x3000, sizeof(PT3));
-	cb_copyin(NULL, PT2, 0x4000, sizeof(PT2));
-	cb_setreg(NULL, 4, 0x1000);
-
-	cb_setmsr(NULL, MSR_EFER, EFER_LMA | EFER_LME);
-	cb_setcr(NULL, 4, CR4_PAE | CR4_VMXE);
-	cb_setcr(NULL, 3, 0x2000);
-	cb_setcr(NULL, 0, CR0_PG | CR0_PE | CR0_NE);
-
-	setup_stand_gdt(gdtr);
-	cb_copyin(NULL, gdtr, 0x5000, sizeof(gdtr));
-        cb_setgdt(NULL, 0x5000, sizeof(gdtr));
-
-	cb_exec(NULL, addr);
-	return (0);
-}
-
-static int
-freebsd_load(void)
-{
-	void *h;
-	void (*func)(struct loader_callbacks *, void *, int, int);
-
-	h = dlopen("/boot/userboot.so", RTLD_LOCAL);
-	if (!h) {
-		printf("%s\n", dlerror());
-		return (1);
-	}
-	func = dlsym(h, "loader_main");
-	if (!func) {
-		printf("%s\n", dlerror());
-		return (1);
-	}
-
-	func(&cb, NULL, USERBOOT_VERSION_3, disk_fd >= 0);
-	return (0);
-}
-
 int
 main(int argc, char** argv)
 {
+	void *h;
+	void (*func)(struct loader_callbacks *, void *, int, int);
 	uint64_t mem_size;
 	int opt, error;
 	uint64_t stand_addr;
@@ -712,7 +576,7 @@ main(int argc, char** argv)
 	mem_size = 256 * MB;
 	disk_image = NULL;
 
-	while ((opt = getopt(argc, argv, "d:h:m:S:I:")) != -1) {
+	while ((opt = getopt(argc, argv, "d:h:m:S:")) != -1) {
 		switch (opt) {
 		case 'd':
 			disk_image = optarg;
@@ -744,7 +608,7 @@ main(int argc, char** argv)
 			
 			break;
 		}
-		
+
 		case '?':
 			usage();
 		}
@@ -782,16 +646,24 @@ main(int argc, char** argv)
 	term.c_lflag &= ~(ICANON|ECHO);
 	term.c_iflag &= ~ICRNL;
 	tcsetattr(0, TCSAFLUSH, &term);
+	if (stand_image) {
+		if (stand_load(&cb, stand_image, stand_addr))
+			exit(1);
+		exit(0);
+	}
+	h = dlopen("/boot/userboot.so", RTLD_LOCAL);
+	if (!h) {
+		printf("%s\n", dlerror());
+		return (1);
+	}
+	func = dlsym(h, "loader_main");
+	if (!func) {
+		printf("%s\n", dlerror());
+		return (1);
+	}
 
 	if (disk_image) {
 		disk_fd = open(disk_image, O_RDONLY);
 	}
-
-	if (stand_image) {
-		if (stand_load(stand_image, stand_addr))
-			exit(1);
-	}else{
-		if (freebsd_load())
-			exit(1);
-	}
+	func(&cb, NULL, USERBOOT_VERSION_3, disk_fd >= 0);
 }

Added: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/standalone.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/standalone.c	Sun Aug  4 19:17:06 2013	(r253935)
@@ -0,0 +1,192 @@
+/*-
+ * Copyright (c) 2011 NetApp, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c 253922 2013-08-04 01:22:26Z syuu $
+ */
+
+/*-
+ * Copyright (c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c 253922 2013-08-04 01:22:26Z syuu $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: user/syuu/bhyve_standalone_guest/usr.sbin/bhyveload/bhyveload.c 253922 2013-08-04 01:22:26Z syuu $");
+
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <machine/specialreg.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "userboot.h"
+
+#define MSR_EFER        0xc0000080
+#define CR4_PAE         0x00000020
+#define CR4_PSE         0x00000010
+#define CR0_PG          0x80000000
+#define	CR0_PE		0x00000001	/* Protected mode Enable */
+#define	CR0_NE		0x00000020	/* Numeric Error enable (EX16 vs IRQ13) */
+
+#define PG_V	0x001
+#define PG_RW	0x002
+#define PG_U	0x004
+#define PG_PS	0x080
+
+typedef u_int64_t p4_entry_t;
+typedef u_int64_t p3_entry_t;
+typedef u_int64_t p2_entry_t;
+
+#define	GUEST_NULL_SEL		0
+#define	GUEST_CODE_SEL		1
+#define	GUEST_DATA_SEL		2
+#define	GUEST_GDTR_LIMIT	(3 * 8 - 1)
+
+int stand_load(struct loader_callbacks *cb, char *image, uint64_t addr);
+
+static void
+setup_stand_gdt(uint64_t *gdtr)
+{
+	gdtr[GUEST_NULL_SEL] = 0;
+	gdtr[GUEST_CODE_SEL] = 0x0020980000000000;
+	gdtr[GUEST_DATA_SEL] = 0x0000900000000000;
+}
+
+int
+stand_load(struct loader_callbacks *cb, char *image, uint64_t addr)
+{
+	int i;
+	int fd;
+	struct stat sb;
+	char *buf;
+	uint32_t		stack[1024];
+	p4_entry_t		PT4[512];
+	p3_entry_t		PT3[512];
+	p2_entry_t		PT2[512];
+	uint64_t		gdtr[3];
+
+	if ((fd = open(image, O_RDONLY)) < 0) {
+		perror("open");
+		return (1);
+	}
+	if (fstat(fd, &sb)) {
+		perror("fstat");
+		return (1);
+	}
+	buf = alloca(sb.st_size);
+	if (read(fd, buf, sb.st_size) != sb.st_size) {
+		perror("read");
+		return (1);
+	}
+	if (close(fd) < 0) {
+		perror("close");
+		return (1);
+	}
+	if (cb->copyin(NULL, buf, addr, sb.st_size)) {
+		perror("copyin");
+		return (1);
+	}
+
+	bzero(PT4, PAGE_SIZE);
+	bzero(PT3, PAGE_SIZE);
+	bzero(PT2, PAGE_SIZE);
+
+	/*
+	 * Build a scratch stack at physical 0x1000, page tables:
+	 *	PT4 at 0x2000,
+	 *	PT3 at 0x3000,
+	 *	PT2 at 0x4000,
+	 *      gdtr at 0x5000,
+	 */
+
+	/*
+	 * This is kinda brutal, but every single 1GB VM memory segment
+	 * points to the same first 1GB of physical memory.  But it is
+	 * more than adequate.
+	 */
+	for (i = 0; i < 512; i++) {
+		/* Each slot of the level 4 pages points to the same level 3 page */
+		PT4[i] = (p4_entry_t) 0x3000;
+		PT4[i] |= PG_V | PG_RW | PG_U;
+
+		/* Each slot of the level 3 pages points to the same level 2 page */
+		PT3[i] = (p3_entry_t) 0x4000;
+		PT3[i] |= PG_V | PG_RW | PG_U;
+
+		/* The level 2 page slots are mapped with 2MB pages for 1GB. */
+		PT2[i] = i * (2 * 1024 * 1024);
+		PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+	}
+
+#ifdef DEBUG
+	printf("Start @ %#llx ...\n", addr);
+#endif
+
+	cb->copyin(NULL, stack, 0x1000, sizeof(stack));
+	cb->copyin(NULL, PT4, 0x2000, sizeof(PT4));
+	cb->copyin(NULL, PT3, 0x3000, sizeof(PT3));
+	cb->copyin(NULL, PT2, 0x4000, sizeof(PT2));
+	cb->setreg(NULL, 4, 0x1000);
+
+	cb->setmsr(NULL, MSR_EFER, EFER_LMA | EFER_LME);
+	cb->setcr(NULL, 4, CR4_PAE | CR4_VMXE);
+	cb->setcr(NULL, 3, 0x2000);
+	cb->setcr(NULL, 0, CR0_PG | CR0_PE | CR0_NE);
+
+	setup_stand_gdt(gdtr);
+	cb->copyin(NULL, gdtr, 0x5000, sizeof(gdtr));
+        cb->setgdt(NULL, 0x5000, sizeof(gdtr));
+
+	cb->exec(NULL, addr);
+	return (0);
+}
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308041917.r74JH6BZ063779>