Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102534990
D33010.id104985.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D33010.id104985.diff
View Options
diff --git a/usr.sbin/bhyve/pci_passthru.h b/usr.sbin/bhyve/pci_passthru.h
--- a/usr.sbin/bhyve/pci_passthru.h
+++ b/usr.sbin/bhyve/pci_passthru.h
@@ -11,5 +11,38 @@
#include "pci_emul.h"
+typedef int (*cfgread_handler)(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
+typedef int (*cfgwrite_handler)(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t val);
+
+struct passthru_softc {
+ struct pci_devinst *psc_pi;
+ /* ROM is handled like a BAR */
+ struct pcibar psc_bar[PCI_BARMAX_WITH_ROM + 1];
+ struct {
+ int capoff;
+ int msgctrl;
+ int emulated;
+ } psc_msi;
+ struct {
+ int capoff;
+ } psc_msix;
+ struct pcisel psc_sel;
+
+ cfgread_handler psc_pcir_rhandler[PCI_REGMAX + 1];
+ cfgwrite_handler psc_pcir_whandler[PCI_REGMAX + 1];
+};
+
uint32_t read_config(const struct pcisel *sel, long reg, int width);
void write_config(const struct pcisel *sel, long reg, int width, uint32_t data);
+int passthru_cfgread_default(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
+int passthru_cfgread_emulate(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
+int passthru_cfgwrite_default(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t val);
+int passthru_cfgwrite_emulate(struct vmctx *ctx, int vcpu,
+ struct pci_devinst *pi, int coff, int bytes, uint32_t val);
+int set_pcir_handler(struct passthru_softc *sc, uint32_t reg, uint32_t len,
+ cfgread_handler rhandler, cfgwrite_handler whandler);
diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c
--- a/usr.sbin/bhyve/pci_passthru.c
+++ b/usr.sbin/bhyve/pci_passthru.c
@@ -77,22 +77,9 @@
#define MSIX_TABLE_COUNT(ctrl) (((ctrl) & PCIM_MSIXCTRL_TABLE_SIZE) + 1)
#define MSIX_CAPLEN 12
-static int pcifd = -1;
+#define PCI_CAP_START_OFFSET 0x40
-struct passthru_softc {
- struct pci_devinst *psc_pi;
- /* ROM is handled like a BAR */
- struct pcibar psc_bar[PCI_BARMAX_WITH_ROM + 1];
- struct {
- int capoff;
- int msgctrl;
- int emulated;
- } psc_msi;
- struct {
- int capoff;
- } psc_msix;
- struct pcisel psc_sel;
-};
+static int pcifd = -1;
static int
msi_caplen(int msgctrl)
@@ -607,6 +594,17 @@
sc->psc_sel.pc_dev = slot;
sc->psc_sel.pc_func = func;
+ /* copy physical PCI header to virtual cfgspace */
+ for (uint32_t i = 0; i < PCI_CAP_START_OFFSET; ++i) {
+ /*
+ * INTLINE and INTPIN shouldn't be aligned with it's physical
+ * value and they are already set by pci_emul_init
+ */
+ if (i == PCIR_INTLINE || i == PCIR_INTPIN)
+ continue;
+ pci_set_cfgdata8(pi, i, read_config(&sc->psc_sel, i, 1));
+ }
+
if (cfginitmsi(sc) != 0) {
warnx("failed to initialize MSI for PCI %d/%d/%d",
bus, slot, func);
@@ -641,6 +639,20 @@
return (error);
}
+int
+set_pcir_handler(struct passthru_softc *sc, uint32_t reg, uint32_t len, cfgread_handler rhandler, cfgwrite_handler whandler)
+{
+ if (reg > PCI_REGMAX || reg + len > PCI_REGMAX + 1)
+ return (-1);
+
+ for (uint32_t i = reg; i < reg + len; ++i) {
+ sc->psc_pcir_rhandler[i] = rhandler;
+ sc->psc_pcir_whandler[i] = whandler;
+ }
+
+ return 0;
+}
+
static int
passthru_legacy_config(nvlist_t *nvl, const char *opts)
{
@@ -774,6 +786,19 @@
get_config_value_node(nvl, "rom"))) != 0)
goto done;
+ /* set default handler for all PCI registers */
+ if ((error = set_pcir_handler(sc, 0, PCI_REGMAX + 1,
+ passthru_cfgread_default, passthru_cfgwrite_default)) != 0)
+ goto done;
+ /* protect PCI header */
+ if ((error = set_pcir_handler(sc, 0, PCI_CAP_START_OFFSET,
+ passthru_cfgread_emulate, passthru_cfgwrite_emulate)) != 0)
+ goto done;
+ /* allow access to command and status register */
+ if ((error = set_pcir_handler(sc, PCIR_COMMAND, 0x04,
+ passthru_cfgread_default, passthru_cfgwrite_default)) != 0)
+ goto done;
+
error = 0; /* success */
done:
if (error) {
@@ -820,30 +845,29 @@
}
static int
-passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
- int coff, int bytes, uint32_t *rv)
+passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int coff,
+ int bytes, uint32_t *rv)
{
struct passthru_softc *sc;
sc = pi->pi_arg;
- /*
- * PCI BARs and MSI capability is emulated.
- */
- if (bar_access(coff) || msicap_access(sc, coff) ||
- msixcap_access(sc, coff))
- return (-1);
+ return sc->psc_pcir_rhandler[coff](ctx, vcpu, pi, coff, bytes, rv);
+}
+
+int
+passthru_cfgread_default(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t *rv)
+{
+ struct passthru_softc *sc;
+
+ sc = pi->pi_arg;
-#ifdef LEGACY_SUPPORT
/*
- * Emulate PCIR_CAP_PTR if this device does not support MSI capability
- * natively.
+ * MSI capability is emulated.
*/
- if (sc->psc_msi.emulated) {
- if (coff >= PCIR_CAP_PTR && coff < PCIR_CAP_PTR + 4)
- return (-1);
- }
-#endif
+ if (msicap_access(sc, coff) || msixcap_access(sc, coff))
+ return (-1);
/*
* Emulate the command register. If a single read reads both the
@@ -864,9 +888,28 @@
return (0);
}
+int
+passthru_cfgread_emulate(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t *rv)
+{
+ return (-1);
+}
+
static int
-passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
- int coff, int bytes, uint32_t val)
+passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int coff,
+ int bytes, uint32_t val)
+{
+
+ struct passthru_softc *sc;
+
+ sc = pi->pi_arg;
+
+ return sc->psc_pcir_whandler[coff](ctx, vcpu, pi, coff, bytes, val);
+}
+
+int
+passthru_cfgwrite_default(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t val)
{
int error, msix_table_entries, i;
struct passthru_softc *sc;
@@ -874,12 +917,6 @@
sc = pi->pi_arg;
- /*
- * PCI BARs are emulated
- */
- if (bar_access(coff))
- return (-1);
-
/*
* MSI capability is emulated
*/
@@ -945,6 +982,13 @@
return (0);
}
+int
+passthru_cfgwrite_emulate(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t val)
+{
+ return (-1);
+}
+
static void
passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx,
uint64_t offset, int size, uint64_t value)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 14, 5:35 PM (3 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14631602
Default Alt Text
D33010.id104985.diff (6 KB)
Attached To
Mode
D33010: bhyve: add hook for PCI header of passthru devices
Attached
Detach File
Event Timeline
Log In to Comment