Fix a bug in the passthru implementation where it would assume that all
devices are MSI-X capable. This in turn would lead it to treat bar 0 as the MSI-X table bar even if the underlying device did not support MSI-X. Fix this by providing an API to query the MSI-X table index of the emulated device. If the underlying device does not support MSI-X then this API will return -1. Obtained from: NetApp
This commit is contained in:
parent
c9a45ab898
commit
803db8c37c
@ -254,6 +254,26 @@ pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size)
|
|||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pci_msix_table_bar(struct pci_devinst *pi)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pi->pi_msix.table != NULL)
|
||||||
|
return (pi->pi_msix.table_bar);
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pci_msix_pba_bar(struct pci_devinst *pi)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pi->pi_msix.table != NULL)
|
||||||
|
return (pi->pi_msix.pba_bar);
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
|
pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
|
||||||
uint32_t *eax, void *arg)
|
uint32_t *eax, void *arg)
|
||||||
|
@ -169,6 +169,8 @@ void pci_lintr_deassert(struct pci_devinst *pi);
|
|||||||
int pci_lintr_request(struct pci_devinst *pi, int ivec);
|
int pci_lintr_request(struct pci_devinst *pi, int ivec);
|
||||||
int pci_msi_enabled(struct pci_devinst *pi);
|
int pci_msi_enabled(struct pci_devinst *pi);
|
||||||
int pci_msix_enabled(struct pci_devinst *pi);
|
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);
|
int pci_msi_msgnum(struct pci_devinst *pi);
|
||||||
void pci_parse_slot(char *opt, int legacy);
|
void pci_parse_slot(char *opt, int legacy);
|
||||||
void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr);
|
void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr);
|
||||||
|
@ -361,6 +361,8 @@ init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base)
|
|||||||
size_t len;
|
size_t len;
|
||||||
struct pci_devinst *pi = sc->psc_pi;
|
struct pci_devinst *pi = sc->psc_pi;
|
||||||
|
|
||||||
|
assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the MSI-X table BAR maps memory intended for
|
* If the MSI-X table BAR maps memory intended for
|
||||||
* other uses, it is at least assured that the table
|
* other uses, it is at least assured that the table
|
||||||
@ -370,7 +372,9 @@ init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base)
|
|||||||
if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar &&
|
if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar &&
|
||||||
((pi->pi_msix.pba_offset - pi->pi_msix.table_offset) < 4096)) {
|
((pi->pi_msix.pba_offset - pi->pi_msix.table_offset) < 4096)) {
|
||||||
/* Need to also emulate the PBA, not supported yet */
|
/* Need to also emulate the PBA, not supported yet */
|
||||||
printf("Unsupported MSI-X table and PBA in same page\n");
|
printf("Unsupported MSI-X configuration: %d/%d/%d\n",
|
||||||
|
sc->psc_sel.pc_bus, sc->psc_sel.pc_dev,
|
||||||
|
sc->psc_sel.pc_func);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +451,7 @@ cfginitbar(struct vmctx *ctx, struct passthru_softc *sc)
|
|||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/* The MSI-X table needs special handling */
|
/* The MSI-X table needs special handling */
|
||||||
if (i == pi->pi_msix.table_bar) {
|
if (i == pci_msix_table_bar(pi)) {
|
||||||
error = init_msix_table(ctx, sc, base);
|
error = init_msix_table(ctx, sc, base);
|
||||||
if (error)
|
if (error)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -688,7 +692,7 @@ passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx,
|
|||||||
|
|
||||||
sc = pi->pi_arg;
|
sc = pi->pi_arg;
|
||||||
|
|
||||||
if (pi->pi_msix.table_bar == baridx) {
|
if (baridx == pci_msix_table_bar(pi)) {
|
||||||
msix_table_write(ctx, vcpu, sc, offset, size, value);
|
msix_table_write(ctx, vcpu, sc, offset, size, value);
|
||||||
} else {
|
} else {
|
||||||
assert(pi->pi_bar[baridx].type == PCIBAR_IO);
|
assert(pi->pi_bar[baridx].type == PCIBAR_IO);
|
||||||
@ -712,7 +716,7 @@ passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx,
|
|||||||
|
|
||||||
sc = pi->pi_arg;
|
sc = pi->pi_arg;
|
||||||
|
|
||||||
if (pi->pi_msix.table_bar == baridx) {
|
if (baridx == pci_msix_table_bar(pi)) {
|
||||||
val = msix_table_read(sc, offset, size);
|
val = msix_table_read(sc, offset, size);
|
||||||
} else {
|
} else {
|
||||||
assert(pi->pi_bar[baridx].type == PCIBAR_IO);
|
assert(pi->pi_bar[baridx].type == PCIBAR_IO);
|
||||||
|
@ -685,8 +685,8 @@ pci_vtnet_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
if (use_msix) {
|
if (use_msix) {
|
||||||
if (baridx == pi->pi_msix.table_bar ||
|
if (baridx == pci_msix_table_bar(pi) ||
|
||||||
baridx == pi->pi_msix.pba_bar) {
|
baridx == pci_msix_pba_bar(pi)) {
|
||||||
pci_emul_msix_twrite(pi, offset, size, value);
|
pci_emul_msix_twrite(pi, offset, size, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -781,8 +781,8 @@ pci_vtnet_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
|
|||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
if (use_msix) {
|
if (use_msix) {
|
||||||
if (baridx == pi->pi_msix.table_bar ||
|
if (baridx == pci_msix_table_bar(pi) ||
|
||||||
baridx == pi->pi_msix.pba_bar) {
|
baridx == pci_msix_pba_bar(pi)) {
|
||||||
return (pci_emul_msix_tread(pi, offset, size));
|
return (pci_emul_msix_tread(pi, offset, size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user