aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Liaw <edliaw@google.com>2023-10-09 20:23:13 +0000
committerEdward Liaw <edliaw@google.com>2023-10-12 22:07:50 +0000
commit984fbcd5cb4de0bee50378b26d86da8d810e2f49 (patch)
treeef2edb14efd15dd53311644d25caaa893f549a02
parent236e58f2f3f5099cbf4e10138f9ac7ca0c79c81c (diff)
downloadlinux-kselftest-984fbcd5cb4de0bee50378b26d86da8d810e2f49.tar.gz
kselftest: Apply android/patches to 6.1 merge
Bug: 303675116 Test: atest vts_linux_kselftest_x86_64 Test: atest vts_linux_kselftest_arm_64 Change-Id: Ic95543014df0bfd50b45572c582e22f4ae24f5d4 Signed-off-by: Edward Liaw <edliaw@google.com>
-rw-r--r--tools/testing/selftests/capabilities/test_execve.c2
-rw-r--r--tools/testing/selftests/exec/execveat.c2
-rwxr-xr-xtools/testing/selftests/exec/execveat.sh33
-rw-r--r--tools/testing/selftests/filesystems/binderfs/binderfs_test.c10
-rwxr-xr-xtools/testing/selftests/futex/functional/run.sh78
-rw-r--r--tools/testing/selftests/kcmp/kcmp_test.c2
-rw-r--r--tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c174
-rw-r--r--tools/testing/selftests/net/psock_tpacket.c32
-rw-r--r--tools/testing/selftests/rtc/rtctest.c2
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c141
-rw-r--r--tools/testing/selftests/timers/valid-adjtimex.c3
-rw-r--r--tools/testing/selftests/vDSO/parse_vdso.c7
-rwxr-xr-xtools/testing/selftests/vm/run_vmtests.sh298
-rw-r--r--tools/testing/selftests/vm/userfaultfd.c86
-rw-r--r--tools/testing/selftests/x86/test_FISTTP.c18
15 files changed, 693 insertions, 195 deletions
diff --git a/tools/testing/selftests/capabilities/test_execve.c b/tools/testing/selftests/capabilities/test_execve.c
index df0ef02b4036..08667a0159c7 100644
--- a/tools/testing/selftests/capabilities/test_execve.c
+++ b/tools/testing/selftests/capabilities/test_execve.c
@@ -91,7 +91,7 @@ static bool create_and_enter_ns(uid_t inner_uid)
uid_t outer_uid;
gid_t outer_gid;
int i;
- bool have_outer_privilege;
+ bool have_outer_privilege = false;
outer_uid = getuid();
outer_gid = getgid();
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index 67bf7254a48f..ecc974e75a9b 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -379,7 +379,7 @@ static int run_tests(void)
static void prerequisites(void)
{
int fd;
- const char *script = "#!/bin/sh\nexit $*\n";
+ const char *script = "#!/system/bin/sh\nexit $*\n";
/* Create ephemeral copies of files */
exe_cp("execveat", "execveat.ephemeral");
diff --git a/tools/testing/selftests/exec/execveat.sh b/tools/testing/selftests/exec/execveat.sh
new file mode 100755
index 000000000000..dc049eaef690
--- /dev/null
+++ b/tools/testing/selftests/exec/execveat.sh
@@ -0,0 +1,33 @@
+#!/system/bin/sh
+
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# These are normally created as part of the kselftest build but for VTS
+# it is probably easier to use a wrapper script that creates them
+# at runtime, on target, as part of the test.
+
+DIR=$(dirname "$0")
+cd $DIR && \
+mkdir -p subdir && \
+echo '#!/system/bin/sh' > script && \
+echo 'exit $*' >> script && \
+chmod +x script && \
+touch Makefile && \
+ln -s -f execveat execveat.symlink && \
+cp execveat execveat.denatured && \
+chmod -x execveat.denatured && \
+./execveat
diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c
index 5f362c0fd890..047b228fcb91 100644
--- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c
+++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c
@@ -291,6 +291,11 @@ static int write_id_mapping(enum idmap_type type, pid_t pid, const char *buf,
return 0;
}
+static bool has_userns()
+{
+ return (access("/proc/self/ns/user", F_OK) == 0);
+}
+
static void change_userns(struct __test_metadata *_metadata, int syncfds[2])
{
int ret;
@@ -378,6 +383,9 @@ static void *binder_version_thread(void *data)
*/
TEST(binderfs_stress)
{
+ if (!has_userns())
+ SKIP(return, "%s: user namespace not supported\n", __func__);
+
int fds[1000];
int syncfds[2];
pid_t pid;
@@ -502,6 +510,8 @@ TEST(binderfs_test_privileged)
TEST(binderfs_test_unprivileged)
{
+ if (!has_userns())
+ SKIP(return, "%s: user namespace not supported\n", __func__);
int ret;
int syncfds[2];
pid_t pid;
diff --git a/tools/testing/selftests/futex/functional/run.sh b/tools/testing/selftests/futex/functional/run.sh
index 5ccd599da6c3..f7bd16078707 100755
--- a/tools/testing/selftests/futex/functional/run.sh
+++ b/tools/testing/selftests/futex/functional/run.sh
@@ -18,6 +18,16 @@
#
###############################################################################
+run_test()
+{
+ $@
+ ret=$?
+ if [ $ret -ne 0 ] && [ $ret -ne 4 ]; then # KSFT_SKIP=4
+ echo "Failed with $ret"
+ rc=1
+ fi
+}
+
# Test for a color capable console
if [ -z "$USE_COLOR" ]; then
tput setf 7 || tput setaf 7
@@ -34,51 +44,57 @@ fi
echo
# requeue pi testing
# without timeouts
-./futex_requeue_pi $COLOR
-./futex_requeue_pi $COLOR -b
-./futex_requeue_pi $COLOR -b -l
-./futex_requeue_pi $COLOR -b -o
-./futex_requeue_pi $COLOR -l
-./futex_requeue_pi $COLOR -o
+run_test ./futex_requeue_pi $COLOR
+run_test ./futex_requeue_pi $COLOR -b
+run_test ./futex_requeue_pi $COLOR -b -l
+run_test ./futex_requeue_pi $COLOR -b -o
+run_test ./futex_requeue_pi $COLOR -l
+run_test ./futex_requeue_pi $COLOR -o
# with timeouts
-./futex_requeue_pi $COLOR -b -l -t 5000
-./futex_requeue_pi $COLOR -l -t 5000
-./futex_requeue_pi $COLOR -b -l -t 500000
-./futex_requeue_pi $COLOR -l -t 500000
-./futex_requeue_pi $COLOR -b -t 5000
-./futex_requeue_pi $COLOR -t 5000
-./futex_requeue_pi $COLOR -b -t 500000
-./futex_requeue_pi $COLOR -t 500000
-./futex_requeue_pi $COLOR -b -o -t 5000
-./futex_requeue_pi $COLOR -l -t 5000
-./futex_requeue_pi $COLOR -b -o -t 500000
-./futex_requeue_pi $COLOR -l -t 500000
+run_test ./futex_requeue_pi $COLOR -b -l -t 5000
+run_test ./futex_requeue_pi $COLOR -l -t 5000
+run_test ./futex_requeue_pi $COLOR -b -l -t 500000
+run_test ./futex_requeue_pi $COLOR -l -t 500000
+run_test ./futex_requeue_pi $COLOR -b -t 5000
+run_test ./futex_requeue_pi $COLOR -t 5000
+run_test ./futex_requeue_pi $COLOR -b -t 500000
+run_test ./futex_requeue_pi $COLOR -t 500000
+run_test ./futex_requeue_pi $COLOR -b -o -t 5000
+run_test ./futex_requeue_pi $COLOR -l -t 5000
+run_test ./futex_requeue_pi $COLOR -b -o -t 500000
+run_test ./futex_requeue_pi $COLOR -l -t 500000
# with long timeout
-./futex_requeue_pi $COLOR -b -l -t 2000000000
-./futex_requeue_pi $COLOR -l -t 2000000000
+run_test ./futex_requeue_pi $COLOR -b -l -t 2000000000
+run_test ./futex_requeue_pi $COLOR -l -t 2000000000
echo
-./futex_requeue_pi_mismatched_ops $COLOR
+run_test ./futex_requeue_pi_mismatched_ops $COLOR
echo
-./futex_requeue_pi_signal_restart $COLOR
+run_test ./futex_requeue_pi_signal_restart $COLOR
echo
-./futex_wait_timeout $COLOR
+run_test ./futex_wait_timeout $COLOR
echo
-./futex_wait_wouldblock $COLOR
+run_test ./futex_wait_wouldblock $COLOR
echo
-./futex_wait_uninitialized_heap $COLOR
-./futex_wait_private_mapped_file $COLOR
+run_test ./futex_wait_uninitialized_heap $COLOR
+run_test ./futex_wait_private_mapped_file $COLOR
-echo
-./futex_wait $COLOR
+# b/234151152
+# Disable because system v shared memory not available
+#echo
+#run_test ./futex_wait $COLOR
echo
-./futex_requeue $COLOR
+run_test ./futex_requeue $COLOR
-echo
-./futex_waitv $COLOR
+# b/234151152
+# Disable because system v shared memory not available
+#echo
+#run_test ./futex_waitv $COLOR
+
+exit $rc
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c
index 25110c7c0b3e..d7a8e321bb16 100644
--- a/tools/testing/selftests/kcmp/kcmp_test.c
+++ b/tools/testing/selftests/kcmp/kcmp_test.c
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
ksft_print_header();
ksft_set_plan(3);
- fd2 = open(kpath, O_RDWR, 0644);
+ fd2 = open(kpath, O_RDWR);
if (fd2 < 0) {
perror("Can't open file");
ksft_exit_fail();
diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c
new file mode 100644
index 000000000000..4af8ca3c4bad
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test checking that memory of protected guests is wiped after teardown.
+ *
+ * Copyright (C) 2022, Google LLC.
+ */
+
+#define _GNU_SOURCE
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <linux/kvm.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include "kselftest.h"
+
+#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31)
+
+#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL)
+#define REG_PC 0x6030000000100040ULL
+
+static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val)
+{
+ uint64_t reg_data;
+ struct kvm_one_reg reg;
+ int ret;
+
+ reg.addr = (__u64) &reg_data;
+ reg_data = val;
+ reg.id = reg_id;
+
+ ret = ioctl(vcpufd, KVM_SET_ONE_REG, &reg);
+ if (ret < 0)
+ ksft_exit_fail_msg("Failed to set reg: %d\n", ret);
+}
+
+static int get_kvm(void)
+{
+ size_t run_size;
+ int kvm, ret;
+
+ kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC);
+ if (kvm < 0)
+ ksft_exit_skip("KVM not supported\n");
+
+ ret = ioctl(kvm, KVM_GET_API_VERSION, NULL);
+ if (ret != 12)
+ ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret);
+
+ run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL);
+ if (run_size < sizeof(struct kvm_run))
+ ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n");
+
+ return kvm;
+}
+
+static int create_protected_vm(int kvm)
+{
+ int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED);
+
+ if (vmfd < 0)
+ ksft_exit_skip("Protected guests not supported: %d\n", vmfd);
+
+ return vmfd;
+}
+
+static int create_vcpu(int vmfd, struct kvm_run **run)
+{
+ struct kvm_vcpu_init vcpu_init;
+ int vcpufd, ret;
+
+ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init);
+ if (ret)
+ ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret);
+
+ vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0);
+ if (vcpufd < 0)
+ ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd);
+
+ *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0);
+ if (!run)
+ ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n");
+
+ ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init);
+ if (ret)
+ ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret);
+
+ return vcpufd;
+}
+
+static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run)
+{
+ int ret = munmap(run, sizeof(*run));
+
+ if (ret)
+ ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret);
+
+ ret = close(vcpufd);
+ if (ret)
+ ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret);
+
+ ret = close(vmfd);
+ if (ret)
+ ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret);
+
+ ret = close(kvm);
+ if (ret)
+ ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret);
+}
+
+int main(void)
+{
+ struct kvm_userspace_memory_region region;
+ long page_size = sysconf(_SC_PAGESIZE);
+ int ret, kvm, vmfd, vcpufd;
+ uint32_t guest_code[2];
+ struct kvm_run *run;
+ uint8_t *guest_mem;
+ size_t run_size;
+
+ kvm = get_kvm();
+ vmfd = create_protected_vm(kvm);
+ vcpufd = create_vcpu(vmfd, &run);
+
+ /* Create a one-page memslot for the guest */
+ guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (guest_mem == MAP_FAILED)
+ ksft_exit_fail_msg("Failed to mmap guest memory\n");
+ region = (struct kvm_userspace_memory_region) {
+ .slot = 0,
+ .guest_phys_addr = 1UL << 30,
+ .memory_size = page_size,
+ .userspace_addr = (uint64_t)guest_mem,
+ };
+
+ /* Copy some code in guest memory. */
+ guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */
+ guest_code[1] = 0x17ffffff; /* b 1b */
+ memcpy(guest_mem, guest_code, sizeof(guest_code));
+ ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &region);
+ if (ret)
+ ksft_exit_fail_msg("Failed to set memory region: %d\n", ret);
+
+ /*
+ * Get the VCPU to run one instruction, to be sure the page containing
+ * the code has been faulted in.
+ */
+ set_one_reg(vcpufd, REG_PC, region.guest_phys_addr);
+ set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size);
+ ret = ioctl(vcpufd, KVM_RUN, NULL);
+ if (ret)
+ ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret);
+ if (run->exit_reason != KVM_EXIT_MMIO)
+ ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason);
+
+ /*
+ * Tear the guest down, and check that the donated memory has been
+ * wiped by the hypervisor.
+ */
+ teardown(kvm, vmfd, vcpufd, run);
+ if (!memcmp(guest_mem, guest_code, sizeof(guest_code)))
+ ksft_exit_fail_msg("Protected guest memory has not been poisoned\n");
+
+ ksft_exit_pass();
+}
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c
index 404a2ce759ab..9696c9e484d5 100644
--- a/tools/testing/selftests/net/psock_tpacket.c
+++ b/tools/testing/selftests/net/psock_tpacket.c
@@ -28,12 +28,15 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/mman.h>
+#include <sys/utsname.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
+#ifndef __ANDROID__
#include <bits/wordsize.h>
+#endif
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
@@ -363,6 +366,7 @@ static inline void *get_next_frame(struct ring *ring, int n)
return f0 + (n * ring->req3.tp_frame_size);
default:
bug_on(1);
+ return NULL;
}
}
@@ -829,9 +833,34 @@ static int test_tpacket(int version, int type)
return 0;
}
+void get_kernel_version(int *version, int *patchlevel)
+{
+ int ret, sublevel;
+ struct utsname utsname;
+
+ ret = uname(&utsname);
+ if (ret) {
+ perror("uname");
+ exit(1);
+ }
+
+ ret = sscanf(utsname.release, "%d.%d.%d", version, patchlevel,
+ &sublevel);
+ if (ret < 0) {
+ perror("sscanf");
+ exit(1);
+ } else if (ret != 3) {
+ printf("Malformed kernel version %s\n", &utsname.release);
+ exit(1);
+ }
+}
+
int main(void)
{
int ret = 0;
+ int version, patchlevel;
+
+ get_kernel_version(&version, &patchlevel);
ret |= test_tpacket(TPACKET_V1, PACKET_RX_RING);
ret |= test_tpacket(TPACKET_V1, PACKET_TX_RING);
@@ -840,7 +869,8 @@ int main(void)
ret |= test_tpacket(TPACKET_V2, PACKET_TX_RING);
ret |= test_tpacket(TPACKET_V3, PACKET_RX_RING);
- ret |= test_tpacket(TPACKET_V3, PACKET_TX_RING);
+ if (version > 4 || (version == 4 && patchlevel >= 11))
+ ret |= test_tpacket(TPACKET_V3, PACKET_TX_RING);
if (ret)
return 1;
diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c
index 2b9d929a24ed..0d2674b43cad 100644
--- a/tools/testing/selftests/rtc/rtctest.c
+++ b/tools/testing/selftests/rtc/rtctest.c
@@ -115,6 +115,7 @@ TEST_F_TIMEOUT(rtc, date_read_loop, READ_LOOP_DURATION_SEC + 2) {
TH_LOG("Performed %ld RTC time reads.", iter_count);
}
+#ifndef __ANDROID__ // b/31578457
TEST_F_TIMEOUT(rtc, uie_read, NUM_UIE + 2) {
int i, rc, irq = 0;
unsigned long data;
@@ -378,6 +379,7 @@ TEST_F_TIMEOUT(rtc, alarm_wkalm_set_minute, 65) {
new = timegm((struct tm *)&tm);
ASSERT_EQ(new, secs);
}
+#endif
static void __attribute__((constructor))
__constructor_order_last(void)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 4ae6c8991307..110ca8bf8e2b 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -13,12 +13,14 @@
* we need to use the kernel's siginfo.h file and trick glibc
* into accepting it.
*/
+#if defined(__GLIBC_PREREQ)
#if !__GLIBC_PREREQ(2, 26)
# include <asm/siginfo.h>
# define __have_siginfo_t 1
# define __have_sigval_t 1
# define __have_sigevent_t 1
#endif
+#endif
#include <errno.h>
#include <linux/filter.h>
@@ -855,6 +857,14 @@ void kill_thread_or_group(struct __test_metadata *_metadata,
exit(42);
}
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_TSYNC_ESRCH not compatible < 5.7
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ * SECCOMP_FILTER_FLAG_SPEC_ALLOW not compatible < 4.17
+ * SECCOMP_FILTER_FLAG_LOG not compatible < 4.14
+ */
+#ifndef __ANDROID__
TEST(KILL_thread)
{
int status;
@@ -873,6 +883,7 @@ TEST(KILL_thread)
ASSERT_TRUE(WIFEXITED(status));
ASSERT_EQ(42, WEXITSTATUS(status));
}
+#endif
TEST(KILL_process)
{
@@ -2047,8 +2058,15 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
/* Make sure we got an appropriate message. */
ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
EXPECT_EQ(0, ret);
- EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY
- : PTRACE_EVENTMSG_SYSCALL_EXIT, msg);
+
+ /*
+ * TODO: b/33027081
+ * PTRACE_EVENTMSG_SYSCALL_ENTRY and PTRACE_EVENTMSG_SYSCALL_EXIT not
+ * compatible < 5.3 (see 201766a)
+ *
+ * EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY
+ * : PTRACE_EVENTMSG_SYSCALL_EXIT, msg);
+ */
/*
* Some architectures only support setting return values during
@@ -2374,6 +2392,14 @@ TEST(seccomp_syscall_mode_lock)
}
/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_TSYNC_ESRCH not compatible < 5.7
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ * SECCOMP_FILTER_FLAG_SPEC_ALLOW not compatible < 4.17
+ * SECCOMP_FILTER_FLAG_LOG not compatible < 4.14
+ */
+#ifndef __ANDROID__
+/*
* Test detection of known and unknown filter flags. Userspace needs to be able
* to check if a filter flag is supported by the current kernel and a good way
* of doing that is by attempting to enter filter mode, with the flag bit in
@@ -2463,6 +2489,7 @@ TEST(detect_seccomp_filter_flags)
flag);
}
}
+#endif
TEST(TSYNC_first)
{
@@ -2844,6 +2871,11 @@ TEST_F(TSYNC, two_siblings_with_one_divergence)
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
}
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_TSYNC_ESRCH not compatible < 5.7
+ */
+#ifndef __ANDROID__
TEST_F(TSYNC, two_siblings_with_one_divergence_no_tid_in_err)
{
long ret, flags;
@@ -2892,6 +2924,7 @@ TEST_F(TSYNC, two_siblings_with_one_divergence_no_tid_in_err)
PTHREAD_JOIN(self->sibling[1].tid, &status);
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
}
+#endif
TEST_F(TSYNC, two_siblings_not_under_filter)
{
@@ -3021,6 +3054,7 @@ TEST(syscall_restart)
};
#if defined(__arm__)
struct utsname utsbuf;
+ int arm_version;
#endif
ASSERT_EQ(0, pipe(pipefd));
@@ -3136,12 +3170,12 @@ TEST(syscall_restart)
ret = get_syscall(_metadata, child_pid);
#if defined(__arm__)
/*
- * FIXME:
* - native ARM registers do NOT expose true syscall.
* - compat ARM registers on ARM64 DO expose true syscall.
*/
ASSERT_EQ(0, uname(&utsbuf));
- if (strncmp(utsbuf.machine, "arm", 3) == 0) {
+ if (sscanf(utsbuf.machine, "armv%d", &arm_version) == 1 &&
+ arm_version < 8) {
EXPECT_EQ(__NR_nanosleep, ret);
} else
#endif
@@ -3252,6 +3286,11 @@ TEST(get_action_avail)
EXPECT_EQ(errno, EOPNOTSUPP);
}
+/*
+ * b/147676645
+ * PTRACE_SECCOMP_GET_METADATA not compatible < 4.16
+ */
+#ifndef __ANDROID__
TEST(get_metadata)
{
pid_t pid;
@@ -3320,6 +3359,7 @@ TEST(get_metadata)
skip:
ASSERT_EQ(0, kill(pid, SIGKILL));
}
+#endif
static int user_notif_syscall(int nr, unsigned int flags)
{
@@ -3340,6 +3380,12 @@ static int user_notif_syscall(int nr, unsigned int flags)
}
#define USER_NOTIF_MAGIC INT_MAX
+
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_basic)
{
pid_t pid;
@@ -3445,7 +3491,13 @@ TEST(user_notification_basic)
EXPECT_EQ(true, WIFEXITED(status));
EXPECT_EQ(0, WEXITSTATUS(status));
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_with_tsync)
{
int ret;
@@ -3468,7 +3520,13 @@ TEST(user_notification_with_tsync)
close(ret);
ASSERT_LE(0, ret);
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_kill_in_middle)
{
pid_t pid;
@@ -3511,6 +3569,7 @@ TEST(user_notification_kill_in_middle)
EXPECT_EQ(ret, -1);
EXPECT_EQ(errno, ENOENT);
}
+#endif
static int handled = -1;
@@ -3520,6 +3579,11 @@ static void signal_handler(int signal)
perror("write from signal");
}
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_signal)
{
pid_t pid;
@@ -3594,7 +3658,13 @@ TEST(user_notification_signal)
EXPECT_EQ(true, WIFEXITED(status));
EXPECT_EQ(0, WEXITSTATUS(status));
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_closed_listener)
{
pid_t pid;
@@ -3627,8 +3697,16 @@ TEST(user_notification_closed_listener)
EXPECT_EQ(true, WIFEXITED(status));
EXPECT_EQ(0, WEXITSTATUS(status));
}
+#endif
/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ * unshare(CLONE_NEWUSER) returns EINVAL with Android
+ * unshare(CLONE_NEWPID) returns EINVAL with Android
+ */
+#ifndef __ANDROID__
+/*
* Check that a pid in a child namespace still shows up as valid in ours.
*/
TEST(user_notification_child_pid_ns)
@@ -3667,8 +3745,15 @@ TEST(user_notification_child_pid_ns)
EXPECT_EQ(0, WEXITSTATUS(status));
close(listener);
}
+#endif
/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ * unshare(CLONE_NEWPID) returns EINVAL with Android
+ */
+#ifndef __ANDROID__
+/*
* Check that a pid in a sibling (i.e. unrelated) namespace shows up as 0, i.e.
* invalid.
*/
@@ -3741,7 +3826,14 @@ TEST(user_notification_sibling_pid_ns)
EXPECT_EQ(true, WIFEXITED(status));
EXPECT_EQ(0, WEXITSTATUS(status));
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ * unshare(CLONE_NEWUSER) returns EINVAL with Android
+ */
+#ifndef __ANDROID__
TEST(user_notification_fault_recv)
{
pid_t pid;
@@ -3782,7 +3874,13 @@ TEST(user_notification_fault_recv)
EXPECT_EQ(true, WIFEXITED(status));
EXPECT_EQ(0, WEXITSTATUS(status));
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_GET_NOTIF_SIZES not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(seccomp_get_notif_sizes)
{
struct seccomp_notif_sizes sizes;
@@ -3791,7 +3889,13 @@ TEST(seccomp_get_notif_sizes)
EXPECT_EQ(sizes.seccomp_notif, sizeof(struct seccomp_notif));
EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp));
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_continue)
{
pid_t pid;
@@ -3877,7 +3981,13 @@ skip:
}
}
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_filter_empty)
{
pid_t pid;
@@ -3926,7 +4036,13 @@ TEST(user_notification_filter_empty)
EXPECT_GT(poll(&pollfd, 1, 2000), 0);
EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
static void *do_thread(void *data)
{
return NULL;
@@ -4012,7 +4128,15 @@ TEST(user_notification_filter_empty_threaded)
EXPECT_GT(poll(&pollfd, 1, 2000), 0);
EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_ADDED_FLAG_SEND not compatible < 5.14
+ * SECCOMP_IOCTL_NOTIF_ADDFD not comptible < 5.9
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_addfd)
{
pid_t pid;
@@ -4170,7 +4294,15 @@ TEST(user_notification_addfd)
close(memfd);
}
+#endif
+/*
+ * b/147676645
+ * SECCOMP_ADDED_FLAG_SEND not compatible < 5.14
+ * SECCOMP_IOCTL_NOTIF_ADDFD not comptible < 5.9
+ * SECCOMP_FILTER_FLAG_NEW_LISTENER not compatible < 5.0
+ */
+#ifndef __ANDROID__
TEST(user_notification_addfd_rlimit)
{
pid_t pid;
@@ -4240,6 +4372,7 @@ TEST(user_notification_addfd_rlimit)
close(memfd);
}
+#endif
/* Make sure PTRACE_O_SUSPEND_SECCOMP requires CAP_SYS_ADMIN. */
FIXTURE(O_SUSPEND_SECCOMP) {
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c
index 48b9a803235a..ecac8fadd939 100644
--- a/tools/testing/selftests/timers/valid-adjtimex.c
+++ b/tools/testing/selftests/timers/valid-adjtimex.c
@@ -39,12 +39,13 @@
#define ADJ_SETOFFSET 0x0100
+#ifndef __ANDROID__
#include <sys/syscall.h>
int clock_adjtime(clockid_t id, struct timex *tx)
{
return syscall(__NR_clock_adjtime, id, tx);
}
-
+#endif
/* clear NTP time_status & time_state */
int clear_time_state(void)
diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
index 413f75620a35..945d4e63296a 100644
--- a/tools/testing/selftests/vDSO/parse_vdso.c
+++ b/tools/testing/selftests/vDSO/parse_vdso.c
@@ -56,13 +56,16 @@ static struct vdso_info
} vdso_info;
/* Straight from the ELF specification. */
-static unsigned long elf_hash(const unsigned char *name)
+static unsigned long elf_hash(const char *s_name)
{
unsigned long h = 0, g;
+ const unsigned char *name = (const unsigned char *)s_name;
+
while (*name)
{
h = (h << 4) + *name++;
- if (g = h & 0xf0000000)
+ g = h & 0xf0000000;
+ if (g)
h ^= g >> 24;
h &= ~g;
}
diff --git a/tools/testing/selftests/vm/run_vmtests.sh b/tools/testing/selftests/vm/run_vmtests.sh
index e780e76c26b8..b936dfe44822 100755
--- a/tools/testing/selftests/vm/run_vmtests.sh
+++ b/tools/testing/selftests/vm/run_vmtests.sh
@@ -8,62 +8,62 @@ ksft_skip=4
mnt=./huge
exitcode=0
-#get huge pagesize and freepages from /proc/meminfo
-while read -r name size unit; do
- if [ "$name" = "HugePages_Free:" ]; then
- freepgs="$size"
- fi
- if [ "$name" = "Hugepagesize:" ]; then
- hpgsize_KB="$size"
- fi
-done < /proc/meminfo
-
-# Simple hugetlbfs tests have a hardcoded minimum requirement of
-# huge pages totaling 256MB (262144KB) in size. The userfaultfd
-# hugetlb test requires a minimum of 2 * nr_cpus huge pages. Take
-# both of these requirements into account and attempt to increase
-# number of huge pages available.
-nr_cpus=$(nproc)
-hpgsize_MB=$((hpgsize_KB / 1024))
-half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
-needmem_KB=$((half_ufd_size_MB * 2 * 1024))
-
-#set proper nr_hugepages
-if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
- nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
- needpgs=$((needmem_KB / hpgsize_KB))
- tries=2
- while [ "$tries" -gt 0 ] && [ "$freepgs" -lt "$needpgs" ]; do
- lackpgs=$((needpgs - freepgs))
- echo 3 > /proc/sys/vm/drop_caches
- if ! echo $((lackpgs + nr_hugepgs)) > /proc/sys/vm/nr_hugepages; then
- echo "Please run this test as root"
- exit $ksft_skip
- fi
- while read -r name size unit; do
- if [ "$name" = "HugePages_Free:" ]; then
- freepgs=$size
- fi
- done < /proc/meminfo
- tries=$((tries - 1))
- done
- if [ "$freepgs" -lt "$needpgs" ]; then
- printf "Not enough huge pages available (%d < %d)\n" \
- "$freepgs" "$needpgs"
- exit 1
- fi
-else
- echo "no hugetlbfs support in kernel?"
- exit 1
-fi
-
-#filter 64bit architectures
-ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
-if [ -z "$ARCH" ]; then
- ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/')
-fi
-VADDR64=0
-echo "$ARCH64STR" | grep "$ARCH" && VADDR64=1
+##get huge pagesize and freepages from /proc/meminfo
+#while read -r name size unit; do
+# if [ "$name" = "HugePages_Free:" ]; then
+# freepgs="$size"
+# fi
+# if [ "$name" = "Hugepagesize:" ]; then
+# hpgsize_KB="$size"
+# fi
+#done < /proc/meminfo
+#
+## Simple hugetlbfs tests have a hardcoded minimum requirement of
+## huge pages totaling 256MB (262144KB) in size. The userfaultfd
+## hugetlb test requires a minimum of 2 * nr_cpus huge pages. Take
+## both of these requirements into account and attempt to increase
+## number of huge pages available.
+#nr_cpus=$(nproc)
+#hpgsize_MB=$((hpgsize_KB / 1024))
+#half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
+#needmem_KB=$((half_ufd_size_MB * 2 * 1024))
+#
+##set proper nr_hugepages
+#if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
+# nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
+# needpgs=$((needmem_KB / hpgsize_KB))
+# tries=2
+# while [ "$tries" -gt 0 ] && [ "$freepgs" -lt "$needpgs" ]; do
+# lackpgs=$((needpgs - freepgs))
+# echo 3 > /proc/sys/vm/drop_caches
+# if ! echo $((lackpgs + nr_hugepgs)) > /proc/sys/vm/nr_hugepages; then
+# echo "Please run this test as root"
+# exit $ksft_skip
+# fi
+# while read -r name size unit; do
+# if [ "$name" = "HugePages_Free:" ]; then
+# freepgs=$size
+# fi
+# done < /proc/meminfo
+# tries=$((tries - 1))
+# done
+# if [ "$freepgs" -lt "$needpgs" ]; then
+# printf "Not enough huge pages available (%d < %d)\n" \
+# "$freepgs" "$needpgs"
+# exit 1
+# fi
+#else
+# echo "no hugetlbfs support in kernel?"
+# exit 1
+#fi
+#
+##filter 64bit architectures
+#ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
+#if [ -z "$ARCH" ]; then
+# ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/')
+#fi
+#VADDR64=0
+#echo "$ARCH64STR" | grep "$ARCH" && VADDR64=1
# Usage: run_test [test binary] [arbitrary test arguments...]
run_test() {
@@ -84,63 +84,63 @@ run_test() {
fi
}
-mkdir "$mnt"
-mount -t hugetlbfs none "$mnt"
-
-run_test ./hugepage-mmap
-
-shmmax=$(cat /proc/sys/kernel/shmmax)
-shmall=$(cat /proc/sys/kernel/shmall)
-echo 268435456 > /proc/sys/kernel/shmmax
-echo 4194304 > /proc/sys/kernel/shmall
-run_test ./hugepage-shm
-echo "$shmmax" > /proc/sys/kernel/shmmax
-echo "$shmall" > /proc/sys/kernel/shmall
-
-run_test ./map_hugetlb
-
-run_test ./hugepage-mremap "$mnt"/huge_mremap
-rm -f "$mnt"/huge_mremap
-
-run_test ./hugepage-vmemmap
-
-run_test ./hugetlb-madvise "$mnt"/madvise-test
-rm -f "$mnt"/madvise-test
-
-echo "NOTE: The above hugetlb tests provide minimal coverage. Use"
-echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"
-echo " hugetlb regression testing."
-
-run_test ./map_fixed_noreplace
-
-# get_user_pages_fast() benchmark
-run_test ./gup_test -u
-# pin_user_pages_fast() benchmark
-run_test ./gup_test -a
-# Dump pages 0, 19, and 4096, using pin_user_pages:
-run_test ./gup_test -ct -F 0x1 0 19 0x1000
-
-uffd_mods=("" ":dev")
-for mod in "${uffd_mods[@]}"; do
- run_test ./userfaultfd anon${mod} 20 16
- # Hugetlb tests require source and destination huge pages. Pass in half
- # the size ($half_ufd_size_MB), which is used for *each*.
- run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32
- run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32 "$mnt"/uffd-test
- rm -f "$mnt"/uffd-test
- run_test ./userfaultfd shmem${mod} 20 16
-done
-
-#cleanup
-umount "$mnt"
-rm -rf "$mnt"
-echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
-
-run_test ./compaction_test
+#mkdir "$mnt"
+#mount -t hugetlbfs none "$mnt"
+#
+#run_test ./hugepage-mmap
+#
+#shmmax=$(cat /proc/sys/kernel/shmmax)
+#shmall=$(cat /proc/sys/kernel/shmall)
+#echo 268435456 > /proc/sys/kernel/shmmax
+#echo 4194304 > /proc/sys/kernel/shmall
+#run_test ./hugepage-shm
+#echo "$shmmax" > /proc/sys/kernel/shmmax
+#echo "$shmall" > /proc/sys/kernel/shmall
+#
+#run_test ./map_hugetlb
+#
+#run_test ./hugepage-mremap "$mnt"/huge_mremap
+#rm -f "$mnt"/huge_mremap
+#
+#run_test ./hugepage-vmemmap
+#
+#run_test ./hugetlb-madvise "$mnt"/madvise-test
+#rm -f "$mnt"/madvise-test
+#
+#echo "NOTE: The above hugetlb tests provide minimal coverage. Use"
+#echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"
+#echo " hugetlb regression testing."
+#
+#run_test ./map_fixed_noreplace
+#
+## get_user_pages_fast() benchmark
+#run_test ./gup_test -u
+## pin_user_pages_fast() benchmark
+#run_test ./gup_test -a
+## Dump pages 0, 19, and 4096, using pin_user_pages:
+#run_test ./gup_test -ct -F 0x1 0 19 0x1000
+#
+#uffd_mods=("" ":dev")
+#for mod in "${uffd_mods[@]}"; do
+# run_test ./userfaultfd anon${mod} 20 16
+# # Hugetlb tests require source and destination huge pages. Pass in half
+# # the size ($half_ufd_size_MB), which is used for *each*.
+# run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32
+# run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32 "$mnt"/uffd-test
+# rm -f "$mnt"/uffd-test
+# run_test ./userfaultfd shmem${mod} 20 16
+#done
+#
+##cleanup
+#umount "$mnt"
+#rm -rf "$mnt"
+#echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
+#
+#run_test ./compaction_test
run_test sudo -u nobody ./on-fault-limit
-run_test ./map_populate
+#run_test ./map_populate
run_test ./mlock-random-test
@@ -152,49 +152,49 @@ run_test ./mremap_test
run_test ./thuge-gen
-if [ $VADDR64 -ne 0 ]; then
- run_test ./virtual_address_range
-
- # virtual address 128TB switch test
- run_test ./va_128TBswitch.sh
-fi # VADDR64
+#if [ $VADDR64 -ne 0 ]; then
+# run_test ./virtual_address_range
+#
+# # virtual address 128TB switch test
+# run_test ./va_128TBswitch.sh
+#fi # VADDR64
# vmalloc stability smoke test
-run_test ./test_vmalloc.sh smoke
+#run_test ./test_vmalloc.sh smoke
run_test ./mremap_dontunmap
-run_test ./test_hmm.sh smoke
-
-# MADV_POPULATE_READ and MADV_POPULATE_WRITE tests
-run_test ./madv_populate
-
-run_test ./memfd_secret
-
-# KSM MADV_MERGEABLE test with 10 identical pages
-run_test ./ksm_tests -M -p 10
-# KSM unmerge test
-run_test ./ksm_tests -U
-# KSM test with 10 zero pages and use_zero_pages = 0
-run_test ./ksm_tests -Z -p 10 -z 0
-# KSM test with 10 zero pages and use_zero_pages = 1
-run_test ./ksm_tests -Z -p 10 -z 1
-# KSM test with 2 NUMA nodes and merge_across_nodes = 1
-run_test ./ksm_tests -N -m 1
-# KSM test with 2 NUMA nodes and merge_across_nodes = 0
-run_test ./ksm_tests -N -m 0
-
-# protection_keys tests
-if [ -x ./protection_keys_32 ]
-then
- run_test ./protection_keys_32
-fi
-
-if [ -x ./protection_keys_64 ]
-then
- run_test ./protection_keys_64
-fi
-
-run_test ./soft-dirty
+#run_test ./test_hmm.sh smoke
+
+## MADV_POPULATE_READ and MADV_POPULATE_WRITE tests
+#run_test ./madv_populate
+#
+#run_test ./memfd_secret
+
+## KSM MADV_MERGEABLE test with 10 identical pages
+#run_test ./ksm_tests -M -p 10
+## KSM unmerge test
+#run_test ./ksm_tests -U
+## KSM test with 10 zero pages and use_zero_pages = 0
+#run_test ./ksm_tests -Z -p 10 -z 0
+## KSM test with 10 zero pages and use_zero_pages = 1
+#run_test ./ksm_tests -Z -p 10 -z 1
+## KSM test with 2 NUMA nodes and merge_across_nodes = 1
+#run_test ./ksm_tests -N -m 1
+## KSM test with 2 NUMA nodes and merge_across_nodes = 0
+#run_test ./ksm_tests -N -m 0
+
+## protection_keys tests
+#if [ -x ./protection_keys_32 ]
+#then
+# run_test ./protection_keys_32
+#fi
+#
+#if [ -x ./protection_keys_64 ]
+#then
+# run_test ./protection_keys_64
+#fi
+#
+#run_test ./soft-dirty
exit $exitcode
diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 297f250c1d95..02cc35b65a7a 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -100,9 +100,11 @@ static int huge_fd;
static unsigned long long *count_verify;
static int uffd = -1;
static int uffd_flags, finished, *pipefd;
+static volatile bool ready_for_fork;
static char *area_src, *area_src_alias, *area_dst, *area_dst_alias, *area_remap;
static char *zeropage;
pthread_attr_t attr;
+pthread_key_t long_jmp_key;
static bool test_collapse;
/* Userfaultfd test statistics */
@@ -821,6 +823,9 @@ static void *uffd_poll_thread(void *arg)
pollfd[1].fd = pipefd[cpu*2];
pollfd[1].events = POLLIN;
+ // Notify the main thread that it can now fork.
+ ready_for_fork = true;
+
for (;;) {
ret = poll(pollfd, 2, -1);
if (ret <= 0) {
@@ -868,15 +873,27 @@ static void *uffd_poll_thread(void *arg)
pthread_mutex_t uffd_read_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void sigusr1_handler(int signum, siginfo_t *siginfo, void *ptr)
+{
+ jmp_buf *env;
+ env = pthread_getspecific(long_jmp_key);
+ longjmp(*env, 1);
+}
+
static void *uffd_read_thread(void *arg)
{
struct uffd_stats *stats = (struct uffd_stats *)arg;
struct uffd_msg msg;
+ jmp_buf env;
+ int setjmp_ret;
- pthread_mutex_unlock(&uffd_read_mutex);
- /* from here cancellation is ok */
+ pthread_setspecific(long_jmp_key, &env);
- for (;;) {
+ pthread_mutex_unlock(&uffd_read_mutex);
+ // One first return setjmp return 0. On second (fake) return from
+ // longjmp() it returns the provided value, which will be 1 in our case.
+ setjmp_ret = setjmp(env);
+ while (!setjmp_ret) {
if (uffd_read_msg(uffd, &msg))
continue;
uffd_handle_page_fault(&msg, stats);
@@ -974,7 +991,7 @@ static int stress(struct uffd_stats *uffd_stats)
(void *)&uffd_stats[cpu]))
return 1;
} else {
- if (pthread_cancel(uffd_threads[cpu]))
+ if (pthread_kill(uffd_threads[cpu], SIGUSR1))
return 1;
if (pthread_join(uffd_threads[cpu], NULL))
return 1;
@@ -1208,6 +1225,10 @@ static int userfaultfd_events_test(void)
char c;
struct uffd_stats stats = { 0 };
+ // All the syscalls below up to pthread_create will ensure that this
+ // write is completed before, the uffd_thread sets it to true.
+ ready_for_fork = false;
+
printf("testing events (fork, remap, remove): ");
fflush(stdout);
@@ -1231,6 +1252,11 @@ static int userfaultfd_events_test(void)
if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats))
err("uffd_poll_thread create");
+ // Wait for the poll_thread to start executing before forking. This is
+ // required to avoid a deadlock, which can happen if poll_thread doesn't
+ // start getting executed by the time fork is invoked.
+ while (!ready_for_fork);
+
pid = fork();
if (pid < 0)
err("fork");
@@ -1261,6 +1287,10 @@ static int userfaultfd_sig_test(void)
char c;
struct uffd_stats stats = { 0 };
+ // All the syscalls below up to pthread_create will ensure that this
+ // write is completed before, the uffd_thread sets it to true.
+ ready_for_fork = false;
+
printf("testing signal delivery: ");
fflush(stdout);
@@ -1288,6 +1318,11 @@ static int userfaultfd_sig_test(void)
if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats))
err("uffd_poll_thread create");
+ // Wait for the poll_thread to start executing before forking. This is
+ // required to avoid a deadlock, which can happen if poll_thread doesn't
+ // start getting executed by the time fork is invoked.
+ while (!ready_for_fork);
+
pid = fork();
if (pid < 0)
err("fork");
@@ -1409,6 +1444,11 @@ static int userfaultfd_minor_test(void)
#define PM_SWAP BIT_ULL(62)
#define PM_PRESENT BIT_ULL(63)
+/*
+ * b/232026677
+ * pagemap not compatible with < 5.14
+ */
+#ifndef __ANDROID__
static int pagemap_open(void)
{
int fd = open("/proc/self/pagemap", O_RDONLY);
@@ -1534,12 +1574,14 @@ static void userfaultfd_pagemap_test(unsigned int test_pgsize)
close(pagemap_fd);
printf("done\n");
}
+#endif
static int userfaultfd_stress(void)
{
void *area;
unsigned long nr;
struct uffdio_register uffdio_register;
+ struct sigaction act;
struct uffd_stats uffd_stats[nr_cpus];
uffd_test_ctx_init(0);
@@ -1554,6 +1596,17 @@ static int userfaultfd_stress(void)
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 16*1024*1024);
+ // For handling thread termination of read thread in the absence of
+ // pthread_cancel().
+ pthread_key_create(&long_jmp_key, NULL);
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = sigusr1_handler;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGUSR1, &act, 0)) {
+ perror("sigaction");
+ return 1;
+ }
+
while (bounces--) {
printf("bounces: %d, mode:", bounces);
if (bounces & BOUNCE_RANDOM)
@@ -1655,6 +1708,11 @@ static int userfaultfd_stress(void)
uffd_stats_report(uffd_stats, nr_cpus);
}
+/*
+ * b/232026677
+ * pagemap not compatible with < 5.14
+ */
+#ifndef __ANDROID__
if (test_type == TEST_ANON) {
/*
* shmem/hugetlb won't be able to run since they have different
@@ -1669,6 +1727,9 @@ static int userfaultfd_stress(void)
*/
userfaultfd_pagemap_test(page_size * 512);
}
+#endif
+
+ pthread_key_delete(long_jmp_key);
return userfaultfd_zeropage_test() || userfaultfd_sig_test()
|| userfaultfd_events_test() || userfaultfd_minor_test();
@@ -1723,7 +1784,24 @@ static void set_test_type(const char *type)
static void parse_test_type_arg(const char *raw_type)
{
char *buf = strdup(raw_type);
+ /* b/234150821
+ * UFFD_FEATURE_PAGEFAULT_FLAG_WP unsupported in kernel <5.7
+ */
+#ifdef __ANDROID__
+ uint64_t features = (
+ UFFD_FEATURE_EVENT_FORK | \
+ UFFD_FEATURE_EVENT_REMAP | \
+ UFFD_FEATURE_EVENT_REMOVE | \
+ UFFD_FEATURE_EVENT_UNMAP | \
+ UFFD_FEATURE_MISSING_HUGETLBFS | \
+ UFFD_FEATURE_MISSING_SHMEM | \
+ UFFD_FEATURE_SIGBUS | \
+ UFFD_FEATURE_THREAD_ID | \
+ UFFD_FEATURE_MINOR_HUGETLBFS | \
+ UFFD_FEATURE_MINOR_SHMEM);
+#else
uint64_t features = UFFD_API_FEATURES;
+#endif
while (buf) {
const char *token = strsep(&buf, ":");
diff --git a/tools/testing/selftests/x86/test_FISTTP.c b/tools/testing/selftests/x86/test_FISTTP.c
index 09789c0ce3e9..c920a57ddb06 100644
--- a/tools/testing/selftests/x86/test_FISTTP.c
+++ b/tools/testing/selftests/x86/test_FISTTP.c
@@ -25,7 +25,11 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fld1""\n"
+#ifdef __clang__
+ " fisttps res16""\n"
+#else
" fisttp res16""\n"
+#endif
" fld1""\n"
" fisttpl res32""\n"
" fld1""\n"
@@ -45,7 +49,11 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fldpi""\n"
+#ifdef __clang__
+ " fisttps res16""\n"
+#else
" fisttp res16""\n"
+#endif
" fldpi""\n"
" fisttpl res32""\n"
" fldpi""\n"
@@ -66,7 +74,13 @@ int test(void)
asm volatile ("\n"
" fldpi""\n"
" fchs""\n"
+#ifdef __clang__
+ " fisttps res16""\n"
+#else
+ // clang will complain: ambiguous instructions require an explicit suffix
+ // (could be 'fisttps', or 'fisttpl')
" fisttp res16""\n"
+#endif
" fldpi""\n"
" fchs""\n"
" fisttpl res32""\n"
@@ -88,7 +102,11 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fldln2""\n"
+#ifdef __clang__
+ " fisttps res16""\n"
+#else
" fisttp res16""\n"
+#endif
" fldln2""\n"
" fisttpl res32""\n"
" fldln2""\n"