[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20201006180839.lvoigzpmr32rrroj@ast-mbp>
Date: Tue, 6 Oct 2020 11:08:39 -0700
From: Alexei Starovoitov <alexei.starovoitov@...il.com>
To: Andrii Nakryiko <andriin@...com>
Cc: bpf@...r.kernel.org, netdev@...r.kernel.org, ast@...com,
daniel@...earbox.net, andrii.nakryiko@...il.com,
kernel-team@...com, Luka Perkov <luka.perkov@...tura.hr>,
Tony Ambardar <tony.ambardar@...il.com>
Subject: Re: [PATCH bpf-next 1/3] libbpf: support safe subset of load/store
instruction resizing with CO-RE
On Thu, Oct 01, 2020 at 06:06:31PM -0700, Andrii Nakryiko wrote:
> Add support for patching instructions of the following form:
> - rX = *(T *)(rY + <off>);
> - *(T *)(rX + <off>) = rY;
> - *(T *)(rX + <off>) = <imm>, where T is one of {u8, u16, u32, u64}.
llvm doesn't generate ST instruction. It never did.
STX is generated, but can it actually be used with relocations?
Looking at the test in patch 3... it's testing LDX only.
ST/STX suppose to work by analogy, but would be good to have a test.
At least of STX.
> +static int insn_mem_sz_to_bytes(struct bpf_insn *insn)
> +{
> + switch (BPF_SIZE(insn->code)) {
> + case BPF_DW: return 8;
> + case BPF_W: return 4;
> + case BPF_H: return 2;
> + case BPF_B: return 1;
> + default: return -1;
> + }
> +}
> +
> +static int insn_bytes_to_mem_sz(__u32 sz)
> +{
> + switch (sz) {
> + case 8: return BPF_DW;
> + case 4: return BPF_W;
> + case 2: return BPF_H;
> + case 1: return BPF_B;
> + default: return -1;
> + }
> +}
filter.h has these two helpers. They're named bytes_to_bpf_size() and bpf_size_to_bytes().
I guess we cannot really share kernel and libbpf implementation, but
could you please name them the same way so it's easier to follow
for folks who read both kernel and libbpf code?
> + if (res->new_sz != res->orig_sz) {
> + mem_sz = insn_mem_sz_to_bytes(insn);
> + if (mem_sz != res->orig_sz) {
> + pr_warn("prog '%s': relo #%d: insn #%d (LDX/ST/STX) unexpected mem size: got %u, exp %u\n",
> + prog->name, relo_idx, insn_idx, mem_sz, res->orig_sz);
> + return -EINVAL;
> + }
> +
> + mem_sz = insn_bytes_to_mem_sz(res->new_sz);
> + if (mem_sz < 0) {
Please use new variable here appropriately named.
Few lines above mem_sz is in bytes while here it's encoding opcode.
Powered by blists - more mailing lists