Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 May 2011 21:53:25 +0000 (UTC)
From:      Peter Grehan <grehan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r222105 - in projects/bhyve: sys/amd64/vmm sys/dev/bvm usr.sbin/bhyve
Message-ID:  <201105192153.p4JLrP1f054643@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grehan
Date: Thu May 19 21:53:25 2011
New Revision: 222105
URL: http://svn.freebsd.org/changeset/base/222105

Log:
  Changes to allow the GENERIC+bhye kernel built from this branch to
  run as a 1/2 CPU guest on an 8.1 bhyve host.
  
  bhyve/inout.c
        inout.h
        fbsdrun.c
   - Rather than exiting on accesses to unhandled i/o ports, emulate
     hardware by returning -1 on reads and ignoring writes to unhandled
     ports. Support the previous mode by allowing a 'strict' parameter
     to be set from the command line.
     The 8.1 guest kernel was vastly cut down from GENERIC and had no
     ISA devices. Booting GENERIC exposes a massive amount of random
     touching of i/o ports (hello syscons/vga/atkbdc).
  
  bhyve/consport.c
  dev/bvm/bvm_console.c
   - implement a simplistic signature for the bvm console by returning
     'bv' for an inw on the port. Also, set the priority of the console
     to CN_REMOTE if the signature was returned. This works better in
     an environment where multiple consoles are in the kernel (hello syscons)
  
  bhyve/rtc.c
   - return 0 for the access to RTC_EQUIPMENT (yes, you syscons)
  
  amd64/vmm/x86.c
            x86.h
   - hide a bunch more CPUID leaf 1 bits from the guest to prevent
     cpufreq drivers from probing.
     The next step will be to move CPUID handling completely into
     user-space. This will allow the full spectrum of changes from
     presenting a lowest-common-denominator CPU type/feature set, to
     exposing (almost) everything that the host can support.
  
  Reviewed by:	neel
  Obtained from:	NetApp

Modified:
  projects/bhyve/sys/amd64/vmm/x86.c
  projects/bhyve/sys/amd64/vmm/x86.h
  projects/bhyve/sys/dev/bvm/bvm_console.c
  projects/bhyve/usr.sbin/bhyve/consport.c
  projects/bhyve/usr.sbin/bhyve/fbsdrun.c
  projects/bhyve/usr.sbin/bhyve/inout.c
  projects/bhyve/usr.sbin/bhyve/inout.h
  projects/bhyve/usr.sbin/bhyve/rtc.c

Modified: projects/bhyve/sys/amd64/vmm/x86.c
==============================================================================
--- projects/bhyve/sys/amd64/vmm/x86.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/sys/amd64/vmm/x86.c	Thu May 19 21:53:25 2011	(r222105)
@@ -75,13 +75,19 @@ x86_emulate_cpuid(uint32_t *eax, uint32_
 			regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT);
 
 			/*
-			 * Don't expose VMX capability.
+			 * Don't expose VMX, SpeedStep or TME capability.
 			 * Advertise x2APIC capability.
 			 */
-			regs[2] &= ~CPUID_0000_0001_FEAT0_VMX;
+			regs[2] &= ~(CPUID_0000_0001_FEAT0_VMX | CPUID2_EST |
+				     CPUID2_TM2);
 			regs[2] |= CPUID2_X2APIC;
 
 			/*
+			 * Hide thermal monitoring
+			 */
+			regs[3] &= ~(CPUID_ACPI | CPUID_TM);
+			
+			/*
 			 * Machine check handling is done in the host.
 			 * Hide MTRR capability.
 			 */
