aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-09-04 12:52:16 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-09-04 12:52:16 +0000
commit6eeccaa91b3884239efc0ad1431bb706c2326540 (patch)
tree71f1edcffd7d96cf129c8f4489b8942e6d234ade /tests
parent291124e3c06f91577777dc2ddecfa38e4de46314 (diff)
downloadsrc-6eeccaa91b3884239efc0ad1431bb706c2326540.tar.gz
src-6eeccaa91b3884239efc0ad1431bb706c2326540.zip
Fix kern_copyin test.
Main part is that kern_copyin on amd64 after LA57 should query the top of UVA for correct operations. In fact it should started doing that after the workaround for AMD bug with IRET in the last user page was fixed by reducing UVA by a page. Also since we started calculating top of UVA, fix MIPS according to the comment. Reported by: lwhsu PR: 248933 Reviewed by: alc, markj Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D26312
Notes
Notes: svn path=/head/; revision=365327
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/kern/kern_copyin.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/tests/sys/kern/kern_copyin.c b/tests/sys/kern/kern_copyin.c
index a8cf0422eec5..ed4225361ec3 100644
--- a/tests/sys/kern/kern_copyin.c
+++ b/tests/sys/kern/kern_copyin.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 The FreeBSD Foundation
+ * Copyright (c) 2015, 2020 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
@@ -31,6 +31,8 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -52,21 +54,54 @@ copyin_checker(uintptr_t uaddr, size_t len)
return (ret == -1 ? errno : 0);
}
+#ifdef __amd64__
+static uintptr_t
+get_maxuser_address(void)
+{
+ size_t len;
+ uintptr_t psstrings;
+ int error, mib[4];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PS_STRINGS;
+ mib[3] = getpid();
+ error = sysctl(mib, nitems(mib), &psstrings, &len, NULL, 0);
+ if (error != 0)
+ return (0);
+
+ if (psstrings == PS_STRINGS_LA57)
+ return (VM_MAXUSER_ADDRESS_LA57);
+ if (psstrings == PS_STRINGS_LA48)
+ return (VM_MAXUSER_ADDRESS_LA48);
+ /* AMD LA48 with clipped UVA */
+ if (psstrings == PS_STRINGS_LA48 - PAGE_SIZE)
+ return (VM_MAXUSER_ADDRESS_LA48 - PAGE_SIZE);
+ return (0);
+}
+#endif
+
#define FMAX ULONG_MAX
ATF_TC_WITHOUT_HEAD(kern_copyin);
ATF_TC_BODY(kern_copyin, tc)
{
char template[] = "copyin.XXXXXX";
+ uintptr_t maxuser;
-#ifdef __mips__
+#if defined(__mips__)
/*
* MIPS has different VM layout: the UVA map on mips ends the
* highest mapped entry at the VM_MAXUSER_ADDRESS - PAGE_SIZE,
* while all other arches map either stack or shared page up
* to the VM_MAXUSER_ADDRESS.
*/
- atf_tc_skip("Platform is not supported.");
+ maxuser = VM_MAXUSER_ADDRESS - PAGE_SIZE;
+#elif defined(__amd64__)
+ maxuser = get_maxuser_address();
+ ATF_REQUIRE(maxuser != 0);
+#else
+ maxuser = VM_MAXUSER_ADDRESS;
#endif
scratch_file = mkstemp(template);
@@ -74,15 +109,15 @@ ATF_TC_BODY(kern_copyin, tc)
unlink(template);
ATF_CHECK(copyin_checker(0, 0) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS - 10, 9) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS - 10, 10) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS - 10, 11) == EFAULT);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS - 1, 1) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS, 0) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS, 1) == EFAULT);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS, 2) == EFAULT);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS + 1, 0) == 0);
- ATF_CHECK(copyin_checker(VM_MAXUSER_ADDRESS + 1, 2) == EFAULT);
+ ATF_CHECK(copyin_checker(maxuser - 10, 9) == 0);
+ ATF_CHECK(copyin_checker(maxuser - 10, 10) == 0);
+ ATF_CHECK(copyin_checker(maxuser - 10, 11) == EFAULT);
+ ATF_CHECK(copyin_checker(maxuser - 1, 1) == 0);
+ ATF_CHECK(copyin_checker(maxuser, 0) == 0);
+ ATF_CHECK(copyin_checker(maxuser, 1) == EFAULT);
+ ATF_CHECK(copyin_checker(maxuser, 2) == EFAULT);
+ ATF_CHECK(copyin_checker(maxuser + 1, 0) == 0);
+ ATF_CHECK(copyin_checker(maxuser + 1, 2) == EFAULT);
ATF_CHECK(copyin_checker(FMAX - 10, 9) == EFAULT);
ATF_CHECK(copyin_checker(FMAX - 10, 10) == EFAULT);
ATF_CHECK(copyin_checker(FMAX - 10, 11) == EFAULT);