Re: [RFC PATCH bpf-next 5/5] selftests/bpf: get_reg_val test exercising fxsave fetch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 12, 2022 at 12:43 AM Dave Marchevsky <davemarchevsky@xxxxxx> wrote:
>
> Add a test which calls bpf_get_reg_val with an xmm reg after forcing fpu
> state save. The test program writes to %xmm10, then calls a BPF program
> which forces fpu save and calls bpf_get_reg_val. This guarantees that
> !fpregs_state_valid check will succeed, forcing bpf_get_reg_val to fetch
> %xmm10's value from task's fpu state.
>
> A bpf_testmod_save_fpregs kfunc helper is added to bpf_testmod to enable
> 'force fpu save'. Existing bpf_dummy_ops test infra is extended to
> support calling the kfunc.
>
> unload_bpf_testmod would often fail with -EAGAIN when running the test
> added in this patch, so a single retry w/ 20ms sleep is added.
>
> Signed-off-by: Dave Marchevsky <davemarchevsky@xxxxxx>
> ---
>  include/linux/bpf.h                           |  1 +
>  kernel/trace/bpf_trace.c                      |  2 +-
>  net/bpf/bpf_dummy_struct_ops.c                | 13 ++++++

split kernel changes from selftests?

>  .../selftests/bpf/bpf_testmod/bpf_testmod.c   | 13 ++++++
>  tools/testing/selftests/bpf/prog_tests/usdt.c | 42 +++++++++++++++++++
>  .../selftests/bpf/progs/test_urandom_usdt.c   | 24 +++++++++++
>  tools/testing/selftests/bpf/test_progs.c      |  7 ++++
>  7 files changed, 101 insertions(+), 1 deletion(-)
>

[...]

> diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> index e585e1cefc77..b2b35138b097 100644
> --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> @@ -1,5 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /* Copyright (c) 2020 Facebook */
> +#include <asm/fpu/api.h>
>  #include <linux/btf.h>
>  #include <linux/btf_ids.h>
>  #include <linux/error-injection.h>
> @@ -25,6 +26,13 @@ bpf_testmod_test_mod_kfunc(int i)
>         *(int *)this_cpu_ptr(&bpf_testmod_ksym_percpu) = i;
>  }
>
> +noinline void
> +bpf_testmod_save_fpregs(void)
> +{
> +       kernel_fpu_begin();
> +       kernel_fpu_end();

this seems to be x86-specific kernel functions, we need to think about
building selftests (including bpf_testmod) on other architectures


> +}
> +
>  struct bpf_testmod_btf_type_tag_1 {
>         int a;
>  };
> @@ -150,6 +158,7 @@ static struct bin_attribute bin_attr_bpf_testmod_file __ro_after_init = {
>
>  BTF_SET_START(bpf_testmod_check_kfunc_ids)
>  BTF_ID(func, bpf_testmod_test_mod_kfunc)
> +BTF_ID(func, bpf_testmod_save_fpregs)
>  BTF_SET_END(bpf_testmod_check_kfunc_ids)
>
>  static const struct btf_kfunc_id_set bpf_testmod_kfunc_set = {
> @@ -166,6 +175,10 @@ static int bpf_testmod_init(void)
>         ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_testmod_kfunc_set);
>         if (ret < 0)
>                 return ret;
> +       ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &bpf_testmod_kfunc_set);
> +       if (ret < 0)
> +               return ret;
> +
>         if (bpf_fentry_test1(0) < 0)
>                 return -EINVAL;
>         return sysfs_create_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file);
> diff --git a/tools/testing/selftests/bpf/prog_tests/usdt.c b/tools/testing/selftests/bpf/prog_tests/usdt.c
> index f98749ac74a7..3866cb004b22 100644
> --- a/tools/testing/selftests/bpf/prog_tests/usdt.c
> +++ b/tools/testing/selftests/bpf/prog_tests/usdt.c
> @@ -8,6 +8,11 @@
>  #include "test_usdt.skel.h"
>  #include "test_urandom_usdt.skel.h"
>
> +/* Need to keep consistent with definition in include/linux/bpf.h */
> +struct bpf_dummy_ops_state {
> +       int val;
> +};
> +
>  int lets_test_this(int);
>
>  static volatile int idx = 2;
> @@ -415,6 +420,41 @@ static void subtest_urandom_usdt(bool auto_attach)
>         test_urandom_usdt__destroy(skel);
>  }
>
> +static void subtest_reg_val_fpustate(void)
> +{
> +       struct bpf_dummy_ops_state in_state;
> +       struct test_urandom_usdt__bss *bss;
> +       struct test_urandom_usdt *skel;
> +       u64 in_args[1];
> +       u64 regval[2];
> +       int err, fd;
> +
> +       in_state.val = 0; /* unused */
> +       in_args[0] = (unsigned long)&in_state;
> +
> +       LIBBPF_OPTS(bpf_test_run_opts, attr,

nit: LIBBPF_OPTS declares variable, so it had to be in variable
declaration block

> +                  .ctx_in = in_args,
> +                  .ctx_size_in = sizeof(in_args),
> +       );
> +
> +       skel = test_urandom_usdt__open_and_load();
> +       if (!ASSERT_OK_PTR(skel, "skel_open"))
> +               return;
> +       bss = skel->bss;
> +
> +       fd = bpf_program__fd(skel->progs.save_fpregs_and_read);
> +       regval[0] = 42;
> +       regval[1] = 0;
> +       asm("movdqa %0, %%xmm10" : "=m"(*(char *)regval));
> +
> +       err = bpf_prog_test_run_opts(fd, &attr);
> +       ASSERT_OK(err, "save_fpregs_and_read");
> +       ASSERT_EQ(bss->fpregs_dummy_opts_xmm_val, 42, "fpregs_dummy_opts_xmm_val");
> +
> +       close(fd);
> +       test_urandom_usdt__destroy(skel);
> +}
> +

[...]



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux