Author: jhibbits
Date: Tue Sep 25 02:34:28 2018
New Revision: 338922
URL: https://svnweb.freebsd.org/changeset/base/338922

Log:
  powerpc: Blacklist the top 64kB range of the lower 4GB PA space
  
  The PHB4 host bridge used by the POWER9 uses a 64kB range in 32-bit
  space at the address 0xffff0000-0xffffffff.  Reserve this range so that
  DMA memory cannot be allocated within this range.  This fixes seemingly
  random crashes on a POWER9 system.  Ideally this range will have been
  reserved by the firmware, but as of now this is not the case.
  
  Submitted by: git_bdragon.rtk0.net
  Reviewed by:  nwhitehorn
  Approved by:  re(kib)
  Differential Revision:        https://reviews.freebsd.org/D17183

Modified:
  head/sys/powerpc/ofw/ofw_machdep.c

Modified: head/sys/powerpc/ofw/ofw_machdep.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c  Mon Sep 24 22:15:04 2018        
(r338921)
+++ head/sys/powerpc/ofw/ofw_machdep.c  Tue Sep 25 02:34:28 2018        
(r338922)
@@ -69,6 +69,10 @@ __FBSDID("$FreeBSD$");
 
 #include <contrib/libfdt/libfdt.h>
 
+#ifdef POWERNV
+#include <powerpc/powernv/opal.h>
+#endif
+
 static void    *fdt;
 int            ofw_real_mode;
 
@@ -338,7 +342,35 @@ excise_initrd_region(struct mem_region *avail, int asz
        return (asz);
 }
 
+#ifdef POWERNV
 static int
+excise_msi_region(struct mem_region *avail, int asz)
+{
+        uint64_t start, end;
+        struct mem_region initrdmap[1];
+
+       /*
+        * This range of physical addresses is used to implement optimized
+        * 32 bit MSI interrupts on POWER9. Exclude it to avoid accidentally
+        * using it for DMA, as this will cause an immediate PHB fence.
+        * While we could theoretically turn off this behavior in the ETU,
+        * doing so would break 32-bit MSI, so just reserve the range in 
+        * the physical map instead.
+        * See section 4.4.2.8 of the PHB4 specification.
+        */
+       start   = 0x00000000ffff0000ul;
+       end     = 0x00000000fffffffful;
+
+       initrdmap[0].mr_start = start;
+       initrdmap[0].mr_size = end - start;
+
+       asz = excise_reserved_regions(avail, asz, initrdmap, 1);
+
+       return (asz);
+}
+#endif
+
+static int
 excise_fdt_reserved(struct mem_region *avail, int asz)
 {
        struct mem_region fdtmap[32];
@@ -428,6 +460,11 @@ ofw_mem_regions(struct mem_region *memp, int *memsz,
         */
        if (OF_hasprop(phandle, "linux,initrd-start"))
                asz = excise_initrd_region(availp, asz);
+#endif
+
+#ifdef POWERNV
+       if (opal_check() == 0)
+               asz = excise_msi_region(availp, asz);
 #endif
 
        *memsz = msz;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to