Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Mar 2015 02:47:14 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r279575 - user/marcel/libvdsk/bhyve
Message-ID:  <201503040247.t242lE4F058098@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Wed Mar  4 02:47:13 2015
New Revision: 279575
URL: https://svnweb.freebsd.org/changeset/base/279575

Log:
  Sync with ^/head

Modified:
  user/marcel/libvdsk/bhyve/bhyve.8
  user/marcel/libvdsk/bhyve/bhyverun.c
  user/marcel/libvdsk/bhyve/bhyverun.h
  user/marcel/libvdsk/bhyve/inout.c
  user/marcel/libvdsk/bhyve/pci_ahci.c
  user/marcel/libvdsk/bhyve/rtc.c
  user/marcel/libvdsk/bhyve/rtc.h
  user/marcel/libvdsk/bhyve/task_switch.c
  user/marcel/libvdsk/bhyve/xmsr.c
Directory Properties:
  user/marcel/libvdsk/bhyve/   (props changed)
  user/marcel/libvdsk/bhyveload/   (props changed)

Modified: user/marcel/libvdsk/bhyve/bhyve.8
==============================================================================
--- user/marcel/libvdsk/bhyve/bhyve.8	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/bhyve.8	Wed Mar  4 02:47:13 2015	(r279575)
@@ -32,7 +32,7 @@
 .Nd "run a guest operating system inside a virtual machine"
 .Sh SYNOPSIS
 .Nm
-.Op Fl abehwxACHPWY
+.Op Fl abehuwxACHPWY
 .Op Fl c Ar numcpus
 .Op Fl g Ar gdbport
 .Op Fl l Ar lpcdev Ns Op , Ns Ar conf
@@ -239,6 +239,8 @@ The host device must have been reserved 
 loader variable as described in
 .Xr vmm 4 .
 .El
+.It Fl u
+RTC keeps UTC time.
 .It Fl U Ar uuid
 Set the universally unique identifier
 .Pq UUID

Modified: user/marcel/libvdsk/bhyve/bhyverun.c
==============================================================================
--- user/marcel/libvdsk/bhyve/bhyverun.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/bhyverun.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -122,7 +122,7 @@ usage(int code)
 {
 
         fprintf(stderr,
-                "Usage: %s [-abehwxACHPWY] [-c vcpus] [-g <gdb port>] [-l <lpc>]\n"
+                "Usage: %s [-abehuwxACHPWY] [-c vcpus] [-g <gdb port>] [-l <lpc>]\n"
 		"       %*s [-m mem] [-p vcpu:hostcpu] [-s <pci>] [-U uuid] <vm>\n"
 		"       -a: local apic is in xAPIC mode (deprecated)\n"
 		"       -A: create ACPI tables\n"
@@ -137,6 +137,7 @@ usage(int code)
 		"       -p: pin 'vcpu' to 'hostcpu'\n"
 		"       -P: vmexit from the guest on pause\n"
 		"       -s: <slot,driver,configinfo> PCI slot config\n"
+		"       -u: RTC keeps UTC time\n"
 		"       -U: uuid\n"
 		"       -w: ignore unimplemented MSRs\n"
 		"       -W: force virtio to use single-vector MSI\n"
@@ -185,20 +186,14 @@ vm_inject_fault(void *arg, int vcpu, int
     int errcode)
 {
 	struct vmctx *ctx;
-	int error;
+	int error, restart_instruction;
 
 	ctx = arg;
-	if (errcode_valid)
-		error = vm_inject_exception2(ctx, vcpu, vector, errcode);
-	else
-		error = vm_inject_exception(ctx, vcpu, vector);
-	assert(error == 0);
+	restart_instruction = 1;
 
-	/*
-	 * Set the instruction length to 0 to ensure that the instruction is
-	 * restarted when the fault handler returns.
-	 */
-	vmexit[vcpu].inst_length = 0;
+	error = vm_inject_exception(ctx, vcpu, vector, errcode_valid, errcode,
+	    restart_instruction);
+	assert(error == 0);
 }
 
 void *
@@ -329,12 +324,6 @@ vmexit_inout(struct vmctx *ctx, struct v
 	}
 
 	error = emulate_inout(ctx, vcpu, vme, strictio);
-	if (!error && in && !string) {
-		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX,
-		    vme->u.inout.eax);
-		assert(error == 0);
-	}
-
 	if (error) {
 		fprintf(stderr, "Unhandled %s%c 0x%04x\n", in ? "in" : "out",
 		    bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port);
@@ -358,7 +347,7 @@ vmexit_rdmsr(struct vmctx *ctx, struct v
 		    vme->u.msr.code, *pvcpu);
 		if (strictmsr) {
 			vm_inject_gp(ctx, *pvcpu);
-			return (VMEXIT_RESTART);
+			return (VMEXIT_CONTINUE);
 		}
 	}
 
@@ -384,7 +373,7 @@ vmexit_wrmsr(struct vmctx *ctx, struct v
 		    vme->u.msr.code, vme->u.msr.wval, *pvcpu);
 		if (strictmsr) {
 			vm_inject_gp(ctx, *pvcpu);
-			return (VMEXIT_RESTART);
+			return (VMEXIT_CONTINUE);
 		}
 	}
 	return (VMEXIT_CONTINUE);
