mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: Marek Szyprowski <m.szyprowski@samsung.com>,
	Michael Kelley <mhklinux@outlook.com>,
	"iommu@lists.linux.dev" <iommu@lists.linux.dev>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: Claire Chang <tientzu@chromium.org>,
	Konrad Rzeszutek Wilk <konrad@kernel.org>,
	Giorgi Kobakhia <gkobakhi@asu.edu>,
	"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: Re: [PATCH] dma: swiotlb: Round restricted DMA pool size down to IO_TLB_SEGSIZE
Date: Wed, 4 Nov 2026 12:40:42 +0000	[thread overview]
Message-ID: <d7135fe4-5e92-4c42-8d6b-3afbc3b1bb33@arm.com> (raw)
In-Reply-To: <8276a107-7115-48e3-a40a-2660fe1beaa5@samsung.com>

On 2026-11-04 7:37 am, Marek Szyprowski wrote:
> On 03.11.2026 22:18, Michael Kelley wrote:
>> From: Marek Szyprowski <m.szyprowski@samsung.com> Sent: Tuesday, November 3, 2026 7:50 AM
>>> All other paths creating a swiotlb pool ensure that nslabs is a multiple
>>> of IO_TLB_SEGSIZE, and the swiotlb code relies on that. Since commit
>>> 0b84e4f8b793 ("swiotlb: Add restricted DMA pool initialization") a
>>> restricted pool can have an arbitrary size taken from the device tree.
>>>
>>> If the pool size is not a multiple of IO_TLB_SEGSIZE, the last segment is
>>> partial and swiotlb_release_slots() reads mem->slots[index + nslabs],
>>> which is one past the end of the slots array when the freed buffer ends
>>> at the end of the pool:
>>>
>>>   BUG: KASAN: slab-out-of-bounds in swiotlb_release_slots
>>>   Read of size 2
>>>
>>> Round the pool size down to a multiple of IO_TLB_SEGSIZE, wasting a bit
>>> of memory, and warn about it.
>> I'm not familiar with the macro scenarios where a device has a
>> restricted pool specified in DT. But I wonder if it would be better to
>> round up instead of down. DT has specified that the device should
>> have a restricted DMA pool of a certain size, and rounding down gives
>> the device a smaller pool than was requested. Could DMA operations
>> then fail because of not having a large enough pool? Rounding down
>> also allows the pool to end up being size zero, which this patch
>> detects and results in a definite failure at device initialization time.
>>
>> What's the tradeoff in rounding up instead?The device restricted
>> pool at least as large as requested. Presumably, being larger than
>> requested doesn't cause any problems for the device or its driver.
>> The downside is using up to 256 KiB more system memory than
>> expected. In an embedded system with only a few MiB of system
>> memory, maybe that's a relatively big problem. I don't know the
>> scenarios well enough to judge whether using a bit more system
>> memory is better or worse than the device not having all the
>> restricted pool space it said it needed for DMA.
> 
> The main problem with enlarging the restricted pool is that the memory
> has been already allocated (reserved) by the generic of_reserved_mem
> code before the rmem_swiotlb_device_init() is called. There might be
> even another reserved region just after the one being processed by
> rmem_swiotlb_device_init(). The reserved region might be specified in
> the device tree exactly, by pointing its base address and size. In
> such case the rmem_swiotlb_device_init() really cannot do anything
> else than using the provided already allocated region partially.
> The only thing that might be improved is freeing the 'wasted' part
> of the region back to the memory allocator if You think that
> printing a warning is not enough.

Realistically, the granularity of any physical memory protection system 
is going to be based on at least 4KB pages, so I don't see much excuse 
for any restricted pool not being aligned to at least the current 2KB 
segment size - if anything I reckon we could just consider it a DT error 
and fail the init rather than worry about rounding either way.

Note that freeing parts of a restricted pool for any other use would not 
be a thing anyway, as they are by definition not a "reusable" region.

Thanks,
Robin.
>> Your commit message also mentions "wasting a bit of memory".
>> What is wasted in the round down case? The rounding down is
>> done before the pool memory is allocated. I would have thought
>> the wasting would occur in the round up case, where the restricted
>> pool is given more memory than the device said it needed.
>>
>> Michael
>>
>>> Reported-by: Giorgi Kobakhia <gkobakhi@asu.edu>
>>> Closes: https://lore.kernel.org/all/20261026032007.1957949-1-gkobakhi@asu.edu/
>>> Fixes: 0b84e4f8b793 ("swiotlb: Add restricted DMA pool initialization")
>>> CC: stable@vger.kernel.org
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> ---
>>>   kernel/dma/swiotlb.c | 15 ++++++++++++++-
>>>   1 file changed, 14 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
>>> index 2c57b49ac7c0..a68f35192582 100644
>>> --- a/kernel/dma/swiotlb.c
>>> +++ b/kernel/dma/swiotlb.c
>>> @@ -2007,6 +2007,19 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
>>>   	 */
>>>   	if (!mem) {
>>>   		struct io_tlb_pool *pool;
>>> +		unsigned long aligned_nslabs = ALIGN_DOWN(nslabs, IO_TLB_SEGSIZE);
>>> +
>>> +		if (aligned_nslabs != nslabs) {
>>> +			dev_warn(dev, "Restricted DMA pool size %zu is not a multiple of %lu, rounding down to %lu bytes\n",
>>> +				 (size_t)rmem->size,
>>> +				 (unsigned long)IO_TLB_SEGSIZE << IO_TLB_SHIFT,
>>> +				 aligned_nslabs << IO_TLB_SHIFT);
>>> +			nslabs = aligned_nslabs;
>>> +		}
>>> +		if (!nslabs) {
>>> +			dev_err(dev, "Restricted DMA pool is too small\n");
>>> +			return -EINVAL;
>>> +		}
>>>
>>>   		mem = kzalloc_obj(*mem);
>>>   		if (!mem)
>>> @@ -2034,7 +2047,7 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
>>>
>>>   			mem->cc_shared = true;
>>>   			ret = set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
>>> -						   rmem->size >> PAGE_SHIFT);
>>> +						   (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
>>>   			if (ret) {
>>>   				dev_err(dev, "Failed to decrypt restricted DMA pool\n");
>>>   				kfree(pool->areas);
>>> --
>>> 2.43.0
>>
> Best regards


  reply	other threads:[~2026-11-04 12:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20261103155032eucas1p10934ce1bc0c0e2f1fa86891fb2626862@eucas1p1.samsung.com>
2026-11-03 15:50 ` Marek Szyprowski
2026-11-03 21:18   ` Michael Kelley
2026-11-04  7:37     ` Marek Szyprowski
2026-11-04 12:40       ` Robin Murphy [this message]
2026-11-04 20:27       ` Michael Kelley

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=d7135fe4-5e92-4c42-8d6b-3afbc3b1bb33@arm.com \
    --to=robin.murphy@arm.com \
    --cc=gkobakhi@asu.edu \
    --cc=iommu@lists.linux.dev \
    --cc=konrad@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mhklinux@outlook.com \
    --cc=stable@vger.kernel.org \
    --cc=tientzu@chromium.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®