Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_gvt-d.c
Show All 27 Lines | |||||
#define PCIR_BDSM 0x5C /* Base of Data Stolen Memory register */ | #define PCIR_BDSM 0x5C /* Base of Data Stolen Memory register */ | ||||
#define PCIR_ASLS_CTL 0xFC /* Opregion start address register */ | #define PCIR_ASLS_CTL 0xFC /* Opregion start address register */ | ||||
/* GVT-d definitions */ | /* GVT-d definitions */ | ||||
#define GVT_D_MAP_GSM 0 | #define GVT_D_MAP_GSM 0 | ||||
#define GVT_D_MAP_OPREGION 1 | #define GVT_D_MAP_OPREGION 1 | ||||
static int | |||||
gvt_d_aslswrite(struct passthru_softc *sc, struct pci_devinst *pi, int coff, | |||||
int bytes, uint32_t val) | |||||
{ | |||||
struct passthru_mmio_mapping *opregion; | |||||
opregion = passthru_get_mmio(sc, GVT_D_MAP_OPREGION); | |||||
if (opregion == NULL) { | |||||
warnx("%s: Unable access opregion", __func__); | |||||
return (0); | |||||
} | |||||
/* write new value to cfg space */ | |||||
if (bytes == 1) { | |||||
pci_set_cfgdata8(pi, coff, val); | |||||
} else if (bytes == 2) { | |||||
pci_set_cfgdata16(pi, coff, val); | |||||
} else { | |||||
pci_set_cfgdata32(pi, coff, val); | |||||
} | |||||
/* get new address of opregion */ | |||||
opregion->gpa = pci_get_cfgdata32(pi, PCIR_ASLS_CTL); | |||||
/* copy opregion into guest mem */ | |||||
opregion->gva = vm_map_gpa(pi->pi_vmctx, opregion->gpa, opregion->len); | |||||
if (opregion->gva == 0) { | |||||
warnx("%s: Unable to map opregion (0x%016lx)", __func__, | |||||
opregion->gpa); | |||||
/* return 0 to avoid emulation of ASLS register */ | |||||
return (0); | |||||
} | |||||
memcpy(opregion->gva, opregion->hva, opregion->len); | |||||
return (0); | |||||
} | |||||
static vm_paddr_t | static vm_paddr_t | ||||
gvt_d_alloc_mmio_memory(const vm_paddr_t host_address, const vm_paddr_t length, | gvt_d_alloc_mmio_memory(const vm_paddr_t host_address, const vm_paddr_t length, | ||||
const vm_paddr_t alignment, const enum e820_memory_type type) | const vm_paddr_t alignment, const enum e820_memory_type type) | ||||
{ | { | ||||
vm_paddr_t address; | vm_paddr_t address; | ||||
/* try to use host address */ | /* try to use host address */ | ||||
address = e820_alloc(host_address, length, E820_ALIGNMENT_NONE, type, | address = e820_alloc(host_address, length, E820_ALIGNMENT_NONE, type, | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if (opregion->gpa != opregion->hpa) { | ||||
* change in the future. | * change in the future. | ||||
*/ | */ | ||||
warnx( | warnx( | ||||
"Warning: Unable to reuse host address of OpRegion. GPU passthrough might not work properly."); | "Warning: Unable to reuse host address of OpRegion. GPU passthrough might not work properly."); | ||||
} | } | ||||
memcpy(opregion->gva, opregion->hva, opregion->len); | memcpy(opregion->gva, opregion->hva, opregion->len); | ||||
return (0); | pci_set_cfgdata32(pi, PCIR_ASLS_CTL, opregion->gpa); | ||||
return (set_pcir_handler(sc, PCIR_ASLS_CTL, 4, passthru_cfgread_emulate, | |||||
gvt_d_aslswrite)); | |||||
} | } | ||||
int | int | ||||
gvt_d_init(struct pci_devinst *const pi, nvlist_t *const nvl __unused) | gvt_d_init(struct pci_devinst *const pi, nvlist_t *const nvl __unused) | ||||
{ | { | ||||
int error; | int error; | ||||
if ((error = gvt_d_setup_gsm(pi)) != 0) { | if ((error = gvt_d_setup_gsm(pi)) != 0) { | ||||
Show All 27 Lines |