1/* 2 * Copyright 2015, Cyril Bur, IBM Corp. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10#include "basic_asm.h" 11#include "gpr_asm.h" 12#include "fpu_asm.h" 13#include "vmx_asm.h" 14#include "vsx_asm.h" 15 16/* 17 * Large caveat here being that the caller cannot expect the 18 * signal to always be sent! The hardware can (AND WILL!) abort 19 * the transaction between the tbegin and the tsuspend (however 20 * unlikely it seems or infrequently it actually happens). 21 * You have been warned. 22 */ 23/* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */ 24FUNC_START(tm_signal_self_context_load) 25 PUSH_BASIC_STACK(512) 26 /* 27 * Don't strictly need to save and restore as it depends on if 28 * we're going to use them, however this reduces messy logic 29 */ 30 PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8) 31 PUSH_FPU(512) 32 PUSH_NVREGS_BELOW_FPU(512) 33 std r3, STACK_FRAME_PARAM(0)(sp) /* pid */ 34 std r4, STACK_FRAME_PARAM(1)(sp) /* gps */ 35 std r5, STACK_FRAME_PARAM(2)(sp) /* fps */ 36 std r6, STACK_FRAME_PARAM(3)(sp) /* vms */ 37 std r7, STACK_FRAME_PARAM(4)(sp) /* vss */ 38 39 ld r3, STACK_FRAME_PARAM(1)(sp) 40 cmpdi r3, 0 41 beq skip_gpr_lc 42 bl load_gpr 43skip_gpr_lc: 44 ld r3, STACK_FRAME_PARAM(2)(sp) 45 cmpdi r3, 0 46 beq skip_fpu_lc 47 bl load_fpu 48skip_fpu_lc: 49 ld r3, STACK_FRAME_PARAM(3)(sp) 50 cmpdi r3, 0 51 beq skip_vmx_lc 52 bl load_vmx 53skip_vmx_lc: 54 ld r3, STACK_FRAME_PARAM(4)(sp) 55 cmpdi r3, 0 56 beq skip_vsx_lc 57 bl load_vsx 58skip_vsx_lc: 59 /* 60 * Set r3 (return value) before tbegin. Use the pid as a known 61 * 'all good' return value, zero is used to indicate a non-doomed 62 * transaction. 63 */ 64 ld r3, STACK_FRAME_PARAM(0)(sp) 65 tbegin. 66 beq 1f 67 tsuspend. /* Can't enter a syscall transactionally */ 68 ld r3, STACK_FRAME_PARAM(1)(sp) 69 cmpdi r3, 0 70 beq skip_gpr_lt 71 /* Get the second half of the array */ 72 addi r3, r3, 8 * 18 73 bl load_gpr 74skip_gpr_lt: 75 ld r3, STACK_FRAME_PARAM(2)(sp) 76 cmpdi r3, 0 77 beq skip_fpu_lt 78 /* Get the second half of the array */ 79 addi r3, r3, 8 * 18 80 bl load_fpu 81skip_fpu_lt: 82 ld r3, STACK_FRAME_PARAM(3)(sp) 83 cmpdi r3, 0 84 beq skip_vmx_lt 85 /* Get the second half of the array */ 86 addi r3, r3, 16 * 12 87 bl load_vmx 88skip_vmx_lt: 89 ld r3, STACK_FRAME_PARAM(4)(sp) 90 cmpdi r3, 0 91 beq skip_vsx_lt 92 /* Get the second half of the array */ 93 addi r3, r3, 16 * 12 94 bl load_vsx 95skip_vsx_lt: 96 li r0, 37 /* sys_kill */ 97 ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */ 98 li r4, 10 /* SIGUSR1 */ 99 sc /* Taking the signal will doom the transaction */ 100 tabort. 0 101 tresume. /* Be super sure we abort */ 102 /* 103 * This will cause us to resume doomed transaction and cause 104 * hardware to cleanup, we'll end up at 1: anything between 105 * tresume. and 1: shouldn't ever run. 106 */ 107 li r3, 0 108 1: 109 POP_VMX(STACK_FRAME_LOCAL(5,0),r4) 110 POP_FPU(512) 111 POP_NVREGS_BELOW_FPU(512) 112 POP_BASIC_STACK(512) 113 blr 114FUNC_END(tm_signal_self_context_load) 115