brintos

brintos / linux-shallow public Read only

0
0
Text · 5.7 KiB · 8b960d0 Raw
333 lines · plain
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (C) 2015-2019 ARM Limited.3// Original author: Dave Martin <Dave.Martin@arm.com>4//5// Simple FPSIMD context switch test6// Repeatedly writes unique test patterns into each FPSIMD register7// and reads them back to verify integrity.8//9// for x in `seq 1 NR_CPUS`; do fpsimd-test & pids=$pids\ $! ; done10// (leave it running for as long as you want...)11// kill $pids12 13#include <asm/unistd.h>14#include "assembler.h"15#include "asm-offsets.h"16 17#define NVR	3218#define MAXVL_B	(128 / 8)19 20.macro _vldr Vn:req, Xt:req21	ld1	{v\Vn\().2d}, [x\Xt]22.endm23 24.macro _vstr Vn:req, Xt:req25	st1	{v\Vn\().2d}, [x\Xt]26.endm27 28// Generate accessor functions to read/write programmatically selected29// FPSIMD registers.30// x0 is the register index to access31// x1 is the memory address to read from (getv,setp) or store to (setv,setp)32// All clobber x0-x233define_accessor setv, NVR, _vldr34define_accessor getv, NVR, _vstr35 36// Declare some storate space to shadow the SVE register contents:37.pushsection .text38.data39.align 440vref:41	.space	MAXVL_B * NVR42scratch:43	.space	MAXVL_B44.popsection45 46// Generate a test pattern for storage in SVE registers47// x0: pid	(16 bits)48// x1: register number (6 bits)49// x2: generation (4 bits)50function pattern51	orr	w1, w0, w1, lsl #1652	orr	w2, w1, w2, lsl #2853 54	ldr	x0, =scratch55	mov	w1, #MAXVL_B / 456 570:	str	w2, [x0], #458	add	w2, w2, #(1 << 22)59	subs	w1, w1, #160	bne	0b61 62	ret63endfunction64 65// Get the address of shadow data for FPSIMD V-register V<xn>66.macro _adrv xd, xn, nrtmp67	ldr	\xd, =vref68	mov	x\nrtmp, #1669	madd	\xd, x\nrtmp, \xn, \xd70.endm71 72// Set up test pattern in a FPSIMD V-register73// x0: pid74// x1: register number75// x2: generation76function setup_vreg77	mov	x4, x3078 79	mov	x6, x180	bl	pattern81	_adrv	x0, x6, 282	mov	x5, x083	ldr	x1, =scratch84	bl	memcpy85 86	mov	x0, x687	mov	x1, x588	bl	setv89 90	ret	x491endfunction92 93// Trivial memory compare: compare x2 bytes starting at address x0 with94// bytes starting at address x1.95// Returns only if all bytes match; otherwise, the program is aborted.96// Clobbers x0-x5.97function memcmp98	cbz	x2, 1f99 100	mov	x5, #01010:	ldrb	w3, [x0, x5]102	ldrb	w4, [x1, x5]103	add	x5, x5, #1104	cmp	w3, w4105	b.ne	barf106	subs	x2, x2, #1107	b.ne	0b108 1091:	ret110endfunction111 112// Verify that a FPSIMD V-register matches its shadow in memory, else abort113// x0: reg number114// Clobbers x0-x5.115function check_vreg116	mov	x3, x30117 118	_adrv	x5, x0, 6119	mov	x4, x0120	ldr	x7, =scratch121 122	mov	x0, x7123	mov	x1, x6124	bl	memfill_ae125 126	mov	x0, x4127	mov	x1, x7128	bl	getv129 130	mov	x0, x5131	mov	x1, x7132	mov	x2, x6133	mov	x30, x3134	b	memcmp135endfunction136 137// Any SVE register modified here can cause corruption in the main138// thread -- but *only* the registers modified here.139function irritator_handler140	// Increment the irritation signal count (x23):141	ldr	x0, [x2, #ucontext_regs + 8 * 23]142	add	x0, x0, #1143	str	x0, [x2, #ucontext_regs + 8 * 23]144 145	// Corrupt some random V-regs146	adr	x0, .text + (irritator_handler - .text) / 16 * 16147	movi	v0.8b, #7148	movi	v9.16b, #9149	movi	v31.8b, #31150 151	ret152endfunction153 154function tickle_handler155	// Increment the signal count (x23):156	ldr	x0, [x2, #ucontext_regs + 8 * 23]157	add	x0, x0, #1158	str	x0, [x2, #ucontext_regs + 8 * 23]159 160	ret161endfunction162 163function terminate_handler164	mov	w21, w0165	mov	x20, x2166 167	puts	"Terminated by signal "168	mov	w0, w21169	bl	putdec170	puts	", no error, iterations="171	ldr	x0, [x20, #ucontext_regs + 8 * 22]172	bl	putdec173	puts	", signals="174	ldr	x0, [x20, #ucontext_regs + 8 * 23]175	bl	putdecn176 177	mov	x0, #0178	mov	x8, #__NR_exit179	svc	#0180endfunction181 182// w0: signal number183// x1: sa_action184// w2: sa_flags185// Clobbers x0-x6,x8186function setsignal187	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!188 189	mov	w4, w0190	mov	x5, x1191	mov	w6, w2192 193	add	x0, sp, #16194	mov	x1, #sa_sz195	bl	memclr196 197	mov	w0, w4198	add	x1, sp, #16199	str	w6, [x1, #sa_flags]200	str	x5, [x1, #sa_handler]201	mov	x2, #0202	mov	x3, #sa_mask_sz203	mov	x8, #__NR_rt_sigaction204	svc	#0205 206	cbz	w0, 1f207 208	puts	"sigaction failure\n"209	b	.Labort210 2111:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)212	ret213endfunction214 215// Main program entry point216.globl _start217function _start218	mov	x23, #0		// signal count219 220	mov	w0, #SIGINT221	adr	x1, terminate_handler222	mov	w2, #SA_SIGINFO223	bl	setsignal224 225	mov	w0, #SIGTERM226	adr	x1, terminate_handler227	mov	w2, #SA_SIGINFO228	bl	setsignal229 230	mov	w0, #SIGUSR1231	adr	x1, irritator_handler232	mov	w2, #SA_SIGINFO233	orr	w2, w2, #SA_NODEFER234	bl	setsignal235 236	mov	w0, #SIGUSR2237	adr	x1, tickle_handler238	mov	w2, #SA_SIGINFO239	orr	w2, w2, #SA_NODEFER240	bl	setsignal241 242	// Sanity-check and report the vector length243 244	mov	x19, #128245	cmp	x19, #128246	b.lo	1f247	cmp	x19, #2048248	b.hi	1f249	tst	x19, #(8 - 1)250	b.eq	2f251 2521:	puts	"Bad vector length: "253	mov	x0, x19254	bl	putdecn255	b	.Labort256 2572:	puts	"Vector length:\t"258	mov	x0, x19259	bl	putdec260	puts	" bits\n"261 262	// Obtain our PID, to ensure test pattern uniqueness between processes263 264	mov	x8, #__NR_getpid265	svc	#0266	mov	x20, x0267 268	puts	"PID:\t"269	mov	x0, x20270	bl	putdecn271 272	mov	x22, #0		// generation number, increments per iteration273.Ltest_loop:274 275	mov	x21, #0		// Set up V-regs & shadow with test pattern2760:	mov	x0, x20277	mov	x1, x21278	and	x2, x22, #0xf279	bl	setup_vreg280	add	x21, x21, #1281	cmp	x21, #NVR282	b.lo	0b283 284// Can't do this when SVE state is volatile across SVC:285	mov	x8, #__NR_sched_yield	// Encourage preemption286	svc	#0287 288	mov	x21, #02890:	mov	x0, x21290	bl	check_vreg291	add	x21, x21, #1292	cmp	x21, #NVR293	b.lo	0b294 295	add	x22, x22, #1296	b	.Ltest_loop297 298.Labort:299	mov	x0, #0300	mov	x1, #SIGABRT301	mov	x8, #__NR_kill302	svc	#0303endfunction304 305function barf306	mov	x10, x0	// expected data307	mov	x11, x1	// actual data308	mov	x12, x2	// data size309 310	puts	"Mismatch: PID="311	mov	x0, x20312	bl	putdec313	puts	", iteration="314	mov	x0, x22315	bl	putdec316	puts	", reg="317	mov	x0, x21318	bl	putdecn319	puts	"\tExpected ["320	mov	x0, x10321	mov	x1, x12322	bl	dumphex323	puts	"]\n\tGot      ["324	mov	x0, x11325	mov	x1, x12326	bl	dumphex327	puts	"]\n"328 329	mov	x8, #__NR_exit330	mov	x1, #1331	svc	#0332endfunction333