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
On Wed, Jan 18, 2023 at 02:41:00PM -0500, Gregory Price wrote:
> ---------- Forwarded message ---------
> From: Peter Zijlstra <peterz(a)infradead.org>
> Date: Wed, Jan 18, 2023 at 12:16 PM
> Subject: Re: [PATCH 1/3] ptrace,syscall_user_dispatch: Implement Syscall
> User Dispatch Suspension
> To: Gregory Price <gourry.memverge(a)gmail.com>
>
>
> On Mon, Jan 09, 2023 at 10:33:46AM -0500, Gregory Price wrote:
> > @@ -36,6 +37,10 @@ bool syscall_user_dispatch(struct pt_regs *regs)
> > struct syscall_user_dispatch *sd = ¤t->syscall_dispatch;
> > char state;
> >
> > + if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) &&
> > + unlikely(current->ptrace &
> PT_SUSPEND_SYSCALL_USER_DISPATCH))
> > + return false;
> > +
> > if (likely(instruction_pointer(regs) - sd->offset < sd->len))
> > return false;
> >
>
> So by making syscall_user_dispatch() return false, we'll make
> syscall_trace_enter() continue to handle things, and supposedly you want
> to land in ptrace_report_syscall_entry(), right?
>
> ... snip ...
>
> Should setting this then not also depend on having
> SYSCALL_WORK_SYSCALL_TRACE set? Because without that, you get 'funny'
> things.
Hm, this is an interesting question. My thoughts are that I want the
process to handle the syscall as-if syscall user dispatch was not
present at all, regardless of SYSCALL_TRACE.
This is because some software, like CRIU, actually injects syscalls to
run in the context of the software in an effort to collect resources.
So I actually *want* those 'funny' things to occur, because they're most
likely intentional. I don't necessarily want to intercept system calls
that subsequently occur (although i might).
So if this feature required SYSCALL_TRACE, you would no longer be able
to inject system calls ala CRIU.
That's also my understanding of the SECCOMP_SUSPEND feature as well,
it's intended specifically to allow *otherwise disallowed* syscalls to
be injected into the process and SECCOMP bypassed. (in this case,
SECCOMP_SUSPEND requires root for exactly this reason).
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.
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
prctl,syscall_user_dispatch: add a getter for configuration info
.../admin-guide/syscall-user-dispatch.rst | 18 +++++++
fs/proc/array.c | 8 +++
include/linux/ptrace.h | 2 +
include/linux/syscall_user_dispatch.h | 7 +++
include/uapi/linux/prctl.h | 3 ++
include/uapi/linux/ptrace.h | 6 ++-
kernel/entry/syscall_user_dispatch.c | 19 +++++++
kernel/ptrace.c | 5 ++
kernel/sys.c | 4 ++
.../syscall_user_dispatch/sud_test.c | 54 +++++++++++++++++++
10 files changed, 125 insertions(+), 1 deletion(-)
--
2.37.3
The KVM rseq test is failing to build in -next due to a commit merged
from the tip tree which adds a wrapper for sys_getcpu() to the rseq
kselftests, conflicting with the wrapper already included in the KVM
selftest:
rseq_test.c:48:13: error: conflicting types for 'sys_getcpu'
48 | static void sys_getcpu(unsigned *cpu)
| ^~~~~~~~~~
In file included from rseq_test.c:23:
../rseq/rseq.c:82:12: note: previous definition of 'sys_getcpu' was here
82 | static int sys_getcpu(unsigned *cpu, unsigned *node)
| ^~~~~~~~~~
Fix this by removing the local wrapper and moving the result check up to
the caller.
Fixes: 99babd04b250 ("selftests/rseq: Implement rseq numa node id field selftest")
Signed-off-by: Mark Brown <broonie(a)kernel.org>
---
This will need to go via the tip tree due to the breaking change being
there.
---
tools/testing/selftests/kvm/rseq_test.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/kvm/rseq_test.c b/tools/testing/selftests/kvm/rseq_test.c
index 3045fdf9bdf5..f74e76d03b7e 100644
--- a/tools/testing/selftests/kvm/rseq_test.c
+++ b/tools/testing/selftests/kvm/rseq_test.c
@@ -41,18 +41,6 @@ static void guest_code(void)
GUEST_SYNC(0);
}
-/*
- * We have to perform direct system call for getcpu() because it's
- * not available until glic 2.29.
- */
-static void sys_getcpu(unsigned *cpu)
-{
- int r;
-
- r = syscall(__NR_getcpu, cpu, NULL, NULL);
- TEST_ASSERT(!r, "getcpu failed, errno = %d (%s)", errno, strerror(errno));
-}
-
static int next_cpu(int cpu)
{
/*
@@ -249,7 +237,9 @@ int main(int argc, char *argv[])
* across the seq_cnt reads.
*/
smp_rmb();
- sys_getcpu(&cpu);
+ r = sys_getcpu(&cpu, NULL);
+ TEST_ASSERT(!r, "getcpu failed, errno = %d (%s)",
+ errno, strerror(errno));
rseq_cpu = rseq_current_cpu_raw();
smp_rmb();
} while (snapshot != atomic_read(&seq_cnt));
---
base-commit: 469a89fd3bb73bb2eea628da2b3e0f695f80b7ce
change-id: 20230106-fix-kvm-rseq-build-41ac58ba1d27
Best regards,
--
Mark Brown <broonie(a)kernel.org>
The common layout for kbuild messages is as follows:
- 2 spaces
- 7 or more characters for the action
- 1 space
- name of the file being built/generated
The custom message formatting included an additional space in the action
part, which leads to misalignments with the rest of kbuild.
To: Alexei Starovoitov <ast(a)kernel.org>
To: Daniel Borkmann <daniel(a)iogearbox.net>
To: Andrii Nakryiko <andrii(a)kernel.org>
To: Martin KaFai Lau <martin.lau(a)linux.dev>
To: Song Liu <song(a)kernel.org>
To: Yonghong Song <yhs(a)fb.com>
To: John Fastabend <john.fastabend(a)gmail.com>
To: KP Singh <kpsingh(a)kernel.org>
To: Stanislav Fomichev <sdf(a)google.com>
To: Hao Luo <haoluo(a)google.com>
To: Jiri Olsa <jolsa(a)kernel.org>
To: Mykola Lysenko <mykolal(a)fb.com>
To: Shuah Khan <shuah(a)kernel.org>
Cc: bpf(a)vger.kernel.org
Cc: linux-kselftest(a)vger.kernel.org
Cc: linux-kernel(a)vger.kernel.org
To: Masahiro Yamada <masahiroy(a)kernel.org>
Cc: linux-kbuild(a)vger.kernel.org
Signed-off-by: Thomas Weißschuh <linux(a)weissschuh.net>
---
Thomas Weißschuh (3):
selftests/bpf: align kbuild messages to standard
bpf: iterators: align kbuild messages to standard
tools/resolve_btfids: align kbuild messages to standard
kernel/bpf/preload/iterators/Makefile | 2 +-
tools/bpf/resolve_btfids/Makefile | 2 +-
tools/testing/selftests/bpf/Makefile | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
---
base-commit: c1649ec55708ae42091a2f1bca1ab49ecd722d55
change-id: 20230118-kbuild-alignment-ca1ce98ea566
Best regards,
--
Thomas Weißschuh <linux(a)weissschuh.net>