svn commit: r279575 - user/marcel/libvdsk/bhyve
Marcel Moolenaar
marcel at FreeBSD.org
Wed Mar 4 02:47:16 UTC 2015
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;
More information about the svn-src-user
mailing list