forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/arch/parisc/kernel/ptrace.c
....@@ -26,7 +26,6 @@
2626 #include <linux/audit.h>
2727
2828 #include <linux/uaccess.h>
29
-#include <asm/pgtable.h>
3029 #include <asm/processor.h>
3130 #include <asm/asm-offsets.h>
3231
....@@ -88,9 +87,9 @@
8887 ptrace_disable(task);
8988 /* Don't wake up the task, but let the
9089 parent know something happened. */
91
- force_sig_fault(SIGTRAP, TRAP_TRACE,
92
- (void __user *) (task_regs(task)->iaoq[0] & ~3),
93
- task);
90
+ force_sig_fault_to_task(SIGTRAP, TRAP_TRACE,
91
+ (void __user *) (task_regs(task)->iaoq[0] & ~3),
92
+ task);
9493 /* notify_parent(task, SIGCHLD); */
9594 return;
9695 }
....@@ -127,6 +126,12 @@
127126 unsigned long __user *datap = (unsigned long __user *)data;
128127 unsigned long tmp;
129128 long ret = -EIO;
129
+
130
+ unsigned long user_regs_struct_size = sizeof(struct user_regs_struct);
131
+#ifdef CONFIG_64BIT
132
+ if (is_compat_task())
133
+ user_regs_struct_size /= 2;
134
+#endif
130135
131136 switch (request) {
132137
....@@ -183,14 +188,14 @@
183188 return copy_regset_to_user(child,
184189 task_user_regset_view(current),
185190 REGSET_GENERAL,
186
- 0, sizeof(struct user_regs_struct),
191
+ 0, user_regs_struct_size,
187192 datap);
188193
189194 case PTRACE_SETREGS: /* Set all gp regs in the child. */
190195 return copy_regset_from_user(child,
191196 task_user_regset_view(current),
192197 REGSET_GENERAL,
193
- 0, sizeof(struct user_regs_struct),
198
+ 0, user_regs_struct_size,
194199 datap);
195200
196201 case PTRACE_GETFPREGS: /* Get the child FPU state. */
....@@ -304,6 +309,11 @@
304309 }
305310 }
306311 break;
312
+ case PTRACE_GETREGS:
313
+ case PTRACE_SETREGS:
314
+ case PTRACE_GETFPREGS:
315
+ case PTRACE_SETFPREGS:
316
+ return arch_ptrace(child, request, addr, data);
307317
308318 default:
309319 ret = compat_ptrace_request(child, request, addr, data);
....@@ -342,7 +352,7 @@
342352 }
343353
344354 /* Do the secure computing check after ptrace. */
345
- if (secure_computing(NULL) == -1)
355
+ if (secure_computing() == -1)
346356 return -1;
347357
348358 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
....@@ -392,31 +402,11 @@
392402
393403 static int fpr_get(struct task_struct *target,
394404 const struct user_regset *regset,
395
- unsigned int pos, unsigned int count,
396
- void *kbuf, void __user *ubuf)
405
+ struct membuf to)
397406 {
398407 struct pt_regs *regs = task_regs(target);
399
- __u64 *k = kbuf;
400
- __u64 __user *u = ubuf;
401
- __u64 reg;
402408
403
- pos /= sizeof(reg);
404
- count /= sizeof(reg);
405
-
406
- if (kbuf)
407
- for (; count > 0 && pos < ELF_NFPREG; --count)
408
- *k++ = regs->fr[pos++];
409
- else
410
- for (; count > 0 && pos < ELF_NFPREG; --count)
411
- if (__put_user(regs->fr[pos++], u++))
412
- return -EFAULT;
413
-
414
- kbuf = k;
415
- ubuf = u;
416
- pos *= sizeof(reg);
417
- count *= sizeof(reg);
418
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
419
- ELF_NFPREG * sizeof(reg), -1);
409
+ return membuf_write(&to, regs->fr, ELF_NFPREG * sizeof(__u64));
420410 }
421411
422412 static int fpr_set(struct task_struct *target,
....@@ -528,30 +518,14 @@
528518
529519 static int gpr_get(struct task_struct *target,
530520 const struct user_regset *regset,
531
- unsigned int pos, unsigned int count,
532
- void *kbuf, void __user *ubuf)
521
+ struct membuf to)
533522 {
534523 struct pt_regs *regs = task_regs(target);
535
- unsigned long *k = kbuf;
536
- unsigned long __user *u = ubuf;
537
- unsigned long reg;
524
+ unsigned int pos;
538525
539
- pos /= sizeof(reg);
540
- count /= sizeof(reg);
541
-
542
- if (kbuf)
543
- for (; count > 0 && pos < ELF_NGREG; --count)
544
- *k++ = get_reg(regs, pos++);
545
- else
546
- for (; count > 0 && pos < ELF_NGREG; --count)
547
- if (__put_user(get_reg(regs, pos++), u++))
548
- return -EFAULT;
549
- kbuf = k;
550
- ubuf = u;
551
- pos *= sizeof(reg);
552
- count *= sizeof(reg);
553
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
554
- ELF_NGREG * sizeof(reg), -1);
526
+ for (pos = 0; pos < ELF_NGREG; pos++)
527
+ membuf_store(&to, get_reg(regs, pos));
528
+ return 0;
555529 }
556530
557531 static int gpr_set(struct task_struct *target,
....@@ -589,12 +563,12 @@
589563 [REGSET_GENERAL] = {
590564 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
591565 .size = sizeof(long), .align = sizeof(long),
592
- .get = gpr_get, .set = gpr_set
566
+ .regset_get = gpr_get, .set = gpr_set
593567 },
594568 [REGSET_FP] = {
595569 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
596570 .size = sizeof(__u64), .align = sizeof(__u64),
597
- .get = fpr_get, .set = fpr_set
571
+ .regset_get = fpr_get, .set = fpr_set
598572 }
599573 };
600574
....@@ -608,31 +582,15 @@
608582
609583 static int gpr32_get(struct task_struct *target,
610584 const struct user_regset *regset,
611
- unsigned int pos, unsigned int count,
612
- void *kbuf, void __user *ubuf)
585
+ struct membuf to)
613586 {
614587 struct pt_regs *regs = task_regs(target);
615
- compat_ulong_t *k = kbuf;
616
- compat_ulong_t __user *u = ubuf;
617
- compat_ulong_t reg;
588
+ unsigned int pos;
618589
619
- pos /= sizeof(reg);
620
- count /= sizeof(reg);
590
+ for (pos = 0; pos < ELF_NGREG; pos++)
591
+ membuf_store(&to, (compat_ulong_t)get_reg(regs, pos));
621592
622
- if (kbuf)
623
- for (; count > 0 && pos < ELF_NGREG; --count)
624
- *k++ = get_reg(regs, pos++);
625
- else
626
- for (; count > 0 && pos < ELF_NGREG; --count)
627
- if (__put_user((compat_ulong_t) get_reg(regs, pos++), u++))
628
- return -EFAULT;
629
-
630
- kbuf = k;
631
- ubuf = u;
632
- pos *= sizeof(reg);
633
- count *= sizeof(reg);
634
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
635
- ELF_NGREG * sizeof(reg), -1);
593
+ return 0;
636594 }
637595
638596 static int gpr32_set(struct task_struct *target,
....@@ -673,12 +631,12 @@
673631 [REGSET_GENERAL] = {
674632 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
675633 .size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
676
- .get = gpr32_get, .set = gpr32_set
634
+ .regset_get = gpr32_get, .set = gpr32_set
677635 },
678636 [REGSET_FP] = {
679637 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
680638 .size = sizeof(__u64), .align = sizeof(__u64),
681
- .get = fpr_get, .set = fpr_set
639
+ .regset_get = fpr_get, .set = fpr_set
682640 }
683641 };
684642
....@@ -798,3 +756,38 @@
798756 return roff->name;
799757 return NULL;
800758 }
759
+
760
+/**
761
+ * regs_within_kernel_stack() - check the address in the stack
762
+ * @regs: pt_regs which contains kernel stack pointer.
763
+ * @addr: address which is checked.
764
+ *
765
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
766
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
767
+ */
768
+int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
769
+{
770
+ return ((addr & ~(THREAD_SIZE - 1)) ==
771
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
772
+}
773
+
774
+/**
775
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
776
+ * @regs: pt_regs which contains kernel stack pointer.
777
+ * @n: stack entry number.
778
+ *
779
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
780
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
781
+ * this returns 0.
782
+ */
783
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
784
+{
785
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
786
+
787
+ addr -= n;
788
+
789
+ if (!regs_within_kernel_stack(regs, (unsigned long)addr))
790
+ return 0;
791
+
792
+ return *addr;
793
+}