summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2013-04-26 02:24:50 +0000
committerneel <neel@FreeBSD.org>2013-04-26 02:24:50 +0000
commite682d8007302053c408e2be8b790f8b7bb01c071 (patch)
tree2f6ad8f929b96f6e9ca19b67d5a061065a53c49b /usr.sbin/bhyve
parent508d67d2f78da676b3dce0a390a2b5e6c2f7e68d (diff)
downloadFreeBSD-src-e682d8007302053c408e2be8b790f8b7bb01c071.zip
FreeBSD-src-e682d8007302053c408e2be8b790f8b7bb01c071.tar.gz
Gripe if some <slot,function> tuple is specified more than once instead of
silently overwriting the previous assignment. Gripe if the emulation is not recognized instead of silently ignoring the emulated device. If an error is detected by pci_parse_slot() then exit from the command line parsing loop in main(). Submitted by (initial version): Chris Torek (chris.torek@gmail.com)
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r--usr.sbin/bhyve/bhyverun.c12
-rw-r--r--usr.sbin/bhyve/pci_emul.c53
-rw-r--r--usr.sbin/bhyve/pci_emul.h2
3 files changed, 47 insertions, 20 deletions
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
index 3218ca4..66883be 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -631,11 +631,15 @@ main(int argc, char *argv[])
guest_tslice = atoi(optarg);
break;
case 's':
- pci_parse_slot(optarg, 0);
- break;
+ if (pci_parse_slot(optarg, 0) != 0)
+ exit(1);
+ else
+ break;
case 'S':
- pci_parse_slot(optarg, 1);
- break;
+ if (pci_parse_slot(optarg, 1) != 0)
+ exit(1);
+ else
+ break;
case 'm':
memsize = strtoul(optarg, NULL, 0) * MB;
break;
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index 1abb69c..37f1778 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -100,6 +100,8 @@ static uint64_t pci_emul_membase64;
#define PCI_EMUL_MEMBASE64 0xD000000000UL
#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL
+static struct pci_devemu *pci_emul_finddev(char *name);
+
static int pci_emul_devices;
/*
@@ -123,17 +125,18 @@ static int pci_emul_devices;
static void
pci_parse_slot_usage(char *aopt)
{
- printf("Invalid PCI slot info field \"%s\"\n", aopt);
- free(aopt);
+
+ fprintf(stderr, "Invalid PCI slot info field \"%s\"\n", aopt);
}
-void
+int
pci_parse_slot(char *opt, int legacy)
{
char *slot, *func, *emul, *config;
char *str, *cpy;
- int snum, fnum;
+ int error, snum, fnum;
+ error = -1;
str = cpy = strdup(opt);
config = NULL;
@@ -152,19 +155,40 @@ pci_parse_slot(char *opt, int legacy)
}
if (emul == NULL) {
- pci_parse_slot_usage(cpy);
- return;
+ pci_parse_slot_usage(opt);
+ goto done;
}
snum = atoi(slot);
fnum = func ? atoi(func) : 0;
+
if (snum < 0 || snum >= MAXSLOTS || fnum < 0 || fnum >= MAXFUNCS) {
- pci_parse_slot_usage(cpy);
- } else {
- pci_slotinfo[snum][fnum].si_name = emul;
- pci_slotinfo[snum][fnum].si_param = config;
- pci_slotinfo[snum][fnum].si_legacy = legacy;
+ pci_parse_slot_usage(opt);
+ goto done;
}
+
+ if (pci_slotinfo[snum][fnum].si_name != NULL) {
+ fprintf(stderr, "pci slot %d:%d already occupied!\n",
+ snum, fnum);
+ goto done;
+ }
+
+ if (pci_emul_finddev(emul) == NULL) {
+ fprintf(stderr, "pci slot %d:%d: unknown device \"%s\"\n",
+ snum, fnum, emul);
+ goto done;
+ }
+
+ error = 0;
+ pci_slotinfo[snum][fnum].si_name = emul;
+ pci_slotinfo[snum][fnum].si_param = config;
+ pci_slotinfo[snum][fnum].si_legacy = legacy;
+
+done:
+ if (error)
+ free(cpy);
+
+ return (error);
}
static int
@@ -988,10 +1012,9 @@ init_pci(struct vmctx *ctx)
si = &pci_slotinfo[slot][func];
if (si->si_name != NULL) {
pde = pci_emul_finddev(si->si_name);
- if (pde != NULL) {
- pci_emul_init(ctx, pde, slot, func,
- si->si_param);
- }
+ assert(pde != NULL);
+ pci_emul_init(ctx, pde, slot, func,
+ si->si_param);
}
}
}
diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h
index db218bb..654b2f6 100644
--- a/usr.sbin/bhyve/pci_emul.h
+++ b/usr.sbin/bhyve/pci_emul.h
@@ -206,7 +206,7 @@ int pci_msix_enabled(struct pci_devinst *pi);
int pci_msix_table_bar(struct pci_devinst *pi);
int pci_msix_pba_bar(struct pci_devinst *pi);
int pci_msi_msgnum(struct pci_devinst *pi);
-void pci_parse_slot(char *opt, int legacy);
+int pci_parse_slot(char *opt, int legacy);
void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr);
int pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum);
int pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size,
OpenPOWER on IntegriCloud