Search code examples
x86-64tracebpfebpfbcc-bpf

How do I access xmm registers in an eBPF program


I am trying to use bcc-tools to trace a user process using uprobe, but some functions take floating point arguments. According to x86_64 ABI, these values are normally passed in the xmm registers.

The eBPF functions in bcc takes a struct pt_regs * argument and in that I can get access to (a copy of ?) most "usual" registers, but not the xmm registers.

Is there a way to accomplish this ? Or is this something that was overlooked in the design of eBPF


Solution

  • TL;DR This is not an issue with BPF, neither uprobes nor kprobes can access AVX registers such as xmm registers.


    uprobe programs are actually loaded in the kernel as kprobe programs (i.e., BPF_PROG_TYPE_KPROBE).

    Contrary to most BPF programs, kprobe programs have access to an unmodified, unrestricted context argument at the hook point. What I mean is that the argument of BPF programs is often a mirror of the actual object given at the hook point, with accesses rewritten by the verifier. For example, several BPF programs take struct __sk_buff as argument, which is actually a mirror of sk_buff (see this other StackOverflow answer for more details). kprobe program, on the contrary, have access to the raw struct pt_regs object (the convert_ctx_access field of struct bpf_verifier_ops is null).

    From this we can conclude that kprobes (which receive struct pt_regs) don't have access to the AVX registers. So it's a limitation of kprobes and not of BPF. One reason for this might simply be the low support for AVX registers in the kernel. Please see this StackOverflow answer for further information.