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
This commit is contained in:
Corvin Köhne 2023-05-10 12:31:50 +02:00
parent 9f135336f5
commit 90c3a1b662
No known key found for this signature in database
GPG Key ID: D854DA56315E026A
4 changed files with 87 additions and 1 deletions

View File

@ -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 \

View File

@ -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);

View File

@ -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);
}

View File

@ -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,