diff options
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r-- | usr.sbin/bhyve/bhyverun.c | 12 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 53 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 2 |
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, |