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
This commit is contained in:
Justin Hibbits 2018-09-25 02:34:28 +00:00
parent 189bd7a978
commit fd8cf3be5f

View File

@ -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,6 +342,34 @@ 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)
{
@ -430,6 +462,11 @@ ofw_mem_regions(struct mem_region *memp, int *memsz,
asz = excise_initrd_region(availp, asz);
#endif
#ifdef POWERNV
if (opal_check() == 0)
asz = excise_msi_region(availp, asz);
#endif
*memsz = msz;
*availsz = asz;
}