forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/arch/x86/kernel/ptrace.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* By Ross Biro 1/23/92 */
23 /*
34 * Pentium III FXSR, SSE support
....@@ -27,7 +28,6 @@
2728 #include <linux/nospec.h>
2829
2930 #include <linux/uaccess.h>
30
-#include <asm/pgtable.h>
3131 #include <asm/processor.h>
3232 #include <asm/fpu/internal.h>
3333 #include <asm/fpu/signal.h>
....@@ -40,7 +40,8 @@
4040 #include <asm/hw_breakpoint.h>
4141 #include <asm/traps.h>
4242 #include <asm/syscall.h>
43
-#include <asm/mmu_context.h>
43
+#include <asm/fsgsbase.h>
44
+#include <asm/io_bitmap.h>
4445
4546 #include "tls.h"
4647
....@@ -154,35 +155,6 @@
154155
155156 #define FLAG_MASK FLAG_MASK_32
156157
157
-/*
158
- * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
159
- * when it traps. The previous stack will be directly underneath the saved
160
- * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
161
- *
162
- * Now, if the stack is empty, '&regs->sp' is out of range. In this
163
- * case we try to take the previous stack. To always return a non-null
164
- * stack pointer we fall back to regs as stack if no previous stack
165
- * exists.
166
- *
167
- * This is valid only for kernel mode traps.
168
- */
169
-unsigned long kernel_stack_pointer(struct pt_regs *regs)
170
-{
171
- unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
172
- unsigned long sp = (unsigned long)&regs->sp;
173
- u32 *prev_esp;
174
-
175
- if (context == (sp & ~(THREAD_SIZE - 1)))
176
- return sp;
177
-
178
- prev_esp = (u32 *)(context);
179
- if (*prev_esp)
180
- return (unsigned long)*prev_esp;
181
-
182
- return (unsigned long)regs;
183
-}
184
-EXPORT_SYMBOL_GPL(kernel_stack_pointer);
185
-
186158 static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
187159 {
188160 BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
....@@ -209,6 +181,9 @@
209181 static int set_segment_reg(struct task_struct *task,
210182 unsigned long offset, u16 value)
211183 {
184
+ if (WARN_ON_ONCE(task == current))
185
+ return -EIO;
186
+
212187 /*
213188 * The value argument was already truncated to 16 bits.
214189 */
....@@ -229,16 +204,14 @@
229204 case offsetof(struct user_regs_struct, ss):
230205 if (unlikely(value == 0))
231206 return -EIO;
207
+ fallthrough;
232208
233209 default:
234210 *pt_regs_access(task_pt_regs(task), offset) = value;
235211 break;
236212
237213 case offsetof(struct user_regs_struct, gs):
238
- if (task == current)
239
- set_user_gs(task_pt_regs(task), value);
240
- else
241
- task_user_gs(task) = value;
214
+ task_user_gs(task) = value;
242215 }
243216
244217 return 0;
....@@ -298,32 +271,33 @@
298271 static int set_segment_reg(struct task_struct *task,
299272 unsigned long offset, u16 value)
300273 {
274
+ if (WARN_ON_ONCE(task == current))
275
+ return -EIO;
276
+
301277 /*
302278 * The value argument was already truncated to 16 bits.
303279 */
304280 if (invalid_selector(value))
305281 return -EIO;
306282
283
+ /*
284
+ * Writes to FS and GS will change the stored selector. Whether
285
+ * this changes the segment base as well depends on whether
286
+ * FSGSBASE is enabled.
287
+ */
288
+
307289 switch (offset) {
308290 case offsetof(struct user_regs_struct,fs):
309291 task->thread.fsindex = value;
310
- if (task == current)
311
- loadsegment(fs, task->thread.fsindex);
312292 break;
313293 case offsetof(struct user_regs_struct,gs):
314294 task->thread.gsindex = value;
315
- if (task == current)
316
- load_gs_index(task->thread.gsindex);
317295 break;
318296 case offsetof(struct user_regs_struct,ds):
319297 task->thread.ds = value;
320
- if (task == current)
321
- loadsegment(ds, task->thread.ds);
322298 break;
323299 case offsetof(struct user_regs_struct,es):
324300 task->thread.es = value;
325
- if (task == current)
326
- loadsegment(es, task->thread.es);
327301 break;
328302
329303 /*
....@@ -342,49 +316,6 @@
342316 }
343317
344318 return 0;
345
-}
346
-
347
-static unsigned long task_seg_base(struct task_struct *task,
348
- unsigned short selector)
349
-{
350
- unsigned short idx = selector >> 3;
351
- unsigned long base;
352
-
353
- if (likely((selector & SEGMENT_TI_MASK) == 0)) {
354
- if (unlikely(idx >= GDT_ENTRIES))
355
- return 0;
356
-
357
- /*
358
- * There are no user segments in the GDT with nonzero bases
359
- * other than the TLS segments.
360
- */
361
- if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
362
- return 0;
363
-
364
- idx -= GDT_ENTRY_TLS_MIN;
365
- base = get_desc_base(&task->thread.tls_array[idx]);
366
- } else {
367
-#ifdef CONFIG_MODIFY_LDT_SYSCALL
368
- struct ldt_struct *ldt;
369
-
370
- /*
371
- * If performance here mattered, we could protect the LDT
372
- * with RCU. This is a slow path, though, so we can just
373
- * take the mutex.
374
- */
375
- mutex_lock(&task->mm->context.lock);
376
- ldt = task->mm->context.ldt;
377
- if (unlikely(!ldt || idx >= ldt->nr_entries))
378
- base = 0;
379
- else
380
- base = get_desc_base(ldt->entries + idx);
381
- mutex_unlock(&task->mm->context.lock);
382
-#else
383
- base = 0;
384
-#endif
385
- }
386
-
387
- return base;
388319 }
389320
390321 #endif /* CONFIG_X86_32 */
....@@ -440,22 +371,12 @@
440371 case offsetof(struct user_regs_struct,fs_base):
441372 if (value >= TASK_SIZE_MAX)
442373 return -EIO;
443
- /*
444
- * When changing the segment base, use do_arch_prctl_64
445
- * to set either thread.fs or thread.fsindex and the
446
- * corresponding GDT slot.
447
- */
448
- if (child->thread.fsbase != value)
449
- return do_arch_prctl_64(child, ARCH_SET_FS, value);
374
+ x86_fsbase_write_task(child, value);
450375 return 0;
451376 case offsetof(struct user_regs_struct,gs_base):
452
- /*
453
- * Exactly the same here as the %fs handling above.
454
- */
455377 if (value >= TASK_SIZE_MAX)
456378 return -EIO;
457
- if (child->thread.gsbase != value)
458
- return do_arch_prctl_64(child, ARCH_SET_GS, value);
379
+ x86_gsbase_write_task(child, value);
459380 return 0;
460381 #endif
461382 }
....@@ -479,18 +400,10 @@
479400 return get_flags(task);
480401
481402 #ifdef CONFIG_X86_64
482
- case offsetof(struct user_regs_struct, fs_base): {
483
- if (task->thread.fsindex == 0)
484
- return task->thread.fsbase;
485
- else
486
- return task_seg_base(task, task->thread.fsindex);
487
- }
488
- case offsetof(struct user_regs_struct, gs_base): {
489
- if (task->thread.gsindex == 0)
490
- return task->thread.gsbase;
491
- else
492
- return task_seg_base(task, task->thread.gsindex);
493
- }
403
+ case offsetof(struct user_regs_struct, fs_base):
404
+ return x86_fsbase_read_task(task);
405
+ case offsetof(struct user_regs_struct, gs_base):
406
+ return x86_gsbase_read_task(task);
494407 #endif
495408 }
496409
....@@ -499,26 +412,12 @@
499412
500413 static int genregs_get(struct task_struct *target,
501414 const struct user_regset *regset,
502
- unsigned int pos, unsigned int count,
503
- void *kbuf, void __user *ubuf)
415
+ struct membuf to)
504416 {
505
- if (kbuf) {
506
- unsigned long *k = kbuf;
507
- while (count >= sizeof(*k)) {
508
- *k++ = getreg(target, pos);
509
- count -= sizeof(*k);
510
- pos += sizeof(*k);
511
- }
512
- } else {
513
- unsigned long __user *u = ubuf;
514
- while (count >= sizeof(*u)) {
515
- if (__put_user(getreg(target, pos), u++))
516
- return -EFAULT;
517
- count -= sizeof(*u);
518
- pos += sizeof(*u);
519
- }
520
- }
417
+ int reg;
521418
419
+ for (reg = 0; to.left; reg++)
420
+ membuf_store(&to, getreg(target, reg * sizeof(unsigned long)));
522421 return 0;
523422 }
524423
....@@ -566,7 +465,7 @@
566465 break;
567466 }
568467
569
- thread->debugreg6 |= (DR_TRAP0 << i);
468
+ thread->virtual_dr6 |= (DR_TRAP0 << i);
570469 }
571470
572471 /*
....@@ -702,7 +601,7 @@
702601 if (bp)
703602 val = bp->hw.info.address;
704603 } else if (n == 6) {
705
- val = thread->debugreg6;
604
+ val = thread->virtual_dr6 ^ DR6_RESERVED; /* Flip back to arch polarity */
706605 } else if (n == 7) {
707606 val = thread->ptrace_dr7;
708607 }
....@@ -758,7 +657,7 @@
758657 if (n < HBP_NUM) {
759658 rc = ptrace_set_breakpoint_addr(tsk, n, val);
760659 } else if (n == 6) {
761
- thread->debugreg6 = val;
660
+ thread->virtual_dr6 = val ^ DR6_RESERVED; /* Flip to positive polarity */
762661 rc = 0;
763662 } else if (n == 7) {
764663 rc = ptrace_write_dr7(tsk, val);
....@@ -775,20 +674,21 @@
775674 static int ioperm_active(struct task_struct *target,
776675 const struct user_regset *regset)
777676 {
778
- return target->thread.io_bitmap_max / regset->size;
677
+ struct io_bitmap *iobm = target->thread.io_bitmap;
678
+
679
+ return iobm ? DIV_ROUND_UP(iobm->max, regset->size) : 0;
779680 }
780681
781682 static int ioperm_get(struct task_struct *target,
782683 const struct user_regset *regset,
783
- unsigned int pos, unsigned int count,
784
- void *kbuf, void __user *ubuf)
684
+ struct membuf to)
785685 {
786
- if (!target->thread.io_bitmap_ptr)
686
+ struct io_bitmap *iobm = target->thread.io_bitmap;
687
+
688
+ if (!iobm)
787689 return -ENXIO;
788690
789
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
790
- target->thread.io_bitmap_ptr,
791
- 0, IO_BITMAP_BYTES);
691
+ return membuf_write(&to, iobm->bitmap, IO_BITMAP_BYTES);
792692 }
793693
794694 /*
....@@ -799,9 +699,6 @@
799699 void ptrace_disable(struct task_struct *child)
800700 {
801701 user_disable_single_step(child);
802
-#ifdef TIF_SYSCALL_EMU
803
- clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
804
-#endif
805702 }
806703
807704 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
....@@ -946,14 +843,39 @@
946843 static int putreg32(struct task_struct *child, unsigned regno, u32 value)
947844 {
948845 struct pt_regs *regs = task_pt_regs(child);
846
+ int ret;
949847
950848 switch (regno) {
951849
952850 SEG32(cs);
953851 SEG32(ds);
954852 SEG32(es);
955
- SEG32(fs);
956
- SEG32(gs);
853
+
854
+ /*
855
+ * A 32-bit ptracer on a 64-bit kernel expects that writing
856
+ * FS or GS will also update the base. This is needed for
857
+ * operations like PTRACE_SETREGS to fully restore a saved
858
+ * CPU state.
859
+ */
860
+
861
+ case offsetof(struct user32, regs.fs):
862
+ ret = set_segment_reg(child,
863
+ offsetof(struct user_regs_struct, fs),
864
+ value);
865
+ if (ret == 0)
866
+ child->thread.fsbase =
867
+ x86_fsgsbase_read_task(child, value);
868
+ return ret;
869
+
870
+ case offsetof(struct user32, regs.gs):
871
+ ret = set_segment_reg(child,
872
+ offsetof(struct user_regs_struct, gs),
873
+ value);
874
+ if (ret == 0)
875
+ child->thread.gsbase =
876
+ x86_fsgsbase_read_task(child, value);
877
+ return ret;
878
+
957879 SEG32(ss);
958880
959881 R32(ebx, bx);
....@@ -1069,28 +991,15 @@
1069991
1070992 static int genregs32_get(struct task_struct *target,
1071993 const struct user_regset *regset,
1072
- unsigned int pos, unsigned int count,
1073
- void *kbuf, void __user *ubuf)
994
+ struct membuf to)
1074995 {
1075
- if (kbuf) {
1076
- compat_ulong_t *k = kbuf;
1077
- while (count >= sizeof(*k)) {
1078
- getreg32(target, pos, k++);
1079
- count -= sizeof(*k);
1080
- pos += sizeof(*k);
1081
- }
1082
- } else {
1083
- compat_ulong_t __user *u = ubuf;
1084
- while (count >= sizeof(*u)) {
1085
- compat_ulong_t word;
1086
- getreg32(target, pos, &word);
1087
- if (__put_user(word, u++))
1088
- return -EFAULT;
1089
- count -= sizeof(*u);
1090
- pos += sizeof(*u);
1091
- }
1092
- }
996
+ int reg;
1093997
998
+ for (reg = 0; to.left; reg++) {
999
+ u32 val;
1000
+ getreg32(target, reg * 4, &val);
1001
+ membuf_store(&to, val);
1002
+ }
10941003 return 0;
10951004 }
10961005
....@@ -1300,25 +1209,25 @@
13001209 .core_note_type = NT_PRSTATUS,
13011210 .n = sizeof(struct user_regs_struct) / sizeof(long),
13021211 .size = sizeof(long), .align = sizeof(long),
1303
- .get = genregs_get, .set = genregs_set
1212
+ .regset_get = genregs_get, .set = genregs_set
13041213 },
13051214 [REGSET_FP] = {
13061215 .core_note_type = NT_PRFPREG,
13071216 .n = sizeof(struct user_i387_struct) / sizeof(long),
13081217 .size = sizeof(long), .align = sizeof(long),
1309
- .active = regset_xregset_fpregs_active, .get = xfpregs_get, .set = xfpregs_set
1218
+ .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set
13101219 },
13111220 [REGSET_XSTATE] = {
13121221 .core_note_type = NT_X86_XSTATE,
13131222 .size = sizeof(u64), .align = sizeof(u64),
1314
- .active = xstateregs_active, .get = xstateregs_get,
1223
+ .active = xstateregs_active, .regset_get = xstateregs_get,
13151224 .set = xstateregs_set
13161225 },
13171226 [REGSET_IOPERM64] = {
13181227 .core_note_type = NT_386_IOPERM,
13191228 .n = IO_BITMAP_LONGS,
13201229 .size = sizeof(long), .align = sizeof(long),
1321
- .active = ioperm_active, .get = ioperm_get
1230
+ .active = ioperm_active, .regset_get = ioperm_get
13221231 },
13231232 };
13241233
....@@ -1341,24 +1250,24 @@
13411250 .core_note_type = NT_PRSTATUS,
13421251 .n = sizeof(struct user_regs_struct32) / sizeof(u32),
13431252 .size = sizeof(u32), .align = sizeof(u32),
1344
- .get = genregs32_get, .set = genregs32_set
1253
+ .regset_get = genregs32_get, .set = genregs32_set
13451254 },
13461255 [REGSET_FP] = {
13471256 .core_note_type = NT_PRFPREG,
13481257 .n = sizeof(struct user_i387_ia32_struct) / sizeof(u32),
13491258 .size = sizeof(u32), .align = sizeof(u32),
1350
- .active = regset_fpregs_active, .get = fpregs_get, .set = fpregs_set
1259
+ .active = regset_fpregs_active, .regset_get = fpregs_get, .set = fpregs_set
13511260 },
13521261 [REGSET_XFP] = {
13531262 .core_note_type = NT_PRXFPREG,
13541263 .n = sizeof(struct user32_fxsr_struct) / sizeof(u32),
13551264 .size = sizeof(u32), .align = sizeof(u32),
1356
- .active = regset_xregset_fpregs_active, .get = xfpregs_get, .set = xfpregs_set
1265
+ .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set
13571266 },
13581267 [REGSET_XSTATE] = {
13591268 .core_note_type = NT_X86_XSTATE,
13601269 .size = sizeof(u64), .align = sizeof(u64),
1361
- .active = xstateregs_active, .get = xstateregs_get,
1270
+ .active = xstateregs_active, .regset_get = xstateregs_get,
13621271 .set = xstateregs_set
13631272 },
13641273 [REGSET_TLS] = {
....@@ -1367,13 +1276,13 @@
13671276 .size = sizeof(struct user_desc),
13681277 .align = sizeof(struct user_desc),
13691278 .active = regset_tls_active,
1370
- .get = regset_tls_get, .set = regset_tls_set
1279
+ .regset_get = regset_tls_get, .set = regset_tls_set
13711280 },
13721281 [REGSET_IOPERM32] = {
13731282 .core_note_type = NT_386_IOPERM,
13741283 .n = IO_BITMAP_BYTES / sizeof(u32),
13751284 .size = sizeof(u32), .align = sizeof(u32),
1376
- .active = ioperm_active, .get = ioperm_get
1285
+ .active = ioperm_active, .regset_get = ioperm_get
13771286 },
13781287 };
13791288
....@@ -1413,33 +1322,19 @@
14131322 #endif
14141323 }
14151324
1416
-static void fill_sigtrap_info(struct task_struct *tsk,
1417
- struct pt_regs *regs,
1418
- int error_code, int si_code,
1419
- struct siginfo *info)
1325
+void send_sigtrap(struct pt_regs *regs, int error_code, int si_code)
14201326 {
1327
+ struct task_struct *tsk = current;
1328
+
14211329 tsk->thread.trap_nr = X86_TRAP_DB;
14221330 tsk->thread.error_code = error_code;
14231331
1424
- info->si_signo = SIGTRAP;
1425
- info->si_code = si_code;
1426
- info->si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
1427
-}
1428
-
1429
-void user_single_step_siginfo(struct task_struct *tsk,
1430
- struct pt_regs *regs,
1431
- struct siginfo *info)
1432
-{
1433
- fill_sigtrap_info(tsk, regs, 0, TRAP_BRKPT, info);
1434
-}
1435
-
1436
-void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
1437
- int error_code, int si_code)
1438
-{
1439
- struct siginfo info;
1440
-
1441
- clear_siginfo(&info);
1442
- fill_sigtrap_info(tsk, regs, error_code, si_code, &info);
14431332 /* Send us the fake SIGTRAP */
1444
- force_sig_info(SIGTRAP, &info, tsk);
1333
+ force_sig_fault(SIGTRAP, si_code,
1334
+ user_mode(regs) ? (void __user *)regs->ip : NULL);
1335
+}
1336
+
1337
+void user_single_step_report(struct pt_regs *regs)
1338
+{
1339
+ send_sigtrap(regs, 0, TRAP_BRKPT);
14451340 }