@@ -462,9 +451,11 @@ static int
 vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
 {
 
+	assert(vmexit->inst_length == 0);
+
 	stats.vmexit_bogus++;
 
-	return (VMEXIT_RESTART);
+	return (VMEXIT_CONTINUE);
 }
 
 static int
@@ -494,9 +485,11 @@ static int
 vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
 {
 
+	assert(vmexit->inst_length == 0);
+
 	stats.vmexit_mtrap++;
 
-	return (VMEXIT_RESTART);
+	return (VMEXIT_CONTINUE);
 }
 
 static int
@@ -581,7 +574,7 @@ static vmexit_handler_t handler[VM_EXITC
 };
 
 static void
-vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
+vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
 {
 	int error, rc, prevcpu;
 	enum vm_exitcode exitcode;
@@ -596,8 +589,11 @@ vm_loop(struct vmctx *ctx, int vcpu, uin
 	error = vm_active_cpus(ctx, &active_cpus);
 	assert(CPU_ISSET(vcpu, &active_cpus));
 
+	error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, startrip);
+	assert(error == 0);
+
 	while (1) {
-		error = vm_run(ctx, vcpu, rip, &vmexit[vcpu]);
+		error = vm_run(ctx, vcpu, &vmexit[vcpu]);
 		if (error != 0)
 			break;
 
@@ -614,10 +610,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uin
 
 		switch (rc) {
 		case VMEXIT_CONTINUE:
-                        rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length;
-			break;
-		case VMEXIT_RESTART:
-                        rip = vmexit[vcpu].rip;
 			break;
 		case VMEXIT_ABORT:
 			abort();
@@ -694,6 +686,7 @@ main(int argc, char *argv[])
 {
 	int c, error, gdb_port, err, bvmcons;
 	int dump_guest_memory, max_vcpus, mptgen;
+	int rtc_localtime;
 	struct vmctx *ctx;
 	uint64_t rip;
 	size_t memsize;
@@ -705,8 +698,9 @@ main(int argc, char *argv[])
 	guest_ncpus = 1;
 	memsize = 256 * MB;
 	mptgen = 1;
+	rtc_localtime = 1;
 
-	while ((c = getopt(argc, argv, "abehwxACHIPWYp:g:c:s:m:l:U:")) != -1) {
+	while ((c = getopt(argc, argv, "abehuwxACHIPWYp:g:c:s:m:l:U:")) != -1) {
 		switch (c) {
 		case 'a':
 			x2apic_mode = 0;
@@ -766,6 +760,9 @@ main(int argc, char *argv[])
 		case 'e':
 			strictio = 1;
 			break;
+		case 'u':
+			rtc_localtime = 0;
+			break;
 		case 'U':
 			guest_uuid_str = optarg;
 			break;
@@ -829,7 +826,7 @@ main(int argc, char *argv[])
 	pci_irq_init(ctx);
 	ioapic_init(ctx);
 
-	rtc_init(ctx);
+	rtc_init(ctx, rtc_localtime);
 	sci_init(ctx);
 
 	/*

Modified: user/marcel/libvdsk/bhyve/bhyverun.h
==============================================================================
--- user/marcel/libvdsk/bhyve/bhyverun.h	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/bhyverun.h	Wed Mar  4 02:47:13 2015	(r279575)
@@ -35,9 +35,8 @@
 #define	__CTASSERT(x, y)	typedef char __assert ## y[(x) ? 1 : -1]
 #endif
 
-#define	VMEXIT_CONTINUE		1	/* continue from next instruction */
-#define	VMEXIT_RESTART		2	/* restart current instruction */
-#define	VMEXIT_ABORT		3	/* abort the vm run loop */
+#define	VMEXIT_CONTINUE		(0)
+#define	VMEXIT_ABORT		(-1)
 
 struct vmctx;
 extern int guest_ncpus;

Modified: user/marcel/libvdsk/bhyve/inout.c
==============================================================================
--- user/marcel/libvdsk/bhyve/inout.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/inout.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -104,7 +104,7 @@ int
 emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
 {
 	int addrsize, bytes, flags, in, port, prot, rep;
-	uint32_t val;
+	uint32_t eax, val;
 	inout_func_t handler;
 	void *arg;
 	int error, retval;
@@ -214,16 +214,20 @@ emulate_inout(struct vmctx *ctx, int vcp
 		}
 
 		/* Restart the instruction if more iterations remain */
-		if (retval == 0 && count != 0)
-			vmexit->inst_length = 0;
-	} else {
-		if (!in) {
-			val = vmexit->u.inout.eax & vie_size2mask(bytes);
+		if (retval == 0 && count != 0) {
+			error = vm_restart_instruction(ctx, vcpu);
+			assert(error == 0);
 		}
+	} else {
+		eax = vmexit->u.inout.eax;
+		val = eax & vie_size2mask(bytes);
 		retval = handler(ctx, vcpu, in, port, bytes, &val, arg);
 		if (retval == 0 && in) {
-			vmexit->u.inout.eax &= ~vie_size2mask(bytes);
-			vmexit->u.inout.eax |= val & vie_size2mask(bytes);
+			eax &= ~vie_size2mask(bytes);
+			eax |= val & vie_size2mask(bytes);
+			error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX,
+			    eax);
+			assert(error == 0);
 		}
 	}
 	return (retval);

Modified: user/marcel/libvdsk/bhyve/pci_ahci.c
==============================================================================
--- user/marcel/libvdsk/bhyve/pci_ahci.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/pci_ahci.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -1968,7 +1968,8 @@ pci_ahci_init(struct vmctx *ctx, struct 
 
 open_fail:
 	if (ret) {
-		blockif_close(sc->port[0].bctx);
+		if (sc->port[0].bctx != NULL)
+			blockif_close(sc->port[0].bctx);
 		free(sc);
 	}
 

Modified: user/marcel/libvdsk/bhyve/rtc.c
==============================================================================
--- user/marcel/libvdsk/bhyve/rtc.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/rtc.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -30,10 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
-#include <sys/time.h>
 
-#include <stdio.h>
-#include <string.h>
 #include <time.h>
 #include <assert.h>
 
@@ -41,47 +38,11 @@ __FBSDID("$FreeBSD$");
 #include <vmmapi.h>
 
 #include "acpi.h"
-#include "inout.h"
 #include "pci_lpc.h"
 #include "rtc.h"
 
-#define	IO_RTC	0x70
+#define	IO_RTC		0x70
 
-#define RTC_SEC		0x00	/* seconds */
-#define	RTC_SEC_ALARM	0x01
-#define	RTC_MIN		0x02
-#define	RTC_MIN_ALARM	0x03
-#define	RTC_HRS		0x04
-#define	RTC_HRS_ALARM	0x05
-#define	RTC_WDAY	0x06
-#define	RTC_DAY		0x07
-#define	RTC_MONTH	0x08
-#define	RTC_YEAR	0x09
-#define	RTC_CENTURY	0x32	/* current century */
-
-#define RTC_STATUSA	0xA
-#define  RTCSA_TUP	 0x80	/* time update, don't look now */
-
-#define	RTC_STATUSB	0xB
-#define	 RTCSB_DST	 0x01
-#define	 RTCSB_24HR	 0x02
-#define	 RTCSB_BIN	 0x04	/* 0 = BCD, 1 = Binary */
-#define	 RTCSB_PINTR	 0x40	/* 1 = enable periodic clock interrupt */
-#define	 RTCSB_HALT      0x80	/* stop clock updates */
-
-#define RTC_INTR	0x0c	/* status register C (R) interrupt source */
-
-#define RTC_STATUSD	0x0d	/* status register D (R) Lost Power */
-#define  RTCSD_PWR	 0x80	/* clock power OK */
-
-#define	RTC_NVRAM_START	0x0e
-#define	RTC_NVRAM_END	0x7f
-#define RTC_NVRAM_SZ	(128 - RTC_NVRAM_START)
-#define	nvoff(x)	((x) - RTC_NVRAM_START)
-
-#define	RTC_DIAG	0x0e
-#define RTC_RSTCODE	0x0f
-#define	RTC_EQUIPMENT	0x14
 #define	RTC_LMEM_LSB	0x34
 #define	RTC_LMEM_MSB	0x35
 #define	RTC_HMEM_LSB	0x5b
@@ -92,249 +53,30 @@ __FBSDID("$FreeBSD$");
 #define	m_16MB		(16*1024*1024)
 #define	m_4GB		(4ULL*1024*1024*1024)
 
-static int addr;
-
-static uint8_t rtc_nvram[RTC_NVRAM_SZ];
-
-/* XXX initialize these to default values as they would be from BIOS */
-static uint8_t status_a, status_b;
-
-static struct {
-	uint8_t  hours;
-	uint8_t  mins;
-	uint8_t  secs;
-} rtc_alarm;
-
-static u_char const bin2bcd_data[] = {
-	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
-	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
-	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
-	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
-	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
-};
-#define	bin2bcd(bin)	(bin2bcd_data[bin])
-
-#define	rtcout(val)	((status_b & RTCSB_BIN) ? (val) : bin2bcd((val)))
-
-static void
-timevalfix(struct timeval *t1)
-{
-
-	if (t1->tv_usec < 0) {
-		t1->tv_sec--;
-		t1->tv_usec += 1000000;
-	}
-	if (t1->tv_usec >= 1000000) {
-		t1->tv_sec++;
-		t1->tv_usec -= 1000000;
-	}
-}
-
-static void
-timevalsub(struct timeval *t1, const struct timeval *t2)
-{
-
-	t1->tv_sec -= t2->tv_sec;
-	t1->tv_usec -= t2->tv_usec;
-	timevalfix(t1);
-}
-
-static int
-rtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
-		 uint32_t *eax, void *arg)
-{
-	if (bytes != 1)
-		return (-1);
-
-	if (in) {
-		/* straight read of this register will return 0xFF */
-		*eax = 0xff;
-		return (0);
-	}
-
-	switch (*eax & 0x7f) {
-	case RTC_SEC:
-	case RTC_SEC_ALARM:
-	case RTC_MIN:
-	case RTC_MIN_ALARM:
-	case RTC_HRS:
-	case RTC_HRS_ALARM:
-	case RTC_WDAY:
-	case RTC_DAY:
-	case RTC_MONTH:
-	case RTC_YEAR:
-	case RTC_STATUSA:
-	case RTC_STATUSB:
-	case RTC_INTR:
-	case RTC_STATUSD:
-	case RTC_NVRAM_START ... RTC_NVRAM_END:
-		break;
-	default:
-		return (-1);
-	}
-
-	addr = *eax & 0x7f;
-	return (0);
-}
-
-static int
-rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
-		 uint32_t *eax, void *arg)
+/*
+ * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970
+ */
+static time_t
+rtc_time(struct vmctx *ctx, int use_localtime)
 {
-	int hour;
+	struct tm tm;
 	time_t t;
-	struct timeval cur, delta;
-
-	static struct timeval last;
-	static struct tm tm;
 
-	if (bytes != 1)
-		return (-1);
-
-	gettimeofday(&cur, NULL);
-
-	/*
-	 * Increment the cached time only once per second so we can guarantee
-	 * that the guest has at least one second to read the hour:min:sec
-	 * separately and still get a coherent view of the time.
-	 */
-	delta = cur;
-	timevalsub(&delta, &last);
-	if (delta.tv_sec >= 1 && (status_b & RTCSB_HALT) == 0) {
-		t = cur.tv_sec;
+	time(&t);
+	if (use_localtime) {
 		localtime_r(&t, &tm);
-		last = cur;
-	}
-
-	if (in) {
-		switch (addr) {
-		case RTC_SEC_ALARM:
-			*eax = rtc_alarm.secs;
-			break;
-		case RTC_MIN_ALARM:
-			*eax = rtc_alarm.mins;
-			break;
-		case RTC_HRS_ALARM:
-			*eax = rtc_alarm.hours;
-			break;
-		case RTC_SEC:
-			*eax = rtcout(tm.tm_sec);
-			return (0);
-		case RTC_MIN:
-			*eax = rtcout(tm.tm_min);
-			return (0);
-		case RTC_HRS:
-			if (status_b & RTCSB_24HR)
-				hour = tm.tm_hour;
-			else
-				hour = (tm.tm_hour % 12) + 1;
-			
-			*eax = rtcout(hour);
-
-			/*
-			 * If we are representing time in the 12-hour format
-			 * then set the MSB to indicate PM.
-			 */
-			if ((status_b & RTCSB_24HR) == 0 && tm.tm_hour >= 12)
-				*eax |= 0x80;
-
-			return (0);
-		case RTC_WDAY:
-			*eax = rtcout(tm.tm_wday + 1);
-			return (0);
-		case RTC_DAY:
-			*eax = rtcout(tm.tm_mday);
-			return (0);
-		case RTC_MONTH:
-			*eax = rtcout(tm.tm_mon + 1);
-			return (0);
-		case RTC_YEAR:
-			*eax = rtcout(tm.tm_year % 100);
-			return (0);
-		case RTC_STATUSA:
-			*eax = status_a;
-			return (0);
-		case RTC_STATUSB:
-			*eax = status_b;
-			return (0);
-		case RTC_INTR:
-			*eax = 0;
-			return (0);
-		case RTC_STATUSD:
-			*eax = RTCSD_PWR;
-			return (0);
-		case RTC_NVRAM_START ... RTC_NVRAM_END:
-			*eax = rtc_nvram[addr - RTC_NVRAM_START];
-			return (0);
-		default:
-			return (-1);
-		}
+		t = timegm(&tm);
 	}
-
-	switch (addr) {
-	case RTC_STATUSA:
-		status_a = *eax & ~RTCSA_TUP;
-		break;
-	case RTC_STATUSB:
-		/* XXX not implemented yet XXX */
-		if (*eax & RTCSB_PINTR)
-			return (-1);
-		status_b = *eax;
-		break;
-	case RTC_STATUSD:
-		/* ignore write */
-		break;
-	case RTC_SEC_ALARM:
-		rtc_alarm.secs = *eax;
-		break;
-	case RTC_MIN_ALARM:
-		rtc_alarm.mins = *eax;
-		break;
-	case RTC_HRS_ALARM:
-		rtc_alarm.hours = *eax;
-		break;
-	case RTC_SEC:
-	case RTC_MIN:
-	case RTC_HRS:
-	case RTC_WDAY:
-	case RTC_DAY:
-	case RTC_MONTH:
-	case RTC_YEAR:
-		/*
-		 * Ignore writes to the time of day registers
-		 */
-		break;
-	case RTC_NVRAM_START ... RTC_NVRAM_END:
-		rtc_nvram[addr - RTC_NVRAM_START] = *eax;
-		break;
-	default:
-		return (-1);
-	}
-	return (0);
+	return (t);
 }
 
 void
-rtc_init(struct vmctx *ctx)
+rtc_init(struct vmctx *ctx, int use_localtime)
 {	
-	struct timeval cur;
-	struct tm tm;
 	size_t himem;
 	size_t lomem;
 	int err;
 
-	err = gettimeofday(&cur, NULL);
-	assert(err == 0);
-	(void) localtime_r(&cur.tv_sec, &tm);
-
-	memset(rtc_nvram, 0, sizeof(rtc_nvram));
-
-	rtc_nvram[nvoff(RTC_CENTURY)] = bin2bcd((tm.tm_year + 1900) / 100);
-
 	/* XXX init diag/reset code/equipment/checksum ? */
 
 	/*
@@ -344,17 +86,22 @@ rtc_init(struct vmctx *ctx)
 	 * 0x5b/0x5c/0x5d - 64KB chunks above 4GB
 	 */
 	lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB;
-	rtc_nvram[nvoff(RTC_LMEM_LSB)] = lomem;
-	rtc_nvram[nvoff(RTC_LMEM_MSB)] = lomem >> 8;
+	err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem);
+	assert(err == 0);
+	err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8);
+	assert(err == 0);
 
 	himem = vm_get_highmem_size(ctx) / m_64KB;
-	rtc_nvram[nvoff(RTC_HMEM_LSB)] = himem;
-	rtc_nvram[nvoff(RTC_HMEM_SB)]  = himem >> 8;
-	rtc_nvram[nvoff(RTC_HMEM_MSB)] = himem >> 16;
-}
+	err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem);
+	assert(err == 0);
+	err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8);
+	assert(err == 0);
+	err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16);
+	assert(err == 0);
 
-INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler);
-INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler);
+	err = vm_rtc_settime(ctx, rtc_time(ctx, use_localtime));
+	assert(err == 0);
+}
 
 static void
 rtc_dsdt(void)

