This RFC patch is part of effort to control code motion across
control flow boundaries in BPF. First, some use cases on why
we want to prevent speculative code motion. The patch is on
top of another patch https://reviews.llvm.org/D82112
("[RFC][BPF] Implement getUserCost() for BPFTargetTransformInfo").
Use case 1: bpf map value or some other data with a range.
data = bpf_map_lookup_elem(&map, &key); if (!data) return 0; payload = data->payload; len = bpf_probe_read_kernel_str(payload, 16, &task->comm); if (len <= 16) payload += len; ...
The compiler may generate code like:
data = bpf_map_lookup_elem(&map, &key); if (!data) return 0; payload = data->payload; len = bpf_probe_read_kernel_str(payload, 16, &task->comm); new_payload = payload + len; if (len > 16) new_payload = payload ...
The "payload + len" may cause kernel verifier failure as
the "len" can be anything at this moment.
Use case 2: CO-RE relocatons
field_exist = ... if (field_exist) { offset = non-memory-access-builtin-expr1; } else { offset = non-memory-access-builtin-expr2; } use "offset" to read kernel memory
The compiler may generate code like:
field_exist = ... offset = non-memory-access-builtin-expr1; if (!field_exist) offset = non-memory-access-builtin-expr2; use "offset" to read kernel memory
This may cause failures since if field_exist is false and
libbpf is not able to perform relation
for "offset = non-memory-access-builtin-expr1".
The instruction itself will be rewritten as
an illegal instruction and this will cause
program load failures.
To address the above issues, people use
. inline assembly . artificial complex control flow
to prevent the above optimizations.
Another BPF patch will have target specific
implementation of TTI.getUserCost() to control
the cost of code motion across control flows.
This patch mostly focused on SimplifyCFG commandline
option SpeculateOneExpensiveInst, which has default
true. We could like to disable it if a particular
BPF backend attribute is set. This patch implemented
a mechanism for backend can disallow SpeculateOneExpensiveInst.
Specifically, BPF target will disallow SpeculateOneExpensiveInst
if BPF attribute "adjustopt" is set.