File Index
Files and directories
Sign in
FILE

rseq-or1k-bits.h

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/rseq/rseq-or1k-bits.h C
  1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2
  3#include "rseq-bits-template.h"
  4
  5#if defined(RSEQ_TEMPLATE_MO_RELAXED) && \
  6	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
  7
  8static inline __always_inline
  9int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_storev)(intptr_t *v, intptr_t expect, intptr_t newv,
 10				int cpu)
 11{
 12	RSEQ_INJECT_C(9)
 13
 14	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
 15				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[cmpfail]")
 16#ifdef RSEQ_COMPARE_TWICE
 17				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
 18				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error2]")
 19#endif
 20				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
 21				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
 22				  RSEQ_INJECT_ASM(3)
 23				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[cmpfail]")
 24				  RSEQ_INJECT_ASM(4)
 25#ifdef RSEQ_COMPARE_TWICE
 26				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
 27				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[error2]")
 28#endif
 29				  RSEQ_ASM_OP_FINAL_STORE(v, newv, 3)
 30				  RSEQ_INJECT_ASM(5)
 31				  RSEQ_ASM_DEFINE_ABORT(4, abort)
 32				  : /* gcc asm goto does not allow outputs */
 33				  : [cpu_id]		"r" (cpu),
 34				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
 35				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
 36				    [v]			"m" (*v),
 37				    [expect]		"r" (expect),
 38				    [newv]		"r" (newv)
 39				    RSEQ_INJECT_INPUT
 40				  : "memory", RSEQ_ASM_TMP_REG_1
 41				    RSEQ_INJECT_CLOBBER
 42				  : abort, cmpfail
 43#ifdef RSEQ_COMPARE_TWICE
 44				    , error1, error2
 45#endif
 46	);
 47
 48	return 0;
 49abort:
 50	RSEQ_INJECT_FAILED
 51	return -1;
 52cmpfail:
 53	return 1;
 54#ifdef RSEQ_COMPARE_TWICE
 55error1:
 56	rseq_bug("cpu_id comparison failed");
 57error2:
 58	rseq_bug("expected value comparison failed");
 59#endif
 60}
 61
 62static inline __always_inline
 63int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpnev_storeoffp_load)(intptr_t *v, intptr_t expectnot,
 64			       off_t voffp, intptr_t *load, int cpu)
 65{
 66	RSEQ_INJECT_C(9)
 67
 68	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
 69				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[cmpfail]")
 70#ifdef RSEQ_COMPARE_TWICE
 71				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
 72				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error2]")
 73#endif
 74				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
 75				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
 76				  RSEQ_INJECT_ASM(3)
 77				  RSEQ_ASM_OP_CMPNE(v, expectnot, "%l[cmpfail]")
 78				  RSEQ_INJECT_ASM(4)
 79#ifdef RSEQ_COMPARE_TWICE
 80				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
 81				  RSEQ_ASM_OP_CMPNE(v, expectnot, "%l[error2]")
 82#endif
 83				  RSEQ_ASM_OP_R_LOAD(v)
 84				  RSEQ_ASM_OP_R_STORE(load)
 85				  RSEQ_ASM_OP_R_LOAD_OFF(voffp)
 86				  RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
 87				  RSEQ_INJECT_ASM(5)
 88				  RSEQ_ASM_DEFINE_ABORT(4, abort)
 89				  : /* gcc asm goto does not allow outputs */
 90				  : [cpu_id]		"r" (cpu),
 91				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
 92				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
 93				    [v]			"m" (*v),
 94				    [expectnot]		"r" (expectnot),
 95				    [load]		"m" (*load),
 96				    [voffp]		"Ir" (voffp)
 97				    RSEQ_INJECT_INPUT
 98				  : "memory", RSEQ_ASM_TMP_REG_1
 99				    RSEQ_INJECT_CLOBBER
