summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2013-12-19 22:27:28 +0000
committerneel <neel@FreeBSD.org>2013-12-19 22:27:28 +0000
commit5dab6f9ed3816204ff73fd075abfaba1ed5c7673 (patch)
tree81dd8d189453616dbd9a81a4f5e621bb5244b98f /usr.sbin/bhyve
parent86d162fb60a778f9693153d552ce23a379a36131 (diff)
downloadFreeBSD-src-5dab6f9ed3816204ff73fd075abfaba1ed5c7673.zip
FreeBSD-src-5dab6f9ed3816204ff73fd075abfaba1ed5c7673.tar.gz
Add an option to ignore accesses by the guest to unimplemented MSRs.
Also, ignore a couple of SandyBridge uncore PMC MSRs that Centos 6.4 writes to during boot. Reviewed by: grehan
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r--usr.sbin/bhyve/bhyve.84
-rw-r--r--usr.sbin/bhyve/bhyverun.c50
-rw-r--r--usr.sbin/bhyve/xmsr.c17
-rw-r--r--usr.sbin/bhyve/xmsr.h1
4 files changed, 58 insertions, 14 deletions
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
index b83211a..8e817cf 100644
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -32,7 +32,7 @@
.Nd "run a guest operating system inside a virtual machine"
.Sh SYNOPSIS
.Nm
-.Op Fl aehAHPW
+.Op Fl aehwAHPW
.Op Fl c Ar numcpus
.Op Fl g Ar gdbport
.Op Fl p Ar pinnedcpu
@@ -229,6 +229,8 @@ Force
.Nm
to exit when a guest issues an access to an I/O port that is not emulated.
This is intended for debug purposes.
+.It Fl w
+Ignore accesses to unimplemented Model Specific Registers (MSRs). This is intended for debug purposes.
.It Fl h
Print help message and exit.
.It Ar vmname
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
index 0ea2904..7afac49 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -87,6 +87,7 @@ static int guest_vmexit_on_hlt, guest_vmexit_on_pause, disable_x2apic;
static int virtio_msix = 1;
static int strictio;
+static int strictmsr = 1;
static int acpi;
@@ -122,7 +123,7 @@ usage(int code)
{
fprintf(stderr,
- "Usage: %s [-aehAHIPW] [-g <gdb port>] [-s <pci>] [-S <pci>]\n"
+ "Usage: %s [-aehwAHIPW] [-g <gdb port>] [-s <pci>] [-S <pci>]\n"
" %*s [-c vcpus] [-p pincpu] [-m mem] [-l <lpc>] <vm>\n"
" -a: local apic is in XAPIC mode (default is X2APIC)\n"
" -A: create an ACPI table\n"
@@ -137,7 +138,8 @@ usage(int code)
" -s: <slot,driver,configinfo> PCI slot config\n"
" -S: <slot,driver,configinfo> legacy PCI slot config\n"
" -l: LPC device configuration\n"
- " -m: memory size in MB\n",
+ " -m: memory size in MB\n"
+ " -w: ignore unimplemented MSRs\n",
progname, (int)strlen(progname), "");
exit(code);
@@ -310,20 +312,43 @@ vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
static int
vmexit_rdmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
{
- fprintf(stderr, "vm exit rdmsr 0x%x, cpu %d\n", vme->u.msr.code,
- *pvcpu);
- return (VMEXIT_ABORT);
+ uint64_t val;
+ uint32_t eax, edx;
+ int error;
+
+ val = 0;
+ error = emulate_rdmsr(ctx, *pvcpu, vme->u.msr.code, &val);
+ if (error != 0) {
+ fprintf(stderr, "rdmsr to register %#x on vcpu %d\n",
+ vme->u.msr.code, *pvcpu);
+ if (strictmsr)
+ return (VMEXIT_ABORT);
+ }
+
+ eax = val;
+ error = vm_set_register(ctx, *pvcpu, VM_REG_GUEST_RAX, eax);
+ assert(error == 0);
+
+ edx = val >> 32;
+ error = vm_set_register(ctx, *pvcpu, VM_REG_GUEST_RDX, edx);
+ assert(error == 0);
+
+ return (VMEXIT_CONTINUE);
}
static int
vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
{
- int newcpu;
- int retval = VMEXIT_CONTINUE;
-
- newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval);
+ int error;
- return (retval);
+ error = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code, vme->u.msr.wval);
+ if (error != 0) {
+ fprintf(stderr, "wrmsr to register %#x(%#lx) on vcpu %d\n",
+ vme->u.msr.code, vme->u.msr.wval, *pvcpu);
+ if (strictmsr)
+ return (VMEXIT_ABORT);
+ }
+ return (VMEXIT_CONTINUE);
}
static int
@@ -577,7 +602,7 @@ main(int argc, char *argv[])
guest_ncpus = 1;
memsize = 256 * MB;
- while ((c = getopt(argc, argv, "abehAHIPWp:g:c:s:S:m:l:")) != -1) {
+ while ((c = getopt(argc, argv, "abehwAHIPWp:g:c:s:S:m:l:")) != -1) {
switch (c) {
case 'a':
disable_x2apic = 1;
@@ -636,6 +661,9 @@ main(int argc, char *argv[])
case 'e':
strictio = 1;
break;
+ case 'w':
+ strictmsr = 0;
+ break;
case 'W':
virtio_msix = 0;
break;
diff --git a/usr.sbin/bhyve/xmsr.c b/usr.sbin/bhyve/xmsr.c
index 9c05f02..ba94125 100644
--- a/usr.sbin/bhyve/xmsr.c
+++ b/usr.sbin/bhyve/xmsr.c
@@ -43,6 +43,19 @@ int
emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t val)
{
- printf("Unknown WRMSR code %x, val %lx, cpu %d\n", code, val, vcpu);
- exit(1);
+ switch (code) {
+ case 0xd04: /* Sandy Bridge uncore PMC MSRs */
+ case 0xc24:
+ return (0);
+ default:
+ break;
+ }
+ return (-1);
+}
+
+int
+emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t *val)
+{
+
+ return (-1);
}
diff --git a/usr.sbin/bhyve/xmsr.h b/usr.sbin/bhyve/xmsr.h
index 8cebcea..b097cf8 100644
--- a/usr.sbin/bhyve/xmsr.h
+++ b/usr.sbin/bhyve/xmsr.h
@@ -30,5 +30,6 @@
#define _XMSR_H_
int emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t val);
+int emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t *val);
#endif
OpenPOWER on IntegriCloud