From: Marek Szyprowski <m.szyprowski@samsung.com>
To: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Cc: Robin Murphy <robin.murphy@arm.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
Bumyong Lee <bumyong.lee@samsung.com>,
iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH] swiotlb: use the adjusted address for the highmem page lookup
Date: Wed, 9 Sep 2026 11:30:30 +0200 [thread overview]
Message-ID: <b4992b2b-ef81-4fd8-ab0b-a42d0fe06ef7@samsung.com> (raw)
In-Reply-To: <20260905084210.148255-1-donggeunyoo.kernel@gmail.com>
On 05.09.2026 10:42, Donggeun Yoo wrote:
> swiotlb_bounce() reads the page frame number from the slot's recorded
> orig_addr, then advances orig_addr by tlb_offset to reach the address
> the caller asked about. The highmem branch mixes the two: the offset
> within the page comes from the adjusted address, the page from the value
> before it.
>
> Once the adjustment crosses a page boundary the pair no longer describes
> one location, and the whole copy lands one page below the intended one
> for a positive tlb_offset, one above for a negative one. DMA_FROM_DEVICE
> writes the device data over the wrong page and leaves the intended one
> stale, DMA_TO_DEVICE feeds the device from a page the mapping may not
> cover. Partial syncs through dma_sync_single_range_for_*() are what make
> tlb_offset non-zero.
>
> The branch test is picked the same way, so a slot recorded in lowmem can
> be adjusted into highmem and the lowmem path then hands a highmem
> address to phys_to_virt().
>
> Take both from orig_addr once it is final and keep pfn in the branch
> that uses it. PhysHighMem() asks the question straight from the address,
> as dma-debug already does.
>
> Fixes: 5f89468e2f06 ("swiotlb: manipulate orig_addr when tlb_addr has offset")
> Cc: stable@vger.kernel.org
> Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Applied to dma-mapping-fixes, thanks!
> ---
> Reproduced under QEMU (qemu-system-arm -M virt, 2G) with a 32-bit ARM
> kernel built from multi_v7_defconfig plus CONFIG_ARM_LPAE=y and
> CONFIG_HIGHMEM=y, which brings in CONFIG_SWIOTLB, booted with
> swiotlb=force. A test module maps two highmem pages at page offset 3840,
> writes a pattern into the bounce buffer 500 bytes in and calls
> dma_sync_single_range_for_cpu() over that range, so that 3840 + 500
> crosses into the second page:
>
> before: swbug: pages pfn=700d4 highmem=1
> swbug: orig phys=700d4f00 (page off 3840)
> swbug: RESULT page0_off=244 page1_off=-1
> after: swbug: RESULT page0_off=-1 page1_off=244
>
> The pattern lands one page below its intended location without the
> change and in the right place with it.
>
> kernel/dma/swiotlb.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index ded7016a46a7..aa2f1c4588b9 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -1019,7 +1019,6 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size
> int index = (tlb_addr - mem->start) >> IO_TLB_SHIFT;
> phys_addr_t orig_addr = mem->slots[index].orig_addr;
> size_t alloc_size = mem->slots[index].alloc_size;
> - unsigned long pfn = PFN_DOWN(orig_addr);
> unsigned char *vaddr = mem->vaddr + tlb_addr - mem->start;
> int tlb_offset;
>
> @@ -1052,7 +1051,8 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size
> size = alloc_size;
> }
>
> - if (PageHighMem(pfn_to_page(pfn))) {
> + if (PhysHighMem(orig_addr)) {
> + unsigned long pfn = PFN_DOWN(orig_addr);
> unsigned int offset = orig_addr & ~PAGE_MASK;
> struct page *page;
> unsigned int sz = 0;
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
prev parent reply other threads:[~2026-09-09 9:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20260905084219eucas1p281d736780f5951d867a487e88f7d9709@eucas1p2.samsung.com>
2026-09-05 8:42 ` [PATCH] swiotlb: use the adjusted address for the highmem page lookup Donggeun Yoo
2026-09-05 15:45 ` Michael Kelley
2026-09-05 18:54 ` Donggeun Yoo
2026-09-05 20:07 ` Michael Kelley
2026-09-05 20:08 ` Michael Kelley
2026-09-09 9:30 ` Marek Szyprowski [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b4992b2b-ef81-4fd8-ab0b-a42d0fe06ef7@samsung.com \
--to=m.szyprowski@samsung.com \
--cc=bumyong.lee@samsung.com \
--cc=donggeunyoo.kernel@gmail.com \
--cc=iommu@lists.linux.dev \
--cc=konrad.wilk@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.