Modified: user/marcel/libvdsk/bhyve/rtc.h
==============================================================================
--- user/marcel/libvdsk/bhyve/rtc.h	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/rtc.h	Wed Mar  4 02:47:13 2015	(r279575)
@@ -29,6 +29,6 @@
 #ifndef _RTC_H_
 #define _RTC_H_
 
-void	rtc_init(struct vmctx *ctx);
+void	rtc_init(struct vmctx *ctx, int use_localtime);
 
 #endif /* _RTC_H_ */

Modified: user/marcel/libvdsk/bhyve/task_switch.c
==============================================================================
--- user/marcel/libvdsk/bhyve/task_switch.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/task_switch.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -725,21 +725,11 @@ vmexit_task_switch(struct vmctx *ctx, st
 	assert(paging->cpu_mode == CPU_MODE_PROTECTED);
 
 	/*
-	 * Calculate the %eip to store in the old TSS before modifying the
-	 * 'inst_length'.
+	 * Calculate the instruction pointer to store in the old TSS.
 	 */
 	eip = vmexit->rip + vmexit->inst_length;
 
 	/*
-	 * Set the 'inst_length' to '0'.
-	 *
-	 * If an exception is triggered during emulation of the task switch
-	 * then the exception handler should return to the instruction that
-	 * caused the task switch as opposed to the subsequent instruction.
-	 */
-	vmexit->inst_length = 0;
-
-	/*
 	 * Section 4.6, "Access Rights" in Intel SDM Vol 3.
 	 * The following page table accesses are implicitly supervisor mode:
 	 * - accesses to GDT or LDT to load segment descriptors
@@ -883,8 +873,8 @@ vmexit_task_switch(struct vmctx *ctx, st
 	 * after this point will be handled in the context of the new task and
 	 * the saved instruction pointer will belong to the new task.
 	 */
-	vmexit->rip = newtss.tss_eip;
-	assert(vmexit->inst_length == 0);
+	error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, newtss.tss_eip);
+	assert(error == 0);
 
 	/* Load processor state from new TSS */
 	error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov);

Modified: user/marcel/libvdsk/bhyve/xmsr.c
==============================================================================
--- user/marcel/libvdsk/bhyve/xmsr.c	Wed Mar  4 02:44:21 2015	(r279574)
+++ user/marcel/libvdsk/bhyve/xmsr.c	Wed Mar  4 02:47:13 2015	(r279575)
@@ -188,6 +188,15 @@ emulate_rdmsr(struct vmctx *ctx, int vcp
 			*val = 0;
 			break;
 
+		/*
+		 * OpenBSD guests test bit 0 of this MSR to detect if the
+		 * workaround for erratum 721 is already applied.
+		 * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf
+		 */
+		case 0xC0011029:
+			*val = 1;
+			break;
+
 		default:
 			error = -1;
 			break;



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