123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /* SPDX-License-Identifier: GPL-2.0-or-later */
- /*
- * Copyright 2015, Cyril Bur, IBM Corp.
- */
- #include "basic_asm.h"
- #include "gpr_asm.h"
- #include "fpu_asm.h"
- #include "vmx_asm.h"
- #include "vsx_asm.h"
- /*
- * Large caveat here being that the caller cannot expect the
- * signal to always be sent! The hardware can (AND WILL!) abort
- * the transaction between the tbegin and the tsuspend (however
- * unlikely it seems or infrequently it actually happens).
- * You have been warned.
- */
- /* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */
- FUNC_START(tm_signal_self_context_load)
- PUSH_BASIC_STACK(512)
- /*
- * Don't strictly need to save and restore as it depends on if
- * we're going to use them, however this reduces messy logic
- */
- PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8)
- PUSH_FPU(512)
- PUSH_NVREGS_BELOW_FPU(512)
- std r3, STACK_FRAME_PARAM(0)(sp) /* pid */
- std r4, STACK_FRAME_PARAM(1)(sp) /* gps */
- std r5, STACK_FRAME_PARAM(2)(sp) /* fps */
- std r6, STACK_FRAME_PARAM(3)(sp) /* vms */
- std r7, STACK_FRAME_PARAM(4)(sp) /* vss */
- ld r3, STACK_FRAME_PARAM(1)(sp)
- cmpdi r3, 0
- beq skip_gpr_lc
- bl load_gpr
- skip_gpr_lc:
- ld r3, STACK_FRAME_PARAM(2)(sp)
- cmpdi r3, 0
- beq skip_fpu_lc
- bl load_fpu
- skip_fpu_lc:
- ld r3, STACK_FRAME_PARAM(3)(sp)
- cmpdi r3, 0
- beq skip_vmx_lc
- bl load_vmx
- skip_vmx_lc:
- ld r3, STACK_FRAME_PARAM(4)(sp)
- cmpdi r3, 0
- beq skip_vsx_lc
- bl load_vsx
- skip_vsx_lc:
- /*
- * Set r3 (return value) before tbegin. Use the pid as a known
- * 'all good' return value, zero is used to indicate a non-doomed
- * transaction.
- */
- ld r3, STACK_FRAME_PARAM(0)(sp)
- tbegin.
- beq 1f
- tsuspend. /* Can't enter a syscall transactionally */
- ld r3, STACK_FRAME_PARAM(1)(sp)
- cmpdi r3, 0
- beq skip_gpr_lt
- /* Get the second half of the array */
- addi r3, r3, 8 * 18
- bl load_gpr
- skip_gpr_lt:
- ld r3, STACK_FRAME_PARAM(2)(sp)
- cmpdi r3, 0
- beq skip_fpu_lt
- /* Get the second half of the array */
- addi r3, r3, 8 * 18
- bl load_fpu
- skip_fpu_lt:
- ld r3, STACK_FRAME_PARAM(3)(sp)
- cmpdi r3, 0
- beq skip_vmx_lt
- /* Get the second half of the array */
- addi r3, r3, 16 * 12
- bl load_vmx
- skip_vmx_lt:
- ld r3, STACK_FRAME_PARAM(4)(sp)
- cmpdi r3, 0
- beq skip_vsx_lt
- /* Get the second half of the array */
- addi r3, r3, 16 * 12
- bl load_vsx
- skip_vsx_lt:
- li r0, 37 /* sys_kill */
- ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */
- li r4, 10 /* SIGUSR1 */
- sc /* Taking the signal will doom the transaction */
- tabort. 0
- tresume. /* Be super sure we abort */
- /*
- * This will cause us to resume doomed transaction and cause
- * hardware to cleanup, we'll end up at 1: anything between
- * tresume. and 1: shouldn't ever run.
- */
- li r3, 0
- 1:
- POP_VMX(STACK_FRAME_LOCAL(5,0),r4)
- POP_FPU(512)
- POP_NVREGS_BELOW_FPU(512)
- POP_BASIC_STACK(512)
- blr
- FUNC_END(tm_signal_self_context_load)
|