diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 209 |
1 files changed, 105 insertions, 104 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 9a0d24c390a3..75fb40498b41 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -362,7 +362,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, | |||
362 | void *kbuf, void __user *ubuf) | 362 | void *kbuf, void __user *ubuf) |
363 | { | 363 | { |
364 | #ifdef CONFIG_VSX | 364 | #ifdef CONFIG_VSX |
365 | double buf[33]; | 365 | u64 buf[33]; |
366 | int i; | 366 | int i; |
367 | #endif | 367 | #endif |
368 | flush_fp_to_thread(target); | 368 | flush_fp_to_thread(target); |
@@ -371,15 +371,15 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, | |||
371 | /* copy to local buffer then write that out */ | 371 | /* copy to local buffer then write that out */ |
372 | for (i = 0; i < 32 ; i++) | 372 | for (i = 0; i < 32 ; i++) |
373 | buf[i] = target->thread.TS_FPR(i); | 373 | buf[i] = target->thread.TS_FPR(i); |
374 | memcpy(&buf[32], &target->thread.fpscr, sizeof(double)); | 374 | buf[32] = target->thread.fp_state.fpscr; |
375 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); | 375 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); |
376 | 376 | ||
377 | #else | 377 | #else |
378 | BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != | 378 | BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != |
379 | offsetof(struct thread_struct, TS_FPR(32))); | 379 | offsetof(struct thread_fp_state, fpr[32][0])); |
380 | 380 | ||
381 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 381 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
382 | &target->thread.fpr, 0, -1); | 382 | &target->thread.fp_state, 0, -1); |
383 | #endif | 383 | #endif |
384 | } | 384 | } |
385 | 385 | ||
@@ -388,7 +388,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, | |||
388 | const void *kbuf, const void __user *ubuf) | 388 | const void *kbuf, const void __user *ubuf) |
389 | { | 389 | { |
390 | #ifdef CONFIG_VSX | 390 | #ifdef CONFIG_VSX |
391 | double buf[33]; | 391 | u64 buf[33]; |
392 | int i; | 392 | int i; |
393 | #endif | 393 | #endif |
394 | flush_fp_to_thread(target); | 394 | flush_fp_to_thread(target); |
@@ -400,14 +400,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, | |||
400 | return i; | 400 | return i; |
401 | for (i = 0; i < 32 ; i++) | 401 | for (i = 0; i < 32 ; i++) |
402 | target->thread.TS_FPR(i) = buf[i]; | 402 | target->thread.TS_FPR(i) = buf[i]; |
403 | memcpy(&target->thread.fpscr, &buf[32], sizeof(double)); | 403 | target->thread.fp_state.fpscr = buf[32]; |
404 | return 0; | 404 | return 0; |
405 | #else | 405 | #else |
406 | BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != | 406 | BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != |
407 | offsetof(struct thread_struct, TS_FPR(32))); | 407 | offsetof(struct thread_fp_state, fpr[32][0])); |
408 | 408 | ||
409 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 409 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
410 | &target->thread.fpr, 0, -1); | 410 | &target->thread.fp_state, 0, -1); |
411 | #endif | 411 | #endif |
412 | } | 412 | } |
413 | 413 | ||
@@ -440,11 +440,11 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset, | |||
440 | 440 | ||
441 | flush_altivec_to_thread(target); | 441 | flush_altivec_to_thread(target); |
442 | 442 | ||
443 | BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != | 443 | BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != |
444 | offsetof(struct thread_struct, vr[32])); | 444 | offsetof(struct thread_vr_state, vr[32])); |
445 | 445 | ||
446 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 446 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
447 | &target->thread.vr, 0, | 447 | &target->thread.vr_state, 0, |
448 | 33 * sizeof(vector128)); | 448 | 33 * sizeof(vector128)); |
449 | if (!ret) { | 449 | if (!ret) { |
450 | /* | 450 | /* |
@@ -471,11 +471,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset, | |||
471 | 471 | ||
472 | flush_altivec_to_thread(target); | 472 | flush_altivec_to_thread(target); |
473 | 473 | ||
474 | BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != | 474 | BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != |
475 | offsetof(struct thread_struct, vr[32])); | 475 | offsetof(struct thread_vr_state, vr[32])); |
476 | 476 | ||
477 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 477 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
478 | &target->thread.vr, 0, 33 * sizeof(vector128)); | 478 | &target->thread.vr_state, 0, |
479 | 33 * sizeof(vector128)); | ||
479 | if (!ret && count > 0) { | 480 | if (!ret && count > 0) { |
480 | /* | 481 | /* |
481 | * We use only the first word of vrsave. | 482 | * We use only the first word of vrsave. |
@@ -514,13 +515,13 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset, | |||
514 | unsigned int pos, unsigned int count, | 515 | unsigned int pos, unsigned int count, |
515 | void *kbuf, void __user *ubuf) | 516 | void *kbuf, void __user *ubuf) |
516 | { | 517 | { |
517 | double buf[32]; | 518 | u64 buf[32]; |
518 | int ret, i; | 519 | int ret, i; |
519 | 520 | ||
520 | flush_vsx_to_thread(target); | 521 | flush_vsx_to_thread(target); |
521 | 522 | ||
522 | for (i = 0; i < 32 ; i++) | 523 | for (i = 0; i < 32 ; i++) |
523 | buf[i] = target->thread.fpr[i][TS_VSRLOWOFFSET]; | 524 | buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; |
524 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 525 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
525 | buf, 0, 32 * sizeof(double)); | 526 | buf, 0, 32 * sizeof(double)); |
526 | 527 | ||
@@ -531,7 +532,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset, | |||
531 | unsigned int pos, unsigned int count, | 532 | unsigned int pos, unsigned int count, |
532 | const void *kbuf, const void __user *ubuf) | 533 | const void *kbuf, const void __user *ubuf) |
533 | { | 534 | { |
534 | double buf[32]; | 535 | u64 buf[32]; |
535 | int ret,i; | 536 | int ret,i; |
536 | 537 | ||
537 | flush_vsx_to_thread(target); | 538 | flush_vsx_to_thread(target); |
@@ -539,7 +540,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset, | |||
539 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 540 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
540 | buf, 0, 32 * sizeof(double)); | 541 | buf, 0, 32 * sizeof(double)); |
541 | for (i = 0; i < 32 ; i++) | 542 | for (i = 0; i < 32 ; i++) |
542 | target->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; | 543 | target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; |
543 | 544 | ||
544 | 545 | ||
545 | return ret; | 546 | return ret; |
@@ -657,7 +658,7 @@ static const struct user_regset native_regsets[] = { | |||
657 | #endif | 658 | #endif |
658 | #ifdef CONFIG_SPE | 659 | #ifdef CONFIG_SPE |
659 | [REGSET_SPE] = { | 660 | [REGSET_SPE] = { |
660 | .n = 35, | 661 | .core_note_type = NT_PPC_SPE, .n = 35, |
661 | .size = sizeof(u32), .align = sizeof(u32), | 662 | .size = sizeof(u32), .align = sizeof(u32), |
662 | .active = evr_active, .get = evr_get, .set = evr_set | 663 | .active = evr_active, .get = evr_get, .set = evr_set |
663 | }, | 664 | }, |
@@ -854,8 +855,8 @@ void user_enable_single_step(struct task_struct *task) | |||
854 | 855 | ||
855 | if (regs != NULL) { | 856 | if (regs != NULL) { |
856 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 857 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
857 | task->thread.dbcr0 &= ~DBCR0_BT; | 858 | task->thread.debug.dbcr0 &= ~DBCR0_BT; |
858 | task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; | 859 | task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; |
859 | regs->msr |= MSR_DE; | 860 | regs->msr |= MSR_DE; |
860 | #else | 861 | #else |
861 | regs->msr &= ~MSR_BE; | 862 | regs->msr &= ~MSR_BE; |
@@ -871,8 +872,8 @@ void user_enable_block_step(struct task_struct *task) | |||
871 | 872 | ||
872 | if (regs != NULL) { | 873 | if (regs != NULL) { |
873 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 874 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
874 | task->thread.dbcr0 &= ~DBCR0_IC; | 875 | task->thread.debug.dbcr0 &= ~DBCR0_IC; |
875 | task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT; | 876 | task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; |
876 | regs->msr |= MSR_DE; | 877 | regs->msr |= MSR_DE; |
877 | #else | 878 | #else |
878 | regs->msr &= ~MSR_SE; | 879 | regs->msr &= ~MSR_SE; |
@@ -894,16 +895,16 @@ void user_disable_single_step(struct task_struct *task) | |||
894 | * And, after doing so, if all debug flags are off, turn | 895 | * And, after doing so, if all debug flags are off, turn |
895 | * off DBCR0(IDM) and MSR(DE) .... Torez | 896 | * off DBCR0(IDM) and MSR(DE) .... Torez |
896 | */ | 897 | */ |
897 | task->thread.dbcr0 &= ~DBCR0_IC; | 898 | task->thread.debug.dbcr0 &= ~(DBCR0_IC|DBCR0_BT); |
898 | /* | 899 | /* |
899 | * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. | 900 | * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. |
900 | */ | 901 | */ |
901 | if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, | 902 | if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, |
902 | task->thread.dbcr1)) { | 903 | task->thread.debug.dbcr1)) { |
903 | /* | 904 | /* |
904 | * All debug events were off..... | 905 | * All debug events were off..... |
905 | */ | 906 | */ |
906 | task->thread.dbcr0 &= ~DBCR0_IDM; | 907 | task->thread.debug.dbcr0 &= ~DBCR0_IDM; |
907 | regs->msr &= ~MSR_DE; | 908 | regs->msr &= ~MSR_DE; |
908 | } | 909 | } |
909 | #else | 910 | #else |
@@ -1022,14 +1023,14 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
1022 | */ | 1023 | */ |
1023 | 1024 | ||
1024 | /* DAC's hold the whole address without any mode flags */ | 1025 | /* DAC's hold the whole address without any mode flags */ |
1025 | task->thread.dac1 = data & ~0x3UL; | 1026 | task->thread.debug.dac1 = data & ~0x3UL; |
1026 | 1027 | ||
1027 | if (task->thread.dac1 == 0) { | 1028 | if (task->thread.debug.dac1 == 0) { |
1028 | dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); | 1029 | dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); |
1029 | if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, | 1030 | if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, |
1030 | task->thread.dbcr1)) { | 1031 | task->thread.debug.dbcr1)) { |
1031 | task->thread.regs->msr &= ~MSR_DE; | 1032 | task->thread.regs->msr &= ~MSR_DE; |
1032 | task->thread.dbcr0 &= ~DBCR0_IDM; | 1033 | task->thread.debug.dbcr0 &= ~DBCR0_IDM; |
1033 | } | 1034 | } |
1034 | return 0; | 1035 | return 0; |
1035 | } | 1036 | } |
@@ -1041,7 +1042,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
1041 | 1042 | ||
1042 | /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 | 1043 | /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 |
1043 | register */ | 1044 | register */ |
1044 | task->thread.dbcr0 |= DBCR0_IDM; | 1045 | task->thread.debug.dbcr0 |= DBCR0_IDM; |
1045 | 1046 | ||
1046 | /* Check for write and read flags and set DBCR0 | 1047 | /* Check for write and read flags and set DBCR0 |
1047 | accordingly */ | 1048 | accordingly */ |
@@ -1071,10 +1072,10 @@ static long set_instruction_bp(struct task_struct *child, | |||
1071 | struct ppc_hw_breakpoint *bp_info) | 1072 | struct ppc_hw_breakpoint *bp_info) |
1072 | { | 1073 | { |
1073 | int slot; | 1074 | int slot; |
1074 | int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0); | 1075 | int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0); |
1075 | int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0); | 1076 | int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0); |
1076 | int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0); | 1077 | int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0); |
1077 | int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0); | 1078 | int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0); |
1078 | 1079 | ||
1079 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) | 1080 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) |
1080 | slot2_in_use = 1; | 1081 | slot2_in_use = 1; |
@@ -1093,9 +1094,9 @@ static long set_instruction_bp(struct task_struct *child, | |||
1093 | /* We need a pair of IAC regsisters */ | 1094 | /* We need a pair of IAC regsisters */ |
1094 | if ((!slot1_in_use) && (!slot2_in_use)) { | 1095 | if ((!slot1_in_use) && (!slot2_in_use)) { |
1095 | slot = 1; | 1096 | slot = 1; |
1096 | child->thread.iac1 = bp_info->addr; | 1097 | child->thread.debug.iac1 = bp_info->addr; |
1097 | child->thread.iac2 = bp_info->addr2; | 1098 | child->thread.debug.iac2 = bp_info->addr2; |
1098 | child->thread.dbcr0 |= DBCR0_IAC1; | 1099 | child->thread.debug.dbcr0 |= DBCR0_IAC1; |
1099 | if (bp_info->addr_mode == | 1100 | if (bp_info->addr_mode == |
1100 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | 1101 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) |
1101 | dbcr_iac_range(child) |= DBCR_IAC12X; | 1102 | dbcr_iac_range(child) |= DBCR_IAC12X; |
@@ -1104,9 +1105,9 @@ static long set_instruction_bp(struct task_struct *child, | |||
1104 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 1105 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
1105 | } else if ((!slot3_in_use) && (!slot4_in_use)) { | 1106 | } else if ((!slot3_in_use) && (!slot4_in_use)) { |
1106 | slot = 3; | 1107 | slot = 3; |
1107 | child->thread.iac3 = bp_info->addr; | 1108 | child->thread.debug.iac3 = bp_info->addr; |
1108 | child->thread.iac4 = bp_info->addr2; | 1109 | child->thread.debug.iac4 = bp_info->addr2; |
1109 | child->thread.dbcr0 |= DBCR0_IAC3; | 1110 | child->thread.debug.dbcr0 |= DBCR0_IAC3; |
1110 | if (bp_info->addr_mode == | 1111 | if (bp_info->addr_mode == |
1111 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | 1112 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) |
1112 | dbcr_iac_range(child) |= DBCR_IAC34X; | 1113 | dbcr_iac_range(child) |= DBCR_IAC34X; |
@@ -1126,30 +1127,30 @@ static long set_instruction_bp(struct task_struct *child, | |||
1126 | */ | 1127 | */ |
1127 | if (slot2_in_use || (slot3_in_use == slot4_in_use)) { | 1128 | if (slot2_in_use || (slot3_in_use == slot4_in_use)) { |
1128 | slot = 1; | 1129 | slot = 1; |
1129 | child->thread.iac1 = bp_info->addr; | 1130 | child->thread.debug.iac1 = bp_info->addr; |
1130 | child->thread.dbcr0 |= DBCR0_IAC1; | 1131 | child->thread.debug.dbcr0 |= DBCR0_IAC1; |
1131 | goto out; | 1132 | goto out; |
1132 | } | 1133 | } |
1133 | } | 1134 | } |
1134 | if (!slot2_in_use) { | 1135 | if (!slot2_in_use) { |
1135 | slot = 2; | 1136 | slot = 2; |
1136 | child->thread.iac2 = bp_info->addr; | 1137 | child->thread.debug.iac2 = bp_info->addr; |
1137 | child->thread.dbcr0 |= DBCR0_IAC2; | 1138 | child->thread.debug.dbcr0 |= DBCR0_IAC2; |
1138 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 1139 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
1139 | } else if (!slot3_in_use) { | 1140 | } else if (!slot3_in_use) { |
1140 | slot = 3; | 1141 | slot = 3; |
1141 | child->thread.iac3 = bp_info->addr; | 1142 | child->thread.debug.iac3 = bp_info->addr; |
1142 | child->thread.dbcr0 |= DBCR0_IAC3; | 1143 | child->thread.debug.dbcr0 |= DBCR0_IAC3; |
1143 | } else if (!slot4_in_use) { | 1144 | } else if (!slot4_in_use) { |
1144 | slot = 4; | 1145 | slot = 4; |
1145 | child->thread.iac4 = bp_info->addr; | 1146 | child->thread.debug.iac4 = bp_info->addr; |
1146 | child->thread.dbcr0 |= DBCR0_IAC4; | 1147 | child->thread.debug.dbcr0 |= DBCR0_IAC4; |
1147 | #endif | 1148 | #endif |
1148 | } else | 1149 | } else |
1149 | return -ENOSPC; | 1150 | return -ENOSPC; |
1150 | } | 1151 | } |
1151 | out: | 1152 | out: |
1152 | child->thread.dbcr0 |= DBCR0_IDM; | 1153 | child->thread.debug.dbcr0 |= DBCR0_IDM; |
1153 | child->thread.regs->msr |= MSR_DE; | 1154 | child->thread.regs->msr |= MSR_DE; |
1154 | 1155 | ||
1155 | return slot; | 1156 | return slot; |
@@ -1159,49 +1160,49 @@ static int del_instruction_bp(struct task_struct *child, int slot) | |||
1159 | { | 1160 | { |
1160 | switch (slot) { | 1161 | switch (slot) { |
1161 | case 1: | 1162 | case 1: |
1162 | if ((child->thread.dbcr0 & DBCR0_IAC1) == 0) | 1163 | if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0) |
1163 | return -ENOENT; | 1164 | return -ENOENT; |
1164 | 1165 | ||
1165 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) { | 1166 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) { |
1166 | /* address range - clear slots 1 & 2 */ | 1167 | /* address range - clear slots 1 & 2 */ |
1167 | child->thread.iac2 = 0; | 1168 | child->thread.debug.iac2 = 0; |
1168 | dbcr_iac_range(child) &= ~DBCR_IAC12MODE; | 1169 | dbcr_iac_range(child) &= ~DBCR_IAC12MODE; |
1169 | } | 1170 | } |
1170 | child->thread.iac1 = 0; | 1171 | child->thread.debug.iac1 = 0; |
1171 | child->thread.dbcr0 &= ~DBCR0_IAC1; | 1172 | child->thread.debug.dbcr0 &= ~DBCR0_IAC1; |
1172 | break; | 1173 | break; |
1173 | case 2: | 1174 | case 2: |
1174 | if ((child->thread.dbcr0 & DBCR0_IAC2) == 0) | 1175 | if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0) |
1175 | return -ENOENT; | 1176 | return -ENOENT; |
1176 | 1177 | ||
1177 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) | 1178 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) |
1178 | /* used in a range */ | 1179 | /* used in a range */ |
1179 | return -EINVAL; | 1180 | return -EINVAL; |
1180 | child->thread.iac2 = 0; | 1181 | child->thread.debug.iac2 = 0; |
1181 | child->thread.dbcr0 &= ~DBCR0_IAC2; | 1182 | child->thread.debug.dbcr0 &= ~DBCR0_IAC2; |
1182 | break; | 1183 | break; |
1183 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 1184 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
1184 | case 3: | 1185 | case 3: |
1185 | if ((child->thread.dbcr0 & DBCR0_IAC3) == 0) | 1186 | if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0) |
1186 | return -ENOENT; | 1187 | return -ENOENT; |
1187 | 1188 | ||
1188 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) { | 1189 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) { |
1189 | /* address range - clear slots 3 & 4 */ | 1190 | /* address range - clear slots 3 & 4 */ |
1190 | child->thread.iac4 = 0; | 1191 | child->thread.debug.iac4 = 0; |
1191 | dbcr_iac_range(child) &= ~DBCR_IAC34MODE; | 1192 | dbcr_iac_range(child) &= ~DBCR_IAC34MODE; |
1192 | } | 1193 | } |
1193 | child->thread.iac3 = 0; | 1194 | child->thread.debug.iac3 = 0; |
1194 | child->thread.dbcr0 &= ~DBCR0_IAC3; | 1195 | child->thread.debug.dbcr0 &= ~DBCR0_IAC3; |
1195 | break; | 1196 | break; |
1196 | case 4: | 1197 | case 4: |
1197 | if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) | 1198 | if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0) |
1198 | return -ENOENT; | 1199 | return -ENOENT; |
1199 | 1200 | ||
1200 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) | 1201 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) |
1201 | /* Used in a range */ | 1202 | /* Used in a range */ |
1202 | return -EINVAL; | 1203 | return -EINVAL; |
1203 | child->thread.iac4 = 0; | 1204 | child->thread.debug.iac4 = 0; |
1204 | child->thread.dbcr0 &= ~DBCR0_IAC4; | 1205 | child->thread.debug.dbcr0 &= ~DBCR0_IAC4; |
1205 | break; | 1206 | break; |
1206 | #endif | 1207 | #endif |
1207 | default: | 1208 | default: |
@@ -1231,18 +1232,18 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) | |||
1231 | dbcr_dac(child) |= DBCR_DAC1R; | 1232 | dbcr_dac(child) |= DBCR_DAC1R; |
1232 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | 1233 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) |
1233 | dbcr_dac(child) |= DBCR_DAC1W; | 1234 | dbcr_dac(child) |= DBCR_DAC1W; |
1234 | child->thread.dac1 = (unsigned long)bp_info->addr; | 1235 | child->thread.debug.dac1 = (unsigned long)bp_info->addr; |
1235 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | 1236 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 |
1236 | if (byte_enable) { | 1237 | if (byte_enable) { |
1237 | child->thread.dvc1 = | 1238 | child->thread.debug.dvc1 = |
1238 | (unsigned long)bp_info->condition_value; | 1239 | (unsigned long)bp_info->condition_value; |
1239 | child->thread.dbcr2 |= | 1240 | child->thread.debug.dbcr2 |= |
1240 | ((byte_enable << DBCR2_DVC1BE_SHIFT) | | 1241 | ((byte_enable << DBCR2_DVC1BE_SHIFT) | |
1241 | (condition_mode << DBCR2_DVC1M_SHIFT)); | 1242 | (condition_mode << DBCR2_DVC1M_SHIFT)); |
1242 | } | 1243 | } |
1243 | #endif | 1244 | #endif |
1244 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | 1245 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE |
1245 | } else if (child->thread.dbcr2 & DBCR2_DAC12MODE) { | 1246 | } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { |
1246 | /* Both dac1 and dac2 are part of a range */ | 1247 | /* Both dac1 and dac2 are part of a range */ |
1247 | return -ENOSPC; | 1248 | return -ENOSPC; |
1248 | #endif | 1249 | #endif |
@@ -1252,19 +1253,19 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) | |||
1252 | dbcr_dac(child) |= DBCR_DAC2R; | 1253 | dbcr_dac(child) |= DBCR_DAC2R; |
1253 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | 1254 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) |
1254 | dbcr_dac(child) |= DBCR_DAC2W; | 1255 | dbcr_dac(child) |= DBCR_DAC2W; |
1255 | child->thread.dac2 = (unsigned long)bp_info->addr; | 1256 | child->thread.debug.dac2 = (unsigned long)bp_info->addr; |
1256 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | 1257 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 |
1257 | if (byte_enable) { | 1258 | if (byte_enable) { |
1258 | child->thread.dvc2 = | 1259 | child->thread.debug.dvc2 = |
1259 | (unsigned long)bp_info->condition_value; | 1260 | (unsigned long)bp_info->condition_value; |
1260 | child->thread.dbcr2 |= | 1261 | child->thread.debug.dbcr2 |= |
1261 | ((byte_enable << DBCR2_DVC2BE_SHIFT) | | 1262 | ((byte_enable << DBCR2_DVC2BE_SHIFT) | |
1262 | (condition_mode << DBCR2_DVC2M_SHIFT)); | 1263 | (condition_mode << DBCR2_DVC2M_SHIFT)); |
1263 | } | 1264 | } |
1264 | #endif | 1265 | #endif |
1265 | } else | 1266 | } else |
1266 | return -ENOSPC; | 1267 | return -ENOSPC; |
1267 | child->thread.dbcr0 |= DBCR0_IDM; | 1268 | child->thread.debug.dbcr0 |= DBCR0_IDM; |
1268 | child->thread.regs->msr |= MSR_DE; | 1269 | child->thread.regs->msr |= MSR_DE; |
1269 | 1270 | ||
1270 | return slot + 4; | 1271 | return slot + 4; |
@@ -1276,32 +1277,32 @@ static int del_dac(struct task_struct *child, int slot) | |||
1276 | if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) | 1277 | if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) |
1277 | return -ENOENT; | 1278 | return -ENOENT; |
1278 | 1279 | ||
1279 | child->thread.dac1 = 0; | 1280 | child->thread.debug.dac1 = 0; |
1280 | dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); | 1281 | dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); |
1281 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | 1282 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE |
1282 | if (child->thread.dbcr2 & DBCR2_DAC12MODE) { | 1283 | if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { |
1283 | child->thread.dac2 = 0; | 1284 | child->thread.debug.dac2 = 0; |
1284 | child->thread.dbcr2 &= ~DBCR2_DAC12MODE; | 1285 | child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE; |
1285 | } | 1286 | } |
1286 | child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); | 1287 | child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); |
1287 | #endif | 1288 | #endif |
1288 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | 1289 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 |
1289 | child->thread.dvc1 = 0; | 1290 | child->thread.debug.dvc1 = 0; |
1290 | #endif | 1291 | #endif |
1291 | } else if (slot == 2) { | 1292 | } else if (slot == 2) { |
1292 | if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) | 1293 | if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) |
1293 | return -ENOENT; | 1294 | return -ENOENT; |
1294 | 1295 | ||
1295 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | 1296 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE |
1296 | if (child->thread.dbcr2 & DBCR2_DAC12MODE) | 1297 | if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) |
1297 | /* Part of a range */ | 1298 | /* Part of a range */ |
1298 | return -EINVAL; | 1299 | return -EINVAL; |
1299 | child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); | 1300 | child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); |
1300 | #endif | 1301 | #endif |
1301 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | 1302 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 |
1302 | child->thread.dvc2 = 0; | 1303 | child->thread.debug.dvc2 = 0; |
1303 | #endif | 1304 | #endif |
1304 | child->thread.dac2 = 0; | 1305 | child->thread.debug.dac2 = 0; |
1305 | dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); | 1306 | dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); |
1306 | } else | 1307 | } else |
1307 | return -EINVAL; | 1308 | return -EINVAL; |
@@ -1343,22 +1344,22 @@ static int set_dac_range(struct task_struct *child, | |||
1343 | return -EIO; | 1344 | return -EIO; |
1344 | } | 1345 | } |
1345 | 1346 | ||
1346 | if (child->thread.dbcr0 & | 1347 | if (child->thread.debug.dbcr0 & |
1347 | (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) | 1348 | (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) |
1348 | return -ENOSPC; | 1349 | return -ENOSPC; |
1349 | 1350 | ||
1350 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) | 1351 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) |
1351 | child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); | 1352 | child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); |
1352 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | 1353 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) |
1353 | child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); | 1354 | child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); |
1354 | child->thread.dac1 = bp_info->addr; | 1355 | child->thread.debug.dac1 = bp_info->addr; |
1355 | child->thread.dac2 = bp_info->addr2; | 1356 | child->thread.debug.dac2 = bp_info->addr2; |
1356 | if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) | 1357 | if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) |
1357 | child->thread.dbcr2 |= DBCR2_DAC12M; | 1358 | child->thread.debug.dbcr2 |= DBCR2_DAC12M; |
1358 | else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | 1359 | else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) |
1359 | child->thread.dbcr2 |= DBCR2_DAC12MX; | 1360 | child->thread.debug.dbcr2 |= DBCR2_DAC12MX; |
1360 | else /* PPC_BREAKPOINT_MODE_MASK */ | 1361 | else /* PPC_BREAKPOINT_MODE_MASK */ |
1361 | child->thread.dbcr2 |= DBCR2_DAC12MM; | 1362 | child->thread.debug.dbcr2 |= DBCR2_DAC12MM; |
1362 | child->thread.regs->msr |= MSR_DE; | 1363 | child->thread.regs->msr |= MSR_DE; |
1363 | 1364 | ||
1364 | return 5; | 1365 | return 5; |
@@ -1489,9 +1490,9 @@ static long ppc_del_hwdebug(struct task_struct *child, long data) | |||
1489 | rc = del_dac(child, (int)data - 4); | 1490 | rc = del_dac(child, (int)data - 4); |
1490 | 1491 | ||
1491 | if (!rc) { | 1492 | if (!rc) { |
1492 | if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0, | 1493 | if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0, |
1493 | child->thread.dbcr1)) { | 1494 | child->thread.debug.dbcr1)) { |
1494 | child->thread.dbcr0 &= ~DBCR0_IDM; | 1495 | child->thread.debug.dbcr0 &= ~DBCR0_IDM; |
1495 | child->thread.regs->msr &= ~MSR_DE; | 1496 | child->thread.regs->msr &= ~MSR_DE; |
1496 | } | 1497 | } |
1497 | } | 1498 | } |
@@ -1554,10 +1555,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1554 | 1555 | ||
1555 | flush_fp_to_thread(child); | 1556 | flush_fp_to_thread(child); |
1556 | if (fpidx < (PT_FPSCR - PT_FPR0)) | 1557 | if (fpidx < (PT_FPSCR - PT_FPR0)) |
1557 | tmp = ((unsigned long *)child->thread.fpr) | 1558 | memcpy(&tmp, &child->thread.fp_state.fpr, |
1558 | [fpidx * TS_FPRWIDTH]; | 1559 | sizeof(long)); |
1559 | else | 1560 | else |
1560 | tmp = child->thread.fpscr.val; | 1561 | tmp = child->thread.fp_state.fpscr; |
1561 | } | 1562 | } |
1562 | ret = put_user(tmp, datalp); | 1563 | ret = put_user(tmp, datalp); |
1563 | break; | 1564 | break; |
@@ -1587,10 +1588,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1587 | 1588 | ||
1588 | flush_fp_to_thread(child); | 1589 | flush_fp_to_thread(child); |
1589 | if (fpidx < (PT_FPSCR - PT_FPR0)) | 1590 | if (fpidx < (PT_FPSCR - PT_FPR0)) |
1590 | ((unsigned long *)child->thread.fpr) | 1591 | memcpy(&child->thread.fp_state.fpr, &data, |
1591 | [fpidx * TS_FPRWIDTH] = data; | 1592 | sizeof(long)); |
1592 | else | 1593 | else |
1593 | child->thread.fpscr.val = data; | 1594 | child->thread.fp_state.fpscr = data; |
1594 | ret = 0; | 1595 | ret = 0; |
1595 | } | 1596 | } |
1596 | break; | 1597 | break; |
@@ -1669,7 +1670,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1669 | if (addr > 0) | 1670 | if (addr > 0) |
1670 | break; | 1671 | break; |
1671 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 1672 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
1672 | ret = put_user(child->thread.dac1, datalp); | 1673 | ret = put_user(child->thread.debug.dac1, datalp); |
1673 | #else | 1674 | #else |
1674 | dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | | 1675 | dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | |
1675 | (child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); | 1676 | (child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); |