Blob Blame History Raw
From 0d45550a184cc5a9f10187a97b9ef8dc7fa13f31 Mon Sep 17 00:00:00 2001
From: Serhei Makarov <smakarov@redhat.com>
Date: Fri, 2 Nov 2018 16:49:23 -0400
Subject: [PATCH 19/32] PR23829 :: fallback defines __BPF_FUNC_MAPPER and
 BPF_J{LT,LE,SLT,SLE} for older kernels

---
 bpf-base.cxx   | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bpf-internal.h | 11 +++++++++++
 2 files changed, 70 insertions(+)

diff --git a/bpf-base.cxx b/bpf-base.cxx
index 277927b72..210efa9aa 100644
--- a/bpf-base.cxx
+++ b/bpf-base.cxx
@@ -140,6 +140,65 @@ is_commutative(opcode code)
 std::map<unsigned, const char *> bpf_func_name_map;
 std::map<std::string, bpf_func_id> bpf_func_id_map;
 
+/* PR23829: On older kernels, bpf.h does not define __BPF_FUNC_MAPPER.
+   As a fallback, use the *earliest* __BPF_FUNC_MAPPER, so stapbpf
+   will not try helpers that only exist on subsequent kernels.
+
+   TODO: This isn't perfect since even older kernels don't have
+   some of these helpers.
+
+   XXX: Note the build limitation in that SystemTap must be compiled
+   against a recent kernel to be able to use the helpers from that
+   kernel. That's also the case when building against recent bpf.h
+   with __BPF_FUNC_MAPPER, so this workaround is not the source of the
+   problem. */
+#ifndef __BPF_FUNC_MAPPER
+#define __BPF_FUNC_MAPPER(FN)		\
+	FN(unspec),			\
+	FN(map_lookup_elem),		\
+	FN(map_update_elem),		\
+	FN(map_delete_elem),		\
+	FN(probe_read),			\
+	FN(ktime_get_ns),		\
+	FN(trace_printk),		\
+	FN(get_prandom_u32),		\
+	FN(get_smp_processor_id),	\
+	FN(skb_store_bytes),		\
+	FN(l3_csum_replace),		\
+	FN(l4_csum_replace),		\
+	FN(tail_call),			\
+	FN(clone_redirect),		\
+	FN(get_current_pid_tgid),	\
+	FN(get_current_uid_gid),	\
+	FN(get_current_comm),		\
+	FN(get_cgroup_classid),		\
+	FN(skb_vlan_push),		\
+	FN(skb_vlan_pop),		\
+	FN(skb_get_tunnel_key),		\
+	FN(skb_set_tunnel_key),		\
+	FN(perf_event_read),		\
+	FN(redirect),			\
+	FN(get_route_realm),		\
+	FN(perf_event_output),		\
+	FN(skb_load_bytes),		\
+	FN(get_stackid),		\
+	FN(csum_diff),			\
+	FN(skb_get_tunnel_opt),		\
+	FN(skb_set_tunnel_opt),		\
+	FN(skb_change_proto),		\
+	FN(skb_change_type),		\
+	FN(skb_under_cgroup),		\
+	FN(get_hash_recalc),		\
+	FN(get_current_task),		\
+	FN(probe_write_user),		\
+	FN(current_task_under_cgroup),	\
+	FN(skb_change_tail),		\
+	FN(skb_pull_data),		\
+	FN(csum_update),		\
+	FN(set_hash_invalid),           \
+
+#endif
+
 void
 init_bpf_helper_tables () // TODO call before script translation
 {
diff --git a/bpf-internal.h b/bpf-internal.h
index 3041bbdf5..82cba2c79 100644
--- a/bpf-internal.h
+++ b/bpf-internal.h
@@ -21,6 +21,17 @@ extern "C" {
 #include <linux/bpf.h>
 }
 
+/* PR23829: These eBPF opcodes were added in recent kernels, and the
+   following 'ad hoc' defines are only used by the embedded-code
+   assembler.  The code generator will convert these opcodes to
+   equivalent operations valid for earlier eBPF. */
+#ifndef BPF_JLT
+#define BPF_JLT		0xa0	/* LT is unsigned, '<' */
+#define BPF_JLE		0xb0	/* LE is unsigned, '<=' */
+#define BPF_JSLT	0xc0	/* SLT is signed, '<' */
+#define BPF_JSLE	0xd0	/* SLE is signed, '<=' */
+#endif
+
 struct systemtap_session;
 struct derived_probe;
 struct vardecl;
-- 
2.14.5