Remove obsolete cmd-line options and code associated with
these. The mux-vcpus option may return at some point, given it's utility in finding bhyve (and FreeBSD) bugs. Approved by: re@ (blanket) Discussed with: neel@
This commit is contained in:
parent
3a2092bad0
commit
94c3b3bffc
@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <pthread_np.h>
|
#include <pthread_np.h>
|
||||||
|
|
||||||
@ -61,9 +60,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "spinup_ap.h"
|
#include "spinup_ap.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
|
||||||
#define DEFAULT_GUEST_HZ 100
|
|
||||||
#define DEFAULT_GUEST_TSLICE 200
|
|
||||||
|
|
||||||
#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */
|
#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */
|
||||||
|
|
||||||
#define VMEXIT_SWITCH 0 /* force vcpu switch in mux mode */
|
#define VMEXIT_SWITCH 0 /* force vcpu switch in mux mode */
|
||||||
@ -77,14 +73,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu);
|
typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu);
|
||||||
|
|
||||||
int guest_tslice = DEFAULT_GUEST_TSLICE;
|
|
||||||
int guest_hz = DEFAULT_GUEST_HZ;
|
|
||||||
char *vmname;
|
char *vmname;
|
||||||
|
|
||||||
int guest_ncpus;
|
int guest_ncpus;
|
||||||
|
|
||||||
static int pincpu = -1;
|
static int pincpu = -1;
|
||||||
static int guest_vcpu_mux;
|
|
||||||
static int guest_vmexit_on_hlt, guest_vmexit_on_pause, disable_x2apic;
|
static int guest_vmexit_on_hlt, guest_vmexit_on_pause, disable_x2apic;
|
||||||
|
|
||||||
static int foundcpus;
|
static int foundcpus;
|
||||||
@ -102,7 +95,7 @@ static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip);
|
|||||||
|
|
||||||
struct vm_exit vmexit[VM_MAXCPU];
|
struct vm_exit vmexit[VM_MAXCPU];
|
||||||
|
|
||||||
struct fbsdstats {
|
struct bhyvestats {
|
||||||
uint64_t vmexit_bogus;
|
uint64_t vmexit_bogus;
|
||||||
uint64_t vmexit_bogus_switch;
|
uint64_t vmexit_bogus_switch;
|
||||||
uint64_t vmexit_hlt;
|
uint64_t vmexit_hlt;
|
||||||
@ -125,28 +118,24 @@ usage(int code)
|
|||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [-aehABHIP][-g <gdb port>][-z <hz>][-s <pci>]"
|
"Usage: %s [-aehAHIP][-g <gdb port>][-s <pci>][-S <pci>]"
|
||||||
"[-S <pci>][-p pincpu][-n <pci>][-m lowmem][-M highmem]"
|
"[-c vcpus][-p pincpu][-m mem]"
|
||||||
" <vmname>\n"
|
" <vmname>\n"
|
||||||
" -a: local apic is in XAPIC mode (default is X2APIC)\n"
|
" -a: local apic is in XAPIC mode (default is X2APIC)\n"
|
||||||
" -A: create an ACPI table\n"
|
" -A: create an ACPI table\n"
|
||||||
" -g: gdb port (default is %d and 0 means don't open)\n"
|
" -g: gdb port (default is %d and 0 means don't open)\n"
|
||||||
" -c: # cpus (default 1)\n"
|
" -c: # cpus (default 1)\n"
|
||||||
" -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
|
" -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
|
||||||
" -B: inject breakpoint exception on vm entry\n"
|
|
||||||
" -H: vmexit from the guest on hlt\n"
|
" -H: vmexit from the guest on hlt\n"
|
||||||
" -I: present an ioapic to the guest\n"
|
" -I: present an ioapic to the guest\n"
|
||||||
" -P: vmexit from the guest on pause\n"
|
" -P: vmexit from the guest on pause\n"
|
||||||
" -e: exit on unhandled i/o access\n"
|
" -e: exit on unhandled i/o access\n"
|
||||||
" -h: help\n"
|
" -h: help\n"
|
||||||
" -z: guest hz (default is %d)\n"
|
|
||||||
" -s: <slot,driver,configinfo> PCI slot config\n"
|
" -s: <slot,driver,configinfo> PCI slot config\n"
|
||||||
" -S: <slot,driver,configinfo> legacy PCI slot config\n"
|
" -S: <slot,driver,configinfo> legacy PCI slot config\n"
|
||||||
" -m: memory size in MB\n"
|
" -m: memory size in MB\n",
|
||||||
" -x: mux vcpus to 1 hcpu\n"
|
progname, DEFAULT_GDB_PORT);
|
||||||
" -t: mux vcpu timeslice hz (default %d)\n",
|
|
||||||
progname, DEFAULT_GDB_PORT, DEFAULT_GUEST_HZ,
|
|
||||||
DEFAULT_GUEST_TSLICE);
|
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,13 +167,6 @@ fbsdrun_vmexit_on_hlt(void)
|
|||||||
return (guest_vmexit_on_hlt);
|
return (guest_vmexit_on_hlt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
fbsdrun_muxed(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (guest_vcpu_mux);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
fbsdrun_start_thread(void *param)
|
fbsdrun_start_thread(void *param)
|
||||||
{
|
{
|
||||||
@ -226,7 +208,7 @@ fbsdrun_addcpu(struct vmctx *ctx, int vcpu, uint64_t rip)
|
|||||||
vmexit[vcpu].rip = rip;
|
vmexit[vcpu].rip = rip;
|
||||||
vmexit[vcpu].inst_length = 0;
|
vmexit[vcpu].inst_length = 0;
|
||||||
|
|
||||||
if (vcpu == BSP || !guest_vcpu_mux){
|
if (vcpu == BSP) {
|
||||||
mt_vmm_info[vcpu].mt_ctx = ctx;
|
mt_vmm_info[vcpu].mt_ctx = ctx;
|
||||||
mt_vmm_info[vcpu].mt_vcpu = vcpu;
|
mt_vmm_info[vcpu].mt_vcpu = vcpu;
|
||||||
|
|
||||||
@ -264,17 +246,10 @@ static int
|
|||||||
vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu,
|
vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu,
|
||||||
uint32_t eax)
|
uint32_t eax)
|
||||||
{
|
{
|
||||||
#if PG_DEBUG /* put all types of debug here */
|
#if BHYVE_DEBUG
|
||||||
if (eax == 0) {
|
/*
|
||||||
pause_noswitch = 1;
|
* put guest-driven debug here
|
||||||
} else if (eax == 1) {
|
*/
|
||||||
pause_noswitch = 0;
|
|
||||||
} else {
|
|
||||||
pause_noswitch = 0;
|
|
||||||
if (eax == 5) {
|
|
||||||
vm_set_capability(ctx, *pvcpu, VM_CAP_MTRAP_EXIT, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return (VMEXIT_CONTINUE);
|
return (VMEXIT_CONTINUE);
|
||||||
}
|
}
|
||||||
@ -337,11 +312,6 @@ vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
|
|||||||
|
|
||||||
newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval);
|
newcpu = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code,vme->u.msr.wval);
|
||||||
|
|
||||||
if (guest_vcpu_mux && *pvcpu != newcpu) {
|
|
||||||
retval = VMEXIT_SWITCH;
|
|
||||||
*pvcpu = newcpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,11 +324,6 @@ vmexit_spinup_ap(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
|
|||||||
newcpu = spinup_ap(ctx, *pvcpu,
|
newcpu = spinup_ap(ctx, *pvcpu,
|
||||||
vme->u.spinup_ap.vcpu, vme->u.spinup_ap.rip);
|
vme->u.spinup_ap.vcpu, vme->u.spinup_ap.rip);
|
||||||
|
|
||||||
if (guest_vcpu_mux && *pvcpu != newcpu) {
|
|
||||||
retval = VMEXIT_SWITCH;
|
|
||||||
*pvcpu = newcpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,58 +343,42 @@ vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
|||||||
return (VMEXIT_ABORT);
|
return (VMEXIT_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bogus_noswitch = 1;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||||
{
|
{
|
||||||
|
|
||||||
stats.vmexit_bogus++;
|
stats.vmexit_bogus++;
|
||||||
|
|
||||||
if (!guest_vcpu_mux || guest_ncpus == 1 || bogus_noswitch) {
|
return (VMEXIT_RESTART);
|
||||||
return (VMEXIT_RESTART);
|
|
||||||
} else {
|
|
||||||
stats.vmexit_bogus_switch++;
|
|
||||||
vmexit->inst_length = 0;
|
|
||||||
*pvcpu = -1;
|
|
||||||
return (VMEXIT_SWITCH);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||||
{
|
{
|
||||||
stats.vmexit_hlt++;
|
|
||||||
if (fbsdrun_muxed()) {
|
|
||||||
*pvcpu = -1;
|
|
||||||
return (VMEXIT_SWITCH);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Just continue execution with the next instruction. We use
|
|
||||||
* the HLT VM exit as a way to be friendly with the host
|
|
||||||
* scheduler.
|
|
||||||
*/
|
|
||||||
return (VMEXIT_CONTINUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pause_noswitch;
|
stats.vmexit_hlt++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just continue execution with the next instruction. We use
|
||||||
|
* the HLT VM exit as a way to be friendly with the host
|
||||||
|
* scheduler.
|
||||||
|
*/
|
||||||
|
return (VMEXIT_CONTINUE);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||||
{
|
{
|
||||||
|
|
||||||
stats.vmexit_pause++;
|
stats.vmexit_pause++;
|
||||||
|
|
||||||
if (fbsdrun_muxed() && !pause_noswitch) {
|
return (VMEXIT_CONTINUE);
|
||||||
*pvcpu = -1;
|
|
||||||
return (VMEXIT_SWITCH);
|
|
||||||
} else {
|
|
||||||
return (VMEXIT_CONTINUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
||||||
{
|
{
|
||||||
|
|
||||||
stats.vmexit_mtrap++;
|
stats.vmexit_mtrap++;
|
||||||
|
|
||||||
return (VMEXIT_RESTART);
|
return (VMEXIT_RESTART);
|
||||||
@ -460,39 +409,6 @@ vmexit_paging(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu)
|
|||||||
return (VMEXIT_CONTINUE);
|
return (VMEXIT_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sigalrm(int sig)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
setup_timeslice(void)
|
|
||||||
{
|
|
||||||
struct sigaction sa;
|
|
||||||
struct itimerval itv;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup a realtime timer to generate a SIGALRM at a
|
|
||||||
* frequency of 'guest_tslice' ticks per second.
|
|
||||||
*/
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
sa.sa_handler = sigalrm;
|
|
||||||
|
|
||||||
error = sigaction(SIGALRM, &sa, NULL);
|
|
||||||
assert(error == 0);
|
|
||||||
|
|
||||||
itv.it_interval.tv_sec = 0;
|
|
||||||
itv.it_interval.tv_usec = 1000000 / guest_tslice;
|
|
||||||
itv.it_value.tv_sec = 0;
|
|
||||||
itv.it_value.tv_usec = 1000000 / guest_tslice;
|
|
||||||
|
|
||||||
error = setitimer(ITIMER_REAL, &itv, NULL);
|
|
||||||
assert(error == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
|
static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
|
||||||
[VM_EXITCODE_INOUT] = vmexit_inout,
|
[VM_EXITCODE_INOUT] = vmexit_inout,
|
||||||
[VM_EXITCODE_VMX] = vmexit_vmx,
|
[VM_EXITCODE_VMX] = vmexit_vmx,
|
||||||
@ -511,9 +427,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
|
|||||||
int error, rc, prevcpu;
|
int error, rc, prevcpu;
|
||||||
enum vm_exitcode exitcode;
|
enum vm_exitcode exitcode;
|
||||||
|
|
||||||
if (guest_vcpu_mux)
|
|
||||||
setup_timeslice();
|
|
||||||
|
|
||||||
if (pincpu >= 0) {
|
if (pincpu >= 0) {
|
||||||
CPU_ZERO(&mask);
|
CPU_ZERO(&mask);
|
||||||
CPU_SET(pincpu + vcpu, &mask);
|
CPU_SET(pincpu + vcpu, &mask);
|
||||||
@ -550,15 +463,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
|
|||||||
rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu);
|
rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu);
|
||||||
|
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case VMEXIT_SWITCH:
|
|
||||||
assert(guest_vcpu_mux);
|
|
||||||
if (vcpu == -1) {
|
|
||||||
stats.cpu_switch_rotate++;
|
|
||||||
vcpu = fbsdrun_get_next_cpu(prevcpu);
|
|
||||||
} else {
|
|
||||||
stats.cpu_switch_direct++;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case VMEXIT_CONTINUE:
|
case VMEXIT_CONTINUE:
|
||||||
rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length;
|
rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length;
|
||||||
break;
|
break;
|
||||||
@ -594,21 +498,20 @@ num_vcpus_allowed(struct vmctx *ctx)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c, error, gdb_port, inject_bkpt, tmp, err, ioapic, bvmcons;
|
int c, error, gdb_port, tmp, err, ioapic, bvmcons;
|
||||||
int max_vcpus;
|
int max_vcpus;
|
||||||
struct vmctx *ctx;
|
struct vmctx *ctx;
|
||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
size_t memsize;
|
size_t memsize;
|
||||||
|
|
||||||
bvmcons = 0;
|
bvmcons = 0;
|
||||||
inject_bkpt = 0;
|
|
||||||
progname = basename(argv[0]);
|
progname = basename(argv[0]);
|
||||||
gdb_port = DEFAULT_GDB_PORT;
|
gdb_port = DEFAULT_GDB_PORT;
|
||||||
guest_ncpus = 1;
|
guest_ncpus = 1;
|
||||||
ioapic = 0;
|
ioapic = 0;
|
||||||
memsize = 256 * MB;
|
memsize = 256 * MB;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "abehABHIPxp:g:c:z:s:S:n:m:")) != -1) {
|
while ((c = getopt(argc, argv, "abehAHIPp:g:c:s:S:m:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
disable_x2apic = 1;
|
disable_x2apic = 1;
|
||||||
@ -619,12 +522,6 @@ main(int argc, char *argv[])
|
|||||||
case 'b':
|
case 'b':
|
||||||
bvmcons = 1;
|
bvmcons = 1;
|
||||||
break;
|
break;
|
||||||
case 'B':
|
|
||||||
inject_bkpt = 1;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
guest_vcpu_mux = 1;
|
|
||||||
break;
|
|
||||||
case 'p':
|
case 'p':
|
||||||
pincpu = atoi(optarg);
|
pincpu = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
@ -634,12 +531,6 @@ main(int argc, char *argv[])
|
|||||||
case 'g':
|
case 'g':
|
||||||
gdb_port = atoi(optarg);
|
gdb_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
|
||||||
guest_hz = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
guest_tslice = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 's':
|
case 's':
|
||||||
if (pci_parse_slot(optarg, 0) != 0)
|
if (pci_parse_slot(optarg, 0) != 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -677,16 +568,6 @@ main(int argc, char *argv[])
|
|||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
usage(1);
|
usage(1);
|
||||||
|
|
||||||
/* No need to mux if guest is uni-processor */
|
|
||||||
if (guest_ncpus <= 1)
|
|
||||||
guest_vcpu_mux = 0;
|
|
||||||
|
|
||||||
/* vmexit on hlt if guest is muxed */
|
|
||||||
if (guest_vcpu_mux) {
|
|
||||||
guest_vmexit_on_hlt = 1;
|
|
||||||
guest_vmexit_on_pause = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vmname = argv[0];
|
vmname = argv[0];
|
||||||
|
|
||||||
ctx = vm_open(vmname);
|
ctx = vm_open(vmname);
|
||||||
@ -765,11 +646,6 @@ main(int argc, char *argv[])
|
|||||||
error = vm_get_register(ctx, BSP, VM_REG_GUEST_RIP, &rip);
|
error = vm_get_register(ctx, BSP, VM_REG_GUEST_RIP, &rip);
|
||||||
assert(error == 0);
|
assert(error == 0);
|
||||||
|
|
||||||
if (inject_bkpt) {
|
|
||||||
error = vm_inject_event(ctx, BSP, VM_HW_EXCEPTION, IDT_BP);
|
|
||||||
assert(error == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* build the guest tables, MP etc.
|
* build the guest tables, MP etc.
|
||||||
*/
|
*/
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct vmctx;
|
struct vmctx;
|
||||||
extern int guest_hz;
|
|
||||||
extern int guest_tslice;
|
|
||||||
extern int guest_ncpus;
|
extern int guest_ncpus;
|
||||||
extern char *vmname;
|
extern char *vmname;
|
||||||
|
|
||||||
|
@ -153,10 +153,10 @@ pit_update_counter(struct counter *c, int latch)
|
|||||||
* of the program.
|
* of the program.
|
||||||
*
|
*
|
||||||
* If the counter's initial value is not programmed we
|
* If the counter's initial value is not programmed we
|
||||||
* assume a value that would be set to generate 'guest_hz'
|
* assume a value that would be set to generate 100
|
||||||
* interrupts per second.
|
* interrupts per second.
|
||||||
*/
|
*/
|
||||||
c->initial = TIMER_DIV(PIT_8254_FREQ, guest_hz);
|
c->initial = TIMER_DIV(PIT_8254_FREQ, 100);
|
||||||
gettimeofday(&c->tv, NULL);
|
gettimeofday(&c->tv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user