Skip to content

Commit f6f7fbc

Browse files
committed
arm64: properly bounce short unaligned buffers.
1 parent a5ebafe commit f6f7fbc

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

sys/arm64/arm64/busdma_bounce.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -845,9 +845,7 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
845845
KASSERT(dmat->common.alignment <= PAGE_SIZE,
846846
("bounced buffer cannot have alignment bigger "
847847
"than PAGE_SIZE: %lu", dmat->common.alignment));
848-
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
849-
sgsize = roundup2(sgsize, dmat->common.alignment);
850-
sgsize = MIN(sgsize, dmat->common.maxsegsz);
848+
sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
851849
curaddr = add_bounce_page(dmat, map, 0, curaddr,
852850
sgsize);
853851
} else if ((map->flags & DMAMAP_COHERENT) == 0) {
@@ -879,7 +877,11 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
879877
/*
880878
* Did we fit?
881879
*/
882-
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
880+
if (buflen != 0) {
881+
bus_dmamap_unload(dmat, map);
882+
return (EFBIG); /* XXX better return value here? */
883+
}
884+
return (0);
883885
}
884886

885887
/*
@@ -892,7 +894,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
892894
int *segp)
893895
{
894896
struct sync_list *sl;
895-
bus_size_t sgsize, max_sgsize;
897+
bus_size_t sgsize;
896898
bus_addr_t curaddr, sl_pend;
897899
vm_offset_t kvaddr, vaddr, sl_vend;
898900
int error;
@@ -931,7 +933,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
931933
/*
932934
* Get the physical address for this segment.
933935
*/
934-
if (pmap == kernel_pmap) {
936+
if (__predict_true(pmap == kernel_pmap)) {
935937
curaddr = pmap_kextract(vaddr);
936938
kvaddr = vaddr;
937939
} else {
@@ -942,23 +944,16 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
942944
/*
943945
* Compute the segment size, and adjust counts.
944946
*/
945-
max_sgsize = MIN(buflen, dmat->common.maxsegsz);
946-
if ((map->flags & DMAMAP_FROM_DMAMEM) != 0) {
947-
sgsize = max_sgsize;
948-
} else {
949-
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
950-
sgsize = MIN(sgsize, max_sgsize);
951-
}
947+
sgsize = MIN(buflen, dmat->common.maxsegsz);
948+
if ((map->flags & DMAMAP_FROM_DMAMEM) == 0)
949+
sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
952950

953951
if (map->pagesneeded != 0 &&
954952
must_bounce(dmat, map, curaddr, sgsize)) {
955953
/* See comment in bounce_bus_dmamap_load_phys */
956954
KASSERT(dmat->common.alignment <= PAGE_SIZE,
957955
("bounced buffer cannot have alignment bigger "
958956
"than PAGE_SIZE: %lu", dmat->common.alignment));
959-
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
960-
sgsize = roundup2(sgsize, dmat->common.alignment);
961-
sgsize = MIN(sgsize, max_sgsize);
962957
curaddr = add_bounce_page(dmat, map, kvaddr, curaddr,
963958
sgsize);
964959
} else if ((map->flags & DMAMAP_COHERENT) == 0) {
@@ -999,7 +994,11 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
999994
/*
1000995
* Did we fit?
1001996
*/
1002-
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
997+
if (buflen != 0) {
998+
bus_dmamap_unload(dmat, map);
999+
return (EFBIG); /* XXX better return value here? */
1000+
}
1001+
return (0);
10031002
}
10041003

10051004
static void

0 commit comments

Comments
 (0)