From 6e0deb8f01a2102a4fb7384e79142e989eddab1f Mon Sep 17 00:00:00 2001 From: Igor Nabirushkin Date: Tue, 16 Nov 2021 10:52:51 +0300 Subject: misc: eventlib: fix building kernel with gcc 11 Eventlib: Add local implementation of __sync_fetch_and_or and __sync_fetch_and_and builtin functions. This fixes eventlib build errors with GCC 11. Bug 3375927 Change-Id: I1a8ed9dcc383242a5fa125df3cfb220c867adaf3 Signed-off-by: Igor Nabirushkin Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2629717 Reviewed-by: Bibek Basu Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/misc/eventlib/eventlib_flt.h | 9 +++--- drivers/misc/eventlib/utility.h | 56 +++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/eventlib/eventlib_flt.h b/drivers/misc/eventlib/eventlib_flt.h index a2dd1f77c..80ce6b87b 100644 --- a/drivers/misc/eventlib/eventlib_flt.h +++ b/drivers/misc/eventlib/eventlib_flt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -24,6 +24,7 @@ #define EVENTLIB_FLT_H #include "eventlib.h" +#include "utility.h" /* Readers' connects/updates/disconnects and writer's checks for updates, are * all fully asynchronous. @@ -157,17 +158,17 @@ struct eventlib_flt_ctx { static inline bool sync_test_and_set_bit(unsigned int n, uint32_t *p) { - return !!(__sync_fetch_and_or(p, (1u << n)) & (1u << n)); + return !!(tracebuf_sync_fetch_and_or_u32(p, (1u << n)) & (1u << n)); } static inline void sync_set_bit(unsigned int n, uint32_t *p) { - __sync_fetch_and_or(p, (1u << n)); + tracebuf_sync_fetch_and_or_u32(p, (1u << n)); } static inline void sync_clear_bit(unsigned int n, uint32_t *p) { - __sync_fetch_and_and(p, ~(1u << n)); + tracebuf_sync_fetch_and_and_u32(p, ~(1u << n)); } /* Below functions are implemented by the filter subsystem interface. diff --git a/drivers/misc/eventlib/utility.h b/drivers/misc/eventlib/utility.h index 83cd49075..a62898b1e 100644 --- a/drivers/misc/eventlib/utility.h +++ b/drivers/misc/eventlib/utility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -125,4 +125,58 @@ static inline uint64_t increment64(volatile uint64_t *addr) return prev; } +#if defined(__aarch64__) && defined(__GNUC__) && (__GNUC__ >= 11) + +static inline uint32_t +tracebuf_sync_fetch_and_or_u32(uint32_t *ptr, uint32_t value) +{ + uint32_t result, tmp, flags = 0; + + asm volatile( + "1: ldxr %w[result], [%[ptr]]\n" + " orr %w[tmp], %w[result], %w[value]\n" + " stlxr %w[flags], %w[tmp], [%[ptr]]\n" + " cbnz %w[flags], 1b\n" + " dmb ish" + : [result] "=&r"(result), [tmp] "=&r"(tmp) + : [value] "r"(value), [flags] "r"(flags), [ptr] "r"(ptr) + : "cc", "memory"); + + return result; +} + +static inline uint32_t +tracebuf_sync_fetch_and_and_u32(uint32_t *ptr, uint32_t value) +{ + uint32_t result, tmp, flags = 0; + + asm volatile( + "1: ldxr %w[result], [%[ptr]]\n" + " and %w[tmp], %w[result], %w[value]\n" + " stlxr %w[flags], %w[tmp], [%[ptr]]\n" + " cbnz %w[flags], 1b\n" + " dmb ish" + : [result] "=&r"(result), [tmp] "=&r"(tmp) + : [value] "r"(value), [flags] "r"(flags), [ptr] "r"(ptr) + : "cc", "memory"); + + return result; +} + +#else + +static inline uint32_t +tracebuf_sync_fetch_and_or_u32(uint32_t *ptr, uint32_t value) +{ + return __sync_fetch_and_or(ptr, value); +} + +static inline uint32_t +tracebuf_sync_fetch_and_and_u32(uint32_t *ptr, uint32_t value) +{ + return __sync_fetch_and_and(ptr, value); +} + +#endif + #endif -- cgit v1.2.2