diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 516 |
1 files changed, 488 insertions, 28 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index ef149880c145..ed2cfe17d25e 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -46,7 +46,7 @@ | |||
46 | /* | 46 | /* |
47 | * Set of msr bits that gdb can change on behalf of a process. | 47 | * Set of msr bits that gdb can change on behalf of a process. |
48 | */ | 48 | */ |
49 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | 49 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
50 | #define MSR_DEBUGCHANGE 0 | 50 | #define MSR_DEBUGCHANGE 0 |
51 | #else | 51 | #else |
52 | #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) | 52 | #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) |
@@ -703,7 +703,7 @@ void user_enable_single_step(struct task_struct *task) | |||
703 | struct pt_regs *regs = task->thread.regs; | 703 | struct pt_regs *regs = task->thread.regs; |
704 | 704 | ||
705 | if (regs != NULL) { | 705 | if (regs != NULL) { |
706 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | 706 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
707 | task->thread.dbcr0 &= ~DBCR0_BT; | 707 | task->thread.dbcr0 &= ~DBCR0_BT; |
708 | task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; | 708 | task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; |
709 | regs->msr |= MSR_DE; | 709 | regs->msr |= MSR_DE; |
@@ -720,7 +720,7 @@ void user_enable_block_step(struct task_struct *task) | |||
720 | struct pt_regs *regs = task->thread.regs; | 720 | struct pt_regs *regs = task->thread.regs; |
721 | 721 | ||
722 | if (regs != NULL) { | 722 | if (regs != NULL) { |
723 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | 723 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
724 | task->thread.dbcr0 &= ~DBCR0_IC; | 724 | task->thread.dbcr0 &= ~DBCR0_IC; |
725 | task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT; | 725 | task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT; |
726 | regs->msr |= MSR_DE; | 726 | regs->msr |= MSR_DE; |
@@ -737,17 +737,25 @@ void user_disable_single_step(struct task_struct *task) | |||
737 | struct pt_regs *regs = task->thread.regs; | 737 | struct pt_regs *regs = task->thread.regs; |
738 | 738 | ||
739 | if (regs != NULL) { | 739 | if (regs != NULL) { |
740 | #if defined(CONFIG_BOOKE) | 740 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
741 | /* If DAC don't clear DBCRO_IDM or MSR_DE */ | 741 | /* |
742 | if (task->thread.dabr) | 742 | * The logic to disable single stepping should be as |
743 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); | 743 | * simple as turning off the Instruction Complete flag. |
744 | else { | 744 | * And, after doing so, if all debug flags are off, turn |
745 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); | 745 | * off DBCR0(IDM) and MSR(DE) .... Torez |
746 | */ | ||
747 | task->thread.dbcr0 &= ~DBCR0_IC; | ||
748 | /* | ||
749 | * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. | ||
750 | */ | ||
751 | if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, | ||
752 | task->thread.dbcr1)) { | ||
753 | /* | ||
754 | * All debug events were off..... | ||
755 | */ | ||
756 | task->thread.dbcr0 &= ~DBCR0_IDM; | ||
746 | regs->msr &= ~MSR_DE; | 757 | regs->msr &= ~MSR_DE; |
747 | } | 758 | } |
748 | #elif defined(CONFIG_40x) | ||
749 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); | ||
750 | regs->msr &= ~MSR_DE; | ||
751 | #else | 759 | #else |
752 | regs->msr &= ~(MSR_SE | MSR_BE); | 760 | regs->msr &= ~(MSR_SE | MSR_BE); |
753 | #endif | 761 | #endif |
@@ -769,8 +777,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
769 | if ((data & ~0x7UL) >= TASK_SIZE) | 777 | if ((data & ~0x7UL) >= TASK_SIZE) |
770 | return -EIO; | 778 | return -EIO; |
771 | 779 | ||
772 | #ifndef CONFIG_BOOKE | 780 | #ifndef CONFIG_PPC_ADV_DEBUG_REGS |
773 | |||
774 | /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. | 781 | /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. |
775 | * It was assumed, on previous implementations, that 3 bits were | 782 | * It was assumed, on previous implementations, that 3 bits were |
776 | * passed together with the data address, fitting the design of the | 783 | * passed together with the data address, fitting the design of the |
@@ -789,21 +796,22 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
789 | 796 | ||
790 | /* Move contents to the DABR register */ | 797 | /* Move contents to the DABR register */ |
791 | task->thread.dabr = data; | 798 | task->thread.dabr = data; |
792 | 799 | #else /* CONFIG_PPC_ADV_DEBUG_REGS */ | |
793 | #endif | ||
794 | #if defined(CONFIG_BOOKE) | ||
795 | |||
796 | /* As described above, it was assumed 3 bits were passed with the data | 800 | /* As described above, it was assumed 3 bits were passed with the data |
797 | * address, but we will assume only the mode bits will be passed | 801 | * address, but we will assume only the mode bits will be passed |
798 | * as to not cause alignment restrictions for DAC-based processors. | 802 | * as to not cause alignment restrictions for DAC-based processors. |
799 | */ | 803 | */ |
800 | 804 | ||
801 | /* DAC's hold the whole address without any mode flags */ | 805 | /* DAC's hold the whole address without any mode flags */ |
802 | task->thread.dabr = data & ~0x3UL; | 806 | task->thread.dac1 = data & ~0x3UL; |
803 | 807 | ||
804 | if (task->thread.dabr == 0) { | 808 | if (task->thread.dac1 == 0) { |
805 | task->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM); | 809 | dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); |
806 | task->thread.regs->msr &= ~MSR_DE; | 810 | if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, |
811 | task->thread.dbcr1)) { | ||
812 | task->thread.regs->msr &= ~MSR_DE; | ||
813 | task->thread.dbcr0 &= ~DBCR0_IDM; | ||
814 | } | ||
807 | return 0; | 815 | return 0; |
808 | } | 816 | } |
809 | 817 | ||
@@ -814,17 +822,17 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
814 | 822 | ||
815 | /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 | 823 | /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 |
816 | register */ | 824 | register */ |
817 | task->thread.dbcr0 = DBCR0_IDM; | 825 | task->thread.dbcr0 |= DBCR0_IDM; |
818 | 826 | ||
819 | /* Check for write and read flags and set DBCR0 | 827 | /* Check for write and read flags and set DBCR0 |
820 | accordingly */ | 828 | accordingly */ |
829 | dbcr_dac(task) &= ~(DBCR_DAC1R|DBCR_DAC1W); | ||
821 | if (data & 0x1UL) | 830 | if (data & 0x1UL) |
822 | task->thread.dbcr0 |= DBSR_DAC1R; | 831 | dbcr_dac(task) |= DBCR_DAC1R; |
823 | if (data & 0x2UL) | 832 | if (data & 0x2UL) |
824 | task->thread.dbcr0 |= DBSR_DAC1W; | 833 | dbcr_dac(task) |= DBCR_DAC1W; |
825 | |||
826 | task->thread.regs->msr |= MSR_DE; | 834 | task->thread.regs->msr |= MSR_DE; |
827 | #endif | 835 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ |
828 | return 0; | 836 | return 0; |
829 | } | 837 | } |
830 | 838 | ||
@@ -839,6 +847,394 @@ void ptrace_disable(struct task_struct *child) | |||
839 | user_disable_single_step(child); | 847 | user_disable_single_step(child); |
840 | } | 848 | } |
841 | 849 | ||
850 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||
851 | static long set_intruction_bp(struct task_struct *child, | ||
852 | struct ppc_hw_breakpoint *bp_info) | ||
853 | { | ||
854 | int slot; | ||
855 | int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0); | ||
856 | int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0); | ||
857 | int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0); | ||
858 | int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0); | ||
859 | |||
860 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) | ||
861 | slot2_in_use = 1; | ||
862 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) | ||
863 | slot4_in_use = 1; | ||
864 | |||
865 | if (bp_info->addr >= TASK_SIZE) | ||
866 | return -EIO; | ||
867 | |||
868 | if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) { | ||
869 | |||
870 | /* Make sure range is valid. */ | ||
871 | if (bp_info->addr2 >= TASK_SIZE) | ||
872 | return -EIO; | ||
873 | |||
874 | /* We need a pair of IAC regsisters */ | ||
875 | if ((!slot1_in_use) && (!slot2_in_use)) { | ||
876 | slot = 1; | ||
877 | child->thread.iac1 = bp_info->addr; | ||
878 | child->thread.iac2 = bp_info->addr2; | ||
879 | child->thread.dbcr0 |= DBCR0_IAC1; | ||
880 | if (bp_info->addr_mode == | ||
881 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | ||
882 | dbcr_iac_range(child) |= DBCR_IAC12X; | ||
883 | else | ||
884 | dbcr_iac_range(child) |= DBCR_IAC12I; | ||
885 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | ||
886 | } else if ((!slot3_in_use) && (!slot4_in_use)) { | ||
887 | slot = 3; | ||
888 | child->thread.iac3 = bp_info->addr; | ||
889 | child->thread.iac4 = bp_info->addr2; | ||
890 | child->thread.dbcr0 |= DBCR0_IAC3; | ||
891 | if (bp_info->addr_mode == | ||
892 | PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | ||
893 | dbcr_iac_range(child) |= DBCR_IAC34X; | ||
894 | else | ||
895 | dbcr_iac_range(child) |= DBCR_IAC34I; | ||
896 | #endif | ||
897 | } else | ||
898 | return -ENOSPC; | ||
899 | } else { | ||
900 | /* We only need one. If possible leave a pair free in | ||
901 | * case a range is needed later | ||
902 | */ | ||
903 | if (!slot1_in_use) { | ||
904 | /* | ||
905 | * Don't use iac1 if iac1-iac2 are free and either | ||
906 | * iac3 or iac4 (but not both) are free | ||
907 | */ | ||
908 | if (slot2_in_use || (slot3_in_use == slot4_in_use)) { | ||
909 | slot = 1; | ||
910 | child->thread.iac1 = bp_info->addr; | ||
911 | child->thread.dbcr0 |= DBCR0_IAC1; | ||
912 | goto out; | ||
913 | } | ||
914 | } | ||
915 | if (!slot2_in_use) { | ||
916 | slot = 2; | ||
917 | child->thread.iac2 = bp_info->addr; | ||
918 | child->thread.dbcr0 |= DBCR0_IAC2; | ||
919 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | ||
920 | } else if (!slot3_in_use) { | ||
921 | slot = 3; | ||
922 | child->thread.iac3 = bp_info->addr; | ||
923 | child->thread.dbcr0 |= DBCR0_IAC3; | ||
924 | } else if (!slot4_in_use) { | ||
925 | slot = 4; | ||
926 | child->thread.iac4 = bp_info->addr; | ||
927 | child->thread.dbcr0 |= DBCR0_IAC4; | ||
928 | #endif | ||
929 | } else | ||
930 | return -ENOSPC; | ||
931 | } | ||
932 | out: | ||
933 | child->thread.dbcr0 |= DBCR0_IDM; | ||
934 | child->thread.regs->msr |= MSR_DE; | ||
935 | |||
936 | return slot; | ||
937 | } | ||
938 | |||
939 | static int del_instruction_bp(struct task_struct *child, int slot) | ||
940 | { | ||
941 | switch (slot) { | ||
942 | case 1: | ||
943 | if ((child->thread.dbcr0 & DBCR0_IAC1) == 0) | ||
944 | return -ENOENT; | ||
945 | |||
946 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) { | ||
947 | /* address range - clear slots 1 & 2 */ | ||
948 | child->thread.iac2 = 0; | ||
949 | dbcr_iac_range(child) &= ~DBCR_IAC12MODE; | ||
950 | } | ||
951 | child->thread.iac1 = 0; | ||
952 | child->thread.dbcr0 &= ~DBCR0_IAC1; | ||
953 | break; | ||
954 | case 2: | ||
955 | if ((child->thread.dbcr0 & DBCR0_IAC2) == 0) | ||
956 | return -ENOENT; | ||
957 | |||
958 | if (dbcr_iac_range(child) & DBCR_IAC12MODE) | ||
959 | /* used in a range */ | ||
960 | return -EINVAL; | ||
961 | child->thread.iac2 = 0; | ||
962 | child->thread.dbcr0 &= ~DBCR0_IAC2; | ||
963 | break; | ||
964 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | ||
965 | case 3: | ||
966 | if ((child->thread.dbcr0 & DBCR0_IAC3) == 0) | ||
967 | return -ENOENT; | ||
968 | |||
969 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) { | ||
970 | /* address range - clear slots 3 & 4 */ | ||
971 | child->thread.iac4 = 0; | ||
972 | dbcr_iac_range(child) &= ~DBCR_IAC34MODE; | ||
973 | } | ||
974 | child->thread.iac3 = 0; | ||
975 | child->thread.dbcr0 &= ~DBCR0_IAC3; | ||
976 | break; | ||
977 | case 4: | ||
978 | if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) | ||
979 | return -ENOENT; | ||
980 | |||
981 | if (dbcr_iac_range(child) & DBCR_IAC34MODE) | ||
982 | /* Used in a range */ | ||
983 | return -EINVAL; | ||
984 | child->thread.iac4 = 0; | ||
985 | child->thread.dbcr0 &= ~DBCR0_IAC4; | ||
986 | break; | ||
987 | #endif | ||
988 | default: | ||
989 | return -EINVAL; | ||
990 | } | ||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) | ||
995 | { | ||
996 | int byte_enable = | ||
997 | (bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT) | ||
998 | & 0xf; | ||
999 | int condition_mode = | ||
1000 | bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE; | ||
1001 | int slot; | ||
1002 | |||
1003 | if (byte_enable && (condition_mode == 0)) | ||
1004 | return -EINVAL; | ||
1005 | |||
1006 | if (bp_info->addr >= TASK_SIZE) | ||
1007 | return -EIO; | ||
1008 | |||
1009 | if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) { | ||
1010 | slot = 1; | ||
1011 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) | ||
1012 | dbcr_dac(child) |= DBCR_DAC1R; | ||
1013 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | ||
1014 | dbcr_dac(child) |= DBCR_DAC1W; | ||
1015 | child->thread.dac1 = (unsigned long)bp_info->addr; | ||
1016 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | ||
1017 | if (byte_enable) { | ||
1018 | child->thread.dvc1 = | ||
1019 | (unsigned long)bp_info->condition_value; | ||
1020 | child->thread.dbcr2 |= | ||
1021 | ((byte_enable << DBCR2_DVC1BE_SHIFT) | | ||
1022 | (condition_mode << DBCR2_DVC1M_SHIFT)); | ||
1023 | } | ||
1024 | #endif | ||
1025 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1026 | } else if (child->thread.dbcr2 & DBCR2_DAC12MODE) { | ||
1027 | /* Both dac1 and dac2 are part of a range */ | ||
1028 | return -ENOSPC; | ||
1029 | #endif | ||
1030 | } else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) { | ||
1031 | slot = 2; | ||
1032 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) | ||
1033 | dbcr_dac(child) |= DBCR_DAC2R; | ||
1034 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | ||
1035 | dbcr_dac(child) |= DBCR_DAC2W; | ||
1036 | child->thread.dac2 = (unsigned long)bp_info->addr; | ||
1037 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | ||
1038 | if (byte_enable) { | ||
1039 | child->thread.dvc2 = | ||
1040 | (unsigned long)bp_info->condition_value; | ||
1041 | child->thread.dbcr2 |= | ||
1042 | ((byte_enable << DBCR2_DVC2BE_SHIFT) | | ||
1043 | (condition_mode << DBCR2_DVC2M_SHIFT)); | ||
1044 | } | ||
1045 | #endif | ||
1046 | } else | ||
1047 | return -ENOSPC; | ||
1048 | child->thread.dbcr0 |= DBCR0_IDM; | ||
1049 | child->thread.regs->msr |= MSR_DE; | ||
1050 | |||
1051 | return slot + 4; | ||
1052 | } | ||
1053 | |||
1054 | static int del_dac(struct task_struct *child, int slot) | ||
1055 | { | ||
1056 | if (slot == 1) { | ||
1057 | if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) | ||
1058 | return -ENOENT; | ||
1059 | |||
1060 | child->thread.dac1 = 0; | ||
1061 | dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); | ||
1062 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1063 | if (child->thread.dbcr2 & DBCR2_DAC12MODE) { | ||
1064 | child->thread.dac2 = 0; | ||
1065 | child->thread.dbcr2 &= ~DBCR2_DAC12MODE; | ||
1066 | } | ||
1067 | child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); | ||
1068 | #endif | ||
1069 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | ||
1070 | child->thread.dvc1 = 0; | ||
1071 | #endif | ||
1072 | } else if (slot == 2) { | ||
1073 | if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) | ||
1074 | return -ENOENT; | ||
1075 | |||
1076 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1077 | if (child->thread.dbcr2 & DBCR2_DAC12MODE) | ||
1078 | /* Part of a range */ | ||
1079 | return -EINVAL; | ||
1080 | child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); | ||
1081 | #endif | ||
1082 | #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 | ||
1083 | child->thread.dvc2 = 0; | ||
1084 | #endif | ||
1085 | child->thread.dac2 = 0; | ||
1086 | dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); | ||
1087 | } else | ||
1088 | return -EINVAL; | ||
1089 | |||
1090 | return 0; | ||
1091 | } | ||
1092 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | ||
1093 | |||
1094 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1095 | static int set_dac_range(struct task_struct *child, | ||
1096 | struct ppc_hw_breakpoint *bp_info) | ||
1097 | { | ||
1098 | int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK; | ||
1099 | |||
1100 | /* We don't allow range watchpoints to be used with DVC */ | ||
1101 | if (bp_info->condition_mode) | ||
1102 | return -EINVAL; | ||
1103 | |||
1104 | /* | ||
1105 | * Best effort to verify the address range. The user/supervisor bits | ||
1106 | * prevent trapping in kernel space, but let's fail on an obvious bad | ||
1107 | * range. The simple test on the mask is not fool-proof, and any | ||
1108 | * exclusive range will spill over into kernel space. | ||
1109 | */ | ||
1110 | if (bp_info->addr >= TASK_SIZE) | ||
1111 | return -EIO; | ||
1112 | if (mode == PPC_BREAKPOINT_MODE_MASK) { | ||
1113 | /* | ||
1114 | * dac2 is a bitmask. Don't allow a mask that makes a | ||
1115 | * kernel space address from a valid dac1 value | ||
1116 | */ | ||
1117 | if (~((unsigned long)bp_info->addr2) >= TASK_SIZE) | ||
1118 | return -EIO; | ||
1119 | } else { | ||
1120 | /* | ||
1121 | * For range breakpoints, addr2 must also be a valid address | ||
1122 | */ | ||
1123 | if (bp_info->addr2 >= TASK_SIZE) | ||
1124 | return -EIO; | ||
1125 | } | ||
1126 | |||
1127 | if (child->thread.dbcr0 & | ||
1128 | (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) | ||
1129 | return -ENOSPC; | ||
1130 | |||
1131 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) | ||
1132 | child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); | ||
1133 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | ||
1134 | child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); | ||
1135 | child->thread.dac1 = bp_info->addr; | ||
1136 | child->thread.dac2 = bp_info->addr2; | ||
1137 | if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) | ||
1138 | child->thread.dbcr2 |= DBCR2_DAC12M; | ||
1139 | else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) | ||
1140 | child->thread.dbcr2 |= DBCR2_DAC12MX; | ||
1141 | else /* PPC_BREAKPOINT_MODE_MASK */ | ||
1142 | child->thread.dbcr2 |= DBCR2_DAC12MM; | ||
1143 | child->thread.regs->msr |= MSR_DE; | ||
1144 | |||
1145 | return 5; | ||
1146 | } | ||
1147 | #endif /* CONFIG_PPC_ADV_DEBUG_DAC_RANGE */ | ||
1148 | |||
1149 | static long ppc_set_hwdebug(struct task_struct *child, | ||
1150 | struct ppc_hw_breakpoint *bp_info) | ||
1151 | { | ||
1152 | if (bp_info->version != 1) | ||
1153 | return -ENOTSUPP; | ||
1154 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||
1155 | /* | ||
1156 | * Check for invalid flags and combinations | ||
1157 | */ | ||
1158 | if ((bp_info->trigger_type == 0) || | ||
1159 | (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE | | ||
1160 | PPC_BREAKPOINT_TRIGGER_RW)) || | ||
1161 | (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) || | ||
1162 | (bp_info->condition_mode & | ||
1163 | ~(PPC_BREAKPOINT_CONDITION_MODE | | ||
1164 | PPC_BREAKPOINT_CONDITION_BE_ALL))) | ||
1165 | return -EINVAL; | ||
1166 | #if CONFIG_PPC_ADV_DEBUG_DVCS == 0 | ||
1167 | if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) | ||
1168 | return -EINVAL; | ||
1169 | #endif | ||
1170 | |||
1171 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) { | ||
1172 | if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) || | ||
1173 | (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)) | ||
1174 | return -EINVAL; | ||
1175 | return set_intruction_bp(child, bp_info); | ||
1176 | } | ||
1177 | if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) | ||
1178 | return set_dac(child, bp_info); | ||
1179 | |||
1180 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1181 | return set_dac_range(child, bp_info); | ||
1182 | #else | ||
1183 | return -EINVAL; | ||
1184 | #endif | ||
1185 | #else /* !CONFIG_PPC_ADV_DEBUG_DVCS */ | ||
1186 | /* | ||
1187 | * We only support one data breakpoint | ||
1188 | */ | ||
1189 | if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) || | ||
1190 | ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) || | ||
1191 | (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) || | ||
1192 | (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) || | ||
1193 | (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)) | ||
1194 | return -EINVAL; | ||
1195 | |||
1196 | if (child->thread.dabr) | ||
1197 | return -ENOSPC; | ||
1198 | |||
1199 | if ((unsigned long)bp_info->addr >= TASK_SIZE) | ||
1200 | return -EIO; | ||
1201 | |||
1202 | child->thread.dabr = (unsigned long)bp_info->addr; | ||
1203 | |||
1204 | return 1; | ||
1205 | #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ | ||
1206 | } | ||
1207 | |||
1208 | static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) | ||
1209 | { | ||
1210 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||
1211 | int rc; | ||
1212 | |||
1213 | if (data <= 4) | ||
1214 | rc = del_instruction_bp(child, (int)data); | ||
1215 | else | ||
1216 | rc = del_dac(child, (int)data - 4); | ||
1217 | |||
1218 | if (!rc) { | ||
1219 | if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0, | ||
1220 | child->thread.dbcr1)) { | ||
1221 | child->thread.dbcr0 &= ~DBCR0_IDM; | ||
1222 | child->thread.regs->msr &= ~MSR_DE; | ||
1223 | } | ||
1224 | } | ||
1225 | return rc; | ||
1226 | #else | ||
1227 | if (data != 1) | ||
1228 | return -EINVAL; | ||
1229 | if (child->thread.dabr == 0) | ||
1230 | return -ENOENT; | ||
1231 | |||
1232 | child->thread.dabr = 0; | ||
1233 | |||
1234 | return 0; | ||
1235 | #endif | ||
1236 | } | ||
1237 | |||
842 | /* | 1238 | /* |
843 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, | 1239 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, |
844 | * we mark them as obsolete now, they will be removed in a future version | 1240 | * we mark them as obsolete now, they will be removed in a future version |
@@ -932,13 +1328,77 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
932 | break; | 1328 | break; |
933 | } | 1329 | } |
934 | 1330 | ||
1331 | case PPC_PTRACE_GETHWDBGINFO: { | ||
1332 | struct ppc_debug_info dbginfo; | ||
1333 | |||
1334 | dbginfo.version = 1; | ||
1335 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||
1336 | dbginfo.num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS; | ||
1337 | dbginfo.num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS; | ||
1338 | dbginfo.num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS; | ||
1339 | dbginfo.data_bp_alignment = 4; | ||
1340 | dbginfo.sizeof_condition = 4; | ||
1341 | dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE | | ||
1342 | PPC_DEBUG_FEATURE_INSN_BP_MASK; | ||
1343 | #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE | ||
1344 | dbginfo.features |= | ||
1345 | PPC_DEBUG_FEATURE_DATA_BP_RANGE | | ||
1346 | PPC_DEBUG_FEATURE_DATA_BP_MASK; | ||
1347 | #endif | ||
1348 | #else /* !CONFIG_PPC_ADV_DEBUG_REGS */ | ||
1349 | dbginfo.num_instruction_bps = 0; | ||
1350 | dbginfo.num_data_bps = 1; | ||
1351 | dbginfo.num_condition_regs = 0; | ||
1352 | #ifdef CONFIG_PPC64 | ||
1353 | dbginfo.data_bp_alignment = 8; | ||
1354 | #else | ||
1355 | dbginfo.data_bp_alignment = 4; | ||
1356 | #endif | ||
1357 | dbginfo.sizeof_condition = 0; | ||
1358 | dbginfo.features = 0; | ||
1359 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | ||
1360 | |||
1361 | if (!access_ok(VERIFY_WRITE, data, | ||
1362 | sizeof(struct ppc_debug_info))) | ||
1363 | return -EFAULT; | ||
1364 | ret = __copy_to_user((struct ppc_debug_info __user *)data, | ||
1365 | &dbginfo, sizeof(struct ppc_debug_info)) ? | ||
1366 | -EFAULT : 0; | ||
1367 | break; | ||
1368 | } | ||
1369 | |||
1370 | case PPC_PTRACE_SETHWDEBUG: { | ||
1371 | struct ppc_hw_breakpoint bp_info; | ||
1372 | |||
1373 | if (!access_ok(VERIFY_READ, data, | ||
1374 | sizeof(struct ppc_hw_breakpoint))) | ||
1375 | return -EFAULT; | ||
1376 | ret = __copy_from_user(&bp_info, | ||
1377 | (struct ppc_hw_breakpoint __user *)data, | ||
1378 | sizeof(struct ppc_hw_breakpoint)) ? | ||
1379 | -EFAULT : 0; | ||
1380 | if (!ret) | ||
1381 | ret = ppc_set_hwdebug(child, &bp_info); | ||
1382 | break; | ||
1383 | } | ||
1384 | |||
1385 | case PPC_PTRACE_DELHWDEBUG: { | ||
1386 | ret = ppc_del_hwdebug(child, addr, data); | ||
1387 | break; | ||
1388 | } | ||
1389 | |||
935 | case PTRACE_GET_DEBUGREG: { | 1390 | case PTRACE_GET_DEBUGREG: { |
936 | ret = -EINVAL; | 1391 | ret = -EINVAL; |
937 | /* We only support one DABR and no IABRS at the moment */ | 1392 | /* We only support one DABR and no IABRS at the moment */ |
938 | if (addr > 0) | 1393 | if (addr > 0) |
939 | break; | 1394 | break; |
1395 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||
1396 | ret = put_user(child->thread.dac1, | ||
1397 | (unsigned long __user *)data); | ||
1398 | #else | ||
940 | ret = put_user(child->thread.dabr, | 1399 | ret = put_user(child->thread.dabr, |
941 | (unsigned long __user *)data); | 1400 | (unsigned long __user *)data); |
1401 | #endif | ||
942 | break; | 1402 | break; |
943 | } | 1403 | } |
944 | 1404 | ||