Author: whu
Date: Thu Jul 30 07:26:11 2020
New Revision: 363689
URL: https://svnweb.freebsd.org/changeset/base/363689

Log:
  Prevent framebuffer mmio space from being allocated to other devices on 
HyperV.
  
  On Gen2 VMs, Hyper-V provides mmio space for framebuffer.
  This mmio address range is not useable for other PCI devices.
  Currently only efifb driver is using this range without reserving
  it from system.
  Therefore, vmbus driver reserves it before any other PCI device
  drivers start to request mmio addresses.
  
  PR:           222996
  Submitted by: w...@microsoft.com
  Reported by:  dmitry_kules...@ukr.net
  Reviewed by:  de...@microsoft.com
  Sponsored by: Microsoft

Modified:
  head/sys/dev/hyperv/vmbus/vmbus.c

Modified: head/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c   Thu Jul 30 07:11:08 2020        
(r363688)
+++ head/sys/dev/hyperv/vmbus/vmbus.c   Thu Jul 30 07:26:11 2020        
(r363689)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/linker.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 #include <machine/intr_machdep.h>
+#include <machine/metadata.h>
 #include <machine/md_var.h>
 #include <machine/resource.h>
 #include <x86/include/apicvar.h>
@@ -1332,12 +1334,66 @@ vmbus_get_mmio_res(device_t dev)
        vmbus_get_mmio_res_pass(dev, parse_32);
 }
 
+/*
+ * On Gen2 VMs, Hyper-V provides mmio space for framebuffer.
+ * This mmio address range is not useable for other PCI devices.
+ * Currently only efifb driver is using this range without reserving
+ * it from system.
+ * Therefore, vmbus driver reserves it before any other PCI device
+ * drivers start to request mmio addresses.
+ */
+static struct resource *hv_fb_res;
+
 static void
+vmbus_fb_mmio_res(device_t dev)
+{
+       struct efi_fb *efifb;
+       caddr_t kmdp;
+
+       struct vmbus_softc *sc = device_get_softc(dev);
+       int rid = 0;
+
+       kmdp = preload_search_by_type("elf kernel");
+       if (kmdp == NULL)
+               kmdp = preload_search_by_type("elf64 kernel");
+       efifb = (struct efi_fb *)preload_search_info(kmdp,
+           MODINFO_METADATA | MODINFOMD_EFI_FB);
+       if (efifb == NULL) {
+               if (bootverbose)
+                       device_printf(dev,
+                           "fb has no preloaded kernel efi information\n");
+               /* We are on Gen1 VM, just return. */
+               return;
+       } else {
+               if (bootverbose)
+                       device_printf(dev,
+                           "efifb: fb_addr: %#jx, size: %#jx, "
+                           "actual size needed: 0x%x\n",
+                           efifb->fb_addr, efifb->fb_size,
+                           (int) efifb->fb_height * efifb->fb_width);
+       }
+
+       hv_fb_res = pcib_host_res_alloc(&sc->vmbus_mmio_res, dev,
+           SYS_RES_MEMORY, &rid,
+           efifb->fb_addr, efifb->fb_addr + efifb->fb_size, efifb->fb_size,
+           RF_ACTIVE | rman_make_alignment_flags(PAGE_SIZE));
+
+       if (hv_fb_res && bootverbose)
+               device_printf(dev,
+                   "successfully reserved memory for framebuffer "
+                   "starting at %#jx, size %#jx\n",
+                   efifb->fb_addr, efifb->fb_size);
+}
+
+static void
 vmbus_free_mmio_res(device_t dev)
 {
        struct vmbus_softc *sc = device_get_softc(dev);
 
        pcib_host_res_free(dev, &sc->vmbus_mmio_res);
+
+       if (hv_fb_res)
+               hv_fb_res = NULL;
 }
 #endif /* NEW_PCIB */
 
@@ -1387,6 +1443,7 @@ vmbus_doattach(struct vmbus_softc *sc)
 
 #ifdef NEW_PCIB
        vmbus_get_mmio_res(sc->vmbus_dev);
+       vmbus_fb_mmio_res(sc->vmbus_dev);
 #endif
 
        sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to