From fb32f0284f86d5a613095a2965e6f99fb45c01b3 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 13 Sep 2024 17:34:52 +0200 Subject: [PATCH] fix(libscap): use the correct memory barrier for ARM64 Signed-off-by: Andrea Terzolo --- .../libpman/src/ringbuffer_definitions.h | 21 +------ userspace/libscap/engine/bpf/scap_bpf.h | 9 +-- userspace/libscap/linux/barrier.h | 59 ++++++++++++++++++- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/userspace/libpman/src/ringbuffer_definitions.h b/userspace/libpman/src/ringbuffer_definitions.h index 8c134b7a79..1f224926bc 100644 --- a/userspace/libpman/src/ringbuffer_definitions.h +++ b/userspace/libpman/src/ringbuffer_definitions.h @@ -20,6 +20,7 @@ limitations under the License. #include "state.h" #include +#include /* Taken from libbpf: /src/ringbuf.c */ struct ring { @@ -50,23 +51,3 @@ static inline int roundup_len(uint32_t len) { /* round up to 8 byte alignment */ return (len + 7) / 8 * 8; } - -/* Taken from libbpf: `include/linux/compiler.h` */ - -#define READ_ONCE(x) (*(volatile typeof(x) *)&x) -#define WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v) - -#define barrier() asm volatile("" ::: "memory") - -#define smp_store_release(p, v) \ - do { \ - barrier(); \ - WRITE_ONCE(*p, v); \ - } while(0) - -#define smp_load_acquire(p) \ - ({ \ - typeof(*p) ___p = READ_ONCE(*p); \ - barrier(); \ - ___p; \ - }) diff --git a/userspace/libscap/engine/bpf/scap_bpf.h b/userspace/libscap/engine/bpf/scap_bpf.h index 6c454646fc..a61dd3d5c2 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.h +++ b/userspace/libscap/engine/bpf/scap_bpf.h @@ -20,6 +20,7 @@ limitations under the License. #include #include +#include struct perf_event_sample { struct perf_event_header header; @@ -49,9 +50,7 @@ static inline void scap_bpf_get_buf_pointers(scap_device *dev, *phead = header->data_head; *ptail = header->data_tail; - // clang-format off - asm volatile("" ::: "memory"); - // clang-format on + mem_barrier(); uint64_t cons = *ptail % header->data_size; // consumer position uint64_t prod = *phead % header->data_size; // producer position @@ -154,9 +153,7 @@ static inline void scap_bpf_advance_tail(struct scap_device *dev) { header = (struct perf_event_mmap_page *)dev->m_buffer; - // clang-format off - asm volatile("" ::: "memory"); - // clang-format on + mem_barrier(); ASSERT(dev->m_lastreadsize > 0); /* `header->data_tail` is the consumer position. */ diff --git a/userspace/libscap/linux/barrier.h b/userspace/libscap/linux/barrier.h index 5cfc22f600..4bfaa856d2 100644 --- a/userspace/libscap/linux/barrier.h +++ b/userspace/libscap/linux/barrier.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 /* -Copyright (C) 2023 The Falco Authors. +Copyright (C) 2024 The Falco Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,4 +17,61 @@ limitations under the License. */ #pragma once +// This is taken from kernel headers `/include/linux/compiler.h` +// Used by libpman and scap_bpf engine + +#define READ_ONCE(x) (*(volatile typeof(x) *)&x) +#define WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v) + +#define barrier() asm volatile("" ::: "memory") + +#if defined(__x86_64__) + +#define smp_mb() asm volatile("lock; addl $0,-132(%%rsp)" ::: "memory", "cc") + +#define smp_store_release(p, v) \ + do { \ + barrier(); \ + WRITE_ONCE(*p, v); \ + } while(0) + +#define smp_load_acquire(p) \ + ({ \ + typeof(*p) ___p = READ_ONCE(*p); \ + barrier(); \ + ___p; \ + }) + +#elif defined(__aarch64__) + +#define smp_mb() asm volatile("dmb ish" ::: "memory") + +#endif + +#ifndef smp_mb +#define smp_mb() __sync_synchronize() +#endif + +#ifndef smp_store_release +#define smp_store_release(p, v) \ + do { \ + smp_mb(); \ + WRITE_ONCE(*p, v); \ + } while(0) +#endif + +#ifndef smp_load_acquire +#define smp_load_acquire(p) \ + ({ \ + typeof(*p) ___p = READ_ONCE(*p); \ + smp_mb(); \ + ___p; \ + }) +#endif + +// This is defined by us +#if defined(__x86_64__) +#define mem_barrier() asm volatile("" ::: "memory") +#else #define mem_barrier() __sync_synchronize() +#endif