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
This commit is contained in:
parent
7c5710dbaf
commit
851d84f1b5
@ -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
|
||||
|
@ -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;
|
||||
int error;
|
||||
|
||||
newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval);
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user