1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2023 ARM Limited 4 * 5 * Verify that the TPIDR2 register context in signal frames is restored. 6 */ 7 8#include <signal.h> 9#include <ucontext.h> 10#include <sys/auxv.h> 11#include <sys/prctl.h> 12#include <unistd.h> 13#include <asm/sigcontext.h> 14 15#include "test_signals_utils.h" 16#include "testcases.h" 17 18#define SYS_TPIDR2 "S3_3_C13_C0_5" 19 20static uint64_t get_tpidr2(void) 21{ 22 uint64_t val; 23 24 asm volatile ( 25 "mrs %0, " SYS_TPIDR2 "\n" 26 : "=r"(val) 27 : 28 : "cc"); 29 30 return val; 31} 32 33static void set_tpidr2(uint64_t val) 34{ 35 asm volatile ( 36 "msr " SYS_TPIDR2 ", %0\n" 37 : 38 : "r"(val) 39 : "cc"); 40} 41 42 43static uint64_t initial_tpidr2; 44 45static bool save_tpidr2(struct tdescr *td) 46{ 47 initial_tpidr2 = get_tpidr2(); 48 fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2); 49 50 return true; 51} 52 53static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 54{ 55 uint64_t my_tpidr2 = get_tpidr2(); 56 57 my_tpidr2++; 58 fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2); 59 set_tpidr2(my_tpidr2); 60 61 return 0; 62} 63 64static void check_tpidr2(struct tdescr *td) 65{ 66 uint64_t tpidr2 = get_tpidr2(); 67 68 td->pass = tpidr2 == initial_tpidr2; 69 70 if (td->pass) 71 fprintf(stderr, "TPIDR2 restored\n"); 72 else 73 fprintf(stderr, "TPIDR2 was %lx but is now %lx\n", 74 initial_tpidr2, tpidr2); 75} 76 77struct tdescr tde = { 78 .name = "TPIDR2 restore", 79 .descr = "Validate that TPIDR2 is restored from the sigframe", 80 .feats_required = FEAT_SME, 81 .timeout = 3, 82 .sig_trig = SIGUSR1, 83 .init = save_tpidr2, 84 .run = modify_tpidr2, 85 .check_result = check_tpidr2, 86}; 87