Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_passthru.c
Show First 20 Lines • Show All 513 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) | cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) | ||||
{ | { | ||||
int i, error; | int i, error; | ||||
struct pci_devinst *pi; | struct pci_devinst *pi; | ||||
struct pci_bar_io bar; | struct pci_bar_io bar; | ||||
enum pcibar_type bartype; | enum pcibar_type bartype; | ||||
uint64_t base, size; | uint64_t base, old_base, size; | ||||
pi = sc->psc_pi; | pi = sc->psc_pi; | ||||
/* | /* | ||||
* Initialize BAR registers | * Initialize BAR registers | ||||
*/ | */ | ||||
for (i = 0; i <= PCI_BARMAX; i++) { | for (i = 0; i <= PCI_BARMAX; i++) { | ||||
bzero(&bar, sizeof(bar)); | bzero(&bar, sizeof(bar)); | ||||
Show All 20 Lines | for (i = 0; i <= PCI_BARMAX; i++) { | ||||
size = bar.pbi_length; | size = bar.pbi_length; | ||||
if (bartype != PCIBAR_IO) { | if (bartype != PCIBAR_IO) { | ||||
if (((base | size) & PAGE_MASK) != 0) { | if (((base | size) & PAGE_MASK) != 0) { | ||||
warnx("passthru device %d/%d/%d BAR %d: " | warnx("passthru device %d/%d/%d BAR %d: " | ||||
"base %#lx or size %#lx not page aligned\n", | "base %#lx or size %#lx not page aligned\n", | ||||
sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, | sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, | ||||
sc->psc_sel.pc_func, i, base, size); | sc->psc_sel.pc_func, i, base, size); | ||||
return (-1); | |||||
} | } | ||||
if ((base & PAGE_MASK) != 0) { | |||||
jhb: Do you have a device with a BAR smaller than a page that you are using with pass through? | |||||
Done Inline ActionsWhen I tested this many years ago I did it with passthru of ahci, on something like Skylake. Even today, looking at my w/s Kabylake, I do see ahci0@pci0:0:23:0: class=0x010601 rev=0x21 hdr=0x00 vendor=0x8086 device=0x9d03 subvendor=0x1458 subdevice=0x1000 vendor = 'Intel Corporation' device = 'Sunrise Point-LP SATA Controller [AHCI mode]' class = mass storage subclass = SATA bar [10] = type Memory, range 32, base 0xdf348000, size 8192, enabled bar [14] = type Memory, range 32, base 0xdf34c000, size 256, enabled bar [18] = type I/O Port, range 32, base 0xf090, size 8, enabled bar [1c] = type I/O Port, range 32, base 0xf080, size 4, enabled bar [20] = type I/O Port, range 32, base 0xf060, size 32, enabled bar [24] = type Memory, range 32, base 0xdf34b000, size 2048, enabled cap 05[80] = MSI supports 1 message enabled with 1 message And these are obviously not MSI(X) bars. kib: When I tested this many years ago I did it with passthru of ahci, on something like Skylake. | |||||
Not Done Inline ActionsHummm. I wonder if we really think it's ok to pass through the entire page to the guest in this case as it means exposing BARs of other devices to the guest (probably a bad idea) or if instead we want to treat this case like the MSI-X table where we intercept reads and writes to this BAR instead. This change should probably be a separate change in its own right though and not related to DMAR IMO. jhb: Hummm. I wonder if we really think it's ok to pass through the entire page to the guest in… | |||||
Done Inline ActionsThe per-commit split of this review can be seen at https://kib.kiev.ua/git/gitweb.cgi?p=deviant3.git;a=shortlog;h=refs/heads/dmar_bhyve_integ kib: The per-commit split of this review can be seen at https://kib.kiev.ua/git/gitweb.cgi? | |||||
old_base = base; | |||||
base = trunc_page(base); | |||||
size += old_base - base; | |||||
} | |||||
if ((size & PAGE_MASK) != 0) | |||||
size = round_page(size); | |||||
} | } | ||||
/* Cache information about the "real" BAR */ | /* Cache information about the "real" BAR */ | ||||
sc->psc_bar[i].type = bartype; | sc->psc_bar[i].type = bartype; | ||||
sc->psc_bar[i].size = size; | sc->psc_bar[i].size = size; | ||||
sc->psc_bar[i].addr = base; | sc->psc_bar[i].addr = base; | ||||
sc->psc_bar[i].lobits = 0; | sc->psc_bar[i].lobits = 0; | ||||
▲ Show 20 Lines • Show All 569 Lines • Show Last 20 Lines |
Do you have a device with a BAR smaller than a page that you are using with pass through?