git: 6374c45fbaf7 - main - bhyve: protect MMIO mapped BDSM register

From: Corvin Köhne <corvink_at_FreeBSD.org>
Date: Tue, 05 Aug 2025 14:03:20 UTC
The branch main has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=6374c45fbaf76d31b2090e5f93bb5c0f3d4883a5

commit 6374c45fbaf76d31b2090e5f93bb5c0f3d4883a5
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2024-01-08 14:05:56 +0000
Commit:     Corvin Köhne <corvink@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);
 }