[Bug 273694] [patch] _bus_dmamap_count_pages() may miscount
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 273694] [patch] _bus_dmamap_count_pages() may miscount"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 273694] [patch] _bus_dmamap_count_pages() may miscount"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 273694] [patch] _bus_dmamap_count_pages() may miscount"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 10 Sep 2023 09:31:48 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273694 Bug ID: 273694 Summary: [patch] _bus_dmamap_count_pages() may miscount Product: Base System Version: 14.0-CURRENT Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: jsihv@gmx.com Created attachment 244746 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=244746&action=edit patch files for different architectures While debugging jh7110 board's MMC driver I found out that the problem had been a faulty algorithm in DMA code. _bus_dmamap_count_pages() in sys/riscv/riscv/busdma_bounce.c is called to count a number of new bounce pages needed in order to complete the DMA transfer (this happens at least when physical addresses used for data segments go out of DMA address range). However, unlike a function bounce_bus_dmapmap_load_buffer() which calls it, _bus_dmamap_count_pages() does not take into account that segment size may be limited by dmat->common.maxsegsz which is set when creating bus_dma_tag_t in the driver code. This may lead to a wrong number of pages counted and thus some needed bounce pages will not be created. In my case the consequence was that some addresses outside of device's 32-bit DMA range were assigned to descriptors (IO data structures read by DMA controller) which nevertheless can only contain first 32 bits of those addresses. This causes the whole booting process to halt. After a failed transfer MMC driver code stays waiting for a next interrupt that never arrives. I found that the _bus_dmamap_count_pages() is similarly deficient in other architectures though it's possible this bug hasn't surfaced previously. My actual case is related to charcteristics of Designware's MMC devices (see comments on file dwmmc.c, line 140) which imply maximum size for data segments. I don't see any reason why this issue couldn't affect other architectures as well if circumstances are right, so I've supplied patches for each architecture in an attachment file. ARM and powerpc have the _bus_dmamap_count_pages() function in file busdma_machdep.c while other archs (including ARM64) have it in busdma_bounce.c -- You are receiving this mail because: You are the assignee for the bug.