Path: blob/master/tools/testing/selftests/arm64/fp/zt-test.S
26289 views
// SPDX-License-Identifier: GPL-2.0-only1// Copyright (C) 2021-2 ARM Limited.2// Original author: Mark Brown <broonie@kernel.org>3//4// Scalable Matrix Extension ZT context switch test5// Repeatedly writes unique test patterns into ZT06// and reads them back to verify integrity.78#include <asm/unistd.h>9#include "assembler.h"10#include "asm-offsets.h"11#include "sme-inst.h"1213.arch_extension sve1415#define ZT_SZ 51216#define ZT_B (ZT_SZ / 8)1718// Declare some storage space to shadow ZT register contents and a19// scratch buffer.20.pushsection .text21.data22.align 423ztref:24.space ZT_B25scratch:26.space ZT_B27.popsection282930// Generate a test pattern for storage in ZT31// x0: pid32// x1: generation3334// These values are used to construct a 32-bit pattern that is repeated in the35// scratch buffer as many times as will fit:36// bits 31:24 generation number (increments once per test_loop)37// bits 23: 8 pid38// bits 7: 0 32-bit lane index3940function pattern41mov w3, wzr42bfi w3, w0, #8, #16 // PID43bfi w3, w1, #24, #8 // Generation4445ldr x0, =scratch46mov w1, #ZT_B / 447480: str w3, [x0], #449add w3, w3, #1 // Lane50subs w1, w1, #151b.ne 0b5253ret54endfunction5556// Set up test pattern in a ZT horizontal vector57// x0: pid58// x1: generation59function setup_zt60mov x4, x306162bl pattern // Get pattern in scratch buffer63ldr x0, =ztref64ldr x1, =scratch65mov x2, #ZT_B66bl memcpy6768ldr x0, =ztref69_ldr_zt 0 // load zt0 from pointer x07071ret x472endfunction7374// Trivial memory compare: compare x2 bytes starting at address x0 with75// bytes starting at address x1.76// Returns only if all bytes match; otherwise, the program is aborted.77// Clobbers x0-x5.78function memcmp79cbz x2, 2f8081stp x0, x1, [sp, #-0x20]!82str x2, [sp, #0x10]8384mov x5, #0850: ldrb w3, [x0, x5]86ldrb w4, [x1, x5]87add x5, x5, #188cmp w3, w489b.ne 1f90subs x2, x2, #191b.ne 0b92931: ldr x2, [sp, #0x10]94ldp x0, x1, [sp], #0x2095b.ne barf96972: ret98endfunction99100// Verify that a ZT vector matches its shadow in memory, else abort101// Clobbers x0-x3102function check_zt103mov x3, x30104105ldr x0, =scratch // Poison scratch106mov x1, #ZT_B107bl memfill_ae108109ldr x0, =scratch110_str_zt 0111112ldr x0, =ztref113ldr x1, =scratch114mov x2, #ZT_B115mov x30, x3116b memcmp117endfunction118119// Modify the live SME register state, signal return will undo our changes120function irritator_handler121// Increment the irritation signal count (x23):122ldr x0, [x2, #ucontext_regs + 8 * 23]123add x0, x0, #1124str x0, [x2, #ucontext_regs + 8 * 23]125126// This will reset ZT to all bits 0127smstop128smstart_za129130ret131endfunction132133function tickle_handler134// Increment the signal count (x23):135ldr x0, [x2, #ucontext_regs + 8 * 23]136add x0, x0, #1137str x0, [x2, #ucontext_regs + 8 * 23]138139ret140endfunction141142function terminate_handler143mov w21, w0144mov x20, x2145146puts "Terminated by signal "147mov w0, w21148bl putdec149puts ", no error, iterations="150ldr x0, [x20, #ucontext_regs + 8 * 22]151bl putdec152puts ", signals="153ldr x0, [x20, #ucontext_regs + 8 * 23]154bl putdecn155156mov x0, #0157mov x8, #__NR_exit158svc #0159endfunction160161// w0: signal number162// x1: sa_action163// w2: sa_flags164// Clobbers x0-x6,x8165function setsignal166str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!167168mov w4, w0169mov x5, x1170mov w6, w2171172add x0, sp, #16173mov x1, #sa_sz174bl memclr175176mov w0, w4177add x1, sp, #16178str w6, [x1, #sa_flags]179str x5, [x1, #sa_handler]180mov x2, #0181mov x3, #sa_mask_sz182mov x8, #__NR_rt_sigaction183svc #0184185cbz w0, 1f186187puts "sigaction failure\n"188b .Labort1891901: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)191ret192endfunction193194// Main program entry point195.globl _start196function _start197enable_gcs198199mov x23, #0 // signal count200201mov w0, #SIGINT202adr x1, terminate_handler203mov w2, #SA_SIGINFO204bl setsignal205206mov w0, #SIGTERM207adr x1, terminate_handler208mov w2, #SA_SIGINFO209bl setsignal210211mov w0, #SIGUSR1212adr x1, irritator_handler213mov w2, #SA_SIGINFO214orr w2, w2, #SA_NODEFER215bl setsignal216217mov w0, #SIGUSR2218adr x1, tickle_handler219mov w2, #SA_SIGINFO220orr w2, w2, #SA_NODEFER221bl setsignal222223smstart_za224225// Obtain our PID, to ensure test pattern uniqueness between processes226mov x8, #__NR_getpid227svc #0228mov x20, x0229230puts "PID:\t"231mov x0, x20232bl putdecn233234mov x22, #0 // generation number, increments per iteration235.Ltest_loop:236mov x0, x20237mov x1, x22238bl setup_zt239240mov x8, #__NR_sched_yield // Encourage preemption241svc #0242243mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0244and x1, x0, #3245cmp x1, #2246b.ne svcr_barf247248bl check_zt249250add x22, x22, #1 // Everything still working251b .Ltest_loop252253.Labort:254mov x0, #0255mov x1, #SIGABRT256mov x8, #__NR_kill257svc #0258endfunction259260function barf261// fpsimd.c acitivty log dump hack262// ldr w0, =0xdeadc0de263// mov w8, #__NR_exit264// svc #0265// end hack266267mrs x13, S3_3_C4_C2_2268smstop269mov x10, x0 // expected data270mov x11, x1 // actual data271mov x12, x2 // data size272273puts "Mismatch: PID="274mov x0, x20275bl putdec276puts ", iteration="277mov x0, x22278bl putdec279puts "\tExpected ["280mov x0, x10281mov x1, x12282bl dumphex283puts "]\n\tGot ["284mov x0, x11285mov x1, x12286bl dumphex287puts "]\n"288puts "\tSVCR: "289mov x0, x13290bl putdecn291292mov x8, #__NR_getpid293svc #0294// fpsimd.c acitivty log dump hack295// ldr w0, =0xdeadc0de296// mov w8, #__NR_exit297// svc #0298// ^ end of hack299mov x1, #SIGABRT300mov x8, #__NR_kill301svc #0302// mov x8, #__NR_exit303// mov x1, #1304// svc #0305endfunction306307function svcr_barf308mov x10, x0309310puts "Bad SVCR: "311mov x0, x10312bl putdecn313314mov x8, #__NR_exit315mov x1, #1316svc #0317endfunction318319320