@@ -89,6 +95,17 @@ x86_emulate_cpuid(uint32_t *eax, uint32_
 
 			break;
 
+		case CPUID_0000_0006:
+			/*
+			 * Handle the access, but report 0 for
+			 * all options
+			 */
+			regs[0] = 0;
+			regs[1] = 0;
+			regs[2] = 0;
+			regs[3] = 0;
+			break;
+
 		case CPUID_0000_000B:
 			/*
 			 * XXXSMP fixme

Modified: projects/bhyve/sys/amd64/vmm/x86.h
==============================================================================
--- projects/bhyve/sys/amd64/vmm/x86.h	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/sys/amd64/vmm/x86.h	Thu May 19 21:53:25 2011	(r222105)
@@ -34,6 +34,7 @@
 #define CPUID_0000_0002 (0x2)
 #define CPUID_0000_0003 (0x3)
 #define CPUID_0000_0004 (0x4)
+#define CPUID_0000_0006 (0x6)
 #define	CPUID_0000_000A	(0xA)
 #define	CPUID_0000_000B	(0xB)
 #define CPUID_8000_0000	(0x80000000)

Modified: projects/bhyve/sys/dev/bvm/bvm_console.c
==============================================================================
--- projects/bhyve/sys/dev/bvm/bvm_console.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/sys/dev/bvm/bvm_console.c	Thu May 19 21:53:25 2011	(r222105)
@@ -70,6 +70,8 @@ static int			alt_break_state;
 #define	BVM_CONS_PORT	0x220
 static int bvm_cons_port = BVM_CONS_PORT;
 
+#define BVM_CONS_SIG	('b' << 8 | 'v')
+
 static void	bvm_timeout(void *);
 
 static cn_probe_t	bvm_cnprobe;
@@ -171,14 +173,16 @@ bvm_cnprobe(struct consdev *cp)
 	int disabled, port;
 
 	disabled = 0;
+	cp->cn_pri = CN_DEAD;
+
 	resource_int_value("bvmconsole", 0, "disabled", &disabled);
-	if (disabled)
-		cp->cn_pri = CN_DEAD;
-	else
-		cp->cn_pri = CN_NORMAL;
+	if (!disabled) {
+		if (resource_int_value("bvmconsole", 0, "port", &port) == 0)
+			bvm_cons_port = port;
 
-	if (resource_int_value("bvmconsole", 0, "port", &port) == 0)
-		bvm_cons_port = port;
+		if (inw(bvm_cons_port) == BVM_CONS_SIG)
+			cp->cn_pri = CN_REMOTE;
+	}
 }
 
 static void

Modified: projects/bhyve/usr.sbin/bhyve/consport.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/consport.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/usr.sbin/bhyve/consport.c	Thu May 19 21:53:25 2011	(r222105)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include "inout.h"
 
 #define	BVM_CONSOLE_PORT	0x220
+#define	BVM_CONS_SIG		('b' << 8 | 'v')
 
 static struct termios tio_orig, tio_new;
 
@@ -103,6 +104,11 @@ console_handler(struct vmctx *ctx, int v
 {
 	static int opened;
 
+	if (bytes == 2 && in) {
+		*eax = BVM_CONS_SIG;
+		return (0);
+	}
+
 	if (bytes != 4)
 		return (-1);
 

Modified: projects/bhyve/usr.sbin/bhyve/fbsdrun.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/fbsdrun.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/usr.sbin/bhyve/fbsdrun.c	Thu May 19 21:53:25 2011	(r222105)
@@ -85,6 +85,8 @@ static int guest_vmexit_on_hlt, guest_vm
 
 static int foundcpus;
 
+static int strictio;
+
 static char *lomem_addr;
 static char *himem_addr;
 
@@ -122,7 +124,7 @@ usage(int code)
 {
 
         fprintf(stderr,
-                "Usage: %s [-hBHP][-g <gdb port>][-z <hz>][-s <pci>][-p pincpu]"
+                "Usage: %s [-ehBHP][-g <gdb port>][-z <hz>][-s <pci>][-p pincpu]"
 		"[-n <pci>][-m lowmem][-M highmem] <vm>\n"
 		"       -g: gdb port (default is %d and 0 means don't open)\n"
 		"       -c: # cpus (default 1)\n"
@@ -130,6 +132,7 @@ usage(int code)
 		"       -B: inject breakpoint exception on vm entry\n"
 		"       -H: vmexit from the guest on hlt\n"
 		"       -P: vmexit from the guest on pause\n"
+		"	-e: exit on unhandled i/o access\n"
 		"       -h: help\n"
 		"       -z: guest hz (default is %d)\n"
 		"       -s: <slot,driver,configinfo> PCI slot config\n"
@@ -300,7 +303,7 @@ vmexit_inout(struct vmctx *ctx, struct v
         if (out && port == GUEST_NIO_PORT)
                 return (vmexit_handle_notify(ctx, vme, pvcpu, eax));
 
-	error = emulate_inout(ctx, vcpu, in, port, bytes, &eax);
+	error = emulate_inout(ctx, vcpu, in, port, bytes, &eax, strictio);
 	if (error == 0 && in)
 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, eax);
 
@@ -510,7 +513,7 @@ main(int argc, char *argv[])
 	gdb_port = DEFAULT_GDB_PORT;
 	guest_ncpus = 1;
 
-	while ((c = getopt(argc, argv, "hBHPxp:g:c:z:s:n:m:M:")) != -1) {
+	while ((c = getopt(argc, argv, "ehBHPxp:g:c:z:s:n:m:M:")) != -1) {
 		switch (c) {
 		case 'B':
 			inject_bkpt = 1;
@@ -551,6 +554,9 @@ main(int argc, char *argv[])
 		case 'P':
 			guest_vmexit_on_pause = 1;
 			break;
+		case 'e':
+			strictio = 1;
+			break;
 		case 'h':
 			usage(0);			
 		default:

Modified: projects/bhyve/usr.sbin/bhyve/inout.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/inout.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/usr.sbin/bhyve/inout.c	Thu May 19 21:53:25 2011	(r222105)
@@ -48,9 +48,30 @@ static struct {
 	void		*arg;
 } inout_handlers[MAX_IOPORTS];
 
+static int
+default_inout(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
+              uint32_t *eax, void *arg)
+{
+        if (in) {
+                switch (bytes) {
+                case 4:
+                        *eax = 0xffffffff;
+                        break;
+                case 2:
+                        *eax = 0xffff;
+                        break;
+                case 1:
+                        *eax = 0xff;
+                        break;
+                }
+        }
+        
+        return (0);
+}
+
 int
 emulate_inout(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
-	      uint32_t *eax)
+	      uint32_t *eax, int strict)
 {
 	int flags;
 	inout_func_t handler;
@@ -58,7 +79,9 @@ emulate_inout(struct vmctx *ctx, int vcp
 
 	assert(port < MAX_IOPORTS);
 
-	if ((handler = inout_handlers[port].handler) == NULL)
+	handler = inout_handlers[port].handler;
+
+	if (strict && handler == default_inout)
 		return (-1);
 
 	flags = inout_handlers[port].flags;
@@ -74,7 +97,21 @@ void
 init_inout(void)
 {
 	struct inout_port **iopp, *iop;
+	int i;
+
+	/*
+	 * Set up the default handler for all ports
+	 */
+	for (i = 0; i < MAX_IOPORTS; i++) {
+		inout_handlers[i].name = "default";
+		inout_handlers[i].flags = IOPORT_F_IN | IOPORT_F_OUT;
+		inout_handlers[i].handler = default_inout;
+		inout_handlers[i].arg = NULL;
+	}
 
+	/*
+	 * Overwrite with specified handlers
+	 */
 	SET_FOREACH(iopp, inout_port_set) {
 		iop = *iopp;
 		assert(iop->port < MAX_IOPORTS);

Modified: projects/bhyve/usr.sbin/bhyve/inout.h
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/inout.h	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/usr.sbin/bhyve/inout.h	Thu May 19 21:53:25 2011	(r222105)
@@ -59,7 +59,7 @@ struct inout_port {
 	
 void	init_inout(void);
 int	emulate_inout(struct vmctx *, int vcpu, int in, int port, int bytes,
-		      uint32_t *eax);
+		      uint32_t *eax, int strict);
 int	register_inout(struct inout_port *iop);
 
 #endif	/* _INOUT_H_ */

Modified: projects/bhyve/usr.sbin/bhyve/rtc.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/rtc.c	Thu May 19 21:16:46 2011	(r222104)
+++ projects/bhyve/usr.sbin/bhyve/rtc.c	Thu May 19 21:53:25 2011	(r222105)
@@ -68,6 +68,8 @@ __FBSDID("$FreeBSD$");
 
 #define RTC_RSTCODE	0x0f
 
+#define	RTC_EQUIPMENT	0x14
+
 static int addr;
 
 /* XXX initialize these to default values as they would be from BIOS */
@@ -136,6 +138,7 @@ rtc_addr_handler(struct vmctx *ctx, int 
 	case RTC_STATUSD:
 	case RTC_DIAG:
 	case RTC_RSTCODE:
+	case RTC_EQUIPMENT:
 		break;
 	default:
 		return (-1);
@@ -228,6 +231,9 @@ rtc_data_handler(struct vmctx *ctx, int 
 		case RTC_RSTCODE:
 			*eax = rstcode;
 			return (0);
+		case RTC_EQUIPMENT:
+			*eax = 0;
+			return (0);
 		default:
 			return (-1);
 		}



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