1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* Signal support for 32-bit kernel builds 3 * 4 * Copyright (C) 2001 Matthew Wilcox <willy 5 * Copyright (C) 2006 Kyle McMartin <kyle a 6 * 7 * Code was mostly borrowed from kernel/sig 8 * See kernel/signal.c for additional Copyr 9 */ 10 11 #include <linux/compat.h> 12 #include <linux/module.h> 13 #include <linux/unistd.h> 14 #include <linux/init.h> 15 #include <linux/sched.h> 16 #include <linux/syscalls.h> 17 #include <linux/types.h> 18 #include <linux/errno.h> 19 20 #include <linux/uaccess.h> 21 22 #include "signal32.h" 23 24 #define DEBUG_COMPAT_SIG 0 25 #define DEBUG_COMPAT_SIG_LEVEL 2 26 27 #if DEBUG_COMPAT_SIG 28 #define DBG(LEVEL, ...) \ 29 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \ 30 ? printk(__VA_ARGS__) : (void) 0) 31 #else 32 #define DBG(LEVEL, ...) 33 #endif 34 35 long 36 restore_sigcontext32(struct compat_sigcontext 37 struct pt_regs *regs) 38 { 39 long err = 0; 40 compat_uint_t compat_reg; 41 compat_uint_t compat_regt; 42 int regn; 43 44 /* When loading 32-bit values into 64- 45 sure to clear the upper 32-bits */ 46 DBG(2,"restore_sigcontext32: PER_LINUX 47 DBG(2,"restore_sigcontext32: sc = 0x%p 48 DBG(2,"restore_sigcontext32: compat_si 49 for(regn=0; regn < 32; regn++){ 50 err |= __get_user(compat_reg,& 51 regs->gr[regn] = compat_reg; 52 /* Load upper half */ 53 err |= __get_user(compat_regt, 54 regs->gr[regn] = ((u64)compat_ 55 DBG(3,"restore_sigcontext32: g 56 regn, regs->gr 57 } 58 DBG(2,"restore_sigcontext32: sc->sc_fr 59 /* XXX: BE WARNED FR's are 64-BIT! */ 60 err |= __copy_from_user(regs->fr, sc-> 61 62 /* Better safe than sorry, pass __get_ 63 the same size and let gcc do the up 64 64-bits */ 65 err |= __get_user(compat_reg, &sc->sc_ 66 /* Load upper half */ 67 err |= __get_user(compat_regt, &rf->rf 68 regs->iaoq[0] = ((u64)compat_regt << 3 69 DBG(2,"restore_sigcontext32: upper hal 70 DBG(2,"restore_sigcontext32: sc->sc_ia 71 &sc->sc_iaoq[0], compa 72 73 err |= __get_user(compat_reg, &sc->sc_ 74 /* Load upper half */ 75 err |= __get_user(compat_regt, &rf->rf 76 regs->iaoq[1] = ((u64)compat_regt << 3 77 DBG(2,"restore_sigcontext32: upper hal 78 DBG(2,"restore_sigcontext32: sc->sc_ia 79 &sc->sc_iaoq[1],compat 80 DBG(2,"restore_sigcontext32: iaoq is % 81 regs->iaoq[0],regs->ia 82 83 err |= __get_user(compat_reg, &sc->sc_ 84 /* Load the upper half for iasq */ 85 err |= __get_user(compat_regt, &rf->rf 86 regs->iasq[0] = ((u64)compat_regt << 3 87 DBG(2,"restore_sigcontext32: upper hal 88 89 err |= __get_user(compat_reg, &sc->sc_ 90 /* Load the upper half for iasq */ 91 err |= __get_user(compat_regt, &rf->rf 92 regs->iasq[1] = ((u64)compat_regt << 3 93 DBG(2,"restore_sigcontext32: upper hal 94 DBG(2,"restore_sigcontext32: iasq is % 95 regs->iasq[0],regs->iasq[1]); 96 97 err |= __get_user(compat_reg, &sc->sc_ 98 /* Load the upper half for sar */ 99 err |= __get_user(compat_regt, &rf->rf 100 regs->sar = ((u64)compat_regt << 32) | 101 DBG(2,"restore_sigcontext32: upper_hal 102 DBG(2,"restore_sigcontext32: sar is %# 103 DBG(2,"restore_sigcontext32: r28 is %l 104 105 return err; 106 } 107 108 /* 109 * Set up the sigcontext structure for this pr 110 * This is not an easy task if the kernel is 6 111 * that we examine the process personality to 112 * truncate for a 32-bit userspace. 113 */ 114 long 115 setup_sigcontext32(struct compat_sigcontext __ 116 struct pt_regs *regs, int in_s 117 { 118 compat_int_t flags = 0; 119 long err = 0; 120 compat_uint_t compat_reg; 121 compat_uint_t compat_regb; 122 int regn; 123 124 if (on_sig_stack((unsigned long) sc)) 125 flags |= PARISC_SC_FLAG_ONSTAC 126 127 if (in_syscall) { 128 129 DBG(1,"setup_sigcontext32: in_ 130 131 flags |= PARISC_SC_FLAG_IN_SYS 132 /* Truncate gr31 */ 133 compat_reg = (compat_uint_t)(r 134 /* regs->iaoq is undefined in 135 err |= __put_user(compat_reg, 136 DBG(2,"setup_sigcontext32: sc- 137 &sc->sc_iaoq[0 138 139 /* Store upper half */ 140 compat_reg = (compat_uint_t)(r 141 err |= __put_user(compat_reg, 142 DBG(2,"setup_sigcontext32: upp 143 144 145 compat_reg = (compat_uint_t)(r 146 err |= __put_user(compat_reg, 147 DBG(2,"setup_sigcontext32: sc- 148 &sc->sc_iaoq[1 149 /* Store upper half */ 150 compat_reg = (compat_uint_t)(( 151 err |= __put_user(compat_reg, 152 DBG(2,"setup_sigcontext32: upp 153 154 /* Truncate sr3 */ 155 compat_reg = (compat_uint_t)(r 156 err |= __put_user(compat_reg, 157 err |= __put_user(compat_reg, 158 159 /* Store upper half */ 160 compat_reg = (compat_uint_t)(r 161 err |= __put_user(compat_reg, 162 err |= __put_user(compat_reg, 163 164 DBG(2,"setup_sigcontext32: upp 165 DBG(2,"setup_sigcontext32: upp 166 DBG(1,"setup_sigcontext32: iao 167 regs->gr[31], regs->gr 168 169 } else { 170 171 compat_reg = (compat_uint_t)(r 172 err |= __put_user(compat_reg, 173 DBG(2,"setup_sigcontext32: sc- 174 &sc->sc_iaoq[0 175 /* Store upper half */ 176 compat_reg = (compat_uint_t)(r 177 err |= __put_user(compat_reg, 178 DBG(2,"setup_sigcontext32: upp 179 180 compat_reg = (compat_uint_t)(r 181 err |= __put_user(compat_reg, 182 DBG(2,"setup_sigcontext32: sc- 183 &sc->sc_iaoq[1 184 /* Store upper half */ 185 compat_reg = (compat_uint_t)(r 186 err |= __put_user(compat_reg, 187 DBG(2,"setup_sigcontext32: upp 188 189 190 compat_reg = (compat_uint_t)(r 191 err |= __put_user(compat_reg, 192 DBG(2,"setup_sigcontext32: sc- 193 &sc->sc_iasq[0 194 /* Store upper half */ 195 compat_reg = (compat_uint_t)(r 196 err |= __put_user(compat_reg, 197 DBG(2,"setup_sigcontext32: upp 198 199 200 compat_reg = (compat_uint_t)(r 201 err |= __put_user(compat_reg, 202 DBG(2,"setup_sigcontext32: sc- 203 &sc->sc_iasq[1 204 /* Store upper half */ 205 compat_reg = (compat_uint_t)(r 206 err |= __put_user(compat_reg, 207 DBG(2,"setup_sigcontext32: upp 208 209 /* Print out the IAOQ for debu 210 DBG(1,"setup_sigcontext32: ia0 211 regs->iaoq[0], regs->i 212 } 213 214 err |= __put_user(flags, &sc->sc_flags 215 216 DBG(1,"setup_sigcontext32: Truncating 217 218 for(regn=0; regn < 32; regn++){ 219 /* Truncate a general register 220 compat_reg = (compat_uint_t)(r 221 err |= __put_user(compat_reg, 222 /* Store upper half */ 223 compat_regb = (compat_uint_t)( 224 err |= __put_user(compat_regb, 225 226 /* DEBUG: Write out the "upper 227 DBG(2,"setup_sigcontext32: gr% 228 compat_regb, c 229 } 230 231 /* Copy the floating point registers ( 232 XXX: BE WARNED FR's are 64-BIT! */ 233 DBG(1,"setup_sigcontext32: Copying fro 234 "sc->sc_fr size = %#lx, regs->fr 235 sizeof(regs->fr), sizeof(sc->s 236 err |= __copy_to_user(sc->sc_fr, regs- 237 238 compat_reg = (compat_uint_t)(regs->sar 239 err |= __put_user(compat_reg, &sc->sc_ 240 DBG(2,"setup_sigcontext32: sar is %#x\ 241 /* Store upper half */ 242 compat_reg = (compat_uint_t)(regs->sar 243 err |= __put_user(compat_reg, &rf->rf_ 244 DBG(2,"setup_sigcontext32: upper half 245 DBG(1,"setup_sigcontext32: r28 is %ld\ 246 247 return err; 248 } 249
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.