To: Andrew Morton <akpm@linux-foundation.org>
To: Muchun Song <muchun.song@linux.dev>
To: Oscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@kernel.org>
Cc: Wei Yang <richard.weiyang@linux.alibaba.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-mm@kvack.org
Cc: linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: stable@vger.kernel.org
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