Subject: Re: [PATCH v2 3/4] perf augmented_raw_syscalls: Support arm64 raw syscalls

From: Arnaldo Carvalho de Melo <[email-masked]>
Date: Thu, 6 Jun 2019 11:05:28 -0300

Em Thu, Jun 06, 2019 at 10:46:24AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Jun 06, 2019 at 10:38:38AM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Thu, Jun 06, 2019 at 05:48:44PM +0800, Leo Yan escreveu:
> > > This patch adds support for arm64 raw syscall numbers so that we can use
> > > it on arm64 platform.

> > > After applied this patch, we need to specify macro -D__aarch64__ or
> > > -D__x86_64__ in compilation option so Clang can use the corresponding
> > > syscall numbers for arm64 or x86_64 respectively, other architectures
> > > will report failure when compilation.

> > So, please check what I have in my perf/core branch, I've completely
> > removed arch specific stuff from augmented_raw_syscalls.c.

> > What is done now is use a map to specify what to copy, that same map
> > that is used to state which syscalls should be traced.

> > It uses that tools/perf/arch/arm64/entry/syscalls/mksyscalltbl to figure
> > out the mapping of syscall names to ids, just like is done for x86_64
> > and other arches, falling back to audit-libs when that syscalltbl thing
> > is not present.
 
> Also added:
 
> Fixes: ac96287cae08 ("perf trace: Allow specifying a set of events to add in perfconfig")
 
> For the [email-masked] folks to automagically pick this.

And this extra patch is needed, with yours and this one we finally get
what we want, which points to the kernel verifier blocking something,
exactly what is it that is blocking
(/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o)
and who asked for it, (trace.add_events=...) in a config key-value pair:

[root@quaco ~]# perf trace ls
event syntax error: '/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o'
                     \___ Kernel verifier blocks program loading

(add -v to see detail)
Run 'perf list' for a list of valid events
Error: wrong config key-value pair trace.add_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o
[root@quaco ~]#

commit 6455f983af2657b950d5dd5c45783e31e41ead4a
Author: Arnaldo Carvalho de Melo <[email-masked]>
Date:   Thu Jun 6 10:56:55 2019 -0300

    perf config: Bail out when a handler returns failure for a key-value pair
    
    So perf_config() uses:
    
      int ret = 0;
    
      perf_config_set__for_each_entry(config_set, section, item) {
              ...
              ret = fn();
              if (ret < 0)
                      break;
      }
    
      return ret;
    
    Expecting that that break will imediatelly go to function exit to return
    that error value (ret).
    
    The problem is that perf_config_set__for_each_entry() expands into two
    nested for() loops, one traversing the sections in a config and the
    second the items in each of those sections, so we have to change that
    'break' to a goto label right before that final 'return ret'.
    
    With that, for instance 'perf trace' now correctly bails out when a
    event that is requested to be added via its 'trace.add_events'
    ~/.perfconfig entry gets rejected by the kernel BPF verifier:
    
      # perf trace ls
      event syntax error: '/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o'
                           \___ Kernel verifier blocks program loading
    
      (add -v to see detail)
      Run 'perf list' for a list of valid events
      Error: wrong config key-value pair trace.add_events=/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o
      #
    
    While before it would continue and explode later, when trying to find
    maps that would have been in place had that augmented_raw_syscalls.o
    precompiled BPF proggie been accepted by the, humm, bast... rigorous
    kernel BPF verifier 8-)
    
    Cc: Adrian Hunter <[email-masked]>
    Cc: Alexander Shishkin <[email-masked]>
    Cc: Alexei Starovoitov <[email-masked]>
    Cc: Daniel Borkmann <[email-masked]>
    Cc: Jiri Olsa <[email-masked]>
    Cc: Martin KaFai Lau <[email-masked]>
    Cc: Mathieu Poirier <[email-masked]>
    Cc: Mike Leach <[email-masked]>
    Cc: Namhyung Kim <[email-masked]>
    Cc: Song Liu <[email-masked]>
    Cc: Suzuki Poulouse <[email-masked]>
    Cc: Taeung Song <[email-masked]>
    Cc: Yonghong Song <[email-masked]>
    Fixes: 8a0a9c7e9146 ("perf config: Introduce new init() and exit()")
    Link: https://lkml.kernel.org/n/[email-masked]
    Signed-off-by: Arnaldo Carvalho de Melo <[email-masked]>

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 7e3c1b60120c..e7d2c08d263a 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -739,11 +739,15 @@ int perf_config(config_fn_t fn, void *data)
 			if (ret < 0) {
 				pr_err("Error: wrong config key-value pair %s=%s\n",
 				       key, value);
-				break;
+				/*
+				 * Can't be just a 'break', as perf_config_set__for_each_entry()
+				 * expands to two nested for() loops.
+				 */
+				goto out;
 			}
 		}
 	}
-
+out:
 	return ret;
 }