hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/arch/powerpc/kernel/signal_32.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC
34 *
....@@ -10,11 +11,6 @@
1011 * Derived from "arch/i386/kernel/signal.c"
1112 * Copyright (C) 1991, 1992 Linus Torvalds
1213 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
13
- *
14
- * This program is free software; you can redistribute it and/or
15
- * modify it under the terms of the GNU General Public License
16
- * as published by the Free Software Foundation; either version
17
- * 2 of the License, or (at your option) any later version.
1814 */
1915
2016 #include <linux/sched.h>
....@@ -51,7 +47,6 @@
5147 #include <asm/unistd.h>
5248 #else
5349 #include <asm/ucontext.h>
54
-#include <asm/pgtable.h>
5550 #endif
5651
5752 #include "signal.h"
....@@ -107,22 +102,18 @@
107102 struct mcontext __user *frame)
108103 {
109104 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
110
- int i;
111
- /* Force usr to alway see softe as 1 (interrupts enabled) */
112
- elf_greg_t64 softe = 0x1;
105
+ int val, i;
113106
114107 WARN_ON(!FULL_REGS(regs));
115108
116109 for (i = 0; i <= PT_RESULT; i ++) {
117
- if (i == 14 && !FULL_REGS(regs))
118
- i = 32;
119
- if ( i == PT_SOFTE) {
120
- if(__put_user((unsigned int)softe, &frame->mc_gregs[i]))
121
- return -EFAULT;
122
- else
123
- continue;
124
- }
125
- if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
110
+ /* Force usr to alway see softe as 1 (interrupts enabled) */
111
+ if (i == PT_SOFTE)
112
+ val = 1;
113
+ else
114
+ val = gregs[i];
115
+
116
+ if (__put_user(val, &frame->mc_gregs[i]))
126117 return -EFAULT;
127118 }
128119 return 0;
....@@ -239,146 +230,6 @@
239230 int abigap[56];
240231 };
241232
242
-#ifdef CONFIG_VSX
243
-unsigned long copy_fpr_to_user(void __user *to,
244
- struct task_struct *task)
245
-{
246
- u64 buf[ELF_NFPREG];
247
- int i;
248
-
249
- /* save FPR copy to local buffer then write to the thread_struct */
250
- for (i = 0; i < (ELF_NFPREG - 1) ; i++)
251
- buf[i] = task->thread.TS_FPR(i);
252
- buf[i] = task->thread.fp_state.fpscr;
253
- return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
254
-}
255
-
256
-unsigned long copy_fpr_from_user(struct task_struct *task,
257
- void __user *from)
258
-{
259
- u64 buf[ELF_NFPREG];
260
- int i;
261
-
262
- if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
263
- return 1;
264
- for (i = 0; i < (ELF_NFPREG - 1) ; i++)
265
- task->thread.TS_FPR(i) = buf[i];
266
- task->thread.fp_state.fpscr = buf[i];
267
-
268
- return 0;
269
-}
270
-
271
-unsigned long copy_vsx_to_user(void __user *to,
272
- struct task_struct *task)
273
-{
274
- u64 buf[ELF_NVSRHALFREG];
275
- int i;
276
-
277
- /* save FPR copy to local buffer then write to the thread_struct */
278
- for (i = 0; i < ELF_NVSRHALFREG; i++)
279
- buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
280
- return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
281
-}
282
-
283
-unsigned long copy_vsx_from_user(struct task_struct *task,
284
- void __user *from)
285
-{
286
- u64 buf[ELF_NVSRHALFREG];
287
- int i;
288
-
289
- if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
290
- return 1;
291
- for (i = 0; i < ELF_NVSRHALFREG ; i++)
292
- task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
293
- return 0;
294
-}
295
-
296
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
297
-unsigned long copy_ckfpr_to_user(void __user *to,
298
- struct task_struct *task)
299
-{
300
- u64 buf[ELF_NFPREG];
301
- int i;
302
-
303
- /* save FPR copy to local buffer then write to the thread_struct */
304
- for (i = 0; i < (ELF_NFPREG - 1) ; i++)
305
- buf[i] = task->thread.TS_CKFPR(i);
306
- buf[i] = task->thread.ckfp_state.fpscr;
307
- return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
308
-}
309
-
310
-unsigned long copy_ckfpr_from_user(struct task_struct *task,
311
- void __user *from)
312
-{
313
- u64 buf[ELF_NFPREG];
314
- int i;
315
-
316
- if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
317
- return 1;
318
- for (i = 0; i < (ELF_NFPREG - 1) ; i++)
319
- task->thread.TS_CKFPR(i) = buf[i];
320
- task->thread.ckfp_state.fpscr = buf[i];
321
-
322
- return 0;
323
-}
324
-
325
-unsigned long copy_ckvsx_to_user(void __user *to,
326
- struct task_struct *task)
327
-{
328
- u64 buf[ELF_NVSRHALFREG];
329
- int i;
330
-
331
- /* save FPR copy to local buffer then write to the thread_struct */
332
- for (i = 0; i < ELF_NVSRHALFREG; i++)
333
- buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
334
- return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
335
-}
336
-
337
-unsigned long copy_ckvsx_from_user(struct task_struct *task,
338
- void __user *from)
339
-{
340
- u64 buf[ELF_NVSRHALFREG];
341
- int i;
342
-
343
- if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
344
- return 1;
345
- for (i = 0; i < ELF_NVSRHALFREG ; i++)
346
- task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
347
- return 0;
348
-}
349
-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
350
-#else
351
-inline unsigned long copy_fpr_to_user(void __user *to,
352
- struct task_struct *task)
353
-{
354
- return __copy_to_user(to, task->thread.fp_state.fpr,
355
- ELF_NFPREG * sizeof(double));
356
-}
357
-
358
-inline unsigned long copy_fpr_from_user(struct task_struct *task,
359
- void __user *from)
360
-{
361
- return __copy_from_user(task->thread.fp_state.fpr, from,
362
- ELF_NFPREG * sizeof(double));
363
-}
364
-
365
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
366
-inline unsigned long copy_ckfpr_to_user(void __user *to,
367
- struct task_struct *task)
368
-{
369
- return __copy_to_user(to, task->thread.ckfp_state.fpr,
370
- ELF_NFPREG * sizeof(double));
371
-}
372
-
373
-inline unsigned long copy_ckfpr_from_user(struct task_struct *task,
374
- void __user *from)
375
-{
376
- return __copy_from_user(task->thread.ckfp_state.fpr, from,
377
- ELF_NFPREG * sizeof(double));
378
-}
379
-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
380
-#endif
381
-
382233 /*
383234 * Save the current user registers on the user stack.
384235 * We only save the altivec/spe registers if the process has used
....@@ -470,9 +321,9 @@
470321 return 1;
471322
472323 if (sigret) {
473
- /* Set up the sigreturn trampoline: li r0,sigret; sc */
474
- if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
475
- || __put_user(0x44000002UL, &frame->tramp[1]))
324
+ /* Set up the sigreturn trampoline: li 0,sigret; sc */
325
+ if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
326
+ || __put_user(PPC_INST_SC, &frame->tramp[1]))
476327 return 1;
477328 flush_icache_range((unsigned long) &frame->tramp[0],
478329 (unsigned long) &frame->tramp[2]);
....@@ -611,9 +462,9 @@
611462 if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
612463 return 1;
613464 if (sigret) {
614
- /* Set up the sigreturn trampoline: li r0,sigret; sc */
615
- if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
616
- || __put_user(0x44000002UL, &frame->tramp[1]))
465
+ /* Set up the sigreturn trampoline: li 0,sigret; sc */
466
+ if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
467
+ || __put_user(PPC_INST_SC, &frame->tramp[1]))
617468 return 1;
618469 flush_icache_range((unsigned long) &frame->tramp[0],
619470 (unsigned long) &frame->tramp[2]);
....@@ -644,7 +495,7 @@
644495 if (!sig)
645496 save_r2 = (unsigned int)regs->gpr[2];
646497 err = restore_general_regs(regs, sr);
647
- regs->trap = 0;
498
+ set_trap_norestart(regs);
648499 err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
649500 if (!sig)
650501 regs->gpr[2] = (unsigned long) save_r2;
....@@ -1013,7 +864,7 @@
1013864 #else
1014865 if (__get_user(mcp, &ucp->uc_regs))
1015866 return -EFAULT;
1016
- if (!access_ok(VERIFY_READ, mcp, sizeof(*mcp)))
867
+ if (!access_ok(mcp, sizeof(*mcp)))
1017868 return -EFAULT;
1018869 #endif
1019870 set_current_blocked(&set);
....@@ -1116,7 +967,7 @@
1116967 */
1117968 mctx = (struct mcontext __user *)
1118969 ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
1119
- if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
970
+ if (!access_ok(old_ctx, ctx_size)
1120971 || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
1121972 || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
1122973 || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
....@@ -1124,7 +975,7 @@
1124975 }
1125976 if (new_ctx == NULL)
1126977 return 0;
1127
- if (!access_ok(VERIFY_READ, new_ctx, ctx_size) ||
978
+ if (!access_ok(new_ctx, ctx_size) ||
1128979 fault_in_pages_readable((u8 __user *)new_ctx, ctx_size))
1129980 return -EFAULT;
1130981
....@@ -1154,18 +1005,18 @@
11541005 {
11551006 struct rt_sigframe __user *rt_sf;
11561007 struct pt_regs *regs = current_pt_regs();
1008
+ int tm_restore = 0;
11571009 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
11581010 struct ucontext __user *uc_transact;
11591011 unsigned long msr_hi;
11601012 unsigned long tmp;
1161
- int tm_restore = 0;
11621013 #endif
11631014 /* Always make any pending restarted system calls return -EINTR */
11641015 current->restart_block.fn = do_no_restart_syscall;
11651016
11661017 rt_sf = (struct rt_sigframe __user *)
11671018 (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
1168
- if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
1019
+ if (!access_ok(rt_sf, sizeof(*rt_sf)))
11691020 goto bad;
11701021
11711022 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
....@@ -1209,11 +1060,19 @@
12091060 goto bad;
12101061 }
12111062 }
1212
- if (!tm_restore)
1213
- /* Fall through, for non-TM restore */
1063
+ if (!tm_restore) {
1064
+ /*
1065
+ * Unset regs->msr because ucontext MSR TS is not
1066
+ * set, and recheckpoint was not called. This avoid
1067
+ * hitting a TM Bad thing at RFID
1068
+ */
1069
+ regs->msr &= ~MSR_TS_MASK;
1070
+ }
1071
+ /* Fall through, for non-TM restore */
12141072 #endif
1215
- if (do_setcontext(&rt_sf->uc, regs, 1))
1216
- goto bad;
1073
+ if (!tm_restore)
1074
+ if (do_setcontext(&rt_sf->uc, regs, 1))
1075
+ goto bad;
12171076
12181077 /*
12191078 * It's not clear whether or why it is desirable to save the
....@@ -1240,7 +1099,7 @@
12401099 current->comm, current->pid,
12411100 rt_sf, regs->nip, regs->link);
12421101
1243
- force_sig(SIGSEGV, current);
1102
+ force_sig(SIGSEGV);
12441103 return 0;
12451104 }
12461105
....@@ -1306,7 +1165,7 @@
13061165 current->thread.debug.dbcr0 = new_dbcr0;
13071166 #endif
13081167
1309
- if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) ||
1168
+ if (!access_ok(ctx, sizeof(*ctx)) ||
13101169 fault_in_pages_readable((u8 __user *)ctx, sizeof(*ctx)))
13111170 return -EFAULT;
13121171
....@@ -1329,7 +1188,7 @@
13291188 current->comm, current->pid,
13301189 ctx, regs->nip, regs->link);
13311190
1332
- force_sig(SIGSEGV, current);
1191
+ force_sig(SIGSEGV);
13331192 goto out;
13341193 }
13351194
....@@ -1495,7 +1354,7 @@
14951354 {
14961355 sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
14971356 addr = sr;
1498
- if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
1357
+ if (!access_ok(sr, sizeof(*sr))
14991358 || restore_user_regs(regs, sr, 1))
15001359 goto badframe;
15011360 }
....@@ -1511,6 +1370,6 @@
15111370 current->comm, current->pid,
15121371 addr, regs->nip, regs->link);
15131372
1514
- force_sig(SIGSEGV, current);
1373
+ force_sig(SIGSEGV);
15151374 return 0;
15161375 }