On Thu, Apr 25, 2019 at 09:44:18AM +0200, Pavel Hrdina wrote:
In order to implement devices controller with cgroup v2 we need to
add support for BPF programs, cgroup v2 doesn't have devices controller.
This introduces required helpers wrapping linux syscalls.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
configure.ac | 5 +
include/libvirt/virterror.h | 2 +
src/libvirt_private.syms | 16 ++
src/util/Makefile.inc.am | 2 +
src/util/virbpf.c | 438 ++++++++++++++++++++++++++++++++++++
src/util/virbpf.h | 259 +++++++++++++++++++++
src/util/virerror.c | 2 +
7 files changed, 724 insertions(+)
create mode 100644 src/util/virbpf.c
create mode 100644 src/util/virbpf.h
diff --git a/src/util/virbpf.h b/src/util/virbpf.h
new file mode 100644
index 0000000000..b5874e1e8d
--- /dev/null
+++ b/src/util/virbpf.h
@@ -0,0 +1,259 @@
+/*
+ * virbpf.h: methods for eBPF
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBVIRT_VIRBPF_H
+# define LIBVIRT_VIRBPF_H
#pragma once is the new avocado toast.
+
+# if HAVE_DECL_BPF_PROG_QUERY
+
+# include <linux/bpf.h>
+
+/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
+
+# define VIR_BPF_ALU64_REG(op, dst, src) \
+ ((struct bpf_insn) { \
+ .code = BPF_ALU64 | BPF_OP(op) | BPF_X, \
+ .dst_reg = dst, \
+ .src_reg = src, \
+ .off = 0, \
+ .imm = 0, \
+ })
+
+/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
+
+# define VIR_BPF_ALU64_IMM(op, dst, immval) \
+ ((struct bpf_insn) { \
+ .code = BPF_ALU64 | BPF_OP(op) | BPF_K, \
+ .dst_reg = dst, \
+ .src_reg = 0, \
+ .off = 0, \
+ .imm = immval, \
+ })
+
+/* mov of registers, dst_reg = src_reg */
+
+# define VIR_BPF_MOV64_REG(dst, src) \
+ ((struct bpf_insn) { \
+ .code = BPF_ALU64 | BPF_MOV | BPF_X, \
+ .dst_reg = dst, \
+ .src_reg = src, \
+ .off = 0, \
+ .imm = 0, \
+ })
+
+/* mov of immediates, dst_reg = imm32 */
+
+# define VIR_BPF_MOV64_IMM(dst, immval) \
+ ((struct bpf_insn) { \
+ .code = BPF_ALU64 | BPF_MOV | BPF_K, \
+ .dst_reg = dst, \
+ .src_reg = 0, \
+ .off = 0, \
+ .imm = immval, \
+ })
+
+/* helper to encode 16 byte instruction */
+
+# define _VIR_BPF_LD_IMM64_RAW(dst, src, immval) \
+ ((struct bpf_insn) { \
+ .code = BPF_LD | BPF_DW | BPF_IMM, \
+ .dst_reg = dst, \
+ .src_reg = src, \
+ .off = 0, \
+ .imm = (uint32_t)immval, \
+ }), \
+ ((struct bpf_insn) { \
+ .code = 0, \
+ .dst_reg = 0, \
+ .src_reg = 0, \
+ .off = 0, \
+ .imm = ((uint64_t)immval) >> 32, \
+ })
+
Trust, yada, yada..
Reviewed-by: Ján Tomko <jtomko(a)redhat.com>
Jano