forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/arch/arm64/kernel/ptrace.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Based on arch/arm/kernel/ptrace.c
34 *
....@@ -5,18 +6,6 @@
56 * edited by Linus Torvalds
67 * ARM modifications Copyright (C) 2000 Russell King
78 * Copyright (C) 2012 ARM Ltd.
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
209 */
2110
2211 #include <linux/audit.h>
....@@ -45,7 +34,8 @@
4534 #include <asm/cpufeature.h>
4635 #include <asm/debug-monitors.h>
4736 #include <asm/fpsimd.h>
48
-#include <asm/pgtable.h>
37
+#include <asm/mte.h>
38
+#include <asm/pointer_auth.h>
4939 #include <asm/stacktrace.h>
5040 #include <asm/syscall.h>
5141 #include <asm/traps.h>
....@@ -182,13 +172,7 @@
182172 struct pt_regs *regs)
183173 {
184174 struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
185
- siginfo_t info;
186
-
187
- clear_siginfo(&info);
188
- info.si_signo = SIGTRAP;
189
- info.si_errno = 0;
190
- info.si_code = TRAP_HWBKPT;
191
- info.si_addr = (void __user *)(bkpt->trigger);
175
+ const char *desc = "Hardware breakpoint trap (ptrace)";
192176
193177 #ifdef CONFIG_COMPAT
194178 if (is_compat_task()) {
....@@ -208,10 +192,11 @@
208192 break;
209193 }
210194 }
211
- force_sig_ptrace_errno_trap(si_errno, (void __user *)bkpt->trigger);
195
+ arm64_force_sig_ptrace_errno_trap(si_errno, bkpt->trigger,
196
+ desc);
212197 }
213198 #endif
214
- arm64_force_sig_info(&info, "Hardware breakpoint trap (ptrace)", current);
199
+ arm64_force_sig_fault(SIGTRAP, TRAP_HWBKPT, bkpt->trigger, desc);
215200 }
216201
217202 /*
....@@ -487,11 +472,10 @@
487472
488473 static int hw_break_get(struct task_struct *target,
489474 const struct user_regset *regset,
490
- unsigned int pos, unsigned int count,
491
- void *kbuf, void __user *ubuf)
475
+ struct membuf to)
492476 {
493477 unsigned int note_type = regset->core_note_type;
494
- int ret, idx = 0, offset, limit;
478
+ int ret, idx = 0;
495479 u32 info, ctrl;
496480 u64 addr;
497481
....@@ -500,49 +484,21 @@
500484 if (ret)
501485 return ret;
502486
503
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0,
504
- sizeof(info));
505
- if (ret)
506
- return ret;
507
-
508
- /* Pad */
509
- offset = offsetof(struct user_hwdebug_state, pad);
510
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset,
511
- offset + PTRACE_HBP_PAD_SZ);
512
- if (ret)
513
- return ret;
514
-
487
+ membuf_write(&to, &info, sizeof(info));
488
+ membuf_zero(&to, sizeof(u32));
515489 /* (address, ctrl) registers */
516
- offset = offsetof(struct user_hwdebug_state, dbg_regs);
517
- limit = regset->n * regset->size;
518
- while (count && offset < limit) {
490
+ while (to.left) {
519491 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
520492 if (ret)
521493 return ret;
522
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &addr,
523
- offset, offset + PTRACE_HBP_ADDR_SZ);
524
- if (ret)
525
- return ret;
526
- offset += PTRACE_HBP_ADDR_SZ;
527
-
528494 ret = ptrace_hbp_get_ctrl(note_type, target, idx, &ctrl);
529495 if (ret)
530496 return ret;
531
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &ctrl,
532
- offset, offset + PTRACE_HBP_CTRL_SZ);
533
- if (ret)
534
- return ret;
535
- offset += PTRACE_HBP_CTRL_SZ;
536
-
537
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
538
- offset,
539
- offset + PTRACE_HBP_PAD_SZ);
540
- if (ret)
541
- return ret;
542
- offset += PTRACE_HBP_PAD_SZ;
497
+ membuf_store(&to, addr);
498
+ membuf_store(&to, ctrl);
499
+ membuf_zero(&to, sizeof(u32));
543500 idx++;
544501 }
545
-
546502 return 0;
547503 }
548504
....@@ -602,11 +558,10 @@
602558
603559 static int gpr_get(struct task_struct *target,
604560 const struct user_regset *regset,
605
- unsigned int pos, unsigned int count,
606
- void *kbuf, void __user *ubuf)
561
+ struct membuf to)
607562 {
608563 struct user_pt_regs *uregs = &task_pt_regs(target)->user_regs;
609
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1);
564
+ return membuf_write(&to, uregs, sizeof(*uregs));
610565 }
611566
612567 static int gpr_set(struct task_struct *target, const struct user_regset *regset,
....@@ -639,8 +594,7 @@
639594 */
640595 static int __fpr_get(struct task_struct *target,
641596 const struct user_regset *regset,
642
- unsigned int pos, unsigned int count,
643
- void *kbuf, void __user *ubuf, unsigned int start_pos)
597
+ struct membuf to)
644598 {
645599 struct user_fpsimd_state *uregs;
646600
....@@ -648,13 +602,11 @@
648602
649603 uregs = &target->thread.uw.fpsimd_state;
650604
651
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs,
652
- start_pos, start_pos + sizeof(*uregs));
605
+ return membuf_write(&to, uregs, sizeof(*uregs));
653606 }
654607
655608 static int fpr_get(struct task_struct *target, const struct user_regset *regset,
656
- unsigned int pos, unsigned int count,
657
- void *kbuf, void __user *ubuf)
609
+ struct membuf to)
658610 {
659611 if (!system_supports_fpsimd())
660612 return -EINVAL;
....@@ -662,7 +614,7 @@
662614 if (target == current)
663615 fpsimd_preserve_current_state();
664616
665
- return __fpr_get(target, regset, pos, count, kbuf, ubuf, 0);
617
+ return __fpr_get(target, regset, to);
666618 }
667619
668620 static int __fpr_set(struct task_struct *target,
....@@ -712,15 +664,12 @@
712664 }
713665
714666 static int tls_get(struct task_struct *target, const struct user_regset *regset,
715
- unsigned int pos, unsigned int count,
716
- void *kbuf, void __user *ubuf)
667
+ struct membuf to)
717668 {
718
- unsigned long *tls = &target->thread.uw.tp_value;
719
-
720669 if (target == current)
721670 tls_preserve_current_state();
722671
723
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, tls, 0, -1);
672
+ return membuf_store(&to, target->thread.uw.tp_value);
724673 }
725674
726675 static int tls_set(struct task_struct *target, const struct user_regset *regset,
....@@ -740,13 +689,9 @@
740689
741690 static int system_call_get(struct task_struct *target,
742691 const struct user_regset *regset,
743
- unsigned int pos, unsigned int count,
744
- void *kbuf, void __user *ubuf)
692
+ struct membuf to)
745693 {
746
- int syscallno = task_pt_regs(target)->syscallno;
747
-
748
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
749
- &syscallno, 0, -1);
694
+ return membuf_store(&to, task_pt_regs(target)->syscallno);
750695 }
751696
752697 static int system_call_set(struct task_struct *target,
....@@ -793,24 +738,10 @@
793738 return ALIGN(header->size, SVE_VQ_BYTES);
794739 }
795740
796
-static unsigned int sve_get_size(struct task_struct *target,
797
- const struct user_regset *regset)
798
-{
799
- struct user_sve_header header;
800
-
801
- if (!system_supports_sve())
802
- return 0;
803
-
804
- sve_init_header_from_task(&header, target);
805
- return sve_size_from_header(&header);
806
-}
807
-
808741 static int sve_get(struct task_struct *target,
809742 const struct user_regset *regset,
810
- unsigned int pos, unsigned int count,
811
- void *kbuf, void __user *ubuf)
743
+ struct membuf to)
812744 {
813
- int ret;
814745 struct user_sve_header header;
815746 unsigned int vq;
816747 unsigned long start, end;
....@@ -822,10 +753,7 @@
822753 sve_init_header_from_task(&header, target);
823754 vq = sve_vq_from_vl(header.vl);
824755
825
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &header,
826
- 0, sizeof(header));
827
- if (ret)
828
- return ret;
756
+ membuf_write(&to, &header, sizeof(header));
829757
830758 if (target == current)
831759 fpsimd_preserve_current_state();
....@@ -834,26 +762,18 @@
834762
835763 BUILD_BUG_ON(SVE_PT_FPSIMD_OFFSET != sizeof(header));
836764 if ((header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
837
- return __fpr_get(target, regset, pos, count, kbuf, ubuf,
838
- SVE_PT_FPSIMD_OFFSET);
765
+ return __fpr_get(target, regset, to);
839766
840767 /* Otherwise: full SVE case */
841768
842769 BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
843770 start = SVE_PT_SVE_OFFSET;
844771 end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
845
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
846
- target->thread.sve_state,
847
- start, end);
848
- if (ret)
849
- return ret;
772
+ membuf_write(&to, target->thread.sve_state, end - start);
850773
851774 start = end;
852775 end = SVE_PT_SVE_FPSR_OFFSET(vq);
853
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
854
- start, end);
855
- if (ret)
856
- return ret;
776
+ membuf_zero(&to, end - start);
857777
858778 /*
859779 * Copy fpsr, and fpcr which must follow contiguously in
....@@ -861,16 +781,11 @@
861781 */
862782 start = end;
863783 end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
864
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
865
- &target->thread.uw.fpsimd_state.fpsr,
866
- start, end);
867
- if (ret)
868
- return ret;
784
+ membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr, end - start);
869785
870786 start = end;
871787 end = sve_size_from_header(&header);
872
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
873
- start, end);
788
+ return membuf_zero(&to, end - start);
874789 }
875790
876791 static int sve_set(struct task_struct *target,
....@@ -895,7 +810,7 @@
895810 goto out;
896811
897812 /*
898
- * Apart from PT_SVE_REGS_MASK, all PT_SVE_* flags are consumed by
813
+ * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
899814 * sve_set_vector_length(), which will also validate them for us:
900815 */
901816 ret = sve_set_vector_length(target, header.vl,
....@@ -971,6 +886,211 @@
971886
972887 #endif /* CONFIG_ARM64_SVE */
973888
889
+#ifdef CONFIG_ARM64_PTR_AUTH
890
+static int pac_mask_get(struct task_struct *target,
891
+ const struct user_regset *regset,
892
+ struct membuf to)
893
+{
894
+ /*
895
+ * The PAC bits can differ across data and instruction pointers
896
+ * depending on TCR_EL1.TBID*, which we may make use of in future, so
897
+ * we expose separate masks.
898
+ */
899
+ unsigned long mask = ptrauth_user_pac_mask();
900
+ struct user_pac_mask uregs = {
901
+ .data_mask = mask,
902
+ .insn_mask = mask,
903
+ };
904
+
905
+ if (!system_supports_address_auth())
906
+ return -EINVAL;
907
+
908
+ return membuf_write(&to, &uregs, sizeof(uregs));
909
+}
910
+
911
+static int pac_enabled_keys_get(struct task_struct *target,
912
+ const struct user_regset *regset,
913
+ struct membuf to)
914
+{
915
+ long enabled_keys = ptrauth_get_enabled_keys(target);
916
+
917
+ if (IS_ERR_VALUE(enabled_keys))
918
+ return enabled_keys;
919
+
920
+ return membuf_write(&to, &enabled_keys, sizeof(enabled_keys));
921
+}
922
+
923
+static int pac_enabled_keys_set(struct task_struct *target,
924
+ const struct user_regset *regset,
925
+ unsigned int pos, unsigned int count,
926
+ const void *kbuf, const void __user *ubuf)
927
+{
928
+ int ret;
929
+ long enabled_keys = ptrauth_get_enabled_keys(target);
930
+
931
+ if (IS_ERR_VALUE(enabled_keys))
932
+ return enabled_keys;
933
+
934
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &enabled_keys, 0,
935
+ sizeof(long));
936
+ if (ret)
937
+ return ret;
938
+
939
+ return ptrauth_set_enabled_keys(target, PR_PAC_ENABLED_KEYS_MASK,
940
+ enabled_keys);
941
+}
942
+
943
+#ifdef CONFIG_CHECKPOINT_RESTORE
944
+static __uint128_t pac_key_to_user(const struct ptrauth_key *key)
945
+{
946
+ return (__uint128_t)key->hi << 64 | key->lo;
947
+}
948
+
949
+static struct ptrauth_key pac_key_from_user(__uint128_t ukey)
950
+{
951
+ struct ptrauth_key key = {
952
+ .lo = (unsigned long)ukey,
953
+ .hi = (unsigned long)(ukey >> 64),
954
+ };
955
+
956
+ return key;
957
+}
958
+
959
+static void pac_address_keys_to_user(struct user_pac_address_keys *ukeys,
960
+ const struct ptrauth_keys_user *keys)
961
+{
962
+ ukeys->apiakey = pac_key_to_user(&keys->apia);
963
+ ukeys->apibkey = pac_key_to_user(&keys->apib);
964
+ ukeys->apdakey = pac_key_to_user(&keys->apda);
965
+ ukeys->apdbkey = pac_key_to_user(&keys->apdb);
966
+}
967
+
968
+static void pac_address_keys_from_user(struct ptrauth_keys_user *keys,
969
+ const struct user_pac_address_keys *ukeys)
970
+{
971
+ keys->apia = pac_key_from_user(ukeys->apiakey);
972
+ keys->apib = pac_key_from_user(ukeys->apibkey);
973
+ keys->apda = pac_key_from_user(ukeys->apdakey);
974
+ keys->apdb = pac_key_from_user(ukeys->apdbkey);
975
+}
976
+
977
+static int pac_address_keys_get(struct task_struct *target,
978
+ const struct user_regset *regset,
979
+ struct membuf to)
980
+{
981
+ struct ptrauth_keys_user *keys = &target->thread.keys_user;
982
+ struct user_pac_address_keys user_keys;
983
+
984
+ if (!system_supports_address_auth())
985
+ return -EINVAL;
986
+
987
+ pac_address_keys_to_user(&user_keys, keys);
988
+
989
+ return membuf_write(&to, &user_keys, sizeof(user_keys));
990
+}
991
+
992
+static int pac_address_keys_set(struct task_struct *target,
993
+ const struct user_regset *regset,
994
+ unsigned int pos, unsigned int count,
995
+ const void *kbuf, const void __user *ubuf)
996
+{
997
+ struct ptrauth_keys_user *keys = &target->thread.keys_user;
998
+ struct user_pac_address_keys user_keys;
999
+ int ret;
1000
+
1001
+ if (!system_supports_address_auth())
1002
+ return -EINVAL;
1003
+
1004
+ pac_address_keys_to_user(&user_keys, keys);
1005
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
1006
+ &user_keys, 0, -1);
1007
+ if (ret)
1008
+ return ret;
1009
+ pac_address_keys_from_user(keys, &user_keys);
1010
+
1011
+ return 0;
1012
+}
1013
+
1014
+static void pac_generic_keys_to_user(struct user_pac_generic_keys *ukeys,
1015
+ const struct ptrauth_keys_user *keys)
1016
+{
1017
+ ukeys->apgakey = pac_key_to_user(&keys->apga);
1018
+}
1019
+
1020
+static void pac_generic_keys_from_user(struct ptrauth_keys_user *keys,
1021
+ const struct user_pac_generic_keys *ukeys)
1022
+{
1023
+ keys->apga = pac_key_from_user(ukeys->apgakey);
1024
+}
1025
+
1026
+static int pac_generic_keys_get(struct task_struct *target,
1027
+ const struct user_regset *regset,
1028
+ struct membuf to)
1029
+{
1030
+ struct ptrauth_keys_user *keys = &target->thread.keys_user;
1031
+ struct user_pac_generic_keys user_keys;
1032
+
1033
+ if (!system_supports_generic_auth())
1034
+ return -EINVAL;
1035
+
1036
+ pac_generic_keys_to_user(&user_keys, keys);
1037
+
1038
+ return membuf_write(&to, &user_keys, sizeof(user_keys));
1039
+}
1040
+
1041
+static int pac_generic_keys_set(struct task_struct *target,
1042
+ const struct user_regset *regset,
1043
+ unsigned int pos, unsigned int count,
1044
+ const void *kbuf, const void __user *ubuf)
1045
+{
1046
+ struct ptrauth_keys_user *keys = &target->thread.keys_user;
1047
+ struct user_pac_generic_keys user_keys;
1048
+ int ret;
1049
+
1050
+ if (!system_supports_generic_auth())
1051
+ return -EINVAL;
1052
+
1053
+ pac_generic_keys_to_user(&user_keys, keys);
1054
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
1055
+ &user_keys, 0, -1);
1056
+ if (ret)
1057
+ return ret;
1058
+ pac_generic_keys_from_user(keys, &user_keys);
1059
+
1060
+ return 0;
1061
+}
1062
+#endif /* CONFIG_CHECKPOINT_RESTORE */
1063
+#endif /* CONFIG_ARM64_PTR_AUTH */
1064
+
1065
+#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
1066
+static int tagged_addr_ctrl_get(struct task_struct *target,
1067
+ const struct user_regset *regset,
1068
+ struct membuf to)
1069
+{
1070
+ long ctrl = get_tagged_addr_ctrl(target);
1071
+
1072
+ if (IS_ERR_VALUE(ctrl))
1073
+ return ctrl;
1074
+
1075
+ return membuf_write(&to, &ctrl, sizeof(ctrl));
1076
+}
1077
+
1078
+static int tagged_addr_ctrl_set(struct task_struct *target, const struct
1079
+ user_regset *regset, unsigned int pos,
1080
+ unsigned int count, const void *kbuf, const
1081
+ void __user *ubuf)
1082
+{
1083
+ int ret;
1084
+ long ctrl;
1085
+
1086
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
1087
+ if (ret)
1088
+ return ret;
1089
+
1090
+ return set_tagged_addr_ctrl(target, ctrl);
1091
+}
1092
+#endif
1093
+
9741094 enum aarch64_regset {
9751095 REGSET_GPR,
9761096 REGSET_FPR,
....@@ -983,6 +1103,17 @@
9831103 #ifdef CONFIG_ARM64_SVE
9841104 REGSET_SVE,
9851105 #endif
1106
+#ifdef CONFIG_ARM64_PTR_AUTH
1107
+ REGSET_PAC_MASK,
1108
+ REGSET_PAC_ENABLED_KEYS,
1109
+#ifdef CONFIG_CHECKPOINT_RESTORE
1110
+ REGSET_PACA_KEYS,
1111
+ REGSET_PACG_KEYS,
1112
+#endif
1113
+#endif
1114
+#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
1115
+ REGSET_TAGGED_ADDR_CTRL,
1116
+#endif
9861117 };
9871118
9881119 static const struct user_regset aarch64_regsets[] = {
....@@ -991,7 +1122,7 @@
9911122 .n = sizeof(struct user_pt_regs) / sizeof(u64),
9921123 .size = sizeof(u64),
9931124 .align = sizeof(u64),
994
- .get = gpr_get,
1125
+ .regset_get = gpr_get,
9951126 .set = gpr_set
9961127 },
9971128 [REGSET_FPR] = {
....@@ -1004,7 +1135,7 @@
10041135 .size = sizeof(u32),
10051136 .align = sizeof(u32),
10061137 .active = fpr_active,
1007
- .get = fpr_get,
1138
+ .regset_get = fpr_get,
10081139 .set = fpr_set
10091140 },
10101141 [REGSET_TLS] = {
....@@ -1012,7 +1143,7 @@
10121143 .n = 1,
10131144 .size = sizeof(void *),
10141145 .align = sizeof(void *),
1015
- .get = tls_get,
1146
+ .regset_get = tls_get,
10161147 .set = tls_set,
10171148 },
10181149 #ifdef CONFIG_HAVE_HW_BREAKPOINT
....@@ -1021,7 +1152,7 @@
10211152 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
10221153 .size = sizeof(u32),
10231154 .align = sizeof(u32),
1024
- .get = hw_break_get,
1155
+ .regset_get = hw_break_get,
10251156 .set = hw_break_set,
10261157 },
10271158 [REGSET_HW_WATCH] = {
....@@ -1029,7 +1160,7 @@
10291160 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
10301161 .size = sizeof(u32),
10311162 .align = sizeof(u32),
1032
- .get = hw_break_get,
1163
+ .regset_get = hw_break_get,
10331164 .set = hw_break_set,
10341165 },
10351166 #endif
....@@ -1038,7 +1169,7 @@
10381169 .n = 1,
10391170 .size = sizeof(int),
10401171 .align = sizeof(int),
1041
- .get = system_call_get,
1172
+ .regset_get = system_call_get,
10421173 .set = system_call_set,
10431174 },
10441175 #ifdef CONFIG_ARM64_SVE
....@@ -1048,9 +1179,54 @@
10481179 SVE_VQ_BYTES),
10491180 .size = SVE_VQ_BYTES,
10501181 .align = SVE_VQ_BYTES,
1051
- .get = sve_get,
1182
+ .regset_get = sve_get,
10521183 .set = sve_set,
1053
- .get_size = sve_get_size,
1184
+ },
1185
+#endif
1186
+#ifdef CONFIG_ARM64_PTR_AUTH
1187
+ [REGSET_PAC_MASK] = {
1188
+ .core_note_type = NT_ARM_PAC_MASK,
1189
+ .n = sizeof(struct user_pac_mask) / sizeof(u64),
1190
+ .size = sizeof(u64),
1191
+ .align = sizeof(u64),
1192
+ .regset_get = pac_mask_get,
1193
+ /* this cannot be set dynamically */
1194
+ },
1195
+ [REGSET_PAC_ENABLED_KEYS] = {
1196
+ .core_note_type = NT_ARM_PAC_ENABLED_KEYS,
1197
+ .n = 1,
1198
+ .size = sizeof(long),
1199
+ .align = sizeof(long),
1200
+ .regset_get = pac_enabled_keys_get,
1201
+ .set = pac_enabled_keys_set,
1202
+ },
1203
+#ifdef CONFIG_CHECKPOINT_RESTORE
1204
+ [REGSET_PACA_KEYS] = {
1205
+ .core_note_type = NT_ARM_PACA_KEYS,
1206
+ .n = sizeof(struct user_pac_address_keys) / sizeof(__uint128_t),
1207
+ .size = sizeof(__uint128_t),
1208
+ .align = sizeof(__uint128_t),
1209
+ .regset_get = pac_address_keys_get,
1210
+ .set = pac_address_keys_set,
1211
+ },
1212
+ [REGSET_PACG_KEYS] = {
1213
+ .core_note_type = NT_ARM_PACG_KEYS,
1214
+ .n = sizeof(struct user_pac_generic_keys) / sizeof(__uint128_t),
1215
+ .size = sizeof(__uint128_t),
1216
+ .align = sizeof(__uint128_t),
1217
+ .regset_get = pac_generic_keys_get,
1218
+ .set = pac_generic_keys_set,
1219
+ },
1220
+#endif
1221
+#endif
1222
+#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
1223
+ [REGSET_TAGGED_ADDR_CTRL] = {
1224
+ .core_note_type = NT_ARM_TAGGED_ADDR_CTRL,
1225
+ .n = 1,
1226
+ .size = sizeof(long),
1227
+ .align = sizeof(long),
1228
+ .regset_get = tagged_addr_ctrl_get,
1229
+ .set = tagged_addr_ctrl_set,
10541230 },
10551231 #endif
10561232 };
....@@ -1066,57 +1242,31 @@
10661242 REGSET_COMPAT_VFP,
10671243 };
10681244
1245
+static inline compat_ulong_t compat_get_user_reg(struct task_struct *task, int idx)
1246
+{
1247
+ struct pt_regs *regs = task_pt_regs(task);
1248
+
1249
+ switch (idx) {
1250
+ case 15:
1251
+ return regs->pc;
1252
+ case 16:
1253
+ return pstate_to_compat_psr(regs->pstate);
1254
+ case 17:
1255
+ return regs->orig_x0;
1256
+ default:
1257
+ return regs->regs[idx];
1258
+ }
1259
+}
1260
+
10691261 static int compat_gpr_get(struct task_struct *target,
10701262 const struct user_regset *regset,
1071
- unsigned int pos, unsigned int count,
1072
- void *kbuf, void __user *ubuf)
1263
+ struct membuf to)
10731264 {
1074
- int ret = 0;
1075
- unsigned int i, start, num_regs;
1265
+ int i = 0;
10761266
1077
- /* Calculate the number of AArch32 registers contained in count */
1078
- num_regs = count / regset->size;
1079
-
1080
- /* Convert pos into an register number */
1081
- start = pos / regset->size;
1082
-
1083
- if (start + num_regs > regset->n)
1084
- return -EIO;
1085
-
1086
- for (i = 0; i < num_regs; ++i) {
1087
- unsigned int idx = start + i;
1088
- compat_ulong_t reg;
1089
-
1090
- switch (idx) {
1091
- case 15:
1092
- reg = task_pt_regs(target)->pc;
1093
- break;
1094
- case 16:
1095
- reg = task_pt_regs(target)->pstate;
1096
- reg = pstate_to_compat_psr(reg);
1097
- break;
1098
- case 17:
1099
- reg = task_pt_regs(target)->orig_x0;
1100
- break;
1101
- default:
1102
- reg = task_pt_regs(target)->regs[idx];
1103
- }
1104
-
1105
- if (kbuf) {
1106
- memcpy(kbuf, &reg, sizeof(reg));
1107
- kbuf += sizeof(reg);
1108
- } else {
1109
- ret = copy_to_user(ubuf, &reg, sizeof(reg));
1110
- if (ret) {
1111
- ret = -EFAULT;
1112
- break;
1113
- }
1114
-
1115
- ubuf += sizeof(reg);
1116
- }
1117
- }
1118
-
1119
- return ret;
1267
+ while (to.left)
1268
+ membuf_store(&to, compat_get_user_reg(target, i++));
1269
+ return 0;
11201270 }
11211271
11221272 static int compat_gpr_set(struct task_struct *target,
....@@ -1183,12 +1333,10 @@
11831333
11841334 static int compat_vfp_get(struct task_struct *target,
11851335 const struct user_regset *regset,
1186
- unsigned int pos, unsigned int count,
1187
- void *kbuf, void __user *ubuf)
1336
+ struct membuf to)
11881337 {
11891338 struct user_fpsimd_state *uregs;
11901339 compat_ulong_t fpscr;
1191
- int ret, vregs_end_pos;
11921340
11931341 if (!system_supports_fpsimd())
11941342 return -EINVAL;
....@@ -1202,19 +1350,10 @@
12021350 * The VFP registers are packed into the fpsimd_state, so they all sit
12031351 * nicely together for us. We just need to create the fpscr separately.
12041352 */
1205
- vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t);
1206
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs,
1207
- 0, vregs_end_pos);
1208
-
1209
- if (count && !ret) {
1210
- fpscr = (uregs->fpsr & VFP_FPSCR_STAT_MASK) |
1211
- (uregs->fpcr & VFP_FPSCR_CTRL_MASK);
1212
-
1213
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fpscr,
1214
- vregs_end_pos, VFP_STATE_SIZE);
1215
- }
1216
-
1217
- return ret;
1353
+ membuf_write(&to, uregs, VFP_STATE_SIZE - sizeof(compat_ulong_t));
1354
+ fpscr = (uregs->fpsr & VFP_FPSCR_STAT_MASK) |
1355
+ (uregs->fpcr & VFP_FPSCR_CTRL_MASK);
1356
+ return membuf_store(&to, fpscr);
12181357 }
12191358
12201359 static int compat_vfp_set(struct task_struct *target,
....@@ -1249,11 +1388,10 @@
12491388 }
12501389
12511390 static int compat_tls_get(struct task_struct *target,
1252
- const struct user_regset *regset, unsigned int pos,
1253
- unsigned int count, void *kbuf, void __user *ubuf)
1391
+ const struct user_regset *regset,
1392
+ struct membuf to)
12541393 {
1255
- compat_ulong_t tls = (compat_ulong_t)target->thread.uw.tp_value;
1256
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
1394
+ return membuf_store(&to, (compat_ulong_t)target->thread.uw.tp_value);
12571395 }
12581396
12591397 static int compat_tls_set(struct task_struct *target,
....@@ -1278,7 +1416,7 @@
12781416 .n = COMPAT_ELF_NGREG,
12791417 .size = sizeof(compat_elf_greg_t),
12801418 .align = sizeof(compat_elf_greg_t),
1281
- .get = compat_gpr_get,
1419
+ .regset_get = compat_gpr_get,
12821420 .set = compat_gpr_set
12831421 },
12841422 [REGSET_COMPAT_VFP] = {
....@@ -1287,7 +1425,7 @@
12871425 .size = sizeof(compat_ulong_t),
12881426 .align = sizeof(compat_ulong_t),
12891427 .active = fpr_active,
1290
- .get = compat_vfp_get,
1428
+ .regset_get = compat_vfp_get,
12911429 .set = compat_vfp_set
12921430 },
12931431 };
....@@ -1303,7 +1441,7 @@
13031441 .n = COMPAT_ELF_NGREG,
13041442 .size = sizeof(compat_elf_greg_t),
13051443 .align = sizeof(compat_elf_greg_t),
1306
- .get = compat_gpr_get,
1444
+ .regset_get = compat_gpr_get,
13071445 .set = compat_gpr_set
13081446 },
13091447 [REGSET_FPR] = {
....@@ -1311,7 +1449,7 @@
13111449 .n = VFP_STATE_SIZE / sizeof(compat_ulong_t),
13121450 .size = sizeof(compat_ulong_t),
13131451 .align = sizeof(compat_ulong_t),
1314
- .get = compat_vfp_get,
1452
+ .regset_get = compat_vfp_get,
13151453 .set = compat_vfp_set
13161454 },
13171455 [REGSET_TLS] = {
....@@ -1319,7 +1457,7 @@
13191457 .n = 1,
13201458 .size = sizeof(compat_ulong_t),
13211459 .align = sizeof(compat_ulong_t),
1322
- .get = compat_tls_get,
1460
+ .regset_get = compat_tls_get,
13231461 .set = compat_tls_set,
13241462 },
13251463 #ifdef CONFIG_HAVE_HW_BREAKPOINT
....@@ -1328,7 +1466,7 @@
13281466 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
13291467 .size = sizeof(u32),
13301468 .align = sizeof(u32),
1331
- .get = hw_break_get,
1469
+ .regset_get = hw_break_get,
13321470 .set = hw_break_set,
13331471 },
13341472 [REGSET_HW_WATCH] = {
....@@ -1336,7 +1474,7 @@
13361474 .n = sizeof(struct user_hwdebug_state) / sizeof(u32),
13371475 .size = sizeof(u32),
13381476 .align = sizeof(u32),
1339
- .get = hw_break_get,
1477
+ .regset_get = hw_break_get,
13401478 .set = hw_break_set,
13411479 },
13421480 #endif
....@@ -1345,7 +1483,7 @@
13451483 .n = 1,
13461484 .size = sizeof(int),
13471485 .align = sizeof(int),
1348
- .get = system_call_get,
1486
+ .regset_get = system_call_get,
13491487 .set = system_call_set,
13501488 },
13511489 };
....@@ -1370,9 +1508,7 @@
13701508 else if (off == COMPAT_PT_TEXT_END_ADDR)
13711509 tmp = tsk->mm->end_code;
13721510 else if (off < sizeof(compat_elf_gregset_t))
1373
- return copy_regset_to_user(tsk, &user_aarch32_view,
1374
- REGSET_COMPAT_GPR, off,
1375
- sizeof(compat_ulong_t), ret);
1511
+ tmp = compat_get_user_reg(tsk, off >> 2);
13761512 else if (off >= COMPAT_USER_SZ)
13771513 return -EIO;
13781514 else
....@@ -1384,8 +1520,8 @@
13841520 static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
13851521 compat_ulong_t val)
13861522 {
1387
- int ret;
1388
- mm_segment_t old_fs = get_fs();
1523
+ struct pt_regs newregs = *task_pt_regs(tsk);
1524
+ unsigned int idx = off / 4;
13891525
13901526 if (off & 3 || off >= COMPAT_USER_SZ)
13911527 return -EIO;
....@@ -1393,14 +1529,25 @@
13931529 if (off >= sizeof(compat_elf_gregset_t))
13941530 return 0;
13951531
1396
- set_fs(KERNEL_DS);
1397
- ret = copy_regset_from_user(tsk, &user_aarch32_view,
1398
- REGSET_COMPAT_GPR, off,
1399
- sizeof(compat_ulong_t),
1400
- &val);
1401
- set_fs(old_fs);
1532
+ switch (idx) {
1533
+ case 15:
1534
+ newregs.pc = val;
1535
+ break;
1536
+ case 16:
1537
+ newregs.pstate = compat_psr_to_pstate(val);
1538
+ break;
1539
+ case 17:
1540
+ newregs.orig_x0 = val;
1541
+ break;
1542
+ default:
1543
+ newregs.regs[idx] = val;
1544
+ }
14021545
1403
- return ret;
1546
+ if (!valid_user_regs(&newregs.user_regs, tsk))
1547
+ return -EINVAL;
1548
+
1549
+ *task_pt_regs(tsk) = newregs;
1550
+ return 0;
14041551 }
14051552
14061553 #ifdef CONFIG_HAVE_HW_BREAKPOINT
....@@ -1625,6 +1772,12 @@
16251772 long arch_ptrace(struct task_struct *child, long request,
16261773 unsigned long addr, unsigned long data)
16271774 {
1775
+ switch (request) {
1776
+ case PTRACE_PEEKMTETAGS:
1777
+ case PTRACE_POKEMTETAGS:
1778
+ return mte_ptrace_copy_tags(child, request, addr, data);
1779
+ }
1780
+
16281781 return ptrace_request(child, request, addr, data);
16291782 }
16301783
....@@ -1640,8 +1793,20 @@
16401793 unsigned long saved_reg;
16411794
16421795 /*
1643
- * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
1644
- * used to denote syscall entry/exit:
1796
+ * We have some ABI weirdness here in the way that we handle syscall
1797
+ * exit stops because we indicate whether or not the stop has been
1798
+ * signalled from syscall entry or syscall exit by clobbering a general
1799
+ * purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee
1800
+ * and restoring its old value after the stop. This means that:
1801
+ *
1802
+ * - Any writes by the tracer to this register during the stop are
1803
+ * ignored/discarded.
1804
+ *
1805
+ * - The actual value of the register is not available during the stop,
1806
+ * so the tracer cannot save it and restore it later.
1807
+ *
1808
+ * - Syscall stops behave differently to seccomp and pseudo-step traps
1809
+ * (the latter do not nobble any registers).
16451810 */
16461811 regno = (is_compat_task() ? 12 : 7);
16471812 saved_reg = regs->regs[regno];
....@@ -1668,12 +1833,17 @@
16681833
16691834 int syscall_trace_enter(struct pt_regs *regs)
16701835 {
1671
- if (test_thread_flag(TIF_SYSCALL_TRACE))
1836
+ unsigned long flags = READ_ONCE(current_thread_info()->flags);
1837
+
1838
+ if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
16721839 tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
1840
+ if (flags & _TIF_SYSCALL_EMU)
1841
+ return NO_SYSCALL;
1842
+ }
16731843
16741844 /* Do the secure computing after ptrace; failures should be fast. */
1675
- if (secure_computing(NULL) == -1)
1676
- return -1;
1845
+ if (secure_computing() == -1)
1846
+ return NO_SYSCALL;
16771847
16781848 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
16791849 trace_sys_enter(regs, regs->syscallno);
....@@ -1691,7 +1861,7 @@
16911861 audit_syscall_exit(regs);
16921862
16931863 if (flags & _TIF_SYSCALL_TRACEPOINT)
1694
- trace_sys_exit(regs, regs_return_value(regs));
1864
+ trace_sys_exit(regs, syscall_get_return_value(current, regs));
16951865
16961866 if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
16971867 tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
....@@ -1710,8 +1880,8 @@
17101880 * We also reserve IL for the kernel; SS is handled dynamically.
17111881 */
17121882 #define SPSR_EL1_AARCH64_RES0_BITS \
1713
- (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \
1714
- GENMASK_ULL(20, 13) | GENMASK_ULL(11, 10) | GENMASK_ULL(5, 5))
1883
+ (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 26) | GENMASK_ULL(23, 22) | \
1884
+ GENMASK_ULL(20, 13) | GENMASK_ULL(5, 5))
17151885 #define SPSR_EL1_AARCH32_RES0_BITS \
17161886 (GENMASK_ULL(63, 32) | GENMASK_ULL(22, 22) | GENMASK_ULL(20, 20))
17171887