diff --git a/usr.sbin/bhyve/pci_gvt-d.c b/usr.sbin/bhyve/pci_gvt-d.c --- a/usr.sbin/bhyve/pci_gvt-d.c +++ b/usr.sbin/bhyve/pci_gvt-d.c @@ -33,6 +33,43 @@ #define GVT_D_MAP_GSM 0 #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 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) @@ -144,7 +181,10 @@ 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