drivers/gpu/drm/panthor/panthor_gem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
From: Chia-I Wu <olvaffe@gmail.com>
Pages that can be swapped out should be allocated with __GFP_SKIP_KASAN.
Rather than setting the flag directly, replace GFP_HIGHUSER by
(GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) instead, which should match the
preceding comment better.
On a CONFIG_KASAN_HW_TAGS=y system, without __GFP_SKIP_KASAN, the page
allocator assigns a valid tag to both the kernel mapping and MTE,
instead of assigning the match-all KASAN_TAG_KERNEL tag to the kernel
mapping. If userspace also maps the page with PROT_MTE and modifies the
MTE tag, accessing the page via the kernel mapping results in KASAN
invalid-access, such as
BUG: KASAN: invalid-access in swap_writepage+0xb0/0x21c
Read at addr f5ffff81aa71dff8 by task WM.task-4/6956
Pointer tag: [f5], memory tag: [f9]
While userspace cannot map drm gem objects with PROT_MTE, the problem is
shmem_swapin_cluster. When it swaps in a cluster of pages using our gfp
flags, some of the pages might belong to other mappings that have
PROT_MTE.
Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
---
The latest snapdragons appear to have MTE support. drm/msm might need
the same treatment.
---
drivers/gpu/drm/panthor/panthor_gem.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 13295d7a593df..08c03aa0db2f7 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -1013,7 +1013,8 @@ panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags,
* going to pin these pages.
*/
mapping_set_gfp_mask(bo->base.filp->f_mapping,
- GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
+ (GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) |
+ __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
ret = drm_gem_create_mmap_offset(&bo->base);
if (ret)
---
base-commit: 6101f78b684895d5860a96322e607e0f46f433ad
change-id: 20260512-panthor-kasan-10477239bad1
Best regards,
--
Chia-I Wu <olvaffe@gmail.com>
On Tue, 12 May 2026 10:36:28 -0700 Chia-I Wu via B4 Relay <devnull+olvaffe.gmail.com@kernel.org> wrote: > From: Chia-I Wu <olvaffe@gmail.com> > > Pages that can be swapped out should be allocated with __GFP_SKIP_KASAN. > Rather than setting the flag directly, replace GFP_HIGHUSER by > (GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) instead, which should match the > preceding comment better. I'm not too sure GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE is clearer than GFP_HIGHUSER (without MOVABLE in the name) to reflect we don't want the MOVABLE property. > > On a CONFIG_KASAN_HW_TAGS=y system, without __GFP_SKIP_KASAN, the page > allocator assigns a valid tag to both the kernel mapping and MTE, > instead of assigning the match-all KASAN_TAG_KERNEL tag to the kernel > mapping. If userspace also maps the page with PROT_MTE and modifies the > MTE tag, accessing the page via the kernel mapping results in KASAN > invalid-access, such as > > BUG: KASAN: invalid-access in swap_writepage+0xb0/0x21c > Read at addr f5ffff81aa71dff8 by task WM.task-4/6956 > Pointer tag: [f5], memory tag: [f9] > > While userspace cannot map drm gem objects with PROT_MTE, the problem is > shmem_swapin_cluster. When it swaps in a cluster of pages using our gfp > flags, some of the pages might belong to other mappings that have > PROT_MTE. Okay, let me see if I get this right. The gfp flags we set right now do what we want for out GEM mappings, it's only when swap readahead is involved that this becomes problematic: 1. swapin folio for GEM inode X 2. shmem layer optimistically does a readahead on the global swap, with our GEM gfp flags 3. the next swap entry belongs to some other tmpfs/anonymous mapping (not even something on the same GEM mountpoint actually) 4. because it's our gfp flags that get used for the folio allocation, the KASAN poisoning takes place, thus messing up with the original user-request PROT_MTE To me, this looks like a bad isolation of the readahead logic: we shouldn't cross the inode boundary, because gfp flags for one inode might be completely different from gfp flags for a different inode. Let alone the fact the boundary being crossed here is not just inode, it's basically the entire tmpfs mountpoint. TLDR; I strongly believe we're papering over some more fundamental issue in the shmem swap readahead logic: with MTE, we can no longer assume gfp flags are interchangeable, they have to be enforced and match exactly what the user of the swap entry expects, meaning readahead should be constrained by the inode boundary. > > Signed-off-by: Chia-I Wu <olvaffe@gmail.com> > --- > The latest snapdragons appear to have MTE support. drm/msm might need > the same treatment. > --- > drivers/gpu/drm/panthor/panthor_gem.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c > index 13295d7a593df..08c03aa0db2f7 100644 > --- a/drivers/gpu/drm/panthor/panthor_gem.c > +++ b/drivers/gpu/drm/panthor/panthor_gem.c > @@ -1013,7 +1013,8 @@ panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags, > * going to pin these pages. > */ > mapping_set_gfp_mask(bo->base.filp->f_mapping, > - GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); > + (GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) | > + __GFP_RETRY_MAYFAIL | __GFP_NOWARN); > > ret = drm_gem_create_mmap_offset(&bo->base); > if (ret) > > --- > base-commit: 6101f78b684895d5860a96322e607e0f46f433ad > change-id: 20260512-panthor-kasan-10477239bad1 > > Best regards, > -- > Chia-I Wu <olvaffe@gmail.com> > >
+KASAN and shmem maintainers On Wed, May 13, 2026 at 2:11 AM Boris Brezillon <boris.brezillon@collabora.com> wrote: > > On Tue, 12 May 2026 10:36:28 -0700 > Chia-I Wu via B4 Relay <devnull+olvaffe.gmail.com@kernel.org> wrote: > > > From: Chia-I Wu <olvaffe@gmail.com> > > > > Pages that can be swapped out should be allocated with __GFP_SKIP_KASAN. > > Rather than setting the flag directly, replace GFP_HIGHUSER by > > (GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) instead, which should match the > > preceding comment better. > > I'm not too sure GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE is clearer than > GFP_HIGHUSER (without MOVABLE in the name) to reflect we don't want the > MOVABLE property. > > > > > On a CONFIG_KASAN_HW_TAGS=y system, without __GFP_SKIP_KASAN, the page > > allocator assigns a valid tag to both the kernel mapping and MTE, > > instead of assigning the match-all KASAN_TAG_KERNEL tag to the kernel > > mapping. If userspace also maps the page with PROT_MTE and modifies the > > MTE tag, accessing the page via the kernel mapping results in KASAN > > invalid-access, such as > > > > BUG: KASAN: invalid-access in swap_writepage+0xb0/0x21c > > Read at addr f5ffff81aa71dff8 by task WM.task-4/6956 > > Pointer tag: [f5], memory tag: [f9] > > > > While userspace cannot map drm gem objects with PROT_MTE, the problem is > > shmem_swapin_cluster. When it swaps in a cluster of pages using our gfp > > flags, some of the pages might belong to other mappings that have > > PROT_MTE. > > Okay, let me see if I get this right. The gfp flags we set right now > do what we want for out GEM mappings, it's only when swap readahead is > involved that this becomes problematic: > > 1. swapin folio for GEM inode X > 2. shmem layer optimistically does a readahead on the global swap, with > our GEM gfp flags > 3. the next swap entry belongs to some other tmpfs/anonymous mapping > (not even something on the same GEM mountpoint actually) > 4. because it's our gfp flags that get used for the folio allocation, > the KASAN poisoning takes place, thus messing up with the original > user-request PROT_MTE Yes, that's right. At least that's what I observed. A little more on the last point. shmem readahead allocates a folio for an unrelated mapping using our gfp flags. It unpoisons both the page tag and mte tag for the folio because our gfp flags do not have __GFP_SKIP_KASAN. When the unrelated mapping is an anonymous one, and when do_swap_page maps the folio, arch_swap_restore restores the mte tag. This creates mismatching page tag and mte tag. When, for example, swap_writepage tries to access the folio, kasan triggers a false positive error. > > To me, this looks like a bad isolation of the readahead logic: we > shouldn't cross the inode boundary, because gfp flags for one inode > might be completely different from gfp flags for a different inode. > Let alone the fact the boundary being crossed here is not just inode, > it's basically the entire tmpfs mountpoint. > > TLDR; I strongly believe we're papering over some more fundamental > issue in the shmem swap readahead logic: with MTE, we can no longer > assume gfp flags are interchangeable, they have to be enforced and > match exactly what the user of the swap entry expects, meaning > readahead should be constrained by the inode boundary. I totally agree. shmem should not readahead past its inode. Or perhaps it should force __GFP_SKIP_KASAN when it does. Adding shmem and kasan maintainers for suggestions/corrections. > > > > > Signed-off-by: Chia-I Wu <olvaffe@gmail.com> > > --- > > The latest snapdragons appear to have MTE support. drm/msm might need > > the same treatment. > > --- > > drivers/gpu/drm/panthor/panthor_gem.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c > > index 13295d7a593df..08c03aa0db2f7 100644 > > --- a/drivers/gpu/drm/panthor/panthor_gem.c > > +++ b/drivers/gpu/drm/panthor/panthor_gem.c > > @@ -1013,7 +1013,8 @@ panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags, > > * going to pin these pages. > > */ > > mapping_set_gfp_mask(bo->base.filp->f_mapping, > > - GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); > > + (GFP_HIGHUSER_MOVABLE & ~__GFP_MOVABLE) | > > + __GFP_RETRY_MAYFAIL | __GFP_NOWARN); > > > > ret = drm_gem_create_mmap_offset(&bo->base); > > if (ret) > > > > --- > > base-commit: 6101f78b684895d5860a96322e607e0f46f433ad > > change-id: 20260512-panthor-kasan-10477239bad1 > > > > Best regards, > > -- > > Chia-I Wu <olvaffe@gmail.com> > > > > >
© 2016 - 2026 Red Hat, Inc.