Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright 2015, Cyril Bur, IBM Corp.
0004  */
0005 
0006 #include "basic_asm.h"
0007 #include "gpr_asm.h"
0008 #include "fpu_asm.h"
0009 #include "vmx_asm.h"
0010 #include "vsx_asm.h"
0011 
0012 /*
0013  * Large caveat here being that the caller cannot expect the
0014  * signal to always be sent! The hardware can (AND WILL!) abort
0015  * the transaction between the tbegin and the tsuspend (however
0016  * unlikely it seems or infrequently it actually happens).
0017  * You have been warned.
0018  */
0019 /* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */
0020 FUNC_START(tm_signal_self_context_load)
0021     PUSH_BASIC_STACK(512)
0022     /*
0023      * Don't strictly need to save and restore as it depends on if
0024      * we're going to use them, however this reduces messy logic
0025      */
0026     PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8)
0027     PUSH_FPU(512)
0028     PUSH_NVREGS_BELOW_FPU(512)
0029     std r3, STACK_FRAME_PARAM(0)(sp) /* pid */
0030     std r4, STACK_FRAME_PARAM(1)(sp) /* gps */
0031     std r5, STACK_FRAME_PARAM(2)(sp) /* fps */
0032     std r6, STACK_FRAME_PARAM(3)(sp) /* vms */
0033     std r7, STACK_FRAME_PARAM(4)(sp) /* vss */
0034 
0035     ld r3, STACK_FRAME_PARAM(1)(sp)
0036     cmpdi r3, 0
0037     beq skip_gpr_lc
0038     bl load_gpr
0039 skip_gpr_lc:
0040     ld r3, STACK_FRAME_PARAM(2)(sp)
0041     cmpdi   r3, 0
0042     beq skip_fpu_lc
0043     bl load_fpu
0044 skip_fpu_lc:
0045     ld r3, STACK_FRAME_PARAM(3)(sp)
0046     cmpdi r3, 0
0047     beq skip_vmx_lc
0048     bl load_vmx
0049 skip_vmx_lc:
0050     ld r3, STACK_FRAME_PARAM(4)(sp)
0051     cmpdi   r3, 0
0052     beq skip_vsx_lc
0053     bl load_vsx
0054 skip_vsx_lc:
0055     /*
0056      * Set r3 (return value) before tbegin. Use the pid as a known
0057      * 'all good' return value, zero is used to indicate a non-doomed
0058      * transaction.
0059      */
0060     ld  r3, STACK_FRAME_PARAM(0)(sp)
0061     tbegin.
0062     beq 1f
0063     tsuspend. /* Can't enter a syscall transactionally */
0064     ld  r3, STACK_FRAME_PARAM(1)(sp)
0065     cmpdi   r3, 0
0066     beq skip_gpr_lt
0067     /* Get the second half of the array */
0068     addi    r3, r3, 8 * 18
0069     bl load_gpr
0070 skip_gpr_lt:
0071     ld r3, STACK_FRAME_PARAM(2)(sp)
0072     cmpdi   r3, 0
0073     beq skip_fpu_lt
0074     /* Get the second half of the array */
0075     addi    r3, r3, 8 * 18
0076     bl load_fpu
0077 skip_fpu_lt:
0078     ld r3, STACK_FRAME_PARAM(3)(sp)
0079     cmpdi r3, 0
0080     beq skip_vmx_lt
0081     /* Get the second half of the array */
0082     addi    r3, r3, 16 * 12
0083     bl load_vmx
0084 skip_vmx_lt:
0085     ld r3, STACK_FRAME_PARAM(4)(sp)
0086     cmpdi   r3, 0
0087     beq skip_vsx_lt
0088     /* Get the second half of the array */
0089     addi    r3, r3, 16 * 12
0090     bl load_vsx
0091 skip_vsx_lt:
0092     li  r0, 37 /* sys_kill */
0093     ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */
0094     li r4, 10 /* SIGUSR1 */
0095     sc /* Taking the signal will doom the transaction */
0096     tabort. 0
0097     tresume. /* Be super sure we abort */
0098     /*
0099      * This will cause us to resume doomed transaction and cause
0100      * hardware to cleanup, we'll end up at 1: anything between
0101      * tresume. and 1: shouldn't ever run.
0102      */
0103     li r3, 0
0104     1:
0105     POP_VMX(STACK_FRAME_LOCAL(5,0),r4)
0106     POP_FPU(512)
0107     POP_NVREGS_BELOW_FPU(512)
0108     POP_BASIC_STACK(512)
0109     blr
0110 FUNC_END(tm_signal_self_context_load)