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

From: Leo Yan
Date: Sun Jun 09 2019 - 09:23:58 EST


On Fri, Jun 07, 2019 at 05:58:31PM +0800, Leo Yan wrote:
> Hi Arnaldo,
>
> On Thu, Jun 06, 2019 at 11:44:12AM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Thu, Jun 06, 2019 at 10:12:31PM +0800, Leo Yan escreveu:
> > > Hi Arnaldo,
> > >
> > > On Thu, Jun 06, 2019 at 10:38:38AM -0300, Arnaldo Carvalho de Melo wrote:
> > > > 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.
> > >
> > > Actually I have noticed mksyscalltbl has been enabled for arm64, and
> > > had to say your approach is much better :)
> > >
> > > Thanks for the info and I will try your patch at my side.
> >
> > That is excellent news! I'm eager to hear from you if this perf+BPF
> > integration experiment works for arm64.
>
> I tested with the lastest perf/core branch which contains the patch:
> 'perf augmented_raw_syscalls: Tell which args are filenames and how
> many bytes to copy' and got the error as below:
>
> # perf trace -e string -e /mnt/linux-kernel/linux-cs-dev/tools/perf/examples/bpf/augmented_raw_syscalls.c
> Error: Invalid syscall access, chmod, chown, creat, futimesat, lchown, link, lstat, mkdir, mknod, newfstatat, open, readlink, rename,
> rmdir, stat, statfs, symlink, truncate, unlink
> Hint: try 'perf list syscalls:sys_enter_*'
> Hint: and: 'man syscalls'
>
> So seems mksyscalltbl has not included completely for syscalls, I
> use below command to generate syscalltbl_arm64[] array and it don't
> include related entries for access, chmod, chown, etc ...
>
> You could refer the generated syscalltbl_arm64 in:
> http://paste.ubuntu.com/p/8Bj7Jkm2mP/

After digging into this issue on Arm64, below is summary info:

- arm64 uses the header include/uapi/linux/unistd.h to define system
call numbers, in this header some system calls are not defined (I
think the reason is these system calls are obsolete at the end) so the
corresponding strings are missed in the array syscalltbl_native,
for arm64 the array is defined in the file:
tools/perf/arch/arm64/include/generated/asm/syscalls.c.

On the other hand, the file tools/perf/trace/strace/groups/string
stores the required system call strings, these system call strings
are based on x86_64 platform but not for arm64, the strings mismatch
with the system call defined in the array syscalltbl_native. This
is the reason why reports the fail: "Error: Invalid syscall access,
chmod, chown, creat, futimesat, lchown, link, lstat, mkdir, mknod,
newfstatat, open, readlink, rename, rmdir, stat, statfs, symlink,
truncate, unlink".

I tried to manually remove these reported strings from
tools/perf/trace/strace/groups/string, then 'perf trace' can work
well.

But I don't know what's a good way to proceed. Seems to me, we can
create a dedicated string file
tools/perf/trace/strace/groups/uapi_string which can be used to
match with system calls definitions in include/uapi/linux/unistd.h.
If there have other more general methods, will be great.

- As a side topic, arm64 also supports aarch32 compat system call
which are defined in header arch/arm64/include/asm/unistd32.h.

For either aarch64 or aarch32 system call, both of them finally will
invoke function el0_svc_common() to handle system call [1]. But so
far we don't distinguish the system call numbers is for aarch64 or
aarch32 and always consider it's aarch64 system call.

I think we can set an extra bit (e.g. use the 16th bit in 32 bits
signed int) to indicate it's a aarch32 compat system call, but not
sure if this is general method or not.

Maybe there have existed solution in other architectures for this,
especially other platforms also should support 32 bits and 64 bits
system calls along with the architecture evoluation, so want to
inquiry firstly to avoid duplicate works.

Thanks a lot for suggestions!
Leo.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/syscall.c#n93