v2: Implements the getter/setter interface in ptrace rather than prctl
Syscall user dispatch makes it possible to cleanly intercept system
calls from user-land. However, most transparent checkpoint software
presently leverages some combination of ptrace and system call
injection to place software in a ready-to-checkpoint state.
If Syscall User Dispatch is enabled at the time of being quiesced,
injected system calls will subsequently be interposed upon and
dispatched to the task's signal handler.
This patch set implements 3 features to enable software such as CRIU
to cleanly interpose upon software leveraging syscall user dispatch.
- Implement PTRACE_O_SUSPEND_SYSCALL_USER_DISPATCH, akin to a similar
feature for SECCOMP. This allows a ptracer to temporarily disable
syscall user dispatch, making syscall injection possible.
- Implement an fs/proc extension that reports whether Syscall User
Dispatch is being used in proc/status. A similar value is present
for SECCOMP, and is used to determine whether special logic is
needed during checkpoint/resume.
- Implement a getter interface for Syscall User Dispatch config info.
To resume successfully, the checkpoint/resume software has to
save and restore this information. Presently this configuration
is write-only, with no way for C/R software to save it.
This was done in ptrace because syscall user dispatch is not part of
uapi. The syscall_user_dispatch_config structure was added to the
ptrace exports.
Signed-off-by: Gregory Price <gregory.price(a)memverge.com>
Gregory Price (3):
ptrace,syscall_user_dispatch: Implement Syscall User Dispatch
Suspension
fs/proc/array: Add Syscall User Dispatch to proc status
ptrace,syscall_user_dispatch: add a getter/setter for sud
configuration
.../admin-guide/syscall-user-dispatch.rst | 5 +-
fs/proc/array.c | 8 +++
include/linux/ptrace.h | 2 +
include/linux/syscall_user_dispatch.h | 19 +++++++
include/uapi/linux/ptrace.h | 16 +++++-
kernel/entry/syscall_user_dispatch.c | 54 +++++++++++++++++++
kernel/ptrace.c | 14 +++++
7 files changed, 116 insertions(+), 2 deletions(-)
--
2.39.0
From: Arnd Bergmann <arnd(a)arndb.de>
Using kunit_fail_current_test() in a loadable module causes a link
error like:
ERROR: modpost: "kunit_running" [drivers/gpu/drm/vc4/vc4.ko] undefined!
Export the symbol to allow using it from modules.
Fixes: da43ff045c3f ("drm/vc4: tests: Fail the current test if we access a register")
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
lib/kunit/test.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index c9ebf975e56b..890ba5b3a981 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -21,6 +21,7 @@
#include "try-catch-impl.h"
DEFINE_STATIC_KEY_FALSE(kunit_running);
+EXPORT_SYMBOL_GPL(kunit_running);
#if IS_BUILTIN(CONFIG_KUNIT)
/*
--
2.39.0
Confidential VMs(CVMs) need to execute hypercall instruction as per the CPU
type. Normally KVM emulates the vmcall/vmmcall instruction by patching
the guest code at runtime. Such a guest memory manipulation by KVM is
not allowed with CVMs and is also undesirable in general.
This series adds support of executing hypercall as per the host cpu vendor.
CPU vendor is queried early during selftest setup and guest setup to be
reused later.
Changes in v5:
1) Incorporated suggestions from Sean -
* Rename the APIs to have "this_cpu*" prefix to better convey the
intent of callers to query cpu vendor of the current cpu
* Squash patches together to cache, share cpu vendor type and replace
current callers of "this_cpu*" with checking the saved host cpu vendor
in a single patch.
Changes in v4:
1) Incoporated suggestions from Sean -
* Added APIs to query host cpu type
* Shared the host cpu type with guests to avoid querying the cpu type
again
* Modified kvm_hypercall to execute vmcall/vmmcall according to host
cpu type.
2) Dropped the separate API for kvm_hypercall.
v4:
https://lore.kernel.org/lkml/20221228192438.2835203-1-vannapurve@google.com/
Vishal Annapurve (3):
KVM: selftests: x86: Use "this_cpu" prefix for cpu vendor queries
KVM: selftests: x86: Cache host CPU vendor (AMD vs. Intel)
KVM: selftests: x86: Use host's native hypercall instruction in
kvm_hypercall()
.../selftests/kvm/include/x86_64/processor.h | 28 +++++++++--
.../selftests/kvm/lib/x86_64/processor.c | 46 ++++++++-----------
.../selftests/kvm/x86_64/fix_hypercall_test.c | 4 +-
.../selftests/kvm/x86_64/mmio_warning_test.c | 2 +-
.../kvm/x86_64/pmu_event_filter_test.c | 4 +-
.../vmx_exception_with_invalid_guest_state.c | 2 +-
6 files changed, 51 insertions(+), 35 deletions(-)
--
2.39.0.314.g84b9a713c41-goog
KUnit has several macros and functions intended for use from non-test
code. These hooks, currently the kunit_get_current_test() and
kunit_fail_current_test() macros, didn't work when CONFIG_KUNIT=m.
In order to support this case, the required functions and static data
need to be available unconditionally, even when KUnit itself is not
built-in. The new 'hooks.c' file is therefore always included, and has
both the static key required for kunit_get_current_test(), and a
function pointer to the real implementation of
__kunit_fail_current_test(), which is populated when the KUnit module is
loaded.
This can then be extended for future features which require similar
"hook" behaviour, such as static stubs:
https://lore.kernel.org/all/20221208061841.2186447-1-davidgow@google.com/
Signed-off-by: David Gow <davidgow(a)google.com>
---
This is basically a prerequisite for the stub features working when
KUnit is built as a module, and should nicely make a few other tests
work then, too.
I'm not 100% sold on the whole "fill in a table of function pointers
when kunit.ko is loaded" trick: it is basically just working around the
sensible limitations on depending on modules. I think it should be safe
here, as the functions/macros all have fallback behaviour when no test
is running, and this is just another case of that.
Similarly, I'm sure there must be a better way to compile hooks.o in
when KUNIT=y or KUNIT=m, but the trick of adding it separately as an
obj-y in the lib/ Makefile, then having an #if IS_ENABLED() check in the
file is the only one I've been able to come up with using my meagre
knowledge of Kbuild. Better suggestions welcome!
---
Documentation/dev-tools/kunit/usage.rst | 14 ++++++--------
include/kunit/test-bug.h | 15 ++++++++-------
lib/Makefile | 4 ++++
lib/kunit/Makefile | 3 +++
lib/kunit/hooks.c | 23 +++++++++++++++++++++++
lib/kunit/test.c | 10 ++++------
6 files changed, 48 insertions(+), 21 deletions(-)
create mode 100644 lib/kunit/hooks.c
diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst
index 48f8196d5aad..6424493b93cb 100644
--- a/Documentation/dev-tools/kunit/usage.rst
+++ b/Documentation/dev-tools/kunit/usage.rst
@@ -648,10 +648,9 @@ We can do this via the ``kunit_test`` field in ``task_struct``, which we can
access using the ``kunit_get_current_test()`` function in ``kunit/test-bug.h``.
``kunit_get_current_test()`` is safe to call even if KUnit is not enabled. If
-KUnit is not enabled, was built as a module (``CONFIG_KUNIT=m``), or no test is
-running in the current task, it will return ``NULL``. This compiles down to
-either a no-op or a static key check, so will have a negligible performance
-impact when no test is running.
+KUnit is not enabled, or if no test is running in the current task, it will
+return ``NULL``. This compiles down to either a no-op or a static key check,
+so will have a negligible performance impact when no test is running.
The example below uses this to implement a "mock" implementation of a function, ``foo``:
@@ -726,8 +725,7 @@ structures as shown below:
#endif
``kunit_fail_current_test()`` is safe to call even if KUnit is not enabled. If
-KUnit is not enabled, was built as a module (``CONFIG_KUNIT=m``), or no test is
-running in the current task, it will do nothing. This compiles down to either a
-no-op or a static key check, so will have a negligible performance impact when
-no test is running.
+KUnit is not enabled, or if no test is running in the current task, it will do
+nothing. This compiles down to either a no-op or a static key check, so will
+have a negligible performance impact when no test is running.
diff --git a/include/kunit/test-bug.h b/include/kunit/test-bug.h
index c1b2e14eab64..122f50198903 100644
--- a/include/kunit/test-bug.h
+++ b/include/kunit/test-bug.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * KUnit API allowing dynamic analysis tools to interact with KUnit tests
+ * KUnit API providing hooks for non-test code to interact with tests.
*
* Copyright (C) 2020, Google LLC.
* Author: Uriel Guajardo <urielguajardo(a)google.com>
@@ -9,7 +9,7 @@
#ifndef _KUNIT_TEST_BUG_H
#define _KUNIT_TEST_BUG_H
-#if IS_BUILTIN(CONFIG_KUNIT)
+#if IS_ENABLED(CONFIG_KUNIT)
#include <linux/jump_label.h> /* For static branch */
#include <linux/sched.h>
@@ -43,20 +43,21 @@ static inline struct kunit *kunit_get_current_test(void)
* kunit_fail_current_test() - If a KUnit test is running, fail it.
*
* If a KUnit test is running in the current task, mark that test as failed.
- *
- * This macro will only work if KUnit is built-in (though the tests
- * themselves can be modules). Otherwise, it compiles down to nothing.
*/
#define kunit_fail_current_test(fmt, ...) do { \
if (static_branch_unlikely(&kunit_running)) { \
+ /* Guaranteed to be non-NULL when kunit_running true*/ \
__kunit_fail_current_test(__FILE__, __LINE__, \
fmt, ##__VA_ARGS__); \
} \
} while (0)
-extern __printf(3, 4) void __kunit_fail_current_test(const char *file, int line,
- const char *fmt, ...);
+/* Function pointer defined as a hook in hooks.c, and implemented in test.c */
+typedef __printf(3, 4) void kunit_hook_fn_fail_current_test(const char *file,
+ int line,
+ const char *fmt, ...);
+extern kunit_hook_fn_fail_current_test *__kunit_fail_current_test;
#else
diff --git a/lib/Makefile b/lib/Makefile
index 4d9461bfea42..9031de6ca73c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -126,6 +126,10 @@ CFLAGS_test_fpu.o += $(FPU_CFLAGS)
obj-$(CONFIG_TEST_LIVEPATCH) += livepatch/
obj-$(CONFIG_KUNIT) += kunit/
+# Include the KUnit hooks unconditionally. They'll compile to nothing if
+# CONFIG_KUNIT=n, otherwise will be a small table of static data (static key,
+# function pointers) which need to be built-in even when KUnit is a module.
+obj-y += kunit/hooks.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 29aff6562b42..deeb46cc879b 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -11,6 +11,9 @@ ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
kunit-objs += debugfs.o
endif
+# KUnit 'hooks' are built-in even when KUnit is built as a module.
+lib-y += hooks.o
+
obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
# string-stream-test compiles built-in only.
diff --git a/lib/kunit/hooks.c b/lib/kunit/hooks.c
new file mode 100644
index 000000000000..48189567a774
--- /dev/null
+++ b/lib/kunit/hooks.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit 'Hooks' implementation.
+ *
+ * This file contains code / structures which should be built-in even when
+ * KUnit itself is built as a module.
+ *
+ * Copyright (C) 2022, Google LLC.
+ * Author: David Gow <davidgow(a)google.com>
+ */
+
+/* This file is always built-in, so make sure it's empty if CONFIG_KUNIT=n */
+#if IS_ENABLED(CONFIG_KUNIT)
+
+#include <kunit/test-bug.h>
+
+DEFINE_STATIC_KEY_FALSE(kunit_running);
+EXPORT_SYMBOL(kunit_running);
+
+/* Function pointers for hooks. */
+kunit_hook_fn_fail_current_test *__kunit_fail_current_test;
+EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
+#endif
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index c9ebf975e56b..711fdcce6de8 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -20,13 +20,10 @@
#include "string-stream.h"
#include "try-catch-impl.h"
-DEFINE_STATIC_KEY_FALSE(kunit_running);
-
-#if IS_BUILTIN(CONFIG_KUNIT)
/*
* Fail the current test and print an error message to the log.
*/
-void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
+void __kunit_fail_current_test_impl(const char *file, int line, const char *fmt, ...)
{
va_list args;
int len;
@@ -53,8 +50,6 @@ void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
kunit_kfree(current->kunit_test, buffer);
}
-EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
-#endif
/*
* Enable KUnit tests to run.
@@ -777,6 +772,9 @@ EXPORT_SYMBOL_GPL(kunit_cleanup);
static int __init kunit_init(void)
{
+ /* Install the KUnit hook functions. */
+ __kunit_fail_current_test = __kunit_fail_current_test_impl;
+
kunit_debugfs_init();
#ifdef CONFIG_MODULES
return register_module_notifier(&kunit_mod_nb);
--
2.39.0.314.g84b9a713c41-goog
Hi,
So this is the fix for the bug that actually prevented me to integrate
HID-BPF in v6.2.
While testing the code base with LLVM, I realized that clang was smarter
than I expected it to be, and it sometimes inlined a function or not
depending on the branch. This lead to segfaults because my current code
in linux-next is messing up the bpf programs refcounts assuming that I
had enough observability over the kernel.
So I came back to the drawing board and realized that what I was missing
was exactly a bpf_link, to represent the attachment of a bpf program to
a HID device. This is the bulk of the series, in patch 6/9.
The other patches are cleanups, tests, and also the addition of the
vmtests.sh script I run locally, largely inspired by the one in the bpf
selftests dir. This allows very fast development of HID-BPF, assuming we
have tests that cover the bugs :)
changes in v2:
- took Alexei's remarks into account and renamed the indexes into
prog_table_index and hid_table_index
- fixed unused function as reported by the Intel kbuild bot
Cheers,
Benjamin
Benjamin Tissoires (9):
selftests: hid: add vmtest.sh
selftests: hid: allow to compile hid_bpf with LLVM
selftests: hid: attach/detach 2 bpf programs, not just one
selftests: hid: ensure the program is correctly pinned
selftests: hid: prepare tests for HID_BPF API change
HID: bpf: rework how programs are attached and stored in the kernel
selftests: hid: enforce new attach API
HID: bpf: clean up entrypoint
HID: bpf: reorder BPF registration
Documentation/hid/hid-bpf.rst | 12 +-
drivers/hid/bpf/entrypoints/entrypoints.bpf.c | 9 -
.../hid/bpf/entrypoints/entrypoints.lskel.h | 188 ++++--------
drivers/hid/bpf/hid_bpf_dispatch.c | 28 +-
drivers/hid/bpf/hid_bpf_dispatch.h | 3 -
drivers/hid/bpf/hid_bpf_jmp_table.c | 129 ++++----
include/linux/hid_bpf.h | 7 +
tools/testing/selftests/hid/.gitignore | 1 +
tools/testing/selftests/hid/Makefile | 10 +-
tools/testing/selftests/hid/config.common | 241 +++++++++++++++
tools/testing/selftests/hid/config.x86_64 | 4 +
tools/testing/selftests/hid/hid_bpf.c | 32 +-
tools/testing/selftests/hid/progs/hid.c | 13 +
tools/testing/selftests/hid/vmtest.sh | 284 ++++++++++++++++++
14 files changed, 728 insertions(+), 233 deletions(-)
create mode 100644 tools/testing/selftests/hid/config.common
create mode 100644 tools/testing/selftests/hid/config.x86_64
create mode 100755 tools/testing/selftests/hid/vmtest.sh
--
2.38.1