Use the barrier trick to avoid clang from optimizing the 'size' variable
that can cause the verifier to think that 'size' can be negative:

./upcall_monitor.py
119: (85) call bpf_probe_read_kernel#113
R2 min value is negative, either use unsigned or 'var &= const'
processed 131 insns (limit 1000000) max_states_per_insn 0 total_states
peak_states 9 mark_read 3
Traceback (most recent call last):
File "/ovs/utilities/usdt-scripts/./upcall_monitor.py", line 729, in
odule>
main()
File "/ovs/utilities/usdt-scripts/./upcall_monitor.py", line 697, in
in
b = BPF(text=source, usdt_contexts=usdt, debug=options.debug)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 373, in
init__
self._trace_autoload()
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 1241, in
race_autoload
fn = self.load_func(func_name, BPF.KPROBE)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 412, in
ad_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'kretprobe__ovs_dp_upcall':
permission denied.

Signed-off-by: Adrian Moreno <[email protected]>
---
 utilities/usdt-scripts/upcall_monitor.py | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/utilities/usdt-scripts/upcall_monitor.py 
b/utilities/usdt-scripts/upcall_monitor.py
index 5b78e833f..390abdfe0 100755
--- a/utilities/usdt-scripts/upcall_monitor.py
+++ b/utilities/usdt-scripts/upcall_monitor.py
@@ -151,6 +151,8 @@ ebpf_source = """
 #define MAX_PACKET <MAX_PACKET_VAL>
 #define MAX_KEY    <MAX_KEY_VAL>
 
+#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
+
 struct event_t {
     int result;
     u32 cpu;
@@ -213,6 +215,11 @@ int do_trace(struct pt_regs *ctx) {
         size = MAX_KEY;
     else
         size = event->key_size;
+
+    /* Prevent clang from using register mirroring (or any optimization) on
+     * the 'size' variable. */
+    barrier_var(size);
+
     bpf_usdt_readarg(5, ctx, &addr);
     bpf_probe_read(&event->key, size, (void *)addr);
 
@@ -287,6 +294,10 @@ int kretprobe__ovs_dp_upcall(struct pt_regs *ctx)
     if (size > MAX_PACKET)
         size = MAX_PACKET;
 
+    /* Prevent clang from using register mirroring (or any optimization) on
+     * the 'size' variable. */
+    barrier_var(size);
+
     bpf_probe_read_kernel(event->pkt, size, upcall->skb->data);
     events.ringbuf_submit(event, 0);
     return 0;
-- 
2.49.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to