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

fpsimd-test.S (5625B)


      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 FPSIMD context switch test
      6// Repeatedly writes unique test patterns into each FPSIMD register
      7// and reads them back to verify integrity.
      8//
      9// for x in `seq 1 NR_CPUS`; do fpsimd-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
     17#define NVR	32
     18#define MAXVL_B	(128 / 8)
     19
     20.macro _vldr Vn:req, Xt:req
     21	ld1	{v\Vn\().2d}, [x\Xt]
     22.endm
     23
     24.macro _vstr Vn:req, Xt:req
     25	st1	{v\Vn\().2d}, [x\Xt]
     26.endm
     27
     28// Generate accessor functions to read/write programmatically selected
     29// FPSIMD registers.
     30// x0 is the register index to access
     31// x1 is the memory address to read from (getv,setp) or store to (setv,setp)
     32// All clobber x0-x2
     33define_accessor setv, NVR, _vldr
     34define_accessor getv, NVR, _vstr
     35
     36// Declare some storate space to shadow the SVE register contents:
     37.pushsection .text
     38.data
     39.align 4
     40vref:
     41	.space	MAXVL_B * NVR
     42scratch:
     43	.space	MAXVL_B
     44.popsection
     45
     46// Generate a test pattern for storage in SVE registers
     47// x0: pid	(16 bits)
     48// x1: register number (6 bits)
     49// x2: generation (4 bits)
     50function pattern
     51	orr	w1, w0, w1, lsl #16
     52	orr	w2, w1, w2, lsl #28
     53
     54	ldr	x0, =scratch
     55	mov	w1, #MAXVL_B / 4
     56
     570:	str	w2, [x0], #4
     58	add	w2, w2, #(1 << 22)
     59	subs	w1, w1, #1
     60	bne	0b
     61
     62	ret
     63endfunction
     64
     65// Get the address of shadow data for FPSIMD V-register V<xn>
     66.macro _adrv xd, xn, nrtmp
     67	ldr	\xd, =vref
     68	mov	x\nrtmp, #16
     69	madd	\xd, x\nrtmp, \xn, \xd
     70.endm
     71
     72// Set up test pattern in a FPSIMD V-register
     73// x0: pid
     74// x1: register number
     75// x2: generation
     76function setup_vreg
     77	mov	x4, x30
     78
     79	mov	x6, x1
     80	bl	pattern
     81	_adrv	x0, x6, 2
     82	mov	x5, x0
     83	ldr	x1, =scratch
     84	bl	memcpy
     85
     86	mov	x0, x6
     87	mov	x1, x5
     88	bl	setv
     89
     90	ret	x4
     91endfunction
     92
     93// Trivial memory compare: compare x2 bytes starting at address x0 with
     94// bytes starting at address x1.
     95// Returns only if all bytes match; otherwise, the program is aborted.
     96// Clobbers x0-x5.
     97function memcmp
     98	cbz	x2, 1f
     99
    100	mov	x5, #0
    1010:	ldrb	w3, [x0, x5]
    102	ldrb	w4, [x1, x5]
    103	add	x5, x5, #1
    104	cmp	w3, w4
    105	b.ne	barf
    106	subs	x2, x2, #1
    107	b.ne	0b
    108
    1091:	ret
    110endfunction
    111
    112// Verify that a FPSIMD V-register matches its shadow in memory, else abort
    113// x0: reg number
    114// Clobbers x0-x5.
    115function check_vreg
    116	mov	x3, x30
    117
    118	_adrv	x5, x0, 6
    119	mov	x4, x0
    120	ldr	x7, =scratch
    121
    122	mov	x0, x7
    123	mov	x1, x6
    124	bl	memfill_ae
    125
    126	mov	x0, x4
    127	mov	x1, x7
    128	bl	getv
    129
    130	mov	x0, x5
    131	mov	x1, x7
    132	mov	x2, x6
    133	mov	x30, x3
    134	b	memcmp
    135endfunction
    136
    137// Any SVE register modified here can cause corruption in the main
    138// thread -- but *only* the registers modified here.
    139function irritator_handler
    140	// Increment the irritation signal count (x23):
    141	ldr	x0, [x2, #ucontext_regs + 8 * 23]
    142	add	x0, x0, #1
    143	str	x0, [x2, #ucontext_regs + 8 * 23]
    144
    145	// Corrupt some random V-regs
    146	adr	x0, .text + (irritator_handler - .text) / 16 * 16
    147	movi	v0.8b, #7
    148	movi	v9.16b, #9
    149	movi	v31.8b, #31
    150
    151	ret
    152endfunction
    153
    154function terminate_handler
    155	mov	w21, w0
    156	mov	x20, x2
    157
    158	puts	"Terminated by signal "
    159	mov	w0, w21
    160	bl	putdec
    161	puts	", no error, iterations="
    162	ldr	x0, [x20, #ucontext_regs + 8 * 22]
    163	bl	putdec
    164	puts	", signals="
    165	ldr	x0, [x20, #ucontext_regs + 8 * 23]
    166	bl	putdecn
    167
    168	mov	x0, #0
    169	mov	x8, #__NR_exit
    170	svc	#0
    171endfunction
    172
    173// w0: signal number
    174// x1: sa_action
    175// w2: sa_flags
    176// Clobbers x0-x6,x8
    177function setsignal
    178	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
    179
    180	mov	w4, w0
    181	mov	x5, x1
    182	mov	w6, w2
    183
    184	add	x0, sp, #16
    185	mov	x1, #sa_sz
    186	bl	memclr
    187
    188	mov	w0, w4
    189	add	x1, sp, #16
    190	str	w6, [x1, #sa_flags]
    191	str	x5, [x1, #sa_handler]
    192	mov	x2, #0
    193	mov	x3, #sa_mask_sz
    194	mov	x8, #__NR_rt_sigaction
    195	svc	#0
    196
    197	cbz	w0, 1f
    198
    199	puts	"sigaction failure\n"
    200	b	.Labort
    201
    2021:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
    203	ret
    204endfunction
    205
    206// Main program entry point
    207.globl _start
    208function _start
    209_start:
    210	// Sanity-check and report the vector length
    211
    212	mov	x19, #128
    213	cmp	x19, #128
    214	b.lo	1f
    215	cmp	x19, #2048
    216	b.hi	1f
    217	tst	x19, #(8 - 1)
    218	b.eq	2f
    219
    2201:	puts	"Bad vector length: "
    221	mov	x0, x19
    222	bl	putdecn
    223	b	.Labort
    224
    2252:	puts	"Vector length:\t"
    226	mov	x0, x19
    227	bl	putdec
    228	puts	" bits\n"
    229
    230	// Obtain our PID, to ensure test pattern uniqueness between processes
    231
    232	mov	x8, #__NR_getpid
    233	svc	#0
    234	mov	x20, x0
    235
    236	puts	"PID:\t"
    237	mov	x0, x20
    238	bl	putdecn
    239
    240	mov	x23, #0		// Irritation signal count
    241
    242	mov	w0, #SIGINT
    243	adr	x1, terminate_handler
    244	mov	w2, #SA_SIGINFO
    245	bl	setsignal
    246
    247	mov	w0, #SIGTERM
    248	adr	x1, terminate_handler
    249	mov	w2, #SA_SIGINFO
    250	bl	setsignal
    251
    252	mov	w0, #SIGUSR1
    253	adr	x1, irritator_handler
    254	mov	w2, #SA_SIGINFO
    255	orr	w2, w2, #SA_NODEFER
    256	bl	setsignal
    257
    258	mov	x22, #0		// generation number, increments per iteration
    259.Ltest_loop:
    260
    261	mov	x21, #0		// Set up V-regs & shadow with test pattern
    2620:	mov	x0, x20
    263	mov	x1, x21
    264	and	x2, x22, #0xf
    265	bl	setup_vreg
    266	add	x21, x21, #1
    267	cmp	x21, #NVR
    268	b.lo	0b
    269
    270// Can't do this when SVE state is volatile across SVC:
    271	mov	x8, #__NR_sched_yield	// Encourage preemption
    272	svc	#0
    273
    274	mov	x21, #0
    2750:	mov	x0, x21
    276	bl	check_vreg
    277	add	x21, x21, #1
    278	cmp	x21, #NVR
    279	b.lo	0b
    280
    281	add	x22, x22, #1
    282	b	.Ltest_loop
    283
    284.Labort:
    285	mov	x0, #0
    286	mov	x1, #SIGABRT
    287	mov	x8, #__NR_kill
    288	svc	#0
    289endfunction
    290
    291function barf
    292	mov	x10, x0	// expected data
    293	mov	x11, x1	// actual data
    294	mov	x12, x2	// data size
    295
    296	puts	"Mismatch: PID="
    297	mov	x0, x20
    298	bl	putdec
    299	puts	", iteration="
    300	mov	x0, x22
    301	bl	putdec
    302	puts	", reg="
    303	mov	x0, x21
    304	bl	putdecn
    305	puts	"\tExpected ["
    306	mov	x0, x10
    307	mov	x1, x12
    308	bl	dumphex
    309	puts	"]\n\tGot      ["
    310	mov	x0, x11
    311	mov	x1, x12
    312	bl	dumphex
    313	puts	"]\n"
    314
    315	mov	x8, #__NR_exit
    316	mov	x1, #1
    317	svc	#0
    318endfunction