[GIT PULL] kselftest fix for 4.15-rc1

From: Shuah Khan
Date: Fri Nov 17 2017 - 11:33:33 EST


Hi Linus,

Please pull the following Kselftest update for 4.15-rc1.

This update to Kselftest consists of cleanup patches, fixes, and a new
test for ion buffer sharing.

Fixes include changes to skip firmware tests on systems that aren't
configured to support them, as opposed to failing them.

Patches have been in linux-next for a while. I had to rebase to 4.14 to
resolve a minor conflict with the SPDX-License change selftest Makefile
that went into 4.14-rc8.

Diff for the update is attached.

thanks,
-- Shuah

-----------------------------------------------------------------------------------

The following changes since commit bebc6082da0a9f5d47a1ea2edc099bf671058bd4:

Linux 4.14 (2017-11-12 10:46:13 -0800)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest tags/linux-kselftest-4.15-rc1

for you to fetch changes up to c3e0d179bff503cd56758579a2c33216b40b9b7b:

selftests: firmware: skip unsupported custom firmware fallback tests (2017-11-15 08:27:57 -0700)

----------------------------------------------------------------
linux-kselftest-4.15-rc1

This update to Kselftest consists of cleanup patches, fixes, and a new
test for ion buffer sharing.

Fixes include changes to skip firmware tests on systems that aren't
configured to support them, as opposed to failing them.

----------------------------------------------------------------
Amit Pundir (2):
selftests: firmware: skip unsupported async loading tests
selftests: firmware: skip unsupported custom firmware fallback tests

Greg Hackmann (1):
selftests: vdso_test: support ARM64 targets

Lei Yang (2):
selftests: ftrace: add more config fragments
selftests: memfd_test.c: fix compilation warning.

Masami Hiramatsu (2):
selftests/ftrace: Do not use arch dependent do_IRQ as a target function
selftests/ftrace: Introduce exit_pass and exit_fail

Pintu Agarwal (1):
android/ion: userspace test utility for ion buffer sharing

Shuah Khan (3):
selftests: timers: Update .gitignore with newly added tests
selftests: vm: Update .gitignore with newly added tests
selftests: seccomp: update .gitignore with newly added tests

Steve Muckle (1):
selftests/exec: include cwd in long path calculation

Sumit Semwal (1):
selftests: breakpoints: fix compile error on breakpoint_test_arm64

lei.yang@xxxxxxxxxxxxx (2):
selftests: add missing test result status in memory-hotplug test
selftests: remove obsolete kconfig fragment for cpu-hotplug

tools/testing/selftests/Makefile | 3 +-
tools/testing/selftests/android/Makefile | 46 ++++
tools/testing/selftests/android/ion/.gitignore | 2 +
tools/testing/selftests/android/ion/Makefile | 16 ++
tools/testing/selftests/android/ion/README | 101 ++++++++
tools/testing/selftests/android/ion/config | 4 +
tools/testing/selftests/android/ion/ion.h | 143 ++++++++++++
tools/testing/selftests/android/ion/ion_test.sh | 55 +++++
.../testing/selftests/android/ion/ionapp_export.c | 135 +++++++++++
.../testing/selftests/android/ion/ionapp_import.c | 88 +++++++
tools/testing/selftests/android/ion/ionutils.c | 259 +++++++++++++++++++++
tools/testing/selftests/android/ion/ionutils.h | 55 +++++
tools/testing/selftests/android/ion/ipcsocket.c | 227 ++++++++++++++++++
tools/testing/selftests/android/ion/ipcsocket.h | 35 +++
tools/testing/selftests/android/run.sh | 3 +
.../selftests/breakpoints/breakpoint_test_arm64.c | 1 +
tools/testing/selftests/cpu-hotplug/config | 1 -
tools/testing/selftests/exec/execveat.c | 27 ++-
tools/testing/selftests/firmware/fw_fallback.sh | 38 ++-
tools/testing/selftests/firmware/fw_filesystem.sh | 34 +--
tools/testing/selftests/ftrace/config | 4 +
tools/testing/selftests/ftrace/ftracetest | 7 +
.../selftests/ftrace/test.d/00basic/basic4.tc | 2 +-
.../selftests/ftrace/test.d/event/event-enable.tc | 2 +-
.../selftests/ftrace/test.d/event/event-pid.tc | 2 +-
.../ftrace/test.d/event/subsystem-enable.tc | 2 +-
.../ftrace/test.d/event/toplevel-enable.tc | 2 +-
.../ftrace/test.d/ftrace/fgraph-filter-stack.tc | 2 +-
.../ftrace/test.d/ftrace/fgraph-filter.tc | 2 +-
.../ftrace/test.d/ftrace/func-filter-pid.tc | 2 +-
.../ftrace/test.d/ftrace/func_event_triggers.tc | 5 +-
.../ftrace/test.d/ftrace/func_profiler.tc | 2 +-
.../ftrace/test.d/ftrace/func_set_ftrace_file.tc | 4 +-
.../test.d/ftrace/func_traceonoff_triggers.tc | 2 +-
.../ftrace/test.d/instances/instance-event.tc | 2 +-
.../selftests/ftrace/test.d/instances/instance.tc | 2 +-
.../selftests/ftrace/test.d/kprobe/busy_check.tc | 2 +-
.../selftests/ftrace/test.d/kprobe/kprobe_args.tc | 2 +-
.../ftrace/test.d/kprobe/kprobe_args_type.tc | 2 +-
.../ftrace/test.d/kprobe/kretprobe_args.tc | 2 +-
tools/testing/selftests/ftrace/test.d/template | 1 +
.../ftrace/test.d/trigger/trigger-eventonoff.tc | 2 +-
.../ftrace/test.d/trigger/trigger-filter.tc | 2 +-
.../ftrace/test.d/trigger/trigger-hist-mod.tc | 2 +-
.../ftrace/test.d/trigger/trigger-hist.tc | 2 +-
.../ftrace/test.d/trigger/trigger-multihist.tc | 2 +-
.../ftrace/test.d/trigger/trigger-snapshot.tc | 2 +-

.../ftrace/test.d/trigger/trigger-stacktrace.tc | 2 +-
.../ftrace/test.d/trigger/trigger-traceonoff.tc | 2 +-
tools/testing/selftests/memfd/memfd_test.c | 4 +-
tools/testing/selftests/memory-hotplug/Makefile | 4 +-
tools/testing/selftests/seccomp/.gitignore | 1 +
tools/testing/selftests/timers/.gitignore | 2 +
tools/testing/selftests/vDSO/vdso_test.c | 19 +-
tools/testing/selftests/vm/.gitignore | 2 +
55 files changed, 1303 insertions(+), 71 deletions(-)
create mode 100644 tools/testing/selftests/android/Makefile
create mode 100644 tools/testing/selftests/android/ion/.gitignore
create mode 100644 tools/testing/selftests/android/ion/Makefile
create mode 100644 tools/testing/selftests/android/ion/README
create mode 100644 tools/testing/selftests/android/ion/config
create mode 100644 tools/testing/selftests/android/ion/ion.h
create mode 100755 tools/testing/selftests/android/ion/ion_test.sh
create mode 100644 tools/testing/selftests/android/ion/ionapp_export.c
create mode 100644 tools/testing/selftests/android/ion/ionapp_import.c
create mode 100644 tools/testing/selftests/android/ion/ionutils.c
create mode 100644 tools/testing/selftests/android/ion/ionutils.h
create mode 100644 tools/testing/selftests/android/ion/ipcsocket.c
create mode 100644 tools/testing/selftests/android/ion/ipcsocket.h
create mode 100755 tools/testing/selftests/android/run.sh

-----------------------------------------------------------------------------------
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 3c9c0bbe7dbb..eaf599dc2137 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-TARGETS = bpf
+TARGETS = android
+TARGETS += bpf
TARGETS += breakpoints
TARGETS += capabilities
TARGETS += cpufreq
diff --git a/tools/testing/selftests/android/Makefile b/tools/testing/selftests/android/Makefile
new file mode 100644
index 000000000000..1a7492268993
--- /dev/null
+++ b/tools/testing/selftests/android/Makefile
@@ -0,0 +1,46 @@
+SUBDIRS := ion
+
+TEST_PROGS := run.sh
+
+.PHONY: all clean
+
+include ../lib.mk
+
+all:
+ @for DIR in $(SUBDIRS); do \
+ BUILD_TARGET=$(OUTPUT)/$$DIR; \
+ mkdir $$BUILD_TARGET -p; \
+ make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
+ #SUBDIR test prog name should be in the form: SUBDIR_test.sh
+ TEST=$$DIR"_test.sh"; \
+ if [ -e $$DIR/$$TEST ]; then
+ rsync -a $$DIR/$$TEST $$BUILD_TARGET/;
+ fi
+ done
+
+override define RUN_TESTS
+ @cd $(OUTPUT); ./run.sh
+endef
+
+override define INSTALL_RULE
+ mkdir -p $(INSTALL_PATH)
+ install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES)
+
+ @for SUBDIR in $(SUBDIRS); do \
+ BUILD_TARGET=$(OUTPUT)/$$SUBDIR; \
+ mkdir $$BUILD_TARGET -p; \
+ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$SUBDIR INSTALL_PATH=$(INSTALL_PATH)/$$SUBDIR install; \
+ done;
+endef
+
+override define EMIT_TESTS
+ echo "./run.sh"
+endef
+
+override define CLEAN
+ @for DIR in $(SUBDIRS); do \
+ BUILD_TARGET=$(OUTPUT)/$$DIR; \
+ mkdir $$BUILD_TARGET -p; \
+ make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
+ done
+endef
diff --git a/tools/testing/selftests/android/ion/.gitignore b/tools/testing/selftests/android/ion/.gitignore
new file mode 100644
index 000000000000..67e6f391b2a9
--- /dev/null
+++ b/tools/testing/selftests/android/ion/.gitignore
@@ -0,0 +1,2 @@
+ionapp_export
+ionapp_import
diff --git a/tools/testing/selftests/android/ion/Makefile b/tools/testing/selftests/android/ion/Makefile
new file mode 100644
index 000000000000..96e0c448b39d
--- /dev/null
+++ b/tools/testing/selftests/android/ion/Makefile
@@ -0,0 +1,16 @@
+
+INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/
+CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g
+
+TEST_GEN_FILES := ionapp_export ionapp_import
+
+all: $(TEST_GEN_FILES)
+
+$(TEST_GEN_FILES): ipcsocket.c ionutils.c
+
+TEST_PROGS := ion_test.sh
+
+include ../../lib.mk
+
+$(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c
+$(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c
diff --git a/tools/testing/selftests/android/ion/README b/tools/testing/selftests/android/ion/README
new file mode 100644
index 000000000000..21783e9c451e
--- /dev/null
+++ b/tools/testing/selftests/android/ion/README
@@ -0,0 +1,101 @@
+ION BUFFER SHARING UTILITY
+==========================
+File: ion_test.sh : Utility to test ION driver buffer sharing mechanism.
+Author: Pintu Kumar <pintu.ping@xxxxxxxxx>
+
+Introduction:
+-------------
+This is a test utility to verify ION buffer sharing in user space
+between 2 independent processes.
+It uses unix domain socket (with SCM_RIGHTS) as IPC to transfer an FD to
+another process to share the same buffer.
+This utility demonstrates how ION buffer sharing can be implemented between
+two user space processes, using various heap types.
+The following heap types are supported by ION driver.
+ION_HEAP_TYPE_SYSTEM (0)
+ION_HEAP_TYPE_SYSTEM_CONTIG (1)
+ION_HEAP_TYPE_CARVEOUT (2)
+ION_HEAP_TYPE_CHUNK (3)
+ION_HEAP_TYPE_DMA (4)
+
+By default only the SYSTEM and SYSTEM_CONTIG heaps are supported.
+Each heap is associated with the respective heap id.
+This utility is designed in the form of client/server program.
+The server part (ionapp_export) is the exporter of the buffer.
+It is responsible for creating an ION client, allocating the buffer based on
+the heap id, writing some data to this buffer and then exporting the FD
+(associated with this buffer) to another process using socket IPC.
+This FD is called as buffer FD (which is different than the ION client FD).
+
+The client part (ionapp_import) is the importer of the buffer.
+It retrives the FD from the socket data and installs into its address space.
+This new FD internally points to the same kernel buffer.
+So first it reads the data that is stored in this buffer and prints it.
+Then it writes the different size of data (it could be different data) to the
+same buffer.
+Finally the buffer FD must be closed by both the exporter and importer.
+Thus the same kernel buffer is shared among two user space processes using
+ION driver and only one time allocation.
+
+Prerequisite:
+-------------
+This utility works only if /dev/ion interface is present.
+The following configs needs to be enabled in kernel to include ion driver.
+CONFIG_ANDROID=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_SYSTEM_HEAP=y
+
+This utility requires to be run as root user.
+
+
+Compile and test:
+-----------------
+This utility is made to be run as part of kselftest framework in kernel.
+To compile and run using kselftest you can simply do the following from the
+kernel top directory.
+linux$ make TARGETS=android kselftest
+Or you can also use:
+linux$ make -C tools/testing/selftests TARGETS=android run_tests
+Using the selftest it can directly execute the ion_test.sh script to test the
+buffer sharing using ion system heap.
+Currently the heap size is hard coded as just 10 bytes inside this script.
+You need to be a root user to run under selftest.
+
+You can also compile and test manually using the following steps:
+ion$ make
+These will generate 2 executable: ionapp_export, ionapp_import
+Now you can run the export and import manually by specifying the heap type
+and the heap size.
+You can also directly execute the shell script to run the test automatically.
+Simply use the following command to run the test.
+ion$ sudo ./ion_test.sh
+
+Test Results:
+-------------
+The utility is verified on Ubuntu-32 bit system with Linux Kernel 4.14.
+Here is the snapshot of the test result using kselftest.
+
+linux# make TARGETS=android kselftest
+heap_type: 0, heap_size: 10
+--------------------------------------
+heap type: 0
+ heap id: 1
+heap name: ion_system_heap
+--------------------------------------
+Fill buffer content:
+0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd
+Sharing fd: 6, Client fd: 5
+<ion_close_buffer_fd>: buffer release successfully....
+Received buffer fd: 4
+Read buffer content:
+0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0x0 0x0 0x0 0x0 0x0 0x0
+0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+Fill buffer content:
+0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd
+0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd
+0xfd 0xfd
+<ion_close_buffer_fd>: buffer release successfully....
+ion_test.sh: heap_type: 0 - [PASS]
+
+ion_test.sh: done
diff --git a/tools/testing/selftests/android/ion/config b/tools/testing/selftests/android/ion/config
new file mode 100644
index 000000000000..19db6ca9aa2b
--- /dev/null
+++ b/tools/testing/selftests/android/ion/config
@@ -0,0 +1,4 @@
+CONFIG_ANDROID=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_SYSTEM_HEAP=y
diff --git a/tools/testing/selftests/android/ion/ion.h b/tools/testing/selftests/android/ion/ion.h
new file mode 100644
index 000000000000..f7021ac51335
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ion.h
@@ -0,0 +1,143 @@
+/*
+ * ion.h
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* This file is copied from drivers/staging/android/uapi/ion.h
+ * This local copy is required for the selftest to pass, when build
+ * outside the kernel source tree.
+ * Please keep this file in sync with its original file until the
+ * ion driver is moved outside the staging tree.
+ */
+
+#ifndef _UAPI_LINUX_ION_H
+#define _UAPI_LINUX_ION_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/**
+ * enum ion_heap_types - list of all possible types of heaps
+ * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
+ * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
+ * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved
+ * carveout heap, allocations are physically
+ * contiguous
+ * @ION_HEAP_TYPE_DMA: memory allocated via DMA API
+ * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask
+ * is used to identify the heaps, so only 32
+ * total heap types are supported
+ */
+enum ion_heap_type {
+ ION_HEAP_TYPE_SYSTEM,
+ ION_HEAP_TYPE_SYSTEM_CONTIG,
+ ION_HEAP_TYPE_CARVEOUT,
+ ION_HEAP_TYPE_CHUNK,
+ ION_HEAP_TYPE_DMA,
+ ION_HEAP_TYPE_CUSTOM, /*
+ * must be last so device specific heaps always
+ * are at the end of this enum
+ */
+};
+
+#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8)
+
+/**
+ * allocation flags - the lower 16 bits are used by core ion, the upper 16
+ * bits are reserved for use by the heaps themselves.
+ */
+
+/*
+ * mappings of this buffer should be cached, ion will do cache maintenance
+ * when the buffer is mapped for dma
+ */
+#define ION_FLAG_CACHED 1
+
+/**
+ * DOC: Ion Userspace API
+ *
+ * create a client by opening /dev/ion
+ * most operations handled via following ioctls
+ *
+ */
+
+/**
+ * struct ion_allocation_data - metadata passed from userspace for allocations
+ * @len: size of the allocation
+ * @heap_id_mask: mask of heap ids to allocate from
+ * @flags: flags passed to heap
+ * @handle: pointer that will be populated with a cookie to use to
+ * refer to this allocation
+ *
+ * Provided by userspace as an argument to the ioctl
+ */
+struct ion_allocation_data {
+ __u64 len;
+ __u32 heap_id_mask;
+ __u32 flags;
+ __u32 fd;
+ __u32 unused;
+};
+
+#define MAX_HEAP_NAME 32
+
+/**
+ * struct ion_heap_data - data about a heap
+ * @name - first 32 characters of the heap name
+ * @type - heap type
+ * @heap_id - heap id for the heap
+ */
+struct ion_heap_data {
+ char name[MAX_HEAP_NAME];
+ __u32 type;
+ __u32 heap_id;
+ __u32 reserved0;
+ __u32 reserved1;
+ __u32 reserved2;
+};
+
+/**
+ * struct ion_heap_query - collection of data about all heaps
+ * @cnt - total number of heaps to be copied
+ * @heaps - buffer to copy heap data
+ */
+struct ion_heap_query {
+ __u32 cnt; /* Total number of heaps to be copied */
+ __u32 reserved0; /* align to 64bits */
+ __u64 heaps; /* buffer to be populated */
+ __u32 reserved1;
+ __u32 reserved2;
+};
+
+#define ION_IOC_MAGIC 'I'
+
+/**
+ * DOC: ION_IOC_ALLOC - allocate memory
+ *
+ * Takes an ion_allocation_data struct and returns it with the handle field
+ * populated with the opaque handle for the allocation.
+ */
+#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
+ struct ion_allocation_data)
+
+/**
+ * DOC: ION_IOC_HEAP_QUERY - information about available heaps
+ *
+ * Takes an ion_heap_query structure and populates information about
+ * available Ion heaps.
+ */
+#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \
+ struct ion_heap_query)
+
+#endif /* _UAPI_LINUX_ION_H */
diff --git a/tools/testing/selftests/android/ion/ion_test.sh b/tools/testing/selftests/android/ion/ion_test.sh
new file mode 100755
index 000000000000..a1aff506f5e6
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ion_test.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+heapsize=4096
+TCID="ion_test.sh"
+errcode=0
+
+run_test()
+{
+ heaptype=$1
+ ./ionapp_export -i $heaptype -s $heapsize &
+ sleep 1
+ ./ionapp_import
+ if [ $? -ne 0 ]; then
+ echo "$TCID: heap_type: $heaptype - [FAIL]"
+ errcode=1
+ else
+ echo "$TCID: heap_type: $heaptype - [PASS]"
+ fi
+ sleep 1
+ echo ""
+}
+
+check_root()
+{
+ uid=$(id -u)
+ if [ $uid -ne 0 ]; then
+ echo $TCID: must be run as root >&2
+ exit 0
+ fi
+}
+
+check_device()
+{
+ DEVICE=/dev/ion
+ if [ ! -e $DEVICE ]; then
+ echo $TCID: No $DEVICE device found >&2
+ echo $TCID: May be CONFIG_ION is not set >&2
+ exit 0
+ fi
+}
+
+main_function()
+{
+ check_device
+ check_root
+
+ # ION_SYSTEM_HEAP TEST
+ run_test 0
+ # ION_SYSTEM_CONTIG_HEAP TEST
+ run_test 1
+}
+
+main_function
+echo "$TCID: done"
+exit $errcode
diff --git a/tools/testing/selftests/android/ion/ionapp_export.c b/tools/testing/selftests/android/ion/ionapp_export.c
new file mode 100644
index 000000000000..a944e72621a9
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ionapp_export.c
@@ -0,0 +1,135 @@
+/*
+ * ionapp_export.c
+ *
+ * It is a user space utility to create and export android
+ * ion memory buffer fd to another process using unix domain socket as IPC.
+ * This acts like a server for ionapp_import(client).
+ * So, this server has to be started first before the client.
+ *
+ * Copyright (C) 2017 Pintu Kumar <pintu.ping@xxxxxxxxx>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include "ionutils.h"
+#include "ipcsocket.h"
+
+
+void print_usage(int argc, char *argv[])
+{
+ printf("Usage: %s [-h <help>] [-i <heap id>] [-s <size in bytes>]\n",
+ argv[0]);
+}
+
+int main(int argc, char *argv[])
+{
+ int opt, ret, status, heapid;
+ int sockfd, client_fd, shared_fd;
+ unsigned char *map_buf;
+ unsigned long map_len, heap_type, heap_size, flags;
+ struct ion_buffer_info info;
+ struct socket_info skinfo;
+
+ if (argc < 2) {
+ print_usage(argc, argv);
+ return -1;
+ }
+
+ heap_size = 0;
+ flags = 0;
+
+ while ((opt = getopt(argc, argv, "hi:s:")) != -1) {
+ switch (opt) {
+ case 'h':
+ print_usage(argc, argv);
+ exit(0);
+ break;
+ case 'i':
+ heapid = atoi(optarg);
+ switch (heapid) {
+ case 0:
+ heap_type = ION_HEAP_TYPE_SYSTEM;
+ break;
+ case 1:
+ heap_type = ION_HEAP_TYPE_SYSTEM_CONTIG;
+ break;
+ default:
+ printf("ERROR: heap type not supported\n");
+ exit(1);
+ }
+ break;
+ case 's':
+ heap_size = atoi(optarg);
+ break;
+ default:
+ print_usage(argc, argv);
+ exit(1);
+ break;
+ }
+ }
+
+ if (heap_size <= 0) {
+ printf("heap_size cannot be 0\n");
+ print_usage(argc, argv);
+ exit(1);
+ }
+
+ printf("heap_type: %ld, heap_size: %ld\n", heap_type, heap_size);
+ info.heap_type = heap_type;
+ info.heap_size = heap_size;
+ info.flag_type = flags;
+
+ /* This is server: open the socket connection first */
+ /* Here; 1 indicates server or exporter */
+ status = opensocket(&sockfd, SOCKET_NAME, 1);
+ if (status < 0) {
+ fprintf(stderr, "<%s>: Failed opensocket.\n", __func__);
+ goto err_socket;
+ }
+ skinfo.sockfd = sockfd;
+
+ ret = ion_export_buffer_fd(&info);
+ if (ret < 0) {
+ fprintf(stderr, "FAILED: ion_get_buffer_fd\n");
+ goto err_export;
+ }
+ client_fd = info.ionfd;
+ shared_fd = info.buffd;
+ map_buf = info.buffer;
+ map_len = info.buflen;
+ write_buffer(map_buf, map_len);
+
+ /* share ion buf fd with other user process */
+ printf("Sharing fd: %d, Client fd: %d\n", shared_fd, client_fd);
+ skinfo.datafd = shared_fd;
+ skinfo.buflen = map_len;
+
+ ret = socket_send_fd(&skinfo);
+ if (ret < 0) {
+ fprintf(stderr, "FAILED: socket_send_fd\n");
+ goto err_send;
+ }
+
+err_send:
+err_export:
+ ion_close_buffer_fd(&info);
+
+err_socket:
+ closesocket(sockfd, SOCKET_NAME);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/android/ion/ionapp_import.c b/tools/testing/selftests/android/ion/ionapp_import.c
new file mode 100644
index 000000000000..ae2d704cfa46
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ionapp_import.c
@@ -0,0 +1,88 @@
+/*
+ * ionapp_import.c
+ *
+ * It is a user space utility to receive android ion memory buffer fd
+ * over unix domain socket IPC that can be exported by ionapp_export.
+ * This acts like a client for ionapp_export.
+ *
+ * Copyright (C) 2017 Pintu Kumar <pintu.ping@xxxxxxxxx>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "ionutils.h"
+#include "ipcsocket.h"
+
+
+int main(void)
+{
+ int ret, status;
+ int sockfd, shared_fd;
+ unsigned char *map_buf;
+ unsigned long map_len;
+ struct ion_buffer_info info;
+ struct socket_info skinfo;
+
+ /* This is the client part. Here 0 means client or importer */
+ status = opensocket(&sockfd, SOCKET_NAME, 0);
+ if (status < 0) {
+ fprintf(stderr, "No exporter exists...\n");
+ ret = status;
+ goto err_socket;
+ }
+
+ skinfo.sockfd = sockfd;
+
+ ret = socket_receive_fd(&skinfo);
+ if (ret < 0) {
+ fprintf(stderr, "Failed: socket_receive_fd\n");
+ goto err_recv;
+ }
+
+ shared_fd = skinfo.datafd;
+ printf("Received buffer fd: %d\n", shared_fd);
+ if (shared_fd <= 0) {
+ fprintf(stderr, "ERROR: improper buf fd\n");
+ ret = -1;
+ goto err_fd;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.buffd = shared_fd;
+ info.buflen = ION_BUFFER_LEN;
+
+ ret = ion_import_buffer_fd(&info);
+ if (ret < 0) {
+ fprintf(stderr, "Failed: ion_use_buffer_fd\n");
+ goto err_import;
+ }
+
+ map_buf = info.buffer;
+ map_len = info.buflen;
+ read_buffer(map_buf, map_len);
+
+ /* Write probably new data to the same buffer again */
+ map_len = ION_BUFFER_LEN;
+ write_buffer(map_buf, map_len);
+
+err_import:
+ ion_close_buffer_fd(&info);
+err_fd:
+err_recv:
+err_socket:
+ closesocket(sockfd, SOCKET_NAME);
+
+ return ret;
+}
diff --git a/tools/testing/selftests/android/ion/ionutils.c b/tools/testing/selftests/android/ion/ionutils.c
new file mode 100644
index 000000000000..ce69c14f51fa
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ionutils.c
@@ -0,0 +1,259 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+//#include <stdint.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "ionutils.h"
+#include "ipcsocket.h"
+
+
+void write_buffer(void *buffer, unsigned long len)
+{
+ int i;
+ unsigned char *ptr = (unsigned char *)buffer;
+
+ if (!ptr) {
+ fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
+ return;
+ }
+
+ printf("Fill buffer content:\n");
+ memset(ptr, 0xfd, len);
+ for (i = 0; i < len; i++)
+ printf("0x%x ", ptr[i]);
+ printf("\n");
+}
+
+void read_buffer(void *buffer, unsigned long len)
+{
+ int i;
+ unsigned char *ptr = (unsigned char *)buffer;
+
+ if (!ptr) {
+ fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
+ return;
+ }
+
+ printf("Read buffer content:\n");
+ for (i = 0; i < len; i++)
+ printf("0x%x ", ptr[i]);
+ printf("\n");
+}
+
+int ion_export_buffer_fd(struct ion_buffer_info *ion_info)
+{
+ int i, ret, ionfd, buffer_fd;
+ unsigned int heap_id;
+ unsigned long maplen;
+ unsigned char *map_buffer;
+ struct ion_allocation_data alloc_data;
+ struct ion_heap_query query;
+ struct ion_heap_data heap_data[MAX_HEAP_COUNT];
+
+ if (!ion_info) {
+ fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
+ return -1;
+ }
+
+ /* Create an ION client */
+ ionfd = open(ION_DEVICE, O_RDWR);
+ if (ionfd < 0) {
+ fprintf(stderr, "<%s>: Failed to open ion client: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ memset(&query, 0, sizeof(query));
+ query.cnt = MAX_HEAP_COUNT;
+ query.heaps = (unsigned long int)&heap_data[0];
+ /* Query ION heap_id_mask from ION heap */
+ ret = ioctl(ionfd, ION_IOC_HEAP_QUERY, &query);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed: ION_IOC_HEAP_QUERY: %s\n",
+ __func__, strerror(errno));
+ goto err_query;
+ }
+
+ heap_id = MAX_HEAP_COUNT + 1;
+ for (i = 0; i < query.cnt; i++) {
+ if (heap_data[i].type == ion_info->heap_type) {
+ printf("--------------------------------------\n");
+ printf("heap type: %d\n", heap_data[i].type);
+ printf(" heap id: %d\n", heap_data[i].heap_id);
+ printf("heap name: %s\n", heap_data[i].name);
+ printf("--------------------------------------\n");
+ heap_id = heap_data[i].heap_id;
+ break;
+ }
+ }
+
+ if (heap_id > MAX_HEAP_COUNT) {
+ fprintf(stderr, "<%s>: ERROR: heap type does not exists\n",
+ __func__);
+ goto err_heap;
+ }
+
+ alloc_data.len = ion_info->heap_size;
+ alloc_data.heap_id_mask = 1 << heap_id;
+ alloc_data.flags = ion_info->flag_type;
+
+ /* Allocate memory for this ION client as per heap_type */
+ ret = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed: ION_IOC_ALLOC: %s\n",
+ __func__, strerror(errno));
+ goto err_alloc;
+ }
+
+ /* This will return a valid buffer fd */
+ buffer_fd = alloc_data.fd;
+ maplen = alloc_data.len;
+
+ if (buffer_fd < 0 || maplen <= 0) {
+ fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
+ __func__, buffer_fd, maplen);
+ goto err_fd_data;
+ }
+
+ /* Create memory mapped buffer for the buffer fd */
+ map_buffer = (unsigned char *)mmap(NULL, maplen, PROT_READ|PROT_WRITE,
+ MAP_SHARED, buffer_fd, 0);
+ if (map_buffer == MAP_FAILED) {
+ fprintf(stderr, "<%s>: Failed: mmap: %s\n",
+ __func__, strerror(errno));
+ goto err_mmap;
+ }
+
+ ion_info->ionfd = ionfd;
+ ion_info->buffd = buffer_fd;
+ ion_info->buffer = map_buffer;
+ ion_info->buflen = maplen;
+
+ return 0;
+
+ munmap(map_buffer, maplen);
+
+err_fd_data:
+err_mmap:
+ /* in case of error: close the buffer fd */
+ if (buffer_fd)
+ close(buffer_fd);
+
+err_query:
+err_heap:
+err_alloc:
+ /* In case of error: close the ion client fd */
+ if (ionfd)
+ close(ionfd);
+
+ return -1;
+}
+
+int ion_import_buffer_fd(struct ion_buffer_info *ion_info)
+{
+ int buffd;
+ unsigned char *map_buf;
+ unsigned long map_len;
+
+ if (!ion_info) {
+ fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
+ return -1;
+ }
+
+ map_len = ion_info->buflen;
+ buffd = ion_info->buffd;
+
+ if (buffd < 0 || map_len <= 0) {
+ fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
+ __func__, buffd, map_len);
+ goto err_buffd;
+ }
+
+ map_buf = (unsigned char *)mmap(NULL, map_len, PROT_READ|PROT_WRITE,
+ MAP_SHARED, buffd, 0);
+ if (map_buf == MAP_FAILED) {
+ printf("<%s>: Failed - mmap: %s\n",
+ __func__, strerror(errno));
+ goto err_mmap;
+ }
+
+ ion_info->buffer = map_buf;
+ ion_info->buflen = map_len;
+
+ return 0;
+
+err_mmap:
+ if (buffd)
+ close(buffd);
+
+err_buffd:
+ return -1;
+}
+
+void ion_close_buffer_fd(struct ion_buffer_info *ion_info)
+{
+ if (ion_info) {
+ /* unmap the buffer properly in the end */
+ munmap(ion_info->buffer, ion_info->buflen);
+ /* close the buffer fd */
+ if (ion_info->buffd > 0)
+ close(ion_info->buffd);
+ /* Finally, close the client fd */
+ if (ion_info->ionfd > 0)
+ close(ion_info->ionfd);
+ printf("<%s>: buffer release successfully....\n", __func__);
+ }
+}
+
+int socket_send_fd(struct socket_info *info)
+{
+ int status;
+ int fd, sockfd;
+ struct socketdata skdata;
+
+ if (!info) {
+ fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
+ return -1;
+ }
+
+ sockfd = info->sockfd;
+ fd = info->datafd;
+ memset(&skdata, 0, sizeof(skdata));
+ skdata.data = fd;
+ skdata.len = sizeof(skdata.data);
+ status = sendtosocket(sockfd, &skdata);
+ if (status < 0) {
+ fprintf(stderr, "<%s>: Failed: sendtosocket\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+int socket_receive_fd(struct socket_info *info)
+{
+ int status;
+ int fd, sockfd;
+ struct socketdata skdata;
+
+ if (!info) {
+ fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
+ return -1;
+ }
+
+ sockfd = info->sockfd;
+ memset(&skdata, 0, sizeof(skdata));
+ status = receivefromsocket(sockfd, &skdata);
+ if (status < 0) {
+ fprintf(stderr, "<%s>: Failed: receivefromsocket\n", __func__);
+ return -1;
+ }
+
+ fd = (int)skdata.data;
+ info->datafd = fd;
+
+ return status;
+}
diff --git a/tools/testing/selftests/android/ion/ionutils.h b/tools/testing/selftests/android/ion/ionutils.h
new file mode 100644
index 000000000000..9941eb858576
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ionutils.h
@@ -0,0 +1,55 @@
+#ifndef __ION_UTILS_H
+#define __ION_UTILS_H
+
+#include "ion.h"
+
+#define SOCKET_NAME "ion_socket"
+#define ION_DEVICE "/dev/ion"
+
+#define ION_BUFFER_LEN 4096
+#define MAX_HEAP_COUNT ION_HEAP_TYPE_CUSTOM
+
+struct socket_info {
+ int sockfd;
+ int datafd;
+ unsigned long buflen;
+};
+
+struct ion_buffer_info {
+ int ionfd;
+ int buffd;
+ unsigned int heap_type;
+ unsigned int flag_type;
+ unsigned long heap_size;
+ unsigned long buflen;
+ unsigned char *buffer;
+};
+
+
+/* This is used to fill the data into the mapped buffer */
+void write_buffer(void *buffer, unsigned long len);
+
+/* This is used to read the data from the exported buffer */
+void read_buffer(void *buffer, unsigned long len);
+
+/* This is used to create an ION buffer FD for the kernel buffer
+ * So you can export this same buffer to others in the form of FD
+ */
+int ion_export_buffer_fd(struct ion_buffer_info *ion_info);
+
+/* This is used to import or map an exported FD.
+ * So we point to same buffer without making a copy. Hence zero-copy.
+ */
+int ion_import_buffer_fd(struct ion_buffer_info *ion_info);
+
+/* This is used to close all references for the ION client */
+void ion_close_buffer_fd(struct ion_buffer_info *ion_info);
+
+/* This is used to send FD to another process using socket IPC */
+int socket_send_fd(struct socket_info *skinfo);
+
+/* This is used to receive FD from another process using socket IPC */
+int socket_receive_fd(struct socket_info *skinfo);
+
+
+#endif
diff --git a/tools/testing/selftests/android/ion/ipcsocket.c b/tools/testing/selftests/android/ion/ipcsocket.c
new file mode 100644
index 000000000000..7dc521002095
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ipcsocket.c
@@ -0,0 +1,227 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include "ipcsocket.h"
+
+
+int opensocket(int *sockfd, const char *name, int connecttype)
+{
+ int ret, temp = 1;
+
+ if (!name || strlen(name) > MAX_SOCK_NAME_LEN) {
+ fprintf(stderr, "<%s>: Invalid socket name.\n", __func__);
+ return -1;
+ }
+
+ ret = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed socket: <%s>\n",
+ __func__, strerror(errno));
+ return ret;
+ }
+
+ *sockfd = ret;
+ if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&temp, sizeof(int)) < 0) {
+ fprintf(stderr, "<%s>: Failed setsockopt: <%s>\n",
+ __func__, strerror(errno));
+ goto err;
+ }
+
+ sprintf(sock_name, "/tmp/%s", name);
+
+ if (connecttype == 1) {
+ /* This is for Server connection */
+ struct sockaddr_un skaddr;
+ int clientfd;
+ socklen_t sklen;
+
+ unlink(sock_name);
+ memset(&skaddr, 0, sizeof(skaddr));
+ skaddr.sun_family = AF_LOCAL;
+ strcpy(skaddr.sun_path, sock_name);
+
+ ret = bind(*sockfd, (struct sockaddr *)&skaddr,
+ SUN_LEN(&skaddr));
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed bind: <%s>\n",
+ __func__, strerror(errno));
+ goto err;
+ }
+
+ ret = listen(*sockfd, 5);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed listen: <%s>\n",
+ __func__, strerror(errno));
+ goto err;
+ }
+
+ memset(&skaddr, 0, sizeof(skaddr));
+ sklen = sizeof(skaddr);
+
+ ret = accept(*sockfd, (struct sockaddr *)&skaddr,
+ (socklen_t *)&sklen);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed accept: <%s>\n",
+ __func__, strerror(errno));
+ goto err;
+ }
+
+ clientfd = ret;
+ *sockfd = clientfd;
+ } else {
+ /* This is for client connection */
+ struct sockaddr_un skaddr;
+
+ memset(&skaddr, 0, sizeof(skaddr));
+ skaddr.sun_family = AF_LOCAL;
+ strcpy(skaddr.sun_path, sock_name);
+
+ ret = connect(*sockfd, (struct sockaddr *)&skaddr,
+ SUN_LEN(&skaddr));
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed connect: <%s>\n",
+ __func__, strerror(errno));
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ if (*sockfd)
+ close(*sockfd);
+
+ return ret;
+}
+
+int sendtosocket(int sockfd, struct socketdata *skdata)
+{
+ int ret, buffd;
+ unsigned int len;
+ char cmsg_b[CMSG_SPACE(sizeof(int))];
+ struct cmsghdr *cmsg;
+ struct msghdr msgh;
+ struct iovec iov;
+ struct timeval timeout;
+ fd_set selFDs;
+
+ if (!skdata) {
+ fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
+ return -1;
+ }
+
+ FD_ZERO(&selFDs);
+ FD_SET(0, &selFDs);
+ FD_SET(sockfd, &selFDs);
+ timeout.tv_sec = 20;
+ timeout.tv_usec = 0;
+
+ ret = select(sockfd+1, NULL, &selFDs, NULL, &timeout);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed select: <%s>\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ if (FD_ISSET(sockfd, &selFDs)) {
+ buffd = skdata->data;
+ len = skdata->len;
+ memset(&msgh, 0, sizeof(msgh));
+ msgh.msg_control = &cmsg_b;
+ msgh.msg_controllen = CMSG_LEN(len);
+ iov.iov_base = "OK";
+ iov.iov_len = 2;
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+ cmsg = CMSG_FIRSTHDR(&msgh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(len);
+ memcpy(CMSG_DATA(cmsg), &buffd, len);
+
+ ret = sendmsg(sockfd, &msgh, MSG_DONTWAIT);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed sendmsg: <%s>\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int receivefromsocket(int sockfd, struct socketdata *skdata)
+{
+ int ret, buffd;
+ unsigned int len = 0;
+ char cmsg_b[CMSG_SPACE(sizeof(int))];
+ struct cmsghdr *cmsg;
+ struct msghdr msgh;
+ struct iovec iov;
+ fd_set recvFDs;
+ char data[32];
+
+ if (!skdata) {
+ fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
+ return -1;
+ }
+
+ FD_ZERO(&recvFDs);
+ FD_SET(0, &recvFDs);
+ FD_SET(sockfd, &recvFDs);
+
+ ret = select(sockfd+1, &recvFDs, NULL, NULL, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed select: <%s>\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ if (FD_ISSET(sockfd, &recvFDs)) {
+ len = sizeof(buffd);
+ memset(&msgh, 0, sizeof(msgh));
+ msgh.msg_control = &cmsg_b;
+ msgh.msg_controllen = CMSG_LEN(len);
+ iov.iov_base = data;
+ iov.iov_len = sizeof(data)-1;
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+ cmsg = CMSG_FIRSTHDR(&msgh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(len);
+
+ ret = recvmsg(sockfd, &msgh, MSG_DONTWAIT);
+ if (ret < 0) {
+ fprintf(stderr, "<%s>: Failed recvmsg: <%s>\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ memcpy(&buffd, CMSG_DATA(cmsg), len);
+ skdata->data = buffd;
+ skdata->len = len;
+ }
+ return 0;
+}
+
+int closesocket(int sockfd, char *name)
+{
+ char sockname[MAX_SOCK_NAME_LEN];
+
+ if (sockfd)
+ close(sockfd);
+ sprintf(sockname, "/tmp/%s", name);
+ unlink(sockname);
+ shutdown(sockfd, 2);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/android/ion/ipcsocket.h b/tools/testing/selftests/android/ion/ipcsocket.h
new file mode 100644
index 000000000000..b3e84498a8a1
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ipcsocket.h
@@ -0,0 +1,35 @@
+
+#ifndef _IPCSOCKET_H
+#define _IPCSOCKET_H
+
+
+#define MAX_SOCK_NAME_LEN 64
+
+char sock_name[MAX_SOCK_NAME_LEN];
+
+/* This structure is responsible for holding the IPC data
+ * data: hold the buffer fd
+ * len: just the length of 32-bit integer fd
+ */
+struct socketdata {
+ int data;
+ unsigned int len;
+};
+
+/* This API is used to open the IPC socket connection
+ * name: implies a unique socket name in the system
+ * connecttype: implies server(0) or client(1)
+ */
+int opensocket(int *sockfd, const char *name, int connecttype);
+
+/* This is the API to send socket data over IPC socket */
+int sendtosocket(int sockfd, struct socketdata *data);
+
+/* This is the API to receive socket data over IPC socket */
+int receivefromsocket(int sockfd, struct socketdata *data);
+
+/* This is the API to close the socket connection */
+int closesocket(int sockfd, char *name);
+
+
+#endif
diff --git a/tools/testing/selftests/android/run.sh b/tools/testing/selftests/android/run.sh
new file mode 100755
index 000000000000..dd8edf291454
--- /dev/null
+++ b/tools/testing/selftests/android/run.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+(cd ion; ./ion_test.sh)
diff --git a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
index 960d02100c26..2d95e5adde72 100644
--- a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
+++ b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
@@ -19,6 +19,7 @@

#define _GNU_SOURCE

+#include <asm/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
diff --git a/tools/testing/selftests/cpu-hotplug/config b/tools/testing/selftests/cpu-hotplug/config
index e6ab090cfbf3..d4aca2ad5069 100644
--- a/tools/testing/selftests/cpu-hotplug/config
+++ b/tools/testing/selftests/cpu-hotplug/config
@@ -1,2 +1 @@
CONFIG_NOTIFIER_ERROR_INJECTION=y
-CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index 8d5d1d2ee7c1..67cd4597db2b 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -147,7 +147,7 @@ static void exe_cp(const char *src, const char *dest)
}

#define XX_DIR_LEN 200
-static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
+static int check_execveat_pathmax(int root_dfd, const char *src, int is_script)
{
int fail = 0;
int ii, count, len;
@@ -156,20 +156,30 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)

if (*longpath == '\0') {
/* Create a filename close to PATH_MAX in length */
+ char *cwd = getcwd(NULL, 0);
+
+ if (!cwd) {
+ printf("Failed to getcwd(), errno=%d (%s)\n",
+ errno, strerror(errno));
+ return 2;
+ }
+ strcpy(longpath, cwd);
+ strcat(longpath, "/");
memset(longname, 'x', XX_DIR_LEN - 1);
longname[XX_DIR_LEN - 1] = '/';
longname[XX_DIR_LEN] = '\0';
- count = (PATH_MAX - 3) / XX_DIR_LEN;
+ count = (PATH_MAX - 3 - strlen(cwd)) / XX_DIR_LEN;
for (ii = 0; ii < count; ii++) {
strcat(longpath, longname);
mkdir(longpath, 0755);
}
- len = (PATH_MAX - 3) - (count * XX_DIR_LEN);
+ len = (PATH_MAX - 3 - strlen(cwd)) - (count * XX_DIR_LEN);
if (len <= 0)
len = 1;
memset(longname, 'y', len);
longname[len] = '\0';
strcat(longpath, longname);
+ free(cwd);
}
exe_cp(src, longpath);

@@ -190,7 +200,7 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
}

/*
- * Execute as a long pathname relative to ".". If this is a script,
+ * Execute as a long pathname relative to "/". If this is a script,
* the interpreter will launch but fail to open the script because its
* name ("/dev/fd/5/xxx....") is bigger than PATH_MAX.
*
@@ -200,10 +210,10 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
* the exit status shall be 126."), so allow either.
*/
if (is_script)
- fail += check_execveat_invoked_rc(dot_dfd, longpath, 0,
+ fail += check_execveat_invoked_rc(root_dfd, longpath + 1, 0,
127, 126);
else
- fail += check_execveat(dot_dfd, longpath, 0);
+ fail += check_execveat(root_dfd, longpath + 1, 0);

return fail;
}
@@ -218,6 +228,7 @@ static int run_tests(void)
int subdir_dfd_ephemeral = open_or_die("subdir.ephemeral",
O_DIRECTORY|O_RDONLY);
int dot_dfd = open_or_die(".", O_DIRECTORY|O_RDONLY);
+ int root_dfd = open_or_die("/", O_DIRECTORY|O_RDONLY);
int dot_dfd_path = open_or_die(".", O_DIRECTORY|O_RDONLY|O_PATH);
int dot_dfd_cloexec = open_or_die(".", O_DIRECTORY|O_RDONLY|O_CLOEXEC);
int fd = open_or_die("execveat", O_RDONLY);
@@ -353,8 +364,8 @@ static int run_tests(void)
/* Attempt to execute relative to non-directory => ENOTDIR */
fail += check_execveat_fail(fd, "execveat", 0, ENOTDIR);

- fail += check_execveat_pathmax(dot_dfd, "execveat", 0);
- fail += check_execveat_pathmax(dot_dfd, "script", 1);
+ fail += check_execveat_pathmax(root_dfd, "execveat", 0);
+ fail += check_execveat_pathmax(root_dfd, "script", 1);
return fail;
}

diff --git a/tools/testing/selftests/firmware/fw_fallback.sh b/tools/testing/selftests/firmware/fw_fallback.sh
index a52a3bab532b..34a42c68ebfb 100755
--- a/tools/testing/selftests/firmware/fw_fallback.sh
+++ b/tools/testing/selftests/firmware/fw_fallback.sh
@@ -86,6 +86,11 @@ load_fw_cancel()

load_fw_custom()
{
+ if [ ! -e "$DIR"/trigger_custom_fallback ]; then
+ echo "$0: custom fallback trigger not present, ignoring test" >&2
+ return 1
+ fi
+
local name="$1"
local file="$2"

@@ -108,11 +113,17 @@ load_fw_custom()

# Wait for request to finish.
wait
+ return 0
}


load_fw_custom_cancel()
{
+ if [ ! -e "$DIR"/trigger_custom_fallback ]; then
+ echo "$0: canceling custom fallback trigger not present, ignoring test" >&2
+ return 1
+ fi
+
local name="$1"
local file="$2"

@@ -133,6 +144,7 @@ load_fw_custom_cancel()

# Wait for request to finish.
wait
+ return 0
}

load_fw_fallback_with_child()
@@ -227,20 +239,22 @@ else
echo "$0: cancelling fallback mechanism works"
fi

-load_fw_custom "$NAME" "$FW"
-if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
- echo "$0: firmware was not loaded" >&2
- exit 1
-else
- echo "$0: custom fallback loading mechanism works"
+if load_fw_custom "$NAME" "$FW" ; then
+ if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
+ echo "$0: firmware was not loaded" >&2
+ exit 1
+ else
+ echo "$0: custom fallback loading mechanism works"
+ fi
fi

-load_fw_custom_cancel "nope-$NAME" "$FW"
-if diff -q "$FW" /dev/test_firmware >/dev/null ; then
- echo "$0: firmware was expected to be cancelled" >&2
- exit 1
-else
- echo "$0: cancelling custom fallback mechanism works"
+if load_fw_custom_cancel "nope-$NAME" "$FW" ; then
+ if diff -q "$FW" /dev/test_firmware >/dev/null ; then
+ echo "$0: firmware was expected to be cancelled" >&2
+ exit 1
+ else
+ echo "$0: cancelling custom fallback mechanism works"
+ fi
fi

set +e
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
index 62f2d6f54929..b1f20fef36c7 100755
--- a/tools/testing/selftests/firmware/fw_filesystem.sh
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -70,9 +70,13 @@ if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
exit 1
fi

-if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
- echo "$0: empty filename should not succeed (async)" >&2
- exit 1
+if [ ! -e "$DIR"/trigger_async_request ]; then
+ echo "$0: empty filename: async trigger not present, ignoring test" >&2
+else
+ if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
+ echo "$0: empty filename should not succeed (async)" >&2
+ exit 1
+ fi
fi

# Request a firmware that doesn't exist, it should fail.
@@ -105,17 +109,21 @@ else
fi

# Try the asynchronous version too
-if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
- echo "$0: could not trigger async request" >&2
- exit 1
-fi
-
-# Verify the contents are what we expect.
-if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
- echo "$0: firmware was not loaded (async)" >&2
- exit 1
+if [ ! -e "$DIR"/trigger_async_request ]; then
+ echo "$0: firmware loading: async trigger not present, ignoring test" >&2
else
- echo "$0: async filesystem loading works"
+ if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
+ echo "$0: could not trigger async request" >&2
+ exit 1
+ fi
+
+ # Verify the contents are what we expect.
+ if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
+ echo "$0: firmware was not loaded (async)" >&2
+ exit 1
+ else
+ echo "$0: async filesystem loading works"
+ fi
fi

### Batched requests tests
diff --git a/tools/testing/selftests/ftrace/config b/tools/testing/selftests/ftrace/config
index 8a1c9f949fe0..b01924c71c09 100644
--- a/tools/testing/selftests/ftrace/config
+++ b/tools/testing/selftests/ftrace/config
@@ -1,2 +1,6 @@
CONFIG_KPROBES=y
CONFIG_FTRACE=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_TRACER_SNAPSHOT=y
+CONFIG_STACK_TRACER=y
+CONFIG_HIST_TRIGGERS=y
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index abc706cf7702..f9a9d424c980 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -222,7 +222,14 @@ SIG_RESULT=
SIG_BASE=36 # Use realtime signals
SIG_PID=$$

+exit_pass () {
+ exit 0
+}
+
SIG_FAIL=$((SIG_BASE + FAIL))
+exit_fail () {
+ exit 1
+}
trap 'SIG_RESULT=$FAIL' $SIG_FAIL

SIG_UNRESOLVED=$((SIG_BASE + UNRESOLVED))
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
index aa51f6c17359..0696098d6408 100644
--- a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
+++ b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
@@ -2,4 +2,4 @@
# description: Basic event tracing check
test -f available_events -a -f set_event -a -d events
# check scheduler events are available
-grep -q sched available_events && exit 0 || exit $FAIL
+grep -q sched available_events && exit_pass || exit_fail
diff --git a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc
index 6ff851a75884..9daf034186f5 100644
--- a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc
+++ b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc
@@ -11,7 +11,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

yield() {
diff --git a/tools/testing/selftests/ftrace/test.d/event/event-pid.tc b/tools/testing/selftests/ftrace/test.d/event/event-pid.tc
index cc14feec6e1f..132478b305c2 100644
--- a/tools/testing/selftests/ftrace/test.d/event/event-pid.tc
+++ b/tools/testing/selftests/ftrace/test.d/event/event-pid.tc
@@ -13,7 +13,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

yield() {
diff --git a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
index 85094904aa79..6a37a8642ee6 100644
--- a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
+++ b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
@@ -11,7 +11,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

yield() {
diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
index cc1cf4d30ef5..4e9b6e2c0219 100644
--- a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
+++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
@@ -10,7 +10,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

yield() {
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
index 45df747887e0..1aec99d108eb 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
@@ -28,7 +28,7 @@ do_reset() {
fail() { # msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

disable_tracing
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
index 0387e22e7577..9f8d27ca39cf 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
@@ -18,7 +18,7 @@ do_reset() {
fail() { # msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

disable_tracing
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-pid.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-pid.tc
index 78524fcc25ae..524ce24b3c22 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-pid.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-pid.tc
@@ -51,7 +51,7 @@ do_reset() {
fail() { # msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

yield() {
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
index 9d4afcca1e36..6fed4cf2db81 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
@@ -27,7 +27,7 @@ do_reset() {
fail() { # mesg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

SLEEP_TIME=".1"
@@ -48,8 +48,7 @@ test_event_enabled() {

e=`cat $EVENT_ENABLE`
if [ "$e" != $val ]; then
- echo "Expected $val but found $e"
- exit 1
+ fail "Expected $val but found $e"
fi
}

diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
index fe0dc5a7ea26..b2d5a8febfe8 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
@@ -32,7 +32,7 @@ fail() { # mesg
reset_tracer
echo > set_ftrace_filter
echo $1
- exit $FAIL
+ exit_fail
}

echo "Testing function tracer with profiler:"
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc
index 5ad723724adb..0f3f92622e33 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc
@@ -26,14 +26,14 @@ do_reset() {
fail() { # mesg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

do_reset

FILTER=set_ftrace_filter
FUNC1="schedule"
-FUNC2="do_IRQ"
+FUNC2="do_softirq"

ALL_FUNCS="#### all functions enabled ####"

diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc
index cdc92a371cd7..f6d9ac73268a 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc
@@ -27,7 +27,7 @@ do_reset() {
fail() { # mesg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

SLEEP_TIME=".1"
diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
index d7f48b55df51..4fa0f79144f4 100644
--- a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
+++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
@@ -11,7 +11,7 @@ fail() { # mesg
rmdir foo 2>/dev/null
echo $1
set -e
- exit $FAIL
+ exit_fail
}

cd instances
diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance.tc b/tools/testing/selftests/ftrace/test.d/instances/instance.tc
index ddda62203366..b84651283bf3 100644
--- a/tools/testing/selftests/ftrace/test.d/instances/instance.tc
+++ b/tools/testing/selftests/ftrace/test.d/instances/instance.tc
@@ -11,7 +11,7 @@ fail() { # mesg
rmdir x y z 2>/dev/null
echo $1
set -e
- exit $FAIL
+ exit_fail
}

cd instances
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
index 0e6f415c6152..bbc443a9190c 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
@@ -9,7 +9,7 @@ echo > kprobe_events
echo p:myevent _do_fork > kprobe_events
test -d events/kprobes/myevent
echo 1 > events/kprobes/myevent/enable
-echo > kprobe_events && exit 1 # this must fail
+echo > kprobe_events && exit_fail # this must fail
echo 0 > events/kprobes/myevent/enable
echo > kprobe_events # this must succeed
clear_trace
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
index 679bbd23bcc3..8b43c6804fc3 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
@@ -14,5 +14,5 @@ echo 1 > events/kprobes/testprobe/enable
echo 0 > events/kprobes/testprobe/enable
echo "-:testprobe" >> kprobe_events
clear_trace
-test -d events/kprobes/testprobe && exit 1 || exit 0
+test -d events/kprobes/testprobe && exit_fail || exit_pass

diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
index 17d33ba192f6..2a1755bfc290 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
@@ -35,4 +35,4 @@ check_types $ARGS

echo "-:testprobe" >> kprobe_events
clear_trace
-test -d events/kprobes/testprobe && exit 1 || exit 0
+test -d events/kprobes/testprobe && exit_fail || exit_pass
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
index f1825bdbe3f3..321954683aaa 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
@@ -14,4 +14,4 @@ echo 1 > events/kprobes/testprobe2/enable
echo 0 > events/kprobes/testprobe2/enable
echo '-:testprobe2' >> kprobe_events
clear_trace
-test -d events/kprobes/testprobe2 && exit 1 || exit 0
+test -d events/kprobes/testprobe2 && exit_fail || exit_pass
diff --git a/tools/testing/selftests/ftrace/test.d/template b/tools/testing/selftests/ftrace/test.d/template
index 5448f7abad5f..5c39ceb18a0d 100644
--- a/tools/testing/selftests/ftrace/test.d/template
+++ b/tools/testing/selftests/ftrace/test.d/template
@@ -4,6 +4,7 @@
# Note that all tests are run with "errexit" option.

exit 0 # Return 0 if the test is passed, otherwise return !0
+# Or you can call exit_pass for passed test, and exit_fail for failed test.
# If the test could not run because of lack of feature, call exit_unsupported
# If the test returned unclear results, call exit_unresolved
# If the test is a dummy, or a placeholder, call exit_untested
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-eventonoff.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-eventonoff.tc
index 839ac4320b24..28cc355a3a7b 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-eventonoff.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-eventonoff.tc
@@ -12,7 +12,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-filter.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-filter.tc
index 66873c4b12c9..a48e23eb8a8b 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-filter.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-filter.tc
@@ -12,7 +12,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
index 4237b32769f1..8da80efc44d8 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
@@ -12,7 +12,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
index d24e2b8bd863..449fe9ff91a2 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
@@ -12,7 +12,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
index 4c0774fff378..c5ef8b9d02b3 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
@@ -12,7 +12,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
index 3fc6321e081f..ed38f0050d77 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
@@ -11,7 +11,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-stacktrace.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-stacktrace.tc
index 3652824f81ed..3121d795a868 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-stacktrace.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-stacktrace.tc
@@ -11,7 +11,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-traceonoff.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-traceonoff.tc
index 6d9051cdf408..c59d9eb546da 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-traceonoff.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-traceonoff.tc
@@ -11,7 +11,7 @@ do_reset() {
fail() { #msg
do_reset
echo $1
- exit $FAIL
+ exit_fail
}

if [ ! -f set_event -o ! -d events/sched ]; then
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
index 845e5f67b6f0..132a54f74e88 100644
--- a/tools/testing/selftests/memfd/memfd_test.c
+++ b/tools/testing/selftests/memfd/memfd_test.c
@@ -515,7 +515,7 @@ static void mfd_assert_grow_write(int fd)

buf = malloc(mfd_def_size * 8);
if (!buf) {
- printf("malloc(%d) failed: %m\n", mfd_def_size * 8);
+ printf("malloc(%zu) failed: %m\n", mfd_def_size * 8);
abort();
}

@@ -535,7 +535,7 @@ static void mfd_fail_grow_write(int fd)

buf = malloc(mfd_def_size * 8);
if (!buf) {
- printf("malloc(%d) failed: %m\n", mfd_def_size * 8);
+ printf("malloc(%zu) failed: %m\n", mfd_def_size * 8);
abort();
}

diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile
index 23db11c94b59..86636d207adf 100644
--- a/tools/testing/selftests/memory-hotplug/Makefile
+++ b/tools/testing/selftests/memory-hotplug/Makefile
@@ -4,10 +4,10 @@ all:
include ../lib.mk

TEST_PROGS := mem-on-off-test.sh
-override RUN_TESTS := ./mem-on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]"
+override RUN_TESTS := ./mem-on-off-test.sh -r 2 && echo "selftests: memory-hotplug [PASS]" || echo "selftests: memory-hotplug [FAIL]"
override EMIT_TESTS := echo "$(RUN_TESTS)"

run_full_test:
- @/bin/bash ./mem-on-off-test.sh || echo "memory-hotplug selftests: [FAIL]"
+ @/bin/bash ./mem-on-off-test.sh && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]"

clean:
diff --git a/tools/testing/selftests/seccomp/.gitignore b/tools/testing/selftests/seccomp/.gitignore
index 346d83ca8069..5af29d3a1b0a 100644
--- a/tools/testing/selftests/seccomp/.gitignore
+++ b/tools/testing/selftests/seccomp/.gitignore
@@ -1 +1,2 @@
seccomp_bpf
+seccomp_benchmark
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore
index cc986621f512..2c8ac8416299 100644
--- a/tools/testing/selftests/timers/.gitignore
+++ b/tools/testing/selftests/timers/.gitignore
@@ -18,3 +18,5 @@ threadtest
valid-adjtimex
adjtick
set-tz
+freq-step
+rtctest_setdate
diff --git a/tools/testing/selftests/vDSO/vdso_test.c b/tools/testing/selftests/vDSO/vdso_test.c
index 8daeb7d7032c..2df26bd0099c 100644
--- a/tools/testing/selftests/vDSO/vdso_test.c
+++ b/tools/testing/selftests/vDSO/vdso_test.c
@@ -19,6 +19,19 @@ extern void *vdso_sym(const char *version, const char *name);
extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
extern void vdso_init_from_auxv(void *auxv);

+/*
+ * ARM64's vDSO exports its gettimeofday() implementation with a different
+ * name and version from other architectures, so we need to handle it as
+ * a special case.
+ */
+#if defined(__aarch64__)
+const char *version = "LINUX_2.6.39";
+const char *name = "__kernel_gettimeofday";
+#else
+const char *version = "LINUX_2.6";
+const char *name = "__vdso_gettimeofday";
+#endif
+
int main(int argc, char **argv)
{
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
@@ -31,10 +44,10 @@ int main(int argc, char **argv)

/* Find gettimeofday. */
typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
- gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+ gtod_t gtod = (gtod_t)vdso_sym(version, name);

if (!gtod) {
- printf("Could not find __vdso_gettimeofday\n");
+ printf("Could not find %s\n", name);
return 1;
}

@@ -45,7 +58,7 @@ int main(int argc, char **argv)
printf("The time is %lld.%06lld\n",
(long long)tv.tv_sec, (long long)tv.tv_usec);
} else {
- printf("__vdso_gettimeofday failed\n");
+ printf("%s failed\n", name);
}

return 0;
diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore
index 142c565bb351..1ca2ee4d15b9 100644
--- a/tools/testing/selftests/vm/.gitignore
+++ b/tools/testing/selftests/vm/.gitignore
@@ -8,3 +8,5 @@ on-fault-limit
transhuge-stress
userfaultfd
mlock-intersect-test
+mlock-random-test
+virtual_address_range