Move sleepable verification code to btf_id_allow_sleepable
function. It will be used in following changes.

Signed-off-by: Jiri Olsa <[email protected]>
---
 include/linux/bpf_verifier.h |  3 ++
 kernel/bpf/verifier.c        | 79 +++++++++++++++++++-----------------
 2 files changed, 45 insertions(+), 37 deletions(-)

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 090aa26d1c98..186726fcf52a 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -932,6 +932,9 @@ static inline void bpf_trampoline_unpack_key(u64 key, u32 
*obj_id, u32 *btf_id)
                *btf_id = key & 0x7FFFFFFF;
 }
 
+int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct 
bpf_prog *prog,
+                          const struct btf *btf);
+
 int bpf_check_attach_target(struct bpf_verifier_log *log,
                            const struct bpf_prog *prog,
                            const struct bpf_prog *tgt_prog,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 832a87da5a86..ff29e27a85d0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -24959,6 +24959,47 @@ static bool is_tracing_multi_id(const struct bpf_prog 
*prog, u32 btf_id)
        return is_tracing_multi(prog->expected_attach_type) && 
bpf_multi_func_btf_id[0] == btf_id;
 }
 
+int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct 
bpf_prog *prog,
+                          const struct btf *btf)
+{
+       switch (prog->type) {
+       case BPF_PROG_TYPE_TRACING:
+
+               /* *.multi sleepable programs will pass initial sleepable check,
+                * the actual attached btf ids are checked later during the link
+                * attachment.
+                */
+               if (is_tracing_multi_id(prog, btf_id))
+                       return 0;
+               /* fentry/fexit/fmod_ret progs can be sleepable if they are
+                * attached to ALLOW_ERROR_INJECTION and are not in denylist.
+                */
+               else if (!check_non_sleepable_error_inject(btf_id) &&
+                   within_error_injection_list(addr))
+                       return 0;
+               /* fentry/fexit/fmod_ret progs can also be sleepable if they are
+                * in the fmodret id set with the KF_SLEEPABLE flag.
+                */
+               else {
+                       u32 *flags = btf_kfunc_is_modify_return(btf, btf_id, 
prog);
+
+                       if (flags && (*flags & KF_SLEEPABLE))
+                               return 0;
+               }
+               break;
+       case BPF_PROG_TYPE_LSM:
+               /* LSM progs check that they are attached to bpf_lsm_*() funcs.
+                * Only some of them are sleepable.
+                */
+               if (bpf_lsm_is_sleepable_hook(btf_id))
+                       return 0;
+               break;
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
 int bpf_check_attach_target(struct bpf_verifier_log *log,
                            const struct bpf_prog *prog,
                            const struct bpf_prog *tgt_prog,
@@ -25247,43 +25288,7 @@ int bpf_check_attach_target(struct bpf_verifier_log 
*log,
                }
 
                if (prog->sleepable) {
-                       ret = -EINVAL;
-                       switch (prog->type) {
-                       case BPF_PROG_TYPE_TRACING:
-
-                               /* *.multi sleepable programs will pass initial 
sleepable check,
-                                * the actual attached btf ids are checked 
later during the link
-                                * attachment.
-                                */
-                               if (is_tracing_multi_id(prog, btf_id))
-                                       ret = 0;
-                               /* fentry/fexit/fmod_ret progs can be sleepable 
if they are
-                                * attached to ALLOW_ERROR_INJECTION and are 
not in denylist.
-                                */
-                               else if 
(!check_non_sleepable_error_inject(btf_id) &&
-                                   within_error_injection_list(addr))
-                                       ret = 0;
-                               /* fentry/fexit/fmod_ret progs can also be 
sleepable if they are
-                                * in the fmodret id set with the KF_SLEEPABLE 
flag.
-                                */
-                               else {
-                                       u32 *flags = 
btf_kfunc_is_modify_return(btf, btf_id,
-                                                                               
prog);
-
-                                       if (flags && (*flags & KF_SLEEPABLE))
-                                               ret = 0;
-                               }
-                               break;
-                       case BPF_PROG_TYPE_LSM:
-                               /* LSM progs check that they are attached to 
bpf_lsm_*() funcs.
-                                * Only some of them are sleepable.
-                                */
-                               if (bpf_lsm_is_sleepable_hook(btf_id))
-                                       ret = 0;
-                               break;
-                       default:
-                               break;
-                       }
+                       ret = btf_id_allow_sleepable(btf_id, addr, prog, btf);
                        if (ret) {
                                module_put(mod);
                                bpf_log(log, "%s is not sleepable\n", tname);
-- 
2.53.0


Reply via email to