Page MenuHomeFreeBSD

D54851.id170500.diff
No OneTemporary

D54851.id170500.diff

diff --git a/usr.sbin/bhyve/amd64/pci_lpc.c b/usr.sbin/bhyve/amd64/pci_lpc.c
--- a/usr.sbin/bhyve/amd64/pci_lpc.c
+++ b/usr.sbin/bhyve/amd64/pci_lpc.c
@@ -28,10 +28,12 @@
*/
#include <sys/types.h>
+
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
#include <err.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -46,7 +48,6 @@
#include "pci_emul.h"
#include "pci_irq.h"
#include "pci_lpc.h"
-#include "pci_passthru.h"
#include "pctestdev.h"
#include "tpm_device.h"
#include "uart_emul.h"
@@ -460,34 +461,48 @@
#define LPC_SUBDEV_0 0x0000
static int
-pci_lpc_get_sel(struct pcisel *const sel)
+pci_lpc_get_conf(struct pci_conf *conf)
{
- assert(sel != NULL);
-
- memset(sel, 0, sizeof(*sel));
-
- for (uint8_t slot = 0; slot <= PCI_SLOTMAX; ++slot) {
- uint8_t max_func = 0;
-
- sel->pc_dev = slot;
- sel->pc_func = 0;
+ struct pci_conf_io pcio;
+ struct pci_match_conf pmc;
+ int pcifd;
- if (pci_host_read_config(sel, PCIR_HDRTYPE, 1) & PCIM_MFDEV)
- max_func = PCI_FUNCMAX;
+ pcifd = open("/dev/pci", O_RDONLY);
+ if (pcifd < 0) {
+ warn("%s: Unable to open /dev/pci", __func__);
+ return (-1);
+ }
- for (uint8_t func = 0; func <= max_func; ++func) {
- sel->pc_func = func;
+restart:
+ memset(&pcio, 0, sizeof(pcio));
+ memset(&pmc, 0, sizeof(pmc));
+ pmc.pc_class = PCIC_BRIDGE;
+ pmc.flags = PCI_GETCONF_MATCH_CLASS;
+ do {
+ pcio.pat_buf_len = sizeof(pmc);
+ pcio.num_patterns = 1;
+ pcio.patterns = &pmc;
+ pcio.match_buf_len = sizeof(*conf);
+ pcio.matches = conf;
+ if (ioctl(pcifd, PCIOCGETCONF, &pcio) == -1) {
+ warn("%s: ioctl(PCIOCGETCONF) failed", __func__);
+ break;
+ }
+ if (pcio.num_matches == 0)
+ break;
+ if (pcio.status == PCI_GETCONF_LIST_CHANGED)
+ goto restart;
- if (pci_host_read_config(sel, PCIR_CLASS, 1) ==
- PCIC_BRIDGE &&
- pci_host_read_config(sel, PCIR_SUBCLASS, 1) ==
- PCIS_BRIDGE_ISA) {
- return (0);
- }
+ if (conf->pc_class == PCIC_BRIDGE &&
+ conf->pc_subclass == PCIS_BRIDGE_ISA) {
+ close(pcifd);
+ return (0);
}
- }
+ } while (pcio.status == PCI_GETCONF_MORE_DEVS);
+
+ close(pcifd);
- warnx("%s: Unable to find host selector of LPC bridge.", __func__);
+ warnx("%s: Unable to find host selector of LPC bridge", __func__);
return (-1);
}
@@ -495,8 +510,7 @@
static int
pci_lpc_init(struct pci_devinst *pi, nvlist_t *nvl)
{
- struct pcisel sel = { 0 };
- struct pcisel *selp = NULL;
+ struct pci_conf conf, *confp;
uint16_t device, subdevice, subvendor, vendor;
uint8_t revid;
@@ -521,15 +535,16 @@
if (lpc_init(pi->pi_vmctx) != 0)
return (-1);
- if (pci_lpc_get_sel(&sel) == 0)
- selp = &sel;
+ confp = NULL;
+ if (pci_lpc_get_conf(&conf) == 0)
+ confp = &conf;
- vendor = pci_config_read_reg(selp, nvl, PCIR_VENDOR, 2, LPC_VENDOR);
- device = pci_config_read_reg(selp, nvl, PCIR_DEVICE, 2, LPC_DEV);
- revid = pci_config_read_reg(selp, nvl, PCIR_REVID, 1, LPC_REVID);
- subvendor = pci_config_read_reg(selp, nvl, PCIR_SUBVEND_0, 2,
+ vendor = pci_config_read_reg(confp, nvl, PCIR_VENDOR, 2, LPC_VENDOR);
+ device = pci_config_read_reg(confp, nvl, PCIR_DEVICE, 2, LPC_DEV);
+ revid = pci_config_read_reg(confp, nvl, PCIR_REVID, 1, LPC_REVID);
+ subvendor = pci_config_read_reg(confp, nvl, PCIR_SUBVEND_0, 2,
LPC_SUBVEND_0);
- subdevice = pci_config_read_reg(selp, nvl, PCIR_SUBDEV_0, 2,
+ subdevice = pci_config_read_reg(confp, nvl, PCIR_SUBDEV_0, 2,
LPC_SUBDEV_0);
/* initialize config space */
diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h
--- a/usr.sbin/bhyve/pci_emul.h
+++ b/usr.sbin/bhyve/pci_emul.h
@@ -230,7 +230,7 @@
int init_pci(struct vmctx *ctx);
void pci_callback(void);
-uint32_t pci_config_read_reg(const struct pcisel *host_sel, nvlist_t *nvl,
+uint32_t pci_config_read_reg(const struct pci_conf *host_conf, nvlist_t *nvl,
uint32_t reg, uint8_t size, uint32_t def);
int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx,
enum pcibar_type type, uint64_t size);
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -353,49 +353,51 @@
}
uint32_t
-pci_config_read_reg(const struct pcisel *const host_sel, nvlist_t *nvl,
+pci_config_read_reg(const struct pci_conf *host_conf, nvlist_t *nvl,
const uint32_t reg, const uint8_t size, const uint32_t def)
{
const char *config;
const nvlist_t *pci_regs;
+ uint32_t host;
assert(size == 1 || size == 2 || size == 4);
pci_regs = find_relative_config_node(nvl, "pcireg");
if (pci_regs == NULL) {
- return def;
+ return (def);
}
switch (reg) {
case PCIR_DEVICE:
config = get_config_value_node(pci_regs, "device");
+ host = host_conf != NULL ? host_conf->pc_device : 0;
break;
case PCIR_VENDOR:
config = get_config_value_node(pci_regs, "vendor");
+ host = host_conf != NULL ? host_conf->pc_vendor : 0;
break;
case PCIR_REVID:
config = get_config_value_node(pci_regs, "revid");
+ host = host_conf != NULL ? host_conf->pc_revid : 0;
break;
case PCIR_SUBVEND_0:
config = get_config_value_node(pci_regs, "subvendor");
+ host = host_conf != NULL ? host_conf->pc_subvendor : 0;
break;
case PCIR_SUBDEV_0:
config = get_config_value_node(pci_regs, "subdevice");
+ host = host_conf != NULL ? host_conf->pc_subdevice : 0;
break;
default:
return (-1);
}
if (config == NULL) {
- return def;
- } else if (host_sel != NULL && strcmp(config, "host") == 0) {
-#ifdef __amd64__
- return pci_host_read_config(host_sel, reg, size);
-#else
- errx(1, "cannot fetch host PCI configuration");
-#endif
+ return (def);
+ } else if (host_conf != NULL && strcmp(config, "host") == 0) {
+ return (host);
} else {
- return strtol(config, NULL, 16);
+ return (strtol(config, NULL, 16));
}
}

File Metadata

Mime Type
text/plain
Expires
Fri, May 15, 6:04 PM (4 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33092476
Default Alt Text
D54851.id170500.diff (5 KB)

Event Timeline