Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142677228
D28280.id99009.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D28280.id99009.diff
View Options
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -1098,3 +1098,8 @@
#define PCIM_OSC_CTL_PCIE_PME 0x04 /* PCIe Native Power Mgt Events */
#define PCIM_OSC_CTL_PCIE_AER 0x08 /* PCIe Advanced Error Reporting */
#define PCIM_OSC_CTL_PCIE_CAP_STRUCT 0x10 /* Various Capability Structures */
+
+/*
+ * PCI Vendors
+ */
+#define PCI_VENDOR_INTEL 0x8086
diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5
--- a/usr.sbin/bhyve/bhyve_config.5
+++ b/usr.sbin/bhyve/bhyve_config.5
@@ -133,6 +133,21 @@
.It Va gdb.wait Ta bool Ta false Ta
If the debug server is enabled, wait for a debugger to connect
before starting the guest.
+.It Va lpc.pcir.vendor Ta integer Ta 0x8086 Ta
+Vendor id of the LPC bridge as hex number. On Intel systems
+the LPC bridge uses the physical vendor id as default value.
+.It Va lpc.pcir.device Ta integer Ta 0x7000 Ta
+Device id of the LPC bridge as hex number. On Intel systems
+the LPC bridge uses the physical device id as default value.
+.It Va lpc.pcir.revid Ta integer Ta 0 Ta
+Revision id of the LPC bridge as hex number. On Intel systems
+the LPC bridge uses the physical revision id as default value.
+.It Va lpc.pcir.subvendor Ta integer Ta 0 Ta
+Subvendor id of the LPC bridge as hex number. On Intel systems
+the LPC bridge uses the physical subvendor id as default value.
+.It Va lpc.pcir.subdevice Ta integer Ta 0 Ta
+Subdevice id of the LPC bridge as hex number. On Intel systems
+the LPC bridge uses the physical subdevice id as default value.
.It Va rtc.use_localtime Ta bool Ta true Ta
The real time clock uses the local time of the host.
If this is set to false, the real time clock uses UTC.
diff --git a/usr.sbin/bhyve/config.h b/usr.sbin/bhyve/config.h
--- a/usr.sbin/bhyve/config.h
+++ b/usr.sbin/bhyve/config.h
@@ -99,12 +99,23 @@
void set_config_value_node(nvlist_t *parent, const char *name,
const char *value);
+/*
+ * Similar to set_config_value_node but only sets value if it's unset yet.
+ */
+void set_config_value_node_if_unset(nvlist_t *const parent,
+ const char *const name, const char *const value);
+
/*
* Similar to set_config_value_node but expects a full path to the
* leaf node.
*/
void set_config_value(const char *path, const char *value);
+/*
+ * Similar to set_config_value but only sets the value if it's unset yet.
+ */
+void set_config_value_if_unset(const char *const path, const char *const value);
+
/* Convenience wrappers for boolean variables. */
bool get_config_bool(const char *path);
bool get_config_bool_node(const nvlist_t *parent, const char *name);
diff --git a/usr.sbin/bhyve/config.c b/usr.sbin/bhyve/config.c
--- a/usr.sbin/bhyve/config.c
+++ b/usr.sbin/bhyve/config.c
@@ -135,6 +135,17 @@
nvlist_add_string(parent, name, value);
}
+void
+set_config_value_node_if_unset(nvlist_t *const parent, const char *const name,
+ const char *const value)
+{
+ if (get_config_value_node(parent, name) != NULL) {
+ return;
+ }
+
+ set_config_value_node(parent, name, value);
+}
+
void
set_config_value(const char *path, const char *value)
{
@@ -167,6 +178,16 @@
set_config_value_node(nvl, name, value);
}
+void
+set_config_value_if_unset(const char *const path, const char *const value)
+{
+ if (get_config_value(path) != NULL) {
+ return;
+ }
+
+ set_config_value(path, value);
+}
+
static const char *
get_raw_config_value(const char *path)
{
diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c
--- a/usr.sbin/bhyve/pci_lpc.c
+++ b/usr.sbin/bhyve/pci_lpc.c
@@ -33,6 +33,7 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/pciio.h>
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
@@ -50,6 +51,7 @@
#include "pci_emul.h"
#include "pci_irq.h"
#include "pci_lpc.h"
+#include "pci_passthru.h"
#include "pctestdev.h"
#include "uart_emul.h"
@@ -446,11 +448,57 @@
if (lpc_init(ctx) != 0)
return (-1);
+ char value[16];
+
+ /* on Intel systems lpc is always connected to 0:1f.0 */
+ const struct pcisel sel = { .pc_dev = 0x1f };
+ if (read_config(&sel, PCIR_VENDOR, 2) == PCI_VENDOR_INTEL) {
+ /*
+ * The VID, DID, REVID, SUBVID and SUBDID of lpc need to be
+ * aligned with the physical ones. Without these physical
+ * values, GVT-d GOP driver couldn't work.
+ */
+ snprintf(value, sizeof(value), "0x%04x",
+ read_config(&sel, PCIR_VENDOR, 2));
+ set_config_value_if_unset("lpc.pcir.vendor", value);
+ snprintf(value, sizeof(value), "0x%04x",
+ read_config(&sel, PCIR_DEVICE, 2));
+ set_config_value_if_unset("lpc.pcir.device", value);
+ snprintf(value, sizeof(value), "0x%02x",
+ read_config(&sel, PCIR_REVID, 1));
+ set_config_value_if_unset("lpc.pcir.revid", value);
+ snprintf(value, sizeof(value), "0x%04x",
+ read_config(&sel, PCIR_SUBVEND_0, 2));
+ set_config_value_if_unset("lpc.pcir.subvendor", value);
+ snprintf(value, sizeof(value), "0x%04x",
+ read_config(&sel, PCIR_SUBDEV_0, 2));
+ set_config_value_if_unset("lpc.pcir.subdevice", value);
+ }
+
+ snprintf(value, sizeof(value), "0x%04x", LPC_VENDOR);
+ set_config_value_if_unset("lpc.pcir.vendor", value);
+ snprintf(value, sizeof(value), "0x%04x", LPC_DEV);
+ set_config_value_if_unset("lpc.pcir.device", value);
+ snprintf(value, sizeof(value), "0x%02x", 0);
+ set_config_value_if_unset("lpc.pcir.revid", 0);
+ snprintf(value, sizeof(value), "0x%04x", 0);
+ set_config_value_if_unset("lpc.pcir.subvendor", 0);
+ snprintf(value, sizeof(value), "0x%04x", 0);
+ set_config_value_if_unset("lpc.pcir.subdevice", 0);
+
/* initialize config space */
- pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV);
- pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR);
+ pci_set_cfgdata16(pi, PCIR_VENDOR,
+ strtol(get_config_value("lpc.pcir.vendor"), NULL, 16));
+ pci_set_cfgdata16(pi, PCIR_DEVICE,
+ strtol(get_config_value("lpc.pcir.device"), NULL, 16));
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE);
pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA);
+ pci_set_cfgdata8(pi, PCIR_REVID,
+ strtol(get_config_value("lpc.pcir.revid"), NULL, 16));
+ pci_set_cfgdata16(pi, PCIR_SUBVEND_0,
+ strtol(get_config_value("lpc.pcir.subvendor"), NULL, 16));
+ pci_set_cfgdata16(pi, PCIR_SUBDEV_0,
+ strtol(get_config_value("lpc.pcir.subdevice"), NULL, 16));
lpc_bridge = pi;
diff --git a/usr.sbin/bhyve/pci_passthru.h b/usr.sbin/bhyve/pci_passthru.h
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/pci_passthru.h
@@ -0,0 +1,31 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#pragma once
+
+#include <sys/pciio.h>
+
+#include <vmmapi.h>
+
+#include "pci_emul.h"
+
+struct passthru_softc {
+ struct pci_devinst *psc_pi;
+ struct pcibar psc_bar[PCI_BARMAX + 1];
+ struct {
+ int capoff;
+ int msgctrl;
+ int emulated;
+ } psc_msi;
+ struct {
+ int capoff;
+ } psc_msix;
+ struct pcisel psc_sel;
+};
+
+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);
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
@@ -61,12 +61,11 @@
#include <unistd.h>
#include <machine/vmm.h>
-#include <vmmapi.h>
#include "config.h"
#include "debug.h"
-#include "pci_emul.h"
#include "mem.h"
+#include "pci_passthru.h"
#ifndef _PATH_DEVPCI
#define _PATH_DEVPCI "/dev/pci"
@@ -79,20 +78,6 @@
static int pcifd = -1;
-struct passthru_softc {
- struct pci_devinst *psc_pi;
- struct pcibar psc_bar[PCI_BARMAX + 1];
- struct {
- int capoff;
- int msgctrl;
- int emulated;
- } psc_msi;
- struct {
- int capoff;
- } psc_msix;
- struct pcisel psc_sel;
-};
-
static int
msi_caplen(int msgctrl)
{
@@ -115,9 +100,36 @@
return (len);
}
-static uint32_t
+static int
+pcifd_init() {
+ pcifd = open(_PATH_DEVPCI, O_RDWR, 0);
+ if (pcifd < 0) {
+ warn("failed to open %s", _PATH_DEVPCI);
+ return (1);
+ }
+
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_t pcifd_rights;
+ cap_rights_init(&pcifd_rights, CAP_IOCTL, CAP_READ, CAP_WRITE);
+ if (caph_rights_limit(pcifd, &pcifd_rights) == -1)
+ errx(EX_OSERR, "Unable to apply rights for sandbox");
+
+ const cap_ioctl_t pcifd_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR,
+ PCIOCBARIO, PCIOCBARMMAP };
+ if (caph_ioctls_limit(pcifd, pcifd_ioctls, nitems(pcifd_ioctls)) == -1)
+ errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
+ return (0);
+}
+
+uint32_t
read_config(const struct pcisel *sel, long reg, int width)
{
+ if (pcifd < 0 && pcifd_init()) {
+ return (0);
+ }
+
struct pci_io pi;
bzero(&pi, sizeof(pi));
@@ -131,9 +143,13 @@
return (pi.pi_data);
}
-static void
+void
write_config(const struct pcisel *sel, long reg, int width, uint32_t data)
{
+ if (pcifd < 0 && pcifd_init()) {
+ return;
+ }
+
struct pci_io pi;
bzero(&pi, sizeof(pi));
@@ -630,40 +646,20 @@
int bus, slot, func, error, memflags;
struct passthru_softc *sc;
const char *value;
-#ifndef WITHOUT_CAPSICUM
- cap_rights_t rights;
- cap_ioctl_t pci_ioctls[] =
- { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR, PCIOCBARIO, PCIOCBARMMAP };
-#endif
sc = NULL;
error = 1;
-#ifndef WITHOUT_CAPSICUM
- cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE);
-#endif
-
memflags = vm_get_memflags(ctx);
if (!(memflags & VM_MEM_F_WIRED)) {
warnx("passthru requires guest memory to be wired");
return (error);
}
- if (pcifd < 0) {
- pcifd = open(_PATH_DEVPCI, O_RDWR, 0);
- if (pcifd < 0) {
- warn("failed to open %s", _PATH_DEVPCI);
- return (error);
- }
+ if (pcifd < 0 && pcifd_init()) {
+ return (error);
}
-#ifndef WITHOUT_CAPSICUM
- if (caph_rights_limit(pcifd, &rights) == -1)
- errx(EX_OSERR, "Unable to apply rights for sandbox");
- if (caph_ioctls_limit(pcifd, pci_ioctls, nitems(pci_ioctls)) == -1)
- errx(EX_OSERR, "Unable to apply rights for sandbox");
-#endif
-
#define GET_INT_CONFIG(var, name) do { \
value = get_config_value_node(nvl, name); \
if (value == NULL) { \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 23, 3:47 AM (3 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27874011
Default Alt Text
D28280.id99009.diff (9 KB)
Attached To
Mode
D28280: bhyve: add config option to modify lpc ids
Attached
Detach File
Event Timeline
Log In to Comment