Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jan 2013 02:04:42 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r245020 - in projects/bhyve: sys/amd64/amd64 usr.sbin/bhyve
Message-ID:  <201301040204.r0424gXk029942@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Fri Jan  4 02:04:41 2013
New Revision: 245020
URL: http://svnweb.freebsd.org/changeset/base/245020

Log:
  The "unrestricted guest" capability is a feature of Intel VT-x that allows
  the guest to execute real or unpaged protected mode code - bhyve relies on
  this feature to execute the AP bootstrap code.
  
  Get rid of the hack that allowed bhyve to support SMP guests on processors
  that do not have the "unrestricted guest" capability. This hack was entirely
  FreeBSD-specific and would not work with any other guest OS.
  
  Instead, limit the number of vcpus to 1 when executing on processors without
  "unrestricted guest" capability.
  
  Suggested by:	grehan
  Obtained from:	NetApp

Modified:
  projects/bhyve/sys/amd64/amd64/mp_machdep.c
  projects/bhyve/usr.sbin/bhyve/bhyverun.c
  projects/bhyve/usr.sbin/bhyve/spinup_ap.c

Modified: projects/bhyve/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- projects/bhyve/sys/amd64/amd64/mp_machdep.c	Thu Jan  3 23:21:01 2013	(r245019)
+++ projects/bhyve/sys/amd64/amd64/mp_machdep.c	Fri Jan  4 02:04:41 2013	(r245020)
@@ -145,26 +145,6 @@ struct cpu_info {
 int cpu_apic_ids[MAXCPU];
 int apic_cpuids[MAX_APIC_ID + 1];
 
-/*
- * Trampoline for hypervisor direct 64-bit jump.
- *
- *   0  -	signature for guest->host verification
- *   8  -	virtual address of this page
- *  16  -	instruction virtual address
- *  24  -	stack pointer virtual address
- *  32  -	CR3, physical address of kernel page table
- *  40  -	24-byte area for null/code/data GDT entries
- */
-#define MP_V64T_SIG	0xcafebabecafebabeULL
-struct mp_v64tramp {
-	uint64_t	mt_sig;
-	uint64_t	mt_virt;
-	uint64_t	mt_eip;
-	uint64_t	mt_rsp;
-	uint64_t	mt_cr3;
-	uint64_t	mt_gdtr[3];
-};
-
 /* Holds pending bitmap based IPIs per CPU */
 static volatile u_int cpu_ipi_pending[MAXCPU];
 
@@ -967,29 +947,6 @@ start_all_aps(void)
 		bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
 		bootAP = cpu;
 
-		/*
-		 * If running in a VM that doesn't support the unrestricted
-		 * guest 16-bit mode, forget most of the above and create
-		 * the data block that allows the hypervisor to direct-jump
-		 * into 64-bit mode. Copy this over the top of the 16-bit
-		 * bootstrap. The startup-IPI informs the hypervisor which
-		 * physical page this data block lies in. The hypervisor
-		 * will then use the block to initialise register state of
-		 * the AP in an almost identical fashion to how it builds
-		 * the BSP initial register state.
-		 */
-		if (testenv("hw.use_bvm_mptramp")) {
-			struct mp_v64tramp mv;
-
-			bzero(&mv, sizeof(mv));
-			mv.mt_sig = MP_V64T_SIG;
-			mv.mt_virt = (uint64_t) va;
-			mv.mt_eip = (uint64_t) init_secondary;
-			mv.mt_rsp = (uint64_t) bootSTK;
-			mv.mt_cr3 = KPML4phys;
-			bcopy(&mv, (void *) va, sizeof(mv));
-		}
-
 		/* attempt to start the Application Processor */
 		if (!start_ap(apic_id)) {
 			/* restore the warmstart vector */

Modified: projects/bhyve/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/bhyverun.c	Thu Jan  3 23:21:01 2013	(r245019)
+++ projects/bhyve/usr.sbin/bhyve/bhyverun.c	Fri Jan  4 02:04:41 2013	(r245020)
@@ -573,11 +573,28 @@ vm_loop(struct vmctx *ctx, int vcpu, uin
 	fprintf(stderr, "vm_run error %d, errno %d\n", error, errno);
 }
 
+static int
+num_vcpus_allowed(struct vmctx *ctx)
+{
+	int tmp, error;
+
+	error = vm_get_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, &tmp);
+
+	/*
+	 * The guest is allowed to spinup more than one processor only if the
+	 * UNRESTRICTED_GUEST capability is available.
+	 */
+	if (error == 0)
+		return (VM_MAXCPU);
+	else
+		return (1);
+}
 
 int
 main(int argc, char *argv[])
 {
 	int c, error, gdb_port, inject_bkpt, tmp, err, ioapic, bvmcons;
+	int max_vcpus;
 	struct vmctx *ctx;
 	uint64_t rip;
 
@@ -660,12 +677,6 @@ main(int argc, char *argv[])
 	if (guest_ncpus <= 1)
 		guest_vcpu_mux = 0;
 
-	if (guest_ncpus > VM_MAXCPU) {
-		fprintf(stderr, "%d vCPUs requested, max %d\n",
-		    guest_ncpus, VM_MAXCPU);
-		exit(1);
-	}
-
 	/* vmexit on hlt if guest is muxed */
 	if (guest_vcpu_mux) {
 		guest_vmexit_on_hlt = 1;
@@ -680,6 +691,13 @@ main(int argc, char *argv[])
 		exit(1);
 	}
 
+	max_vcpus = num_vcpus_allowed(ctx);
+	if (guest_ncpus > max_vcpus) {
+		fprintf(stderr, "%d vCPUs requested but only %d available\n",
+			guest_ncpus, max_vcpus);
+		exit(1);
+	}
+
 	if (fbsdrun_vmexit_on_hlt()) {
 		err = vm_get_capability(ctx, BSP, VM_CAP_HALT_EXIT, &tmp);
 		if (err < 0) {

Modified: projects/bhyve/usr.sbin/bhyve/spinup_ap.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/spinup_ap.c	Thu Jan  3 23:21:01 2013	(r245019)
+++ projects/bhyve/usr.sbin/bhyve/spinup_ap.c	Fri Jan  4 02:04:41 2013	(r245020)
@@ -42,26 +42,6 @@ __FBSDID("$FreeBSD$");
 #include "bhyverun.h"
 #include "spinup_ap.h"
 
-/*
- * Trampoline for hypervisor direct 64-bit jump.
- *
- *   0  - signature for guest->host verification
- *   8  - kernel virtual address of trampoline
- *  16  - instruction virtual address
- *  24  - stack pointer virtual address
- *  32  - CR3, physical address of kernel page table
- *  40  - 24-byte area for null/code/data GDT entries
- */
-#define MP_V64T_SIG	0xcafebabecafebabeULL
-struct mp_v64tramp {
-	uint64_t	mt_sig;
-	uint64_t	mt_virt;
-	uint64_t	mt_eip;
-	uint64_t	mt_rsp;
-	uint64_t	mt_cr3;
-	uint64_t	mt_gdtr[3];
-};
-
 static void
 spinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t *rip)
 {
@@ -94,46 +74,6 @@ spinup_ap_realmode(struct vmctx *ctx, in
 	assert(error == 0);
 }
 
-static void
-spinup_ap_direct64(struct vmctx *ctx, int newcpu, uint64_t *rip)
-{
-	struct mp_v64tramp *mvt;
-	char *errstr;
-	int error;
-	uint64_t gdtbase;
-
-	mvt = paddr_guest2host(*rip);
-
-	assert(mvt->mt_sig == MP_V64T_SIG);
-
-	/*
-	 * Set up the 3-entry GDT using memory supplied in the
-	 * guest's trampoline structure.
-	 */
-	vm_setup_freebsd_gdt(mvt->mt_gdtr);
-
-#define  CHECK_ERROR(msg) \
-	if (error != 0) { \
-		errstr = msg; \
-		goto err_exit; \
-	}
-
-        /* entry point */
-	*rip = mvt->mt_eip;
-
-	/* Get the guest virtual address of the GDT */
-        gdtbase = mvt->mt_virt + __offsetof(struct mp_v64tramp, mt_gdtr);
-
-	error = vm_setup_freebsd_registers(ctx, newcpu, mvt->mt_eip,
-					   mvt->mt_cr3, gdtbase, mvt->mt_rsp);
-	CHECK_ERROR("vm_setup_freebsd_registers");
-
-	return;
-err_exit:
-	printf("spinup_ap_direct64: machine state error: %s", errstr);
-	exit(1);
-}
-
 int
 spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip)
 {
@@ -163,22 +103,15 @@ spinup_ap(struct vmctx *ctx, int vcpu, i
 	assert(error == 0);
 
 	/*
-	 * There are 2 startup modes possible here:
-	 *  - if the CPU supports 'unrestricted guest' mode, the spinup can
-	 *    set up the processor state in power-on 16-bit mode, with the CS:IP
-	 *    init'd to the specified low-mem 4K page.
-	 *  - if the guest has requested a 64-bit trampoline in the low-mem 4K
-	 *    page by placing in the specified signature, set up the register
-	 *    state using register state in the signature. Note that this
-	 *    requires accessing guest physical memory to read the signature
-	 *    while 'unrestricted mode' does not.
+	 * Enable the 'unrestricted guest' mode for 'newcpu'.
+	 *
+	 * Set up the processor state in power-on 16-bit mode, with the CS:IP
+	 * init'd to the specified low-mem 4K page.
 	 */
 	error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1);
-	if (error) {
-		spinup_ap_direct64(ctx, newcpu, &rip);
-	} else {
-		spinup_ap_realmode(ctx, newcpu, &rip);
-	}
+	assert(error == 0);
+
+	spinup_ap_realmode(ctx, newcpu, &rip);
 
 	fbsdrun_addcpu(ctx, newcpu, rip);
 



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