Date: Tue, 25 Sep 2018 02:34:28 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r338922 - head/sys/powerpc/ofw Message-ID: <201809250234.w8P2YSDm002046@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201809250234.w8P2YSDm002046>