From: Wei Yang <richard.weiyang@gmail.com>
To: akpm@linux-foundation.org, Liam.Howlett@oracle.com,
lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com
Cc: linux-mm@kvack.org, Wei Yang <richard.weiyang@gmail.com>,
"Liam R . Howlett" <Liam.Howlett@Oracle.com>
Subject: [PATCH 2/2] tools: testing: add unmapped_area() tests
Date: Mon, 27 Jan 2025 07:55:27 +0000 [thread overview]
Message-ID: <20250127075527.16614-3-richard.weiyang@gmail.com> (raw)
In-Reply-To: <20250127075527.16614-1-richard.weiyang@gmail.com>
Leverage the userland vma tests to verify unmapped_area{_topdown}
behavior.
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
CC: Liam R. Howlett <Liam.Howlett@Oracle.com>
CC: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
CC: Vlastimil Babka <vbabka@suse.cz>
CC: Jann Horn <jannh@google.com>
---
tools/testing/vma/vma.c | 177 +++++++++++++++++++++++++++++++
tools/testing/vma/vma_internal.h | 2 +-
2 files changed, 178 insertions(+), 1 deletion(-)
diff --git a/tools/testing/vma/vma.c b/tools/testing/vma/vma.c
index 6c31118d5fe5..3c1817b01ac8 100644
--- a/tools/testing/vma/vma.c
+++ b/tools/testing/vma/vma.c
@@ -1735,6 +1735,182 @@ static bool test_mmap_region_basic(void)
return true;
}
+static bool test_unmapped_area(void)
+{
+ struct mm_struct mm = {};
+ struct vm_unmapped_area_info info = {};
+ unsigned long addr, addr1, addr2, addr3, addr4;
+ unsigned long low = mmap_min_addr + 0x2000, size = 0x1000, gap = 0x1000;
+ unsigned long stack_guard_gap_old = stack_guard_gap;
+
+ VMA_ITERATOR(vmi, &mm, 0);
+
+ current->mm = &mm;
+
+ /* adjust guard gap for test */
+ stack_guard_gap = gap;
+
+ /*
+ * Prepare a range like this:
+ *
+ * 0123456789abcdef
+ * m m m m
+ * ma m m am start_gap = 0
+ * m am m am start_gap = 0x1000
+ * m m aam m start_gap = 0x2000
+ */
+ addr1 = low;
+ __mmap_region(NULL, addr1, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE,
+ addr1 >> PAGE_SHIFT, NULL);
+ addr2 = addr1 + size + (gap * 2);
+ __mmap_region(NULL, addr2, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE,
+ addr2 >> PAGE_SHIFT, NULL);
+ addr3 = addr2 + size + (gap * 4);
+ __mmap_region(NULL, addr3, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE,
+ addr3 >> PAGE_SHIFT, NULL);
+ addr4 = addr3 + size + (gap * 2);
+ __mmap_region(NULL, addr4, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE,
+ addr4 >> PAGE_SHIFT, NULL);
+
+ /* start_gap == 0 */
+ info.length = size;
+ info.low_limit = low;
+ info.high_limit = addr4 + size;
+ info.start_gap = 0;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr1 + size);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr4 - size);
+
+ /* start_gap == 0x1000 */
+ info.start_gap = gap;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr1 + size + info.start_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr4 - size);
+
+ /* start_gap == 0x2000 */
+ info.start_gap = gap * 2;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr2 + size + info.start_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr3 - size);
+
+ cleanup_mm(&mm, &vmi);
+
+ /*
+ * Prepare a range like this with VM_GROWSDOWN set:
+ *
+ * 0123456789abcdef
+ * m m m m
+ * ma m ma m start_gap = 0
+ * m m aa m m start_gap = 0x1000
+ * m m a m m start_gap = 0x2000
+ */
+ addr1 = low;
+ __mmap_region(NULL, addr1, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSDOWN,
+ addr1 >> PAGE_SHIFT, NULL);
+ addr2 = addr1 + size + (gap * 2);
+ __mmap_region(NULL, addr2, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSDOWN,
+ addr2 >> PAGE_SHIFT, NULL);
+ addr3 = addr2 + size + (gap * 4);
+ __mmap_region(NULL, addr3, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSDOWN,
+ addr3 >> PAGE_SHIFT, NULL);
+ addr4 = addr3 + size + (gap * 2);
+ __mmap_region(NULL, addr4, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSDOWN,
+ addr4 >> PAGE_SHIFT, NULL);
+
+ /* start_gap == 0 */
+ info.length = size;
+ info.low_limit = low;
+ info.high_limit = addr4 + size;
+ info.start_gap = 0;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr1 + size);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr4 - stack_guard_gap - size);
+
+ /* start_gap == 0x1000 */
+ info.start_gap = gap;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr2 + size + info.start_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr3 - stack_guard_gap - size);
+
+ /* start_gap == 0x2000 */
+ info.start_gap = gap * 2;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr2 + size + info.start_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr3 - stack_guard_gap - size);
+
+ cleanup_mm(&mm, &vmi);
+
+ /*
+ * Prepare a range like this with VM_GROWSUP set:
+ *
+ * 0123456789abcdef
+ * m m m m
+ * m am m am start_gap = 0
+ * m am m am start_gap = 0x1000
+ * m m aam m start_gap = 0x2000
+ */
+ addr1 = low;
+ __mmap_region(NULL, addr1, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSUP,
+ addr1 >> PAGE_SHIFT, NULL);
+ addr2 = addr1 + size + (gap * 2);
+ __mmap_region(NULL, addr2, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSUP,
+ addr2 >> PAGE_SHIFT, NULL);
+ addr3 = addr2 + size + (gap * 4);
+ __mmap_region(NULL, addr3, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSUP,
+ addr3 >> PAGE_SHIFT, NULL);
+ addr4 = addr3 + size + (gap * 2);
+ __mmap_region(NULL, addr4, size,
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_GROWSUP,
+ addr4 >> PAGE_SHIFT, NULL);
+
+ /* start_gap == 0 */
+ info.length = size;
+ info.low_limit = low;
+ info.high_limit = addr4 + size;
+ info.start_gap = 0;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr1 + size + stack_guard_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr4 - size);
+
+ /* start_gap == 0x1000 */
+ info.start_gap = gap;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr1 + size + stack_guard_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr4 - size);
+
+ /* start_gap == 0x2000 */
+ info.start_gap = gap * 2;
+ addr = unmapped_area(&info);
+ ASSERT_EQ(addr, addr2 + size + info.start_gap);
+ addr = unmapped_area_topdown(&info);
+ ASSERT_EQ(addr, addr3 - size);
+
+ cleanup_mm(&mm, &vmi);
+
+ /* restore stack_guard_gap */
+ stack_guard_gap = stack_guard_gap_old;
+ return true;
+}
+
int main(void)
{
int num_tests = 0, num_fail = 0;
@@ -1769,6 +1945,7 @@ int main(void)
TEST(expand_only_mode);
TEST(mmap_region_basic);
+ TEST(unmapped_area);
#undef TEST
diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
index 1eae23039854..37b47fb85a3b 100644
--- a/tools/testing/vma/vma_internal.h
+++ b/tools/testing/vma/vma_internal.h
@@ -65,7 +65,7 @@ extern unsigned long dac_mmap_min_addr;
#define VM_SHADOW_STACK VM_NONE
#define VM_SOFTDIRTY 0
#define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
-#define VM_GROWSUP VM_NONE
+#define VM_GROWSUP VM_ARCH_1
#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
--
2.34.1
next prev parent reply other threads:[~2025-01-27 7:55 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-27 7:55 [PATCH 0/2] vma: fix unmapped_area() Wei Yang
2025-01-27 7:55 ` [PATCH 1/2] mm/vma: fix gap check for unmapped_area with VM_GROWSDOWN Wei Yang
2025-01-27 12:08 ` Lorenzo Stoakes
2025-01-28 3:30 ` Wei Yang
2025-01-28 6:32 ` Lorenzo Stoakes
2025-01-27 7:55 ` Wei Yang [this message]
2025-01-27 12:26 ` [PATCH 2/2] tools: testing: add unmapped_area() tests Lorenzo Stoakes
2025-01-27 10:50 ` [PATCH 0/2] vma: fix unmapped_area() Lorenzo Stoakes
2025-01-28 1:56 ` Wei Yang
2025-01-28 6:38 ` Lorenzo Stoakes
2025-01-27 14:19 ` Liam R. Howlett
2025-01-28 2:00 ` Wei Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250127075527.16614-3-richard.weiyang@gmail.com \
--to=richard.weiyang@gmail.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=jannh@google.com \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=vbabka@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.