100				  : abort, cmpfail
101#ifdef RSEQ_COMPARE_TWICE
102				    , error1, error2
103#endif
104	);
105	return 0;
106abort:
107	RSEQ_INJECT_FAILED
108	return -1;
109cmpfail:
110	return 1;
111#ifdef RSEQ_COMPARE_TWICE
112error1:
113	rseq_bug("cpu_id comparison failed");
114error2:
115	rseq_bug("expected value comparison failed");
116#endif
117}
118
119static inline __always_inline
120int RSEQ_TEMPLATE_IDENTIFIER(rseq_addv)(intptr_t *v, intptr_t count, int cpu)
121{
122	RSEQ_INJECT_C(9)
123
124	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
125#ifdef RSEQ_COMPARE_TWICE
126				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
127#endif
128				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
129				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
130				  RSEQ_INJECT_ASM(3)
131#ifdef RSEQ_COMPARE_TWICE
132				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
133#endif
134				  RSEQ_ASM_OP_R_LOAD(v)
135				  RSEQ_ASM_OP_R_ADD(count)
136				  RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
137				  RSEQ_INJECT_ASM(4)
138				  RSEQ_ASM_DEFINE_ABORT(4, abort)
139				  : /* gcc asm goto does not allow outputs */
140				  : [cpu_id]		"r" (cpu),
141				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
142				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
143				    [v]			"m" (*v),
144				    [count]		"r" (count)
145				    RSEQ_INJECT_INPUT
146				  : "memory", RSEQ_ASM_TMP_REG_1
147				    RSEQ_INJECT_CLOBBER
148				  : abort
149#ifdef RSEQ_COMPARE_TWICE
150				    , error1
151#endif
152	);
153	return 0;
154abort:
155	RSEQ_INJECT_FAILED
156	return -1;
157#ifdef RSEQ_COMPARE_TWICE
158error1:
159	rseq_bug("cpu_id comparison failed");
160#endif
161}
162
163static inline __always_inline
164int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_cmpeqv_storev)(intptr_t *v, intptr_t expect,
165			      intptr_t *v2, intptr_t expect2,
166			      intptr_t newv, int cpu)
167{
168	RSEQ_INJECT_C(9)
169
170	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
171				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[cmpfail]")
172#ifdef RSEQ_COMPARE_TWICE
173				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
174				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error2]")
175				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error3]")
176#endif
177				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
178				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
179				  RSEQ_INJECT_ASM(3)
180				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[cmpfail]")
181				  RSEQ_INJECT_ASM(4)
182				  RSEQ_ASM_OP_CMPEQ(v2, expect2, "%l[cmpfail]")
183				  RSEQ_INJECT_ASM(5)
184#ifdef RSEQ_COMPARE_TWICE
185				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
186				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[error2]")
187				  RSEQ_ASM_OP_CMPEQ(v2, expect2, "%l[error3]")
188#endif
189				  RSEQ_ASM_OP_FINAL_STORE(v, newv, 3)
190				  RSEQ_INJECT_ASM(6)
191				  RSEQ_ASM_DEFINE_ABORT(4, abort)
192				  : /* gcc asm goto does not allow outputs */
193				  : [cpu_id]		"r" (cpu),
194				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
195				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
196				    [v]			"m" (*v),
197				    [expect]		"r" (expect),
198				    [v2]		"m" (*v2),
199				    [expect2]		"r" (expect2),
200				    [newv]		"r" (newv)
201				    RSEQ_INJECT_INPUT
202				  : "memory", RSEQ_ASM_TMP_REG_1
203				    RSEQ_INJECT_CLOBBER
204				  : abort, cmpfail
205#ifdef RSEQ_COMPARE_TWICE
206				    , error1, error2, error3
207#endif
208	);
209
210	return 0;
211abort:
212	RSEQ_INJECT_FAILED
213	return -1;
214cmpfail:
215	return 1;
216#ifdef RSEQ_COMPARE_TWICE
217error1:
218	rseq_bug("cpu_id comparison failed");
219error2:
220	rseq_bug("expected value comparison failed");
221error3:
222	rseq_bug("2nd expected value comparison failed");
223#endif
224}
225
226#define RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV
227
228/*
229 *   pval = *(ptr+off)
230 *  *pval += inc;
231 */
232static inline __always_inline
233int RSEQ_TEMPLATE_IDENTIFIER(rseq_offset_deref_addv)(intptr_t *ptr, off_t off, intptr_t inc,
234				int cpu)
235{
236	RSEQ_INJECT_C(9)
237
238	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
239#ifdef RSEQ_COMPARE_TWICE
240				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
241#endif
242				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
243				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
244				  RSEQ_INJECT_ASM(3)
245#ifdef RSEQ_COMPARE_TWICE
246				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
247#endif
248				  RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, inc, 3)
249				  RSEQ_INJECT_ASM(4)
250				  RSEQ_ASM_DEFINE_ABORT(4, abort)
251				  : /* gcc asm goto does not allow outputs */
252				  : [cpu_id]		"r" (cpu),
253				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
254				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
255				    [ptr]		"r" (ptr),
256				    [off]		"r" (off),
257				    [inc]		"r" (inc)
258				    RSEQ_INJECT_INPUT
259				  : "memory", RSEQ_ASM_TMP_REG_1
260				    RSEQ_INJECT_CLOBBER
261				  : abort
262#ifdef RSEQ_COMPARE_TWICE
263				    , error1
264#endif
265	);
266	return 0;
267abort:
268	RSEQ_INJECT_FAILED
269	return -1;
270#ifdef RSEQ_COMPARE_TWICE
271error1:
272	rseq_bug("cpu_id comparison failed");
273#endif
274}
275
276#endif /* #if defined(RSEQ_TEMPLATE_MO_RELAXED) &&
277	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
278
279#if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) && \
280	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID))
281
282static inline __always_inline
283int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trystorev_storev)(intptr_t *v, intptr_t expect,
284				 intptr_t *v2, intptr_t newv2,
285				 intptr_t newv, int cpu)
286{
287	RSEQ_INJECT_C(9)
288
289	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
290				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[cmpfail]")
291#ifdef RSEQ_COMPARE_TWICE
292				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
293				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error2]")
294#endif
295				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
296				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
297				  RSEQ_INJECT_ASM(3)
298				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[cmpfail]")
299				  RSEQ_INJECT_ASM(4)
300#ifdef RSEQ_COMPARE_TWICE
301				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
302				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[error2]")
303#endif
304				  RSEQ_ASM_OP_STORE(v2, newv2)
305				  RSEQ_INJECT_ASM(5)
306#ifdef RSEQ_TEMPLATE_MO_RELEASE
307				  RSEQ_ASM_OP_FINAL_STORE_RELEASE(v, newv, 3)
308#else
309				  RSEQ_ASM_OP_FINAL_STORE(v, newv, 3)
310#endif
311				  RSEQ_INJECT_ASM(6)
312				  RSEQ_ASM_DEFINE_ABORT(4, abort)
313				  : /* gcc asm goto does not allow outputs */
314				  : [cpu_id]		"r" (cpu),
315				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
316				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
317				    [expect]		"r" (expect),
318				    [v]			"m" (*v),
319				    [newv]		"r" (newv),
320				    [v2]		"m" (*v2),
321				    [newv2]		"r" (newv2)
322				    RSEQ_INJECT_INPUT
323				  : "memory", RSEQ_ASM_TMP_REG_1
324				    RSEQ_INJECT_CLOBBER
325				  : abort, cmpfail
326#ifdef RSEQ_COMPARE_TWICE
327				    , error1, error2
328#endif
329	);
330
331	return 0;
332abort:
333	RSEQ_INJECT_FAILED
334	return -1;
335cmpfail:
336	return 1;
337#ifdef RSEQ_COMPARE_TWICE
338error1:
339	rseq_bug("cpu_id comparison failed");
340error2:
341	rseq_bug("expected value comparison failed");
342#endif
343}
344
345static inline __always_inline
346int RSEQ_TEMPLATE_IDENTIFIER(rseq_cmpeqv_trymemcpy_storev)(intptr_t *v, intptr_t expect,
347				 void *dst, void *src, size_t len,
348				 intptr_t newv, int cpu)
349{
350	RSEQ_INJECT_C(9)
351	__asm__ __volatile__ goto(RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
352				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[cmpfail]")
353#ifdef RSEQ_COMPARE_TWICE
354				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error1]")
355				  RSEQ_ASM_DEFINE_EXIT_POINT(2f, "%l[error2]")
356#endif
357				  RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
358				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
359				  RSEQ_INJECT_ASM(3)
360				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[cmpfail]")
361				  RSEQ_INJECT_ASM(4)
362#ifdef RSEQ_COMPARE_TWICE
363				  RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
364				  RSEQ_ASM_OP_CMPEQ(v, expect, "%l[error2]")
365#endif
366				  RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)
367				  RSEQ_INJECT_ASM(5)
368#ifdef RSEQ_TEMPLATE_MO_RELEASE
369				  RSEQ_ASM_OP_FINAL_STORE_RELEASE(v, newv, 3)
370#else
371				  RSEQ_ASM_OP_FINAL_STORE(v, newv, 3)
372#endif
373				  RSEQ_INJECT_ASM(6)
374				  RSEQ_ASM_DEFINE_ABORT(4, abort)
375				  : /* gcc asm goto does not allow outputs */
376				  : [cpu_id]		"r" (cpu),
377				    [current_cpu_id]	"m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
378				    [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
379				    [expect]		"r" (expect),
380				    [v]			"m" (*v),
381				    [newv]		"r" (newv),
382				    [dst]		"r" (dst),
383				    [src]		"r" (src),
384				    [len]		"r" (len)
385				    RSEQ_INJECT_INPUT
386				  : "memory", RSEQ_ASM_TMP_REG_1, RSEQ_ASM_TMP_REG_2,
387				    RSEQ_ASM_TMP_REG_3, RSEQ_ASM_TMP_REG_4
388				    RSEQ_INJECT_CLOBBER
389				  : abort, cmpfail
390#ifdef RSEQ_COMPARE_TWICE
391				    , error1, error2
392#endif
393	);
394
395	return 0;
396abort:
397	RSEQ_INJECT_FAILED
398	return -1;
399cmpfail:
400	return 1;
401#ifdef RSEQ_COMPARE_TWICE
402error1:
403	rseq_bug("cpu_id comparison failed");
404error2:
405	rseq_bug("expected value comparison failed");
406#endif
407}
408
409#endif /* #if (defined(RSEQ_TEMPLATE_MO_RELAXED) || defined(RSEQ_TEMPLATE_MO_RELEASE)) &&
410	(defined(RSEQ_TEMPLATE_CPU_ID) || defined(RSEQ_TEMPLATE_MM_CID)) */
411
412#include "rseq-bits-reset.h"
~/ Read-only file preview.