Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115777093
D26506.id77287.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D26506.id77287.diff
View Options
Index: lib/libvmmapi/vmmapi.h
===================================================================
--- lib/libvmmapi/vmmapi.h
+++ lib/libvmmapi/vmmapi.h
@@ -178,6 +178,8 @@
vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
int vm_unmap_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
vm_paddr_t gpa, size_t len);
+int vm_get_vbios(struct vmctx *ctx, int bus, int slot, int func,
+ uint16_t vendor, uint16_t dev_id, uint64_t *bios, uint64_t *size);
int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot,
int func, uint64_t addr, uint64_t msg, int numvec);
int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot,
Index: lib/libvmmapi/vmmapi.c
===================================================================
--- lib/libvmmapi/vmmapi.c
+++ lib/libvmmapi/vmmapi.c
@@ -1000,6 +1000,30 @@
return (ioctl(ctx->fd, VM_UNMAP_PPTDEV_MMIO, &pptmmio));
}
+int
+vm_get_vbios(struct vmctx *ctx, int bus, int slot, int func,
+ uint16_t vendor, uint16_t dev_id, uint64_t *bios, uint64_t *size)
+{
+ int error;
+ struct vm_vbios vbios;
+
+ bzero(&vbios, sizeof(vbios));
+ vbios.bus = bus;
+ vbios.slot = slot;
+ vbios.func = func;
+ vbios.vendor = vendor;
+ vbios.dev_id = dev_id;
+
+ error = ioctl(ctx->fd, VM_GET_VBIOS, &vbios);
+
+ if (bios)
+ *bios = vbios.bios;
+ if (size)
+ *size = vbios.size;
+
+ return (error);
+}
+
int
vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
uint64_t addr, uint64_t msg, int numvec)
@@ -1660,7 +1684,7 @@
VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, VM_ISA_ASSERT_IRQ,
VM_ISA_DEASSERT_IRQ, VM_ISA_PULSE_IRQ, VM_ISA_SET_IRQ_TRIGGER,
VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV,
- VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_UNMAP_PPTDEV_MMIO, VM_PPTDEV_MSI,
+ VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_UNMAP_PPTDEV_MMIO, VM_GET_VBIOS, VM_PPTDEV_MSI,
VM_PPTDEV_MSIX, VM_INJECT_NMI, VM_STATS, VM_STAT_DESC,
VM_SET_X2APIC_STATE, VM_GET_X2APIC_STATE,
VM_GET_HPET_CAPABILITIES, VM_GET_GPA_PMAP, VM_GLA2GPA,
Index: sys/amd64/include/vmm_dev.h
===================================================================
--- sys/amd64/include/vmm_dev.h
+++ sys/amd64/include/vmm_dev.h
@@ -141,6 +141,16 @@
size_t len;
};
+struct vm_vbios {
+ int bus;
+ int slot;
+ int func;
+ uint16_t vendor;
+ uint16_t dev_id;
+ uint64_t bios;
+ uint64_t size;
+};
+
struct vm_pptdev_msi {
int vcpu;
int bus;
@@ -302,6 +312,7 @@
IOCNUM_UNMAP_PPTDEV_MMIO = 45,
IOCNUM_PPTDEV_MSI = 43,
IOCNUM_PPTDEV_MSIX = 44,
+ IOCNUM_GET_VBIOS = 46,
/* statistics */
IOCNUM_VM_STATS = 50,
@@ -412,6 +423,8 @@
_IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio)
#define VM_UNMAP_PPTDEV_MMIO \
_IOW('v', IOCNUM_UNMAP_PPTDEV_MMIO, struct vm_pptdev_mmio)
+#define VM_GET_VBIOS \
+ _IOWR('v', IOCNUM_GET_VBIOS, struct vm_vbios)
#define VM_PPTDEV_MSI \
_IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi)
#define VM_PPTDEV_MSIX \
Index: sys/amd64/vmm/amd/amdgpu.h
===================================================================
--- /dev/null
+++ sys/amd64/vmm/amd/amdgpu.h
@@ -0,0 +1,10 @@
+
+#ifndef _AMD_AMDGPU_H_
+#define _AMD_AMDGPU_H_
+
+#include <machine/vmm_dev.h>
+
+int vm_amdgpu_get_vbios(struct vm *vm, int bus, int slot, int func,
+ uint16_t vendor, uint16_t dev_id, uint64_t *bios, uint64_t *size);
+
+#endif /* !_AMD_AMDGPU_H_ */
\ No newline at end of file
Index: sys/amd64/vmm/amd/amdgpu.c
===================================================================
--- /dev/null
+++ sys/amd64/vmm/amd/amdgpu.c
@@ -0,0 +1,257 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+
+
+#include <sys/param.h>
+#include <sys/bitstring.h>
+#include <sys/bus.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/rangeset.h>
+#include <sys/rwlock.h>
+#include <sys/sbuf.h>
+#include <sys/sx.h>
+#include <sys/turnstile.h>
+#include <sys/vmem.h>
+#include <sys/vmmeter.h>
+#include <sys/sched.h>
+#include <sys/sysctl.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_phys.h>
+#include <vm/vm_radix.h>
+#include <vm/vm_reserv.h>
+#include <vm/uma.h>
+
+#include <machine/pmap.h>
+#include <machine/vmm.h>
+#include <machine/vmparam.h>
+
+#include "amd/amdgpu.h"
+#include "contrib/dev/acpica/include/acpi.h"
+#include "contrib/dev/acpica/include/acpixf.h"
+
+#define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO)
+#define GFP_KERNEL M_WAITOK
+
+//MALLOC_DECLARE(M_KMALLOC);
+MALLOC_DECLARE(M_VMMDEV);
+
+typedef unsigned gfp_t;
+
+static inline gfp_t
+linux_check_m_flags(gfp_t flags)
+{
+ const gfp_t m = M_NOWAIT | M_WAITOK;
+
+ /* make sure either M_NOWAIT or M_WAITOK is set */
+ if ((flags & m) == 0)
+ flags |= M_NOWAIT;
+ else if ((flags & m) == m)
+ flags &= ~M_WAITOK;
+
+ /* mask away LinuxKPI specific flags */
+ return (flags & GFP_NATIVE_MASK);
+}
+
+static inline void *
+kmalloc(size_t size, gfp_t flags)
+{
+ return (malloc(size, M_VMMDEV, linux_check_m_flags(flags)));
+}
+
+static inline void
+kfree(const void *ptr)
+{
+ free(__DECONST(void *, ptr), M_VMMDEV);
+}
+
+static inline void *
+kmemdup(const void *src, size_t len, gfp_t gfp)
+{
+ void *dst;
+
+ dst = kmalloc(roundup2(len, PAGE_SIZE), gfp);
+ if (dst != NULL) {
+ memcpy(dst, src, len);
+ memset((char *)dst + len, 0, roundup2(len, PAGE_SIZE) - len);
+ }
+ return (dst);
+}
+
+#define AMD_VBIOS_SIGNATURE " 761295520"
+#define AMD_VBIOS_SIGNATURE_OFFSET 0x30
+#define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE)
+#define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE)
+#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA)
+#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9)
+
+#define acpi_get_table AcpiGetTable
+
+typedef struct {
+ uint32_t Signature;
+ uint32_t TableLength; //Length
+ uint8_t Revision;
+ uint8_t Checksum;
+ uint8_t OemId[6];
+ uint8_t OemTableId[8]; //UINT64 OemTableId;
+ uint32_t OemRevision;
+ uint32_t CreatorId;
+ uint32_t CreatorRevision;
+} AMD_ACPI_DESCRIPTION_HEADER;
+
+typedef struct {
+ AMD_ACPI_DESCRIPTION_HEADER SHeader;
+ uint8_t TableUUID[16]; //0x24
+ uint32_t VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture.
+ uint32_t Lib1ImageOffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture.
+ uint32_t Reserved[4]; //0x3C
+}UEFI_ACPI_VFCT;
+
+typedef struct {
+ uint32_t PCIBus; //0x4C
+ uint32_t PCIDevice; //0x50
+ uint32_t PCIFunction; //0x54
+ uint16_t VendorID; //0x58
+ uint16_t DeviceID; //0x5A
+ uint16_t SSVID; //0x5C
+ uint16_t SSID; //0x5E
+ uint32_t Revision; //0x60
+ uint32_t ImageLength; //0x64
+}VFCT_IMAGE_HEADER;
+
+
+typedef struct {
+ VFCT_IMAGE_HEADER VbiosHeader;
+ uint8_t VbiosContent[1];
+}GOP_VBIOS_CONTENT;
+
+/* Check if current bios is an ATOM BIOS.
+ * Return true if it is ATOM BIOS. Otherwise, return false.
+ */
+static bool check_atom_bios(uint8_t *bios, size_t size)
+{
+ uint16_t tmp, bios_header_start;
+
+ if (!bios || size < 0x49) {
+ // vbios mem is null or mem size is wrong
+ return false;
+ }
+
+ if (!AMD_IS_VALID_VBIOS(bios)) {
+ // BIOS signature incorrect
+ return false;
+ }
+
+ bios_header_start = bios[0x48] | (bios[0x49] << 8);
+ if (!bios_header_start) {
+ // Can't locate bios header
+ return false;
+ }
+
+ tmp = bios_header_start + 4;
+ if (size < tmp) {
+ // BIOS header is broken
+ return false;
+ }
+
+ if (!memcmp(bios + tmp, "ATOM", 4) ||
+ !memcmp(bios + tmp, "MOTA", 4)) {
+ // ATOMBIOS detected
+ return true;
+ }
+
+ return false;
+}
+
+static int
+amdgpu_get_vbios_vfct(struct vm *vm, int bus, int slot, int func,
+ uint16_t vendor, uint16_t dev_id, uint64_t *bios, uint64_t *size)
+{
+ if (vm == NULL || bios == NULL || size == NULL)
+ return EINVAL;
+
+ struct acpi_table_header *hdr;
+ uint32_t tbl_size;
+ UEFI_ACPI_VFCT *vfct;
+ unsigned offset;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return ENOENT;
+
+ tbl_size = hdr->Length;
+
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT))
+ return ENODEV;
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ offset = vfct->VBIOSImageOffset;
+
+ while (offset < tbl_size) {
+ GOP_VBIOS_CONTENT *vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + offset);
+ VFCT_IMAGE_HEADER *vhdr = &vbios->VbiosHeader;
+
+ offset += sizeof(VFCT_IMAGE_HEADER);
+ if (offset > tbl_size)
+ return ENODEV;
+
+ offset += vhdr->ImageLength;
+ if (offset > tbl_size)
+ return ENODEV;
+
+ if (vhdr->ImageLength &&
+ vhdr->PCIBus == bus &&
+ vhdr->PCIDevice == slot &&
+ vhdr->PCIFunction == func &&
+ vhdr->VendorID == vendor &&
+ vhdr->DeviceID == dev_id) {
+ *bios = (uint64_t)kmemdup(&vbios->VbiosContent,
+ vhdr->ImageLength,
+ GFP_KERNEL);
+
+ if (!check_atom_bios((uint8_t *)*bios, vhdr->ImageLength)) {
+ kfree((void *)*bios);
+ return ENODEV;
+ }
+ *size = vhdr->ImageLength;
+ return 0;
+ }
+ }
+
+ return ENOENT;
+}
+
+int
+vm_amdgpu_get_vbios(struct vm *vm, int bus, int slot, int func,
+ uint16_t vendor, uint16_t dev_id, uint64_t *bios, uint64_t *size)
+{
+ if (amdgpu_get_vbios_vfct(vm, bus, slot, func, vendor, dev_id, bios, size) == 0)
+ goto done;
+
+ return ENOENT;
+
+done:
+ *bios = vtophys(*bios);
+
+ return (0);
+}
Index: sys/amd64/vmm/vmm_dev.c
===================================================================
--- sys/amd64/vmm/vmm_dev.c
+++ sys/amd64/vmm/vmm_dev.c
@@ -60,6 +60,7 @@
#include <machine/vmm_snapshot.h>
#include <x86/apicreg.h>
+#include "amd/amdgpu.h"
#include "vmm_lapic.h"
#include "vmm_stat.h"
#include "vmm_mem.h"
@@ -366,6 +367,7 @@
struct vm_capability *vmcap;
struct vm_pptdev *pptdev;
struct vm_pptdev_mmio *pptmmio;
+ struct vm_vbios *vbios;
struct vm_pptdev_msi *pptmsi;
struct vm_pptdev_msix *pptmsix;
struct vm_nmi *vmnmi;
@@ -436,6 +438,7 @@
case VM_MAP_PPTDEV_MMIO:
case VM_UNMAP_PPTDEV_MMIO:
+ case VM_GET_VBIOS:
case VM_BIND_PPTDEV:
case VM_UNBIND_PPTDEV:
#ifdef COMPAT_FREEBSD12
@@ -526,6 +529,12 @@
error = ppt_unmap_mmio(sc->vm, pptmmio->bus, pptmmio->slot,
pptmmio->func, pptmmio->gpa, pptmmio->len);
break;
+ case VM_GET_VBIOS:
+ vbios = (struct vm_vbios *)data;
+ // currently only amd cpus are supported
+ error = vm_amdgpu_get_vbios(sc->vm, vbios->bus, vbios->slot, vbios->func,
+ vbios->vendor, vbios->dev_id, &vbios->bios, &vbios->size);
+ break;
case VM_BIND_PPTDEV:
pptdev = (struct vm_pptdev *)data;
error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot,
Index: sys/dev/pci/vga_pci.c
===================================================================
--- sys/dev/pci/vga_pci.c
+++ sys/dev/pci/vga_pci.c
@@ -172,21 +172,21 @@
volatile unsigned char *bios;
int i, rid, found;
-#if defined(__amd64__) || defined(__i386__)
- if (vga_pci_is_boot_display(dev)) {
- /*
- * On x86, the System BIOS copy the default display
- * device's Video BIOS at a fixed location in system
- * memory (0xC0000, 128 kBytes long) at boot time.
- *
- * We use this copy for the default boot device, because
- * the original ROM may not be valid after boot.
- */
-
- *size = VGA_PCI_BIOS_SHADOW_SIZE;
- return (pmap_mapbios(VGA_PCI_BIOS_SHADOW_ADDR, *size));
- }
-#endif
+// #if defined(__amd64__) || defined(__i386__)
+// if (vga_pci_is_boot_display(dev)) {
+// /*
+// * On x86, the System BIOS copy the default display
+// * device's Video BIOS at a fixed location in system
+// * memory (0xC0000, 128 kBytes long) at boot time.
+// *
+// * We use this copy for the default boot device, because
+// * the original ROM may not be valid after boot.
+// */
+
+// *size = VGA_PCI_BIOS_SHADOW_SIZE;
+// return (pmap_mapbios(VGA_PCI_BIOS_SHADOW_ADDR, *size));
+// }
+// #endif
pcib = device_get_parent(device_get_parent(dev));
if (device_get_devclass(device_get_parent(pcib)) ==
Index: sys/modules/vmm/Makefile
===================================================================
--- sys/modules/vmm/Makefile
+++ sys/modules/vmm/Makefile
@@ -56,7 +56,8 @@
npt.c \
ivrs_drv.c \
amdvi_hw.c \
- svm_msr.c
+ svm_msr.c \
+ amdgpu.c
.if ${KERN_OPTS:MBHYVE_SNAPSHOT} != ""
SRCS+= vmm_snapshot.c
Index: usr.sbin/bhyve/pci_emul.h
===================================================================
--- usr.sbin/bhyve/pci_emul.h
+++ usr.sbin/bhyve/pci_emul.h
@@ -117,6 +117,12 @@
PENDING
};
+struct pci_vbiosemu {
+ uint64_t hpa;
+ uint64_t len;
+ uint64_t gpa;
+};
+
struct pci_devinst {
struct pci_devemu *pi_d;
struct vmctx *pi_vmctx;
@@ -159,6 +165,8 @@
u_char pi_cfgdata[PCI_REGMAX + 1];
struct pcibar pi_bar[PCI_BARMAX + 1];
+
+ struct pci_vbiosemu vbios;
};
struct msicap {
Index: usr.sbin/bhyve/pci_passthru.c
===================================================================
--- usr.sbin/bhyve/pci_passthru.c
+++ usr.sbin/bhyve/pci_passthru.c
@@ -854,6 +854,15 @@
passthru_cfgwrite_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
int coff, int bytes, uint32_t val);
+static int
+passthru_init_apu(struct vmctx *ctx, struct passthru_softc *sc);
+static int
+passthru_cfgread_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t *rv);
+static int
+passthru_cfgwrite_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t val);
+
static int
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
{
@@ -959,6 +968,14 @@
}
}
+ // init amd apu
+ if (opt != NULL && strcmp(opt, "apu") == 0) {
+ if ((error = passthru_init_apu(ctx, sc)) != 0) {
+ warnx("Failed to init apu");
+ goto done;
+ }
+ }
+
error = 0; /* success */
done:
if (error) {
@@ -1325,6 +1342,37 @@
return (error);
}
+static int
+passthru_init_apu(struct vmctx *ctx, struct passthru_softc *sc)
+{
+ int error;
+
+ uint16_t vendor = read_config(&sc->psc_sel, PCIR_VENDOR, 2);
+ uint16_t dev_id = read_config(&sc->psc_sel, PCIR_DEVICE, 2);
+
+ if ((error = vm_get_vbios(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, vendor, dev_id, &sc->psc_pi->vbios.hpa, &sc->psc_pi->vbios.len)) != 0) {
+ warnx("Failed to load vBIOS (%d)", error);
+ goto done;
+ }
+ if ((sc->psc_pi->vbios.gpa = pci_emul_alloc_mmio(PCIBAR_MEM32, roundup2(sc->psc_pi->vbios.len, PAGE_SIZE), 0x7FF)) == 0) {
+ warnx("Failed to alloc guest memory for vBIOS");
+ error = -ENOMEM;
+ goto done;
+ }
+ if ((error = vm_map_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, sc->psc_pi->vbios.gpa, roundup2(sc->psc_pi->vbios.len, PAGE_SIZE), sc->psc_pi->vbios.hpa)) != 0) {
+ warnx("Failed to map vBIOS to guest");
+ goto done;
+ }
+
+ pci_set_cfgdata32(sc->psc_pi, PCIR_BIOS, sc->psc_pi->vbios.gpa | 0x01);
+
+ sc->psc_pi->pi_d->pe_cfgread = passthru_cfgread_apu;
+ sc->psc_pi->pi_d->pe_cfgwrite = passthru_cfgwrite_apu;
+
+done:
+ return (error);
+}
+
static int
bar_access(int coff)
{
@@ -1443,6 +1491,16 @@
return passthru_cfgread(ctx, vcpu, pi, coff, bytes, rv);
}
+static int
+passthru_cfgread_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t *rv)
+{
+ if (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4)
+ return (-1);
+ else
+ return passthru_cfgread(ctx, vcpu, pi, coff, bytes, rv);
+}
+
static int
passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
int coff, int bytes, uint32_t val)
@@ -1592,6 +1650,37 @@
return passthru_cfgwrite(ctx, vcpu, pi, coff, bytes, val);
}
+static int
+passthru_cfgwrite_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int coff, int bytes, uint32_t val)
+{
+ if (coff == PCIR_BIOS) {
+ struct passthru_softc *sc;
+
+ sc = pi->pi_arg;
+
+ if ((val & ~0x7FF) == 0xFFFFF800) {
+ uint32_t lobits = pci_get_cfgdata32(pi, PCIR_BIOS) & 0x7FF;
+ uint32_t hibits = ~(roundup2(pi->vbios.len, PAGE_SIZE) - 1);
+ pci_set_cfgdata32(pi, PCIR_BIOS, hibits | lobits);
+ vm_unmap_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, pi->vbios.gpa, roundup2(pi->vbios.len, PAGE_SIZE));
+ pi->vbios.gpa = 0;
+ }
+ else {
+ pci_set_cfgdata32(pi, PCIR_BIOS, val);
+ val &= ~0x7FF;
+ if (vm_map_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, val, roundup2(pi->vbios.len, PAGE_SIZE), pi->vbios.hpa))
+ goto done;
+ pi->vbios.gpa = val;
+ }
+ }
+ else
+ return passthru_cfgwrite(ctx, vcpu, pi, coff, bytes, val);
+
+done:
+ return (0);
+}
+
static void
passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx,
uint64_t offset, int size, uint64_t value)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 29, 12:28 PM (11 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17841120
Default Alt Text
D26506.id77287.diff (17 KB)
Attached To
Mode
D26506: [WIP] bhyve: GPU Passthrough for AMD Ryzen V1000
Attached
Detach File
Event Timeline
Log In to Comment