Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F138672021
D36147.id109479.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
D36147.id109479.diff
View Options
Index: usr.sbin/bhyve/bhyve.8
===================================================================
--- usr.sbin/bhyve/bhyve.8
+++ usr.sbin/bhyve/bhyve.8
@@ -390,6 +390,7 @@
.Xc
.El
.Sm on
+.Pp
If
.Cm mac
is not specified, the MAC address is derived from a fixed OUI and the
@@ -520,14 +521,32 @@
.El
.Pp
Pass-through device backends:
-.Bl -tag -width 10n
-.It Ns Ar slot Ns Cm \&/ Ns Ar bus Ns Cm \&/ Ns Ar function
-Connect to a PCI device on the host at the selector described by
+.Sm off
+.Bl -bullet
+.It
+.Cm ppt Ar N Oo , Ar passthru-device-options Oc
+.It
+.Ns Ar bus Cm \&/ Ar slot Cm \&/ Ar function
+.Op , Ar passthru-device-options
+.It
+.Cm pci Ar bus Cm : Ar slot Cm : Ns Ar function
+.Op , Ar passthru-device-options
+.El
+.Sm on
+.Pp
+Connect to a PCI device on the host either named ppt
+.Ns Ar N
+or at the selector described by
.Ar slot ,
.Ar bus ,
and
.Ar function
numbers.
+.Pp
+The
+.Ar passthru-device-options
+are:
+.Bl -tag -width 10n
.It Cm rom= Ns Ar romfile
Add
.Ar romfile
Index: usr.sbin/bhyve/bhyve_config.5
===================================================================
--- usr.sbin/bhyve/bhyve_config.5
+++ usr.sbin/bhyve/bhyve_config.5
@@ -575,6 +575,11 @@
The value of this variable is the size of the memory disk in megabytes.
.El
.Ss PCI Passthrough Settings
+The PCI device to pass through must be attached to the
+.Xr ppt 4
+device driver.
+The device to pass through can be identified either by name or its
+host PCI bus location.
.Bl -column "Name" "integer" "Default"
.It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description
.It Va bus Ta integer Ta Ta
@@ -583,6 +588,10 @@
Host PCI slot address of device to pass through.
.It Va func Ta integer Ta Ta
Host PCI function address of device to pass through.
+.It Va pptdev Ta string Ta Ta
+Name of a
+.Xr ppt 4
+device to pass through.
.It Va rom Ta path Ta Ta
ROM file of the device which will be executed by OVMF to init the device.
.El
Index: usr.sbin/bhyve/pci_passthru.c
===================================================================
--- usr.sbin/bhyve/pci_passthru.c
+++ usr.sbin/bhyve/pci_passthru.c
@@ -56,6 +56,7 @@
#ifndef WITHOUT_CAPSICUM
#include <capsicum_helpers.h>
#endif
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -136,7 +137,7 @@
errx(EX_OSERR, "Unable to apply rights for sandbox");
const cap_ioctl_t pcifd_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR,
- PCIOCBARIO, PCIOCBARMMAP };
+ PCIOCBARIO, PCIOCBARMMAP, PCIOCGETCONF };
if (caph_ioctls_limit(pcifd, pcifd_ioctls, nitems(pcifd_ioctls)) == -1)
errx(EX_OSERR, "Unable to apply rights for sandbox");
#endif
@@ -649,30 +650,39 @@
static int
passthru_legacy_config(nvlist_t *nvl, const char *opts)
{
+ const char *cp;
+ char *tofree;
char value[16];
int bus, slot, func;
if (opts == NULL)
return (0);
- if (sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) {
+ cp = strchr(opts, ',');
+
+ if (strncmp(opts, "ppt", strlen("ppt")) == 0) {
+ tofree = strndup(opts, cp - opts);
+ set_config_value_node(nvl, "pptdev", tofree);
+ free(tofree);
+ } else if (sscanf(opts, "pci0:%d:%d:%d", &bus, &slot, &func) == 3 ||
+ sscanf(opts, "pci%d:%d:%d", &bus, &slot, &func) == 3 ||
+ sscanf(opts, "%d/%d/%d", &bus, &slot, &func) == 3) {
+ snprintf(value, sizeof(value), "%d", bus);
+ set_config_value_node(nvl, "bus", value);
+ snprintf(value, sizeof(value), "%d", slot);
+ set_config_value_node(nvl, "slot", value);
+ snprintf(value, sizeof(value), "%d", func);
+ set_config_value_node(nvl, "func", value);
+ } else {
EPRINTLN("passthru: invalid options \"%s\"", opts);
return (-1);
}
- snprintf(value, sizeof(value), "%d", bus);
- set_config_value_node(nvl, "bus", value);
- snprintf(value, sizeof(value), "%d", slot);
- set_config_value_node(nvl, "slot", value);
- snprintf(value, sizeof(value), "%d", func);
- set_config_value_node(nvl, "func", value);
-
- opts = strchr(opts, ',');
- if (opts == NULL) {
+ if (cp == NULL) {
return (0);
}
- return pci_parse_legacy_config(nvl, opts + 1);
+ return (pci_parse_legacy_config(nvl, cp + 1));
}
static int
@@ -726,6 +736,72 @@
return (0);
}
+static bool
+passthru_lookup_pptdev(const char *name, int *bus, int *slot, int *func)
+{
+ struct pci_conf_io pc;
+ struct pci_conf conf[1];
+ struct pci_match_conf patterns[1];
+ char *cp;
+
+ bzero(&pc, sizeof(struct pci_conf_io));
+ pc.match_buf_len = sizeof(conf);
+ pc.matches = conf;
+
+ bzero(&patterns, sizeof(patterns));
+
+ /*
+ * The pattern structure requires the unit to be split out from
+ * the driver name. Walk backwards from the end of the name to
+ * find the start of the unit.
+ */
+ cp = strchr(name, '\0');
+ assert(cp != NULL);
+ while (cp != name && isdigit(cp[-1]))
+ cp--;
+ if (cp == name || !isdigit(*cp)) {
+ EPRINTLN("Invalid passthru device name %s", name);
+ return (false);
+ }
+ if ((size_t)(cp - name) + 1 > sizeof(patterns[0].pd_name)) {
+ EPRINTLN("Passthru device name %s is too long", name);
+ return (false);
+ }
+ memcpy(patterns[0].pd_name, name, cp - name);
+ patterns[0].pd_unit = strtol(cp, &cp, 10);
+ if (*cp != '\0') {
+ EPRINTLN("Invalid passthru device name %s", name);
+ return (false);
+ }
+ patterns[0].flags = PCI_GETCONF_MATCH_NAME | PCI_GETCONF_MATCH_UNIT;
+ pc.num_patterns = 1;
+ pc.pat_buf_len = sizeof(patterns);
+ pc.patterns = patterns;
+
+ if (ioctl(pcifd, PCIOCGETCONF, &pc) == -1) {
+ EPRINTLN("ioctl(PCIOCGETCONF): %s", strerror(errno));
+ return (false);
+ }
+ if (pc.status != PCI_GETCONF_LAST_DEVICE &&
+ pc.status != PCI_GETCONF_MORE_DEVS) {
+ EPRINTLN("error returned from PCIOCGETCONF ioctl");
+ return (false);
+ }
+ if (pc.num_matches == 0) {
+ EPRINTLN("Passthru device %s not found", name);
+ return (false);
+ }
+
+ if (conf[0].pc_sel.pc_domain != 0) {
+ EPRINTLN("Passthru device %s on unsupported domain", name);
+ return (false);
+ }
+ *bus = conf[0].pc_sel.pc_bus;
+ *slot = conf[0].pc_sel.pc_dev;
+ *func = conf[0].pc_sel.pc_func;
+ return (true);
+}
+
static int
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
{
@@ -755,9 +831,15 @@
var = atoi(value); \
} while (0)
- GET_INT_CONFIG(bus, "bus");
- GET_INT_CONFIG(slot, "slot");
- GET_INT_CONFIG(func, "func");
+ value = get_config_value_node(nvl, "pptdev");
+ if (value != NULL) {
+ if (!passthru_lookup_pptdev(value, &bus, &slot, &func))
+ return (error);
+ } else {
+ GET_INT_CONFIG(bus, "bus");
+ GET_INT_CONFIG(slot, "slot");
+ GET_INT_CONFIG(func, "func");
+ }
if (vm_assign_pptdev(ctx, bus, slot, func) != 0) {
warnx("PCI device at %d/%d/%d is not using the ppt(4) driver",
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 5, 1:42 AM (11 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26627865
Default Alt Text
D36147.id109479.diff (6 KB)
Attached To
Mode
D36147: bhyve: Support other schemes for naming pass-through devices.
Attached
Detach File
Event Timeline
Log In to Comment