Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153384224
D28280.id101983.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D28280.id101983.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
@@ -139,6 +139,26 @@
This value only works when loaded with UEFI mode for VNC, and
used a VNC client that don't support QEMU Extended Key Event
Message (e.g. TightVNC).
+.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/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,61 @@
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) &&
+ (read_config(&sel, PCIR_CLASS, 1) == PCIC_BRIDGE) &&
+ (read_config(&sel, PCIR_SUBCLASS, 1) == PCIS_BRIDGE_ISA)) {
+ /*
+ * The VID, DID, REVID, SUBVID and SUBDID of lpc need to be
+ * aligned with the physical ones. Without these physical
+ * values, GPU passthrough of Intel integrated graphics devices
+ * won't work properly. The Intel GOP driver checks these values
+ * to proof that it runs on the correct platform.
+ */
+ 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,15 @@
+/*-
+ * 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 <vmmapi.h>
+
+#include "pci_emul.h"
+
+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"
@@ -115,9 +114,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 +157,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));
@@ -638,40 +668,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
Tue, Apr 21, 8:31 PM (8 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31931895
Default Alt Text
D28280.id101983.diff (7 KB)
Attached To
Mode
D28280: bhyve: add config option to modify lpc ids
Attached
Detach File
Event Timeline
Log In to Comment