[PATCH 0/2] mm/hugetlb: fix list corruption in allocate_file_region_entries()

From: Xiangfeng Cai

Date: Mon Jul 13 2026 - 13:18:11 EST


To: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
To: Muchun Song <muchun.song@xxxxxxxxx>
To: Oscar Salvador <osalvador@xxxxxxx>
Cc: David Hildenbrand <david@xxxxxxxxxx>
Cc: Wei Yang <richard.weiyang@xxxxxxxxxxxxxxxxx>
Cc: Baoquan He <baoquan.he@xxxxxxxxx>
Cc: Shuah Khan <shuah@xxxxxxxxxx>
Cc: linux-mm@xxxxxxxxx
Cc: linux-kselftest@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: stable@xxxxxxxxxxxxxxx

allocate_file_region_entries() refills resv->region_cache with freshly
allocated file_region descriptors. It allocates with GFP_KERNEL, so it
drops resv->lock, gathers the new entries on a stack-local list head, and
on regaining the lock moves them into resv->region_cache with
list_splice(). list_splice() does not re-initialize the source head, so
if the retry loop iterates again -- which happens when a concurrent
region_* operation on the same shared resv_map consumes cache entries
during the unlocked window -- the next list_add() operates on the stale,
already spliced head and corrupts the list. On a CONFIG_DEBUG_LIST=y
kernel this is a hard BUG(); without list debugging it silently links a
kernel-stack address into resv->region_cache.

This was observed as a real host panic on a dense KVM host where a QEMU
guest-RAM hugetlbfs file was mapped MAP_SHARED by both QEMU and a separate
SPDK/DPDK vhost-user target, generating concurrent region_* traffic on one
shared resv_map.

Patch 1 fixes it by using list_splice_init(). The bug is present in
mainline; the Fixes: commit dates back to v5.10.

Patch 2 adds a selftest that reproduces the race (opt-in --trigger mode,
since it panics a vulnerable host) and runs a safe single-threaded
functional check by default.

Xiangfeng Cai (2):
mm/hugetlb: fix list corruption in allocate_file_region_entries()
selftests/mm: add hugetlb_region_cache_race regression test

mm/hugetlb.c | 2 +-
tools/testing/selftests/mm/.gitignore | 1 +
tools/testing/selftests/mm/Makefile | 1 +
.../selftests/mm/hugetlb_region_cache_race.c | 315 ++++++++++++++++++
tools/testing/selftests/mm/run_vmtests.sh | 1 +
5 files changed, 319 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/mm/hugetlb_region_cache_race.c

--
2.55.0.122.gf85a7e6620