git: 90c3a1b6629c - main - bhyve: add empty GVT-d emulation

From: Corvin Köhne <corvink_at_FreeBSD.org>
Date: Fri, 16 Jun 2023 06:14:13 UTC
The branch main has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=90c3a1b6629c80a7e4c3fa86d6b794596fdf06b4

commit 90c3a1b6629c80a7e4c3fa86d6b794596fdf06b4
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2023-05-10 10:31:50 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2023-06-16 05:53:44 +0000

    bhyve: add empty GVT-d emulation
    
    Don't emulate anything yet. Just check if the user would like to pass an
    Intel GPU to the guest.
    
    Reviewed by:            jhb, markj
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D40038
---
 usr.sbin/bhyve/Makefile       |  1 +
 usr.sbin/bhyve/pci_gvt-d.c    | 55 +++++++++++++++++++++++++++++++++++++++++++
 usr.sbin/bhyve/pci_passthru.c | 22 ++++++++++++++++-
 usr.sbin/bhyve/pci_passthru.h | 10 ++++++++
 4 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
index f01f16d56e6c..08eb41c430d5 100644
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -46,6 +46,7 @@ SRCS=	\
 	pci_e82545.c		\
 	pci_emul.c		\
 	pci_fbuf.c		\
+	pci_gvt-d.c		\
 	pci_hda.c		\
 	pci_hostbridge.c	\
 	pci_irq.c		\
diff --git a/usr.sbin/bhyve/pci_gvt-d.c b/usr.sbin/bhyve/pci_gvt-d.c
new file mode 100644
index 000000000000..767b8ee3127f
--- /dev/null
+++ b/usr.sbin/bhyve/pci_gvt-d.c
@@ -0,0 +1,55 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#include <sys/types.h>
+
+#include <dev/pci/pcireg.h>
+
+#include <errno.h>
+
+#include "pci_gvt-d-opregion.h"
+#include "pci_passthru.h"
+
+#define PCI_VENDOR_INTEL 0x8086
+
+static int
+gvt_d_probe(struct pci_devinst *const pi)
+{
+	struct passthru_softc *sc;
+	uint16_t vendor;
+	uint8_t class;
+
+	sc = pi->pi_arg;
+
+	vendor = read_config(passthru_get_sel(sc), PCIR_VENDOR, 0x02);
+	if (vendor != PCI_VENDOR_INTEL)
+		return (ENXIO);
+
+	class = read_config(passthru_get_sel(sc), PCIR_CLASS, 0x01);
+	if (class != PCIC_DISPLAY)
+		return (ENXIO);
+
+	return (0);
+}
+
+static int
+gvt_d_init(struct pci_devinst *const pi __unused, nvlist_t *const nvl __unused)
+{
+	return (0);
+}
+
+static void
+gvt_d_deinit(struct pci_devinst *const pi __unused)
+{
+}
+
+static struct passthru_dev gvt_d_dev = {
+	.probe = gvt_d_probe,
+	.init = gvt_d_init,
+	.deinit = gvt_d_deinit,
+};
+PASSTHRU_DEV_SET(gvt_d_dev);
diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c
index 3d908b25e445..ac1350833924 100644
--- a/usr.sbin/bhyve/pci_passthru.c
+++ b/usr.sbin/bhyve/pci_passthru.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/vmm.h>
 
-#include "config.h"
 #include "debug.h"
 #include "mem.h"
 #include "pci_passthru.h"
@@ -82,6 +81,8 @@ __FBSDID("$FreeBSD$");
 
 static int pcifd = -1;
 
+SET_DECLARE(passthru_dev_set, struct passthru_dev);
+
 struct passthru_softc {
 	struct pci_devinst *psc_pi;
 	/* ROM is handled like a BAR */
@@ -856,6 +857,8 @@ passthru_init(struct pci_devinst *pi, nvlist_t *nvl)
 {
 	int bus, slot, func, error, memflags;
 	struct passthru_softc *sc;
+	struct passthru_dev **devpp;
+	struct passthru_dev *devp, *dev = NULL;
 	const char *value;
 
 	sc = NULL;
@@ -919,9 +922,26 @@ passthru_init(struct pci_devinst *pi, nvlist_t *nvl)
 	if ((error = set_pcir_handler(sc, PCIR_COMMAND, 0x04, NULL, NULL)) != 0)
 		goto done;
 
+	SET_FOREACH(devpp, passthru_dev_set) {
+		devp = *devpp;
+		assert(devp->probe != NULL);
+		if (devp->probe(pi) == 0) {
+			dev = devp;
+			break;
+		}
+	}
+
+	if (dev != NULL) {
+		error = dev->init(pi, nvl);
+		if (error != 0)
+			goto done;
+	}
+
 	error = 0;		/* success */
 done:
 	if (error) {
+		if (dev != NULL)
+			dev->deinit(pi);
 		free(sc);
 		vm_unassign_pptdev(pi->pi_vmctx, bus, slot, func);
 	}
diff --git a/usr.sbin/bhyve/pci_passthru.h b/usr.sbin/bhyve/pci_passthru.h
index 7ce12a27bba4..49d2bb309f71 100644
--- a/usr.sbin/bhyve/pci_passthru.h
+++ b/usr.sbin/bhyve/pci_passthru.h
@@ -7,8 +7,11 @@
 
 #pragma once
 
+#include <sys/linker_set.h>
+
 #include <vmmapi.h>
 
+#include "config.h"
 #include "pci_emul.h"
 
 struct passthru_mmio_mapping {
@@ -21,6 +24,13 @@ struct passthru_mmio_mapping {
 
 struct passthru_softc;
 
+struct passthru_dev {
+    int (*probe)(struct pci_devinst *pi);
+    int (*init)(struct pci_devinst *pi, nvlist_t *nvl);
+    void (*deinit)(struct pci_devinst *pi);
+};
+#define PASSTHRU_DEV_SET(x) DATA_SET(passthru_dev_set, x)
+
 typedef int (*cfgread_handler)(struct passthru_softc *sc,
     struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
 typedef int (*cfgwrite_handler)(struct passthru_softc *sc,