From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755316AbdKPKvM (ORCPT ); Thu, 16 Nov 2017 05:51:12 -0500 Received: from terminus.zytor.com ([65.50.211.136]:36115 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933819AbdKPKuu (ORCPT ); Thu, 16 Nov 2017 05:50:50 -0500 Date: Thu, 16 Nov 2017 02:46:41 -0800 From: "tip-bot for Kirill A. Shutemov" Message-ID: Cc: npiggin@gmail.com, luto@amacapital.net, kirill.shutemov@linux.intel.com, hpa@zytor.com, torvalds@linux-foundation.org, tglx@linutronix.de, mingo@kernel.org, linux-kernel@vger.kernel.org Reply-To: kirill.shutemov@linux.intel.com, npiggin@gmail.com, luto@amacapital.net, torvalds@linux-foundation.org, hpa@zytor.com, tglx@linutronix.de, mingo@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20171115143607.81541-2-kirill.shutemov@linux.intel.com> References: <20171115143607.81541-2-kirill.shutemov@linux.intel.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/urgent] x86/selftests: Add test for mapping placement for 5-level paging Git-Commit-ID: 97f404ad3e53bf9ac598745066ba2f57c1da3039 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 97f404ad3e53bf9ac598745066ba2f57c1da3039 Gitweb: https://git.kernel.org/tip/97f404ad3e53bf9ac598745066ba2f57c1da3039 Author: Kirill A. Shutemov AuthorDate: Wed, 15 Nov 2017 17:36:07 +0300 Committer: Thomas Gleixner CommitDate: Thu, 16 Nov 2017 11:43:12 +0100 x86/selftests: Add test for mapping placement for 5-level paging 5-level paging provides a 56-bit virtual address space for user space application. But the kernel defaults to mappings below the 47-bit address space boundary, which is the upper bound for 4-level paging, unless an application explicitely request it by using a mmap(2) address hint above the 47-bit boundary. The kernel prevents mappings which spawn across the 47-bit boundary unless mmap(2) was invoked with MAP_FIXED. Add a self-test that covers the corner cases of the interface and validates the correctness of the implementation. [ tglx: Massaged changelog once more ] Signed-off-by: Kirill A. Shutemov Signed-off-by: Thomas Gleixner Cc: Nicholas Piggin Cc: Andy Lutomirski Cc: linux-mm@kvack.org Cc: Linus Torvalds Link: https://lkml.kernel.org/r/20171115143607.81541-2-kirill.shutemov@linux.intel.com --- tools/testing/selftests/x86/5lvl.c | 177 +++++++++++++++++++++++++++++++++++ tools/testing/selftests/x86/Makefile | 2 +- 2 files changed, 178 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/x86/5lvl.c b/tools/testing/selftests/x86/5lvl.c new file mode 100644 index 0000000..2eafdcd --- /dev/null +++ b/tools/testing/selftests/x86/5lvl.c @@ -0,0 +1,177 @@ +#include +#include + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define PAGE_SIZE 4096 +#define LOW_ADDR ((void *) (1UL << 30)) +#define HIGH_ADDR ((void *) (1UL << 50)) + +struct testcase { + void *addr; + unsigned long size; + unsigned long flags; + const char *msg; + unsigned int low_addr_required:1; + unsigned int keep_mapped:1; +}; + +static struct testcase testcases[] = { + { + .addr = NULL, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(NULL)", + .low_addr_required = 1, + }, + { + .addr = LOW_ADDR, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(LOW_ADDR)", + .low_addr_required = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(HIGH_ADDR)", + .keep_mapped = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(HIGH_ADDR) again", + .keep_mapped = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + .msg = "mmap(HIGH_ADDR, MAP_FIXED)", + }, + { + .addr = (void*) -1, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(-1)", + .keep_mapped = 1, + }, + { + .addr = (void*) -1, + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(-1) again", + }, + { + .addr = (void *)((1UL << 47) - PAGE_SIZE), + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap((1UL << 47), 2 * PAGE_SIZE)", + .low_addr_required = 1, + .keep_mapped = 1, + }, + { + .addr = (void *)((1UL << 47) - PAGE_SIZE / 2), + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)", + .low_addr_required = 1, + .keep_mapped = 1, + }, + { + .addr = (void *)((1UL << 47) - PAGE_SIZE), + .size = 2 * PAGE_SIZE, + .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + .msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)", + }, + { + .addr = NULL, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(NULL, MAP_HUGETLB)", + .low_addr_required = 1, + }, + { + .addr = LOW_ADDR, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(LOW_ADDR, MAP_HUGETLB)", + .low_addr_required = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)", + .keep_mapped = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again", + .keep_mapped = 1, + }, + { + .addr = HIGH_ADDR, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)", + }, + { + .addr = (void*) -1, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(-1, MAP_HUGETLB)", + .keep_mapped = 1, + }, + { + .addr = (void*) -1, + .size = 2UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap(-1, MAP_HUGETLB) again", + }, + { + .addr = (void *)((1UL << 47) - PAGE_SIZE), + .size = 4UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, + .msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)", + .low_addr_required = 1, + .keep_mapped = 1, + }, + { + .addr = (void *)((1UL << 47) - (2UL << 20)), + .size = 4UL << 20, + .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + .msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)", + }, +}; + +int main(int argc, char **argv) +{ + int i; + void *p; + + for (i = 0; i < ARRAY_SIZE(testcases); i++) { + struct testcase *t = testcases + i; + + p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0); + + printf("%s: %p - ", t->msg, p); + + if (p == MAP_FAILED) { + printf("FAILED\n"); + continue; + } + + if (t->low_addr_required && p >= (void *)(1UL << 47)) + printf("FAILED\n"); + else + printf("OK\n"); + if (!t->keep_mapped) + munmap(p, t->size); + } + return 0; +} diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 7b1adee..939a337 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -11,7 +11,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer -TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip +TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)