Re: [PATCH v2 2/3] KVM: selftests: arm64: Skip sea_to_user without 1GB hugepages

Like Xu <[email protected]>
Newsgroups dev.linux.lists.kvmarm,dev.linux.lists.sashiko-reviews,org.kernel.vger.kvm
Message-ID <[email protected]>
On 8/18/26 7:36 PM, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] get_free_hugepages() overestimates available hugepages by ignoring reserved pages, which allows the test to proceed and crash with ENOMEM on systems with reserved pools.
> --
> 
> --- Patch [2]: [PATCH v2 2/3] KVM: selftests: arm64: Skip sea_to_user without 1GB hugepages ---
> commit 5fa5666824342b3dd28a5ef6a04bb5ac183257c8
> Author: Like Xu <[email protected]>
> 
> KVM: selftests: arm64: Skip sea_to_user without 1GB hugepages
> 
> This commit adds a check to skip the sea_to_user test if the host does not
> have enough 1GB hugepages available, preventing a hard failure on systems
> without an empty pool.
> 
> [ ... ]
>> diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/selftests/kvm/lib/test_util.c
>> index bab1bd2b775b6..29f9c1d60b1b7 100644
>> --- a/tools/testing/selftests/kvm/lib/test_util.c
>> +++ b/tools/testing/selftests/kvm/lib/test_util.c
>> @@ -222,6 +222,21 @@ size_t get_def_hugetlb_pagesz(void)
>>   	TEST_FAIL("Error in reading /proc/meminfo");
>>   }
>>   
>> +size_t get_free_hugepages(size_t page_size)
>> +{
>> +	char path[128];
>> +	size_t free;
>> +
>> +	snprintf(path, sizeof(path),
>> +		 "/sys/kernel/mm/hugepages/hugepages-%zukB/free_hugepages",
>> +		 page_size >> 10);
>> +	if (!test_sysfs_path(path))
>> +		return 0;
>> +
>> +	free = get_sysfs_val(path);
>> +	return free * page_size;
> 
> [Severity: Medium]
> Does this calculation overestimate the available hugepages by ignoring the
> reserved pool?
> 
> The sysfs free_hugepages value includes pages that are already committed to
> other mappings but not yet allocated (which are tracked via resv_hugepages).
> 
> If the test runs on a host where free_hugepages meets the VM_MEM_SIZE
> requirement but some or all of those pages are reserved, the test will
> incorrectly proceed and still crash with an -ENOMEM abort instead of cleanly
> skipping.
> 
> Could we also read and subtract resv_hugepages to determine the actual
> allocatable count?

For any human to double check:

diff --git a/tools/testing/selftests/kvm/arm64/sea_to_user.c 
b/tools/testing/selftests/kvm/arm64/sea_to_user.c
index 1c2a743ca8e23..7cf95da8e594d 100644
--- a/tools/testing/selftests/kvm/arm64/sea_to_user.c
+++ b/tools/testing/selftests/kvm/arm64/sea_to_user.c
@@ -281,6 +281,12 @@ static struct kvm_vm 
*vm_create_with_sea_handler(struct kvm_vcpu **vcpu)
  	alignment = max(backing_page_size, guest_page_size);
  	num_guest_pages = VM_MEM_SIZE / guest_page_size;

+	/*
+	 * The region is backed by 1GB hugepages; skip gracefully rather than
+	 * failing with mmap() -ENOMEM if the host has none reserved.
+	 */
+	TEST_REQUIRE(get_free_hugepages(backing_page_size) >= VM_MEM_SIZE);
+
  	vm = __vm_create_with_one_vcpu(vcpu, num_guest_pages, guest_code);
  	vm_init_descriptor_tables(vm);
  	vcpu_init_descriptor_tables(*vcpu);
diff --git a/tools/testing/selftests/kvm/include/test_util.h 
b/tools/testing/selftests/kvm/include/test_util.h
index a56271c237ae9..0624922c2735d 100644
--- a/tools/testing/selftests/kvm/include/test_util.h
+++ b/tools/testing/selftests/kvm/include/test_util.h
@@ -168,6 +168,7 @@ struct vm_mem_backing_src_alias {
  bool thp_configured(void);
  size_t get_trans_hugepagesz(void);
  size_t get_def_hugetlb_pagesz(void);
+size_t get_free_hugepages(size_t page_size);
  const struct vm_mem_backing_src_alias *vm_mem_backing_src_alias(u32 i);
  size_t get_backing_src_pagesz(u32 i);
  bool is_backing_src_hugetlb(u32 i);
diff --git a/tools/testing/selftests/kvm/lib/test_util.c 
b/tools/testing/selftests/kvm/lib/test_util.c
index bab1bd2b775b6..3bff9d825e8af 100644
--- a/tools/testing/selftests/kvm/lib/test_util.c
+++ b/tools/testing/selftests/kvm/lib/test_util.c
@@ -222,6 +222,32 @@ size_t get_def_hugetlb_pagesz(void)
  	TEST_FAIL("Error in reading /proc/meminfo");
  }

+size_t get_free_hugepages(size_t page_size)
+{
+	char path[128];
+	size_t free, resv;
+
+	snprintf(path, sizeof(path),
+		 "/sys/kernel/mm/hugepages/hugepages-%zukB/free_hugepages",
+		 page_size >> 10);
+	if (!test_sysfs_path(path))
+		return 0;
+	free = get_sysfs_val(path);
+
+	/*
+	 * free_hugepages still counts pages that are reserved by existing
+	 * mappings but not yet faulted in, so only free minus resv can back a
+	 * new reservation (see available_huge_pages() in mm/hugetlb.c). Ignore
+	 * surplus/overcommit: it does not apply to gigantic pages at runtime.
+	 */
+	snprintf(path, sizeof(path),
+		 "/sys/kernel/mm/hugepages/hugepages-%zukB/resv_hugepages",
+		 page_size >> 10);
+	resv = test_sysfs_path(path) ? get_sysfs_val(path) : 0;
+
+	return free > resv ? (free - resv) * page_size : 0;
+}
+
  #define ANON_FLAGS	(MAP_PRIVATE | MAP_ANONYMOUS)
  #define ANON_HUGE_FLAGS	(ANON_FLAGS | MAP_HUGETLB)

> 
>> +}
>> +
>>   #define ANON_FLAGS	(MAP_PRIVATE | MAP_ANONYMOUS)
>>   #define ANON_HUGE_FLAGS	(ANON_FLAGS | MAP_HUGETLB)
>>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.