cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sve-test.S (9259B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2// Copyright (C) 2015-2019 ARM Limited.
      3// Original author: Dave Martin <Dave.Martin@arm.com>
      4//
      5// Simple Scalable Vector Extension context switch test
      6// Repeatedly writes unique test patterns into each SVE register
      7// and reads them back to verify integrity.
      8//
      9// for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
     10// (leave it running for as long as you want...)
     11// kill $pids
     12
     13#include <asm/unistd.h>
     14#include "assembler.h"
     15#include "asm-offsets.h"
     16#include "sme-inst.h"
     17
     18#define NZR	32
     19#define NPR	16
     20#define MAXVL_B	(2048 / 8)
     21
     22.arch_extension sve
     23
     24.macro _sve_ldr_v zt, xn
     25	ldr	z\zt, [x\xn]
     26.endm
     27
     28.macro _sve_str_v zt, xn
     29	str	z\zt, [x\xn]
     30.endm
     31
     32.macro _sve_ldr_p pt, xn
     33	ldr	p\pt, [x\xn]
     34.endm
     35
     36.macro _sve_str_p pt, xn
     37	str	p\pt, [x\xn]
     38.endm
     39
     40// Generate accessor functions to read/write programmatically selected
     41// SVE registers.
     42// x0 is the register index to access
     43// x1 is the memory address to read from (getz,setp) or store to (setz,setp)
     44// All clobber x0-x2
     45define_accessor setz, NZR, _sve_ldr_v
     46define_accessor getz, NZR, _sve_str_v
     47define_accessor setp, NPR, _sve_ldr_p
     48define_accessor getp, NPR, _sve_str_p
     49
     50// Declare some storate space to shadow the SVE register contents:
     51.pushsection .text
     52.data
     53.align 4
     54zref:
     55	.space	MAXVL_B * NZR
     56pref:
     57	.space	MAXVL_B / 8 * NPR
     58ffrref:
     59	.space	MAXVL_B / 8
     60scratch:
     61	.space	MAXVL_B
     62.popsection
     63
     64// Generate a test pattern for storage in SVE registers
     65// x0: pid	(16 bits)
     66// x1: register number (6 bits)
     67// x2: generation (4 bits)
     68
     69// These values are used to constuct a 32-bit pattern that is repeated in the
     70// scratch buffer as many times as will fit:
     71// bits 31:28	generation number (increments once per test_loop)
     72// bits 27:22	32-bit lane index
     73// bits 21:16	register number
     74// bits 15: 0	pid
     75
     76function pattern
     77	orr	w1, w0, w1, lsl #16
     78	orr	w2, w1, w2, lsl #28
     79
     80	ldr	x0, =scratch
     81	mov	w1, #MAXVL_B / 4
     82
     830:	str	w2, [x0], #4
     84	add	w2, w2, #(1 << 22)
     85	subs	w1, w1, #1
     86	bne	0b
     87
     88	ret
     89endfunction
     90
     91// Get the address of shadow data for SVE Z-register Z<xn>
     92.macro _adrz xd, xn, nrtmp
     93	ldr	\xd, =zref
     94	rdvl	x\nrtmp, #1
     95	madd	\xd, x\nrtmp, \xn, \xd
     96.endm
     97
     98// Get the address of shadow data for SVE P-register P<xn - NZR>
     99.macro _adrp xd, xn, nrtmp
    100	ldr	\xd, =pref
    101	rdvl	x\nrtmp, #1
    102	lsr	x\nrtmp, x\nrtmp, #3
    103	sub	\xn, \xn, #NZR
    104	madd	\xd, x\nrtmp, \xn, \xd
    105.endm
    106
    107// Set up test pattern in a SVE Z-register
    108// x0: pid
    109// x1: register number
    110// x2: generation
    111function setup_zreg
    112	mov	x4, x30
    113
    114	mov	x6, x1
    115	bl	pattern
    116	_adrz	x0, x6, 2
    117	mov	x5, x0
    118	ldr	x1, =scratch
    119	bl	memcpy
    120
    121	mov	x0, x6
    122	mov	x1, x5
    123	bl	setz
    124
    125	ret	x4
    126endfunction
    127
    128// Set up test pattern in a SVE P-register
    129// x0: pid
    130// x1: register number
    131// x2: generation
    132function setup_preg
    133	mov	x4, x30
    134
    135	mov	x6, x1
    136	bl	pattern
    137	_adrp	x0, x6, 2
    138	mov	x5, x0
    139	ldr	x1, =scratch
    140	bl	memcpy
    141
    142	mov	x0, x6
    143	mov	x1, x5
    144	bl	setp
    145
    146	ret	x4
    147endfunction
    148
    149// Set up test pattern in the FFR
    150// x0: pid
    151// x2: generation
    152//
    153// We need to generate a canonical FFR value, which consists of a number of
    154// low "1" bits, followed by a number of zeros. This gives us 17 unique values
    155// per 16 bits of FFR, so we create a 4 bit signature out of the PID and
    156// generation, and use that as the initial number of ones in the pattern.
    157// We fill the upper lanes of FFR with zeros.
    158// Beware: corrupts P0.
    159function setup_ffr
    160#ifndef SSVE
    161	mov	x4, x30
    162
    163	and	w0, w0, #0x3
    164	bfi	w0, w2, #2, #2
    165	mov	w1, #1
    166	lsl	w1, w1, w0
    167	sub	w1, w1, #1
    168
    169	ldr	x0, =ffrref
    170	strh	w1, [x0], 2
    171	rdvl	x1, #1
    172	lsr	x1, x1, #3
    173	sub	x1, x1, #2
    174	bl	memclr
    175
    176	mov	x0, #0
    177	ldr	x1, =ffrref
    178	bl	setp
    179
    180	wrffr	p0.b
    181
    182	ret	x4
    183#else
    184	ret
    185#endif
    186endfunction
    187
    188// Trivial memory compare: compare x2 bytes starting at address x0 with
    189// bytes starting at address x1.
    190// Returns only if all bytes match; otherwise, the program is aborted.
    191// Clobbers x0-x5.
    192function memcmp
    193	cbz	x2, 2f
    194
    195	stp	x0, x1, [sp, #-0x20]!
    196	str	x2, [sp, #0x10]
    197
    198	mov	x5, #0
    1990:	ldrb	w3, [x0, x5]
    200	ldrb	w4, [x1, x5]
    201	add	x5, x5, #1
    202	cmp	w3, w4
    203	b.ne	1f
    204	subs	x2, x2, #1
    205	b.ne	0b
    206
    2071:	ldr	x2, [sp, #0x10]
    208	ldp	x0, x1, [sp], #0x20
    209	b.ne	barf
    210
    2112:	ret
    212endfunction
    213
    214// Verify that a SVE Z-register matches its shadow in memory, else abort
    215// x0: reg number
    216// Clobbers x0-x7.
    217function check_zreg
    218	mov	x3, x30
    219
    220	_adrz	x5, x0, 6
    221	mov	x4, x0
    222	ldr	x7, =scratch
    223
    224	mov	x0, x7
    225	mov	x1, x6
    226	bl	memfill_ae
    227
    228	mov	x0, x4
    229	mov	x1, x7
    230	bl	getz
    231
    232	mov	x0, x5
    233	mov	x1, x7
    234	mov	x2, x6
    235	mov	x30, x3
    236	b	memcmp
    237endfunction
    238
    239// Verify that a SVE P-register matches its shadow in memory, else abort
    240// x0: reg number
    241// Clobbers x0-x7.
    242function check_preg
    243	mov	x3, x30
    244
    245	_adrp	x5, x0, 6
    246	mov	x4, x0
    247	ldr	x7, =scratch
    248
    249	mov	x0, x7
    250	mov	x1, x6
    251	bl	memfill_ae
    252
    253	mov	x0, x4
    254	mov	x1, x7
    255	bl	getp
    256
    257	mov	x0, x5
    258	mov	x1, x7
    259	mov	x2, x6
    260	mov	x30, x3
    261	b	memcmp
    262endfunction
    263
    264// Verify that the FFR matches its shadow in memory, else abort
    265// Beware -- corrupts P0.
    266// Clobbers x0-x5.
    267function check_ffr
    268#ifndef SSVE
    269	mov	x3, x30
    270
    271	ldr	x4, =scratch
    272	rdvl	x5, #1
    273	lsr	x5, x5, #3
    274
    275	mov	x0, x4
    276	mov	x1, x5
    277	bl	memfill_ae
    278
    279	rdffr	p0.b
    280	mov	x0, #0
    281	mov	x1, x4
    282	bl	getp
    283
    284	ldr	x0, =ffrref
    285	mov	x1, x4
    286	mov	x2, x5
    287	mov	x30, x3
    288	b	memcmp
    289#else
    290	ret
    291#endif
    292endfunction
    293
    294// Any SVE register modified here can cause corruption in the main
    295// thread -- but *only* the registers modified here.
    296function irritator_handler
    297	// Increment the irritation signal count (x23):
    298	ldr	x0, [x2, #ucontext_regs + 8 * 23]
    299	add	x0, x0, #1
    300	str	x0, [x2, #ucontext_regs + 8 * 23]
    301
    302	// Corrupt some random Z-regs
    303	adr	x0, .text + (irritator_handler - .text) / 16 * 16
    304	movi	v0.8b, #1
    305	movi	v9.16b, #2
    306	movi	v31.8b, #3
    307#ifndef SSVE
    308	// And P0
    309	rdffr	p0.b
    310	// And FFR
    311	wrffr	p15.b
    312#endif
    313
    314	ret
    315endfunction
    316
    317function terminate_handler
    318	mov	w21, w0
    319	mov	x20, x2
    320
    321	puts	"Terminated by signal "
    322	mov	w0, w21
    323	bl	putdec
    324	puts	", no error, iterations="
    325	ldr	x0, [x20, #ucontext_regs + 8 * 22]
    326	bl	putdec
    327	puts	", signals="
    328	ldr	x0, [x20, #ucontext_regs + 8 * 23]
    329	bl	putdecn
    330
    331	mov	x0, #0
    332	mov	x8, #__NR_exit
    333	svc	#0
    334endfunction
    335
    336// w0: signal number
    337// x1: sa_action
    338// w2: sa_flags
    339// Clobbers x0-x6,x8
    340function setsignal
    341	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
    342
    343	mov	w4, w0
    344	mov	x5, x1
    345	mov	w6, w2
    346
    347	add	x0, sp, #16
    348	mov	x1, #sa_sz
    349	bl	memclr
    350
    351	mov	w0, w4
    352	add	x1, sp, #16
    353	str	w6, [x1, #sa_flags]
    354	str	x5, [x1, #sa_handler]
    355	mov	x2, #0
    356	mov	x3, #sa_mask_sz
    357	mov	x8, #__NR_rt_sigaction
    358	svc	#0
    359
    360	cbz	w0, 1f
    361
    362	puts	"sigaction failure\n"
    363	b	.Labort
    364
    3651:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
    366	ret
    367endfunction
    368
    369// Main program entry point
    370.globl _start
    371function _start
    372_start:
    373#ifdef SSVE
    374	puts	"Streaming mode "
    375	smstart_sm
    376#endif
    377
    378	// Sanity-check and report the vector length
    379
    380	rdvl	x19, #8
    381	cmp	x19, #128
    382	b.lo	1f
    383	cmp	x19, #2048
    384	b.hi	1f
    385	tst	x19, #(8 - 1)
    386	b.eq	2f
    387
    3881:	puts	"Bad vector length: "
    389	mov	x0, x19
    390	bl	putdecn
    391	b	.Labort
    392
    3932:	puts	"Vector length:\t"
    394	mov	x0, x19
    395	bl	putdec
    396	puts	" bits\n"
    397
    398	// Obtain our PID, to ensure test pattern uniqueness between processes
    399
    400	mov	x8, #__NR_getpid
    401	svc	#0
    402	mov	x20, x0
    403
    404	puts	"PID:\t"
    405	mov	x0, x20
    406	bl	putdecn
    407
    408	mov	x23, #0		// Irritation signal count
    409
    410	mov	w0, #SIGINT
    411	adr	x1, terminate_handler
    412	mov	w2, #SA_SIGINFO
    413	bl	setsignal
    414
    415	mov	w0, #SIGTERM
    416	adr	x1, terminate_handler
    417	mov	w2, #SA_SIGINFO
    418	bl	setsignal
    419
    420	mov	w0, #SIGUSR1
    421	adr	x1, irritator_handler
    422	mov	w2, #SA_SIGINFO
    423	orr	w2, w2, #SA_NODEFER
    424	bl	setsignal
    425
    426#ifdef SSVE
    427	smstart_sm		// syscalls will have exited streaming mode
    428#endif
    429
    430	mov	x22, #0		// generation number, increments per iteration
    431.Ltest_loop:
    432	rdvl	x0, #8
    433	cmp	x0, x19
    434	b.ne	vl_barf
    435
    436	mov	x21, #0		// Set up Z-regs & shadow with test pattern
    4370:	mov	x0, x20
    438	mov	x1, x21
    439	and	x2, x22, #0xf
    440	bl	setup_zreg
    441	add	x21, x21, #1
    442	cmp	x21, #NZR
    443	b.lo	0b
    444
    445	mov	x0, x20		// Set up FFR & shadow with test pattern
    446	mov	x1, #NZR + NPR
    447	and	x2, x22, #0xf
    448	bl	setup_ffr
    449
    4500:	mov	x0, x20		// Set up P-regs & shadow with test pattern
    451	mov	x1, x21
    452	and	x2, x22, #0xf
    453	bl	setup_preg
    454	add	x21, x21, #1
    455	cmp	x21, #NZR + NPR
    456	b.lo	0b
    457
    458// Can't do this when SVE state is volatile across SVC:
    459//	mov	x8, #__NR_sched_yield	// Encourage preemption
    460//	svc	#0
    461
    462	mov	x21, #0
    4630:	mov	x0, x21
    464	bl	check_zreg
    465	add	x21, x21, #1
    466	cmp	x21, #NZR
    467	b.lo	0b
    468
    4690:	mov	x0, x21
    470	bl	check_preg
    471	add	x21, x21, #1
    472	cmp	x21, #NZR + NPR
    473	b.lo	0b
    474
    475	bl	check_ffr
    476
    477	add	x22, x22, #1
    478	b	.Ltest_loop
    479
    480.Labort:
    481	mov	x0, #0
    482	mov	x1, #SIGABRT
    483	mov	x8, #__NR_kill
    484	svc	#0
    485endfunction
    486
    487function barf
    488// fpsimd.c acitivty log dump hack
    489//	ldr	w0, =0xdeadc0de
    490//	mov	w8, #__NR_exit
    491//	svc	#0
    492// end hack
    493	mov	x10, x0	// expected data
    494	mov	x11, x1	// actual data
    495	mov	x12, x2	// data size
    496
    497	puts	"Mismatch: PID="
    498	mov	x0, x20
    499	bl	putdec
    500	puts	", iteration="
    501	mov	x0, x22
    502	bl	putdec
    503	puts	", reg="
    504	mov	x0, x21
    505	bl	putdecn
    506	puts	"\tExpected ["
    507	mov	x0, x10
    508	mov	x1, x12
    509	bl	dumphex
    510	puts	"]\n\tGot      ["
    511	mov	x0, x11
    512	mov	x1, x12
    513	bl	dumphex
    514	puts	"]\n"
    515
    516	mov	x8, #__NR_getpid
    517	svc	#0
    518// fpsimd.c acitivty log dump hack
    519//	ldr	w0, =0xdeadc0de
    520//	mov	w8, #__NR_exit
    521//	svc	#0
    522// ^ end of hack
    523	mov	x1, #SIGABRT
    524	mov	x8, #__NR_kill
    525	svc	#0
    526//	mov	x8, #__NR_exit
    527//	mov	x1, #1
    528//	svc	#0
    529endfunction
    530
    531function vl_barf
    532	mov	x10, x0
    533
    534	puts	"Bad active VL: "
    535	mov	x0, x10
    536	bl	putdecn
    537
    538	mov	x8, #__NR_exit
    539	mov	x1, #1
    540	svc	#0
    541endfunction