x86 busdma_bounce: do not make assumptions about alignment of malloc(9) results.

Reported by:	dim
Reviewed by:	dim, jah
Tested by:	dim, pho
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D28108
This commit is contained in:
Konstantin Belousov 2021-01-12 01:42:30 +02:00
parent 895ad33784
commit 8f54940f01

View File

@ -403,6 +403,8 @@ static int
bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags,
bus_dmamap_t *mapp)
{
uintptr_t ma;
size_t malloc_sz;
vm_memattr_t attr;
int mflags;
@ -445,19 +447,20 @@ bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags,
* else allocate a block of contiguous pages because one or more of the
* constraints is something that only the contig allocator can fulfill.
*
* NOTE: The (dmat->common.alignment <= dmat->maxsize) check
* below is just a quick hack. The exact alignment guarantees
* of malloc(9) need to be nailed down, and the code below
* should be rewritten to take that into account.
*
* In the meantime warn the user if malloc gets it wrong.
* Warn the user if we get it wrong.
*/
if (dmat->common.maxsize <= PAGE_SIZE &&
dmat->common.alignment <= dmat->common.maxsize &&
dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
attr == VM_MEMATTR_DEFAULT) {
*vaddr = malloc_domainset(dmat->common.maxsize, M_DEVBUF,
malloc_sz = roundup2(dmat->common.maxsize,
dmat->common.alignment);
ma = (uintptr_t)malloc_domainset(malloc_sz, M_DEVBUF,
DOMAINSET_PREF(dmat->common.domain), mflags);
if (ma != 0) {
*vaddr = (void *)roundup2(ma, dmat->common.alignment);
} else {
*vaddr = NULL;
}
} else if (dmat->common.nsegments >=
howmany(dmat->common.maxsize, MIN(dmat->common.maxsegsz,
PAGE_SIZE)) &&