summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-04-08 20:40:54 +0000
committerjhb <jhb@FreeBSD.org>2014-04-08 20:40:54 +0000
commit98708b1b491049bf9bbb6bc72386b31dad0db1cf (patch)
tree80ce996e84ecc8c0db232c7d7eadd2dfc3616e57
parent7ec723c6aee5b9bd4d349753507de3cdaff593cc (diff)
downloadFreeBSD-src-98708b1b491049bf9bbb6bc72386b31dad0db1cf.zip
FreeBSD-src-98708b1b491049bf9bbb6bc72386b31dad0db1cf.tar.gz
MFC 259635:
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.
-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 4c4a215..78ec90e 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 6c4df9c..aef3314 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -88,6 +88,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;
@@ -123,7 +124,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"
@@ -138,7 +139,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);
@@ -316,20 +318,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
@@ -583,7 +608,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;
@@ -642,6 +667,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