NVIDIA DRIVE OS Linux SDK API Reference

5.1.12.0 Release

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nv_speculation_barrier.h
Go to the documentation of this file.
1 /*
2  * NVIDIA GPZ vulnerability mitigation definitions.
3  *
4  * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of NVIDIA CORPORATION nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * There are two copies (listed at confluence.nvidia.com/x/DtprBg)
33  * of this file for legacy reasons.
34  *
35  * Both files need to be kept in sync if any changes are required.
36  */
37 
38 #ifndef INCLUDED_NV_SPECULATION_BARRIER_H
39 #define INCLUDED_NV_SPECULATION_BARRIER_H
40 
55 #define NV_SPECULATION_BARRIER_VERSION 2
56 
57 /*
58  * GNU-C/MSC/clang - x86/x86_64 : __x86_64, __i386, __i386__
59  * GNU-C - THUMB mode : __GNUC__, __thumb__
60  * GNU-C - ARM modes : __GNUC__, __arm__, __aarch64__
61  * armclang - THUMB mode : __ARMCC_VERSION, __thumb__
62  * armclang - ARM modes : __ARMCC_VERSION, __arm__, __aarch64__
63  * GHS - THUMB mode : __ghs__, __THUMB__
64  * GHS - ARM modes : __ghs__, __ARM__, __ARM64__
65  */
66 
67 #if defined(_M_IX86) || defined(__i386__) || defined(__i386) \
68  || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
69  /* All x86 */
70  #define NV_SPECULATION_BARRIER_x86
71 
72 #elif defined(macintosh) || defined(__APPLE__) \
73  || defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) \
74  || defined(__POWERPC__) || defined(__ppc) || defined(__ppc__) \
75  || defined(__ppc64__) || defined(__PPC__) \
76  || defined(__PPC64__) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)
77  /* All PowerPC */
78  #define NV_SPECULATION_BARRIER_PPC
79 
80 #elif (defined(__GNUC__) && defined(__thumb__)) \
81  || (defined(__ARMCC_VERSION) && defined(__thumb__)) \
82  || (defined(__ghs__) && defined(__THUMB__))
83  /* ARM-thumb mode(<=ARMv7)/T32 (ARMv8) */
84  #define NV_SPECULATION_BARRIER_ARM_COMMON
85  #define NV_SPEC_BARRIER_CSDB ".inst.w 0xf3af8014\n"
86 
87 #elif (defined(__GNUC__) && defined(__arm__)) \
88  || (defined(__ARMCC_VERSION) && defined(__arm__)) \
89  || (defined(__ghs__) && defined(__ARM__))
90  /* aarch32(ARMv8) / arm(<=ARMv7) mode */
91  #define NV_SPECULATION_BARRIER_ARM_COMMON
92  #define NV_SPEC_BARRIER_CSDB ".inst 0xe320f014\n"
93 
94 #elif (defined(__GNUC__) && defined(__aarch64__)) \
95  || (defined(__ARMCC_VERSION) && defined(__aarch64__)) \
96  || (defined(__ghs__) && defined(__ARM64__))
97  /* aarch64(ARMv8) mode */
98  #define NV_SPECULATION_BARRIER_ARM_COMMON
99  #define NV_SPEC_BARRIER_CSDB "HINT #20\n"
100 
101 #else
102  #error "Unknown compiler/chip family"
103 #endif
104 
135 #if defined(NV_SPECULATION_BARRIER_x86)
136 // Delete after all references are changed to nv_speculation_barrier
138 #define speculation_barrier() nv_speculation_barrier()
139 
140 static inline void nv_speculation_barrier(void)
141 {
142 
143 #if defined(_MSC_VER) && !defined(__clang__)
144  _mm_lfence();
145 #endif
146 
147 #if defined(__GNUC__) || defined(__clang__)
148  __asm__ __volatile__ ("lfence" : : : "memory");
149 #endif
150 
151 }
152 
153 #elif defined(NV_SPECULATION_BARRIER_PPC)
154 
155 static inline void nv_speculation_barrier(void)
156 {
157  asm volatile("ori 31,31,0");
158 }
159 
160 #elif defined(NV_SPECULATION_BARRIER_ARM_COMMON)
161 
162 /* Note: Cortex-A9 GNU-assembler seems to complain about DSB SY */
163 static inline void nv_speculation_barrier(void)
164 {
165  asm volatile
166  (
167  "DSB sy\n"
168  "ISB\n"
169  : : : "memory"
170  );
171 }
172 
173 #endif
174 
228 #if defined(NV_SPECULATION_BARRIER_x86)
229 
230 // TODO Add implementation for _MSC_VER and PPC
231 #if defined(__GNUC__) || defined(__clang__)
232 
233 static inline unsigned long nv_array_index_no_speculate(unsigned long index,
234  unsigned long count)
235 {
236  unsigned long mask;
237 
238  __asm__ __volatile__
239  (
240  "CMP %2, %1 \n"
241  "SBB %0, %0 \n"
242  : "=r"(mask) : "r"(index), "r"(count) : "cc"
243  );
244 
245  return (index & mask);
246 }
247 #endif
248 
249 
250 #elif defined(NV_SPECULATION_BARRIER_ARM_COMMON)
251 static inline unsigned long nv_array_index_no_speculate(unsigned long index,
252  unsigned long count)
253 {
254  unsigned long mask;
255 
256  asm volatile
257  (
258  "CMP %[ind], %[cnt] \n"
259  "SBC %[res], %[cnt], %[cnt] \n"
260  NV_SPEC_BARRIER_CSDB
261  : [res] "=r" (mask) : [ind] "r" (index), [cnt] "r" (count): "cc"
262  );
263 
264  return (index & mask);
265 }
266 #endif
267 
270 #endif // INCLUDED_NV_SPECULATION_BARRIER_H