18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* Copyright (C) 2019 ARM Limited */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <asm/unistd.h>
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci.section        .rodata, "a"
78c2ecf20Sopenharmony_cicall_fmt:
88c2ecf20Sopenharmony_ci	.asciz "Calling sigreturn with fake sigframe sized:%zd at SP @%08lX\n"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci.text
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci.globl fake_sigreturn
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/*	fake_sigreturn	x0:&sigframe,  x1:sigframe_size,  x2:misalign_bytes */
158c2ecf20Sopenharmony_cifake_sigreturn:
168c2ecf20Sopenharmony_ci	stp	x29, x30, [sp, #-16]!
178c2ecf20Sopenharmony_ci	mov	x29, sp
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci	mov	x20, x0
208c2ecf20Sopenharmony_ci	mov	x21, x1
218c2ecf20Sopenharmony_ci	mov	x22, x2
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	/* create space on the stack for fake sigframe 16 bytes-aligned */
248c2ecf20Sopenharmony_ci	add	x0, x21, x22
258c2ecf20Sopenharmony_ci	add	x0, x0, #15
268c2ecf20Sopenharmony_ci	bic	x0, x0, #15 /* round_up(sigframe_size + misalign_bytes, 16) */
278c2ecf20Sopenharmony_ci	sub	sp, sp, x0
288c2ecf20Sopenharmony_ci	add	x23, sp, x22 /* new sigframe base with misaligment if any */
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	ldr	x0, =call_fmt
318c2ecf20Sopenharmony_ci	mov	x1, x21
328c2ecf20Sopenharmony_ci	mov	x2, x23
338c2ecf20Sopenharmony_ci	bl	printf
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* memcpy the provided content, while still keeping SP aligned */
368c2ecf20Sopenharmony_ci	mov	x0, x23
378c2ecf20Sopenharmony_ci	mov	x1, x20
388c2ecf20Sopenharmony_ci	mov	x2, x21
398c2ecf20Sopenharmony_ci	bl	memcpy
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	/*
428c2ecf20Sopenharmony_ci	 * Here saving a last minute SP to current->token acts as a marker:
438c2ecf20Sopenharmony_ci	 * if we got here, we are successfully faking a sigreturn; in other
448c2ecf20Sopenharmony_ci	 * words we are sure no bad fatal signal has been raised till now
458c2ecf20Sopenharmony_ci	 * for unrelated reasons, so we should consider the possibly observed
468c2ecf20Sopenharmony_ci	 * fatal signal like SEGV coming from Kernel restore_sigframe() and
478c2ecf20Sopenharmony_ci	 * triggered as expected from our test-case.
488c2ecf20Sopenharmony_ci	 * For simplicity this assumes that current field 'token' is laid out
498c2ecf20Sopenharmony_ci	 * as first in struct tdescr
508c2ecf20Sopenharmony_ci	 */
518c2ecf20Sopenharmony_ci	ldr	x0, current
528c2ecf20Sopenharmony_ci	str	x23, [x0]
538c2ecf20Sopenharmony_ci	/* finally move SP to misaligned address...if any requested */
548c2ecf20Sopenharmony_ci	mov	sp, x23
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	mov	x8, #__NR_rt_sigreturn
578c2ecf20Sopenharmony_ci	svc	#0
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	/*
608c2ecf20Sopenharmony_ci	 * Above sigreturn should not return...looping here leads to a timeout
618c2ecf20Sopenharmony_ci	 * and ensure proper and clean test failure, instead of jumping around
628c2ecf20Sopenharmony_ci	 * on a potentially corrupted stack.
638c2ecf20Sopenharmony_ci	 */
648c2ecf20Sopenharmony_ci	b	.
65