The branch main has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=6374c45fbaf76d31b2090e5f93bb5c0f3d4883a5
commit 6374c45fbaf76d31b2090e5f93bb5c0f3d4883a5 Author: Corvin Köhne <corv...@freebsd.org> AuthorDate: 2024-01-08 14:05:56 +0000 Commit: Corvin Köhne <corv...@freebsd.org> CommitDate: 2025-08-05 14:02:09 +0000 bhyve: protect MMIO mapped BDSM register The Windows graphics driver reads the value of the BDSM register from MMIO space. This value makes no sense in our virtual environment because it's a host address. Therefore, we have to trap and emulate it. Reviewed by: jhb MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D45342 --- usr.sbin/bhyve/amd64/pci_gvt-d.c | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/usr.sbin/bhyve/amd64/pci_gvt-d.c b/usr.sbin/bhyve/amd64/pci_gvt-d.c index 630c5caf4b7b..0ea53689f2b2 100644 --- a/usr.sbin/bhyve/amd64/pci_gvt-d.c +++ b/usr.sbin/bhyve/amd64/pci_gvt-d.c @@ -39,10 +39,47 @@ #define PCIM_BDSM_GSM_ALIGNMENT \ 0x00100000 /* Graphics Stolen Memory is 1 MB aligned */ +#define BDSM_GEN11_MMIO_ADDRESS 0x1080C0 + #define GVT_D_MAP_GSM 0 #define GVT_D_MAP_OPREGION 1 #define GVT_D_MAP_VBT 2 +static uint64_t +gvt_d_dsmbase_read(struct pci_devinst *pi, int baridx __unused, uint64_t offset, + int size) +{ + switch (size) { + case 1: + return (pci_get_cfgdata8(pi, PCIR_BDSM_GEN11 + offset)); + case 2: + return (pci_get_cfgdata16(pi, PCIR_BDSM_GEN11 + offset)); + case 4: + return (pci_get_cfgdata32(pi, PCIR_BDSM_GEN11 + offset)); + default: + return (UINT64_MAX); + } +} + +static void +gvt_d_dsmbase_write(struct pci_devinst *pi, int baridx __unused, + uint64_t offset, int size, uint64_t val) +{ + switch (size) { + case 1: + pci_set_cfgdata8(pi, PCIR_BDSM_GEN11 + offset, val); + break; + case 2: + pci_set_cfgdata16(pi, PCIR_BDSM_GEN11 + offset, val); + break; + case 4: + pci_set_cfgdata32(pi, PCIR_BDSM_GEN11 + offset, val); + break; + default: + break; + } +} + static int set_bdsm_gen3(struct pci_devinst *const pi, vm_paddr_t bdsm_gpa) { @@ -85,6 +122,14 @@ set_bdsm_gen11(struct pci_devinst *const pi, vm_paddr_t bdsm_gpa) return (error); } + /* Protect the BDSM register in MMIO space. */ + error = passthru_set_bar_handler(sc, 0, BDSM_GEN11_MMIO_ADDRESS, sizeof(uint64_t), + gvt_d_dsmbase_read, gvt_d_dsmbase_write); + if (error) { + warnx("%s: Failed to setup handler for BDSM mirror!\n", __func__); + return (error); + } + return (0); }