Re: [PATCH] lib/iomem_copy: fix __iomem casts

From: Ben Dooks

Date: Mon Jun 29 2026 - 07:14:15 EST


On 24/06/2026 17:25, Al Viro wrote:
On Wed, Jun 24, 2026 at 11:17:17AM +0100, Ben Dooks wrote:
On 24/06/2026 00:47, Al Viro wrote:
On Mon, Jun 22, 2026 at 01:48:57PM +0100, Ben Dooks wrote:
The iomem_copy.c code discards __iomem address space when using
the IS_ALIGNED() macro. It would make more sense to fix this in
one place by aing a PTR_ALIGNED_LONG() macro and then doing the
necessary casts there before invoking IS_ALIGNED().

As part of this, also force the pointer to an unsigned long as
pointers are generally not signed, although there is no warning
as yet on treating pointers as signed.

+#define PTR_ALIGNED_LONG(__ptr) IS_ALIGNED((__force unsigned long)__ptr, sizeof(long))

Casting to unsigned long is fine (indeed, casting a pointer to long had
been very odd in the first place), but... why __force? Casts to unsigned long
(de facto uintptr_t) do *not* require __force - they are explicitly allowed,
unless you pass -Wcast-from-as in sparse arguments. -Wall does not turn
those on; -Wsparse-all would, but kbuild doesn't pass that.

Trying to get rid of the address space warning, which requires the
__force part.

It does not require __force - not with the type we are casting to being
unsigned long. As the examples you've quoted demonstrate. See
evaluate_cast() in sparse evaluate.c:
if ((ttype == &ulong_ctype || ttype == uintptr_ctype) && !Wcast_from_as)
tas = &bad_address_space;
with
if (!tas && valid_as(sas))
warning(expr->pos, "cast removes address space '%s' of expression", show_as(sas));
several lines below.

And yes, it is deliberate.

Ah we should also have checked for intptr or long type there,
the original code had long which causes sparse to complain here.


--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html