0001
0002
0003 #include <linux/regset.h>
0004 #include <linux/hw_breakpoint.h>
0005
0006 #include "ptrace-decl.h"
0007
0008 void user_enable_single_step(struct task_struct *task)
0009 {
0010 struct pt_regs *regs = task->thread.regs;
0011
0012 if (regs != NULL) {
0013 task->thread.debug.dbcr0 &= ~DBCR0_BT;
0014 task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC;
0015 regs_set_return_msr(regs, regs->msr | MSR_DE);
0016 }
0017 set_tsk_thread_flag(task, TIF_SINGLESTEP);
0018 }
0019
0020 void user_enable_block_step(struct task_struct *task)
0021 {
0022 struct pt_regs *regs = task->thread.regs;
0023
0024 if (regs != NULL) {
0025 task->thread.debug.dbcr0 &= ~DBCR0_IC;
0026 task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT;
0027 regs_set_return_msr(regs, regs->msr | MSR_DE);
0028 }
0029 set_tsk_thread_flag(task, TIF_SINGLESTEP);
0030 }
0031
0032 void user_disable_single_step(struct task_struct *task)
0033 {
0034 struct pt_regs *regs = task->thread.regs;
0035
0036 if (regs != NULL) {
0037
0038
0039
0040
0041
0042
0043 task->thread.debug.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
0044
0045
0046
0047 if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
0048 task->thread.debug.dbcr1)) {
0049
0050
0051
0052 task->thread.debug.dbcr0 &= ~DBCR0_IDM;
0053 regs_set_return_msr(regs, regs->msr & ~MSR_DE);
0054 }
0055 }
0056 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
0057 }
0058
0059 void ppc_gethwdinfo(struct ppc_debug_info *dbginfo)
0060 {
0061 dbginfo->version = 1;
0062 dbginfo->num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS;
0063 dbginfo->num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS;
0064 dbginfo->num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS;
0065 dbginfo->data_bp_alignment = 4;
0066 dbginfo->sizeof_condition = 4;
0067 dbginfo->features = PPC_DEBUG_FEATURE_INSN_BP_RANGE |
0068 PPC_DEBUG_FEATURE_INSN_BP_MASK;
0069 if (IS_ENABLED(CONFIG_PPC_ADV_DEBUG_DAC_RANGE))
0070 dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_RANGE |
0071 PPC_DEBUG_FEATURE_DATA_BP_MASK;
0072 }
0073
0074 int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
0075 unsigned long __user *datalp)
0076 {
0077
0078 if (addr > 0)
0079 return -EINVAL;
0080 return put_user(child->thread.debug.dac1, datalp);
0081 }
0082
0083 int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data)
0084 {
0085 struct pt_regs *regs = task->thread.regs;
0086 #ifdef CONFIG_HAVE_HW_BREAKPOINT
0087 int ret;
0088 struct thread_struct *thread = &task->thread;
0089 struct perf_event *bp;
0090 struct perf_event_attr attr;
0091 #endif
0092
0093
0094
0095
0096
0097 if (addr > 0)
0098 return -EINVAL;
0099
0100
0101 if ((data & ~0x7UL) >= TASK_SIZE)
0102 return -EIO;
0103
0104
0105
0106
0107
0108
0109
0110 task->thread.debug.dac1 = data & ~0x3UL;
0111
0112 if (task->thread.debug.dac1 == 0) {
0113 dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
0114 if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
0115 task->thread.debug.dbcr1)) {
0116 regs_set_return_msr(regs, regs->msr & ~MSR_DE);
0117 task->thread.debug.dbcr0 &= ~DBCR0_IDM;
0118 }
0119 return 0;
0120 }
0121
0122
0123
0124 if (!(data & 0x3UL))
0125 return -EINVAL;
0126
0127
0128 task->thread.debug.dbcr0 |= DBCR0_IDM;
0129
0130
0131 dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
0132 if (data & 0x1UL)
0133 dbcr_dac(task) |= DBCR_DAC1R;
0134 if (data & 0x2UL)
0135 dbcr_dac(task) |= DBCR_DAC1W;
0136 regs_set_return_msr(regs, regs->msr | MSR_DE);
0137 return 0;
0138 }
0139
0140 static long set_instruction_bp(struct task_struct *child,
0141 struct ppc_hw_breakpoint *bp_info)
0142 {
0143 int slot;
0144 int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0);
0145 int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0);
0146 int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0);
0147 int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0);
0148
0149 if (dbcr_iac_range(child) & DBCR_IAC12MODE)
0150 slot2_in_use = 1;
0151 if (dbcr_iac_range(child) & DBCR_IAC34MODE)
0152 slot4_in_use = 1;
0153
0154 if (bp_info->addr >= TASK_SIZE)
0155 return -EIO;
0156
0157 if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
0158
0159 if (bp_info->addr2 >= TASK_SIZE)
0160 return -EIO;
0161
0162
0163 if (!slot1_in_use && !slot2_in_use) {
0164 slot = 1;
0165 child->thread.debug.iac1 = bp_info->addr;
0166 child->thread.debug.iac2 = bp_info->addr2;
0167 child->thread.debug.dbcr0 |= DBCR0_IAC1;
0168 if (bp_info->addr_mode ==
0169 PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
0170 dbcr_iac_range(child) |= DBCR_IAC12X;
0171 else
0172 dbcr_iac_range(child) |= DBCR_IAC12I;
0173 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
0174 } else if ((!slot3_in_use) && (!slot4_in_use)) {
0175 slot = 3;
0176 child->thread.debug.iac3 = bp_info->addr;
0177 child->thread.debug.iac4 = bp_info->addr2;
0178 child->thread.debug.dbcr0 |= DBCR0_IAC3;
0179 if (bp_info->addr_mode ==
0180 PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
0181 dbcr_iac_range(child) |= DBCR_IAC34X;
0182 else
0183 dbcr_iac_range(child) |= DBCR_IAC34I;
0184 #endif
0185 } else {
0186 return -ENOSPC;
0187 }
0188 } else {
0189
0190
0191
0192 if (!slot1_in_use) {
0193
0194
0195
0196
0197 if (slot2_in_use || slot3_in_use == slot4_in_use) {
0198 slot = 1;
0199 child->thread.debug.iac1 = bp_info->addr;
0200 child->thread.debug.dbcr0 |= DBCR0_IAC1;
0201 goto out;
0202 }
0203 }
0204 if (!slot2_in_use) {
0205 slot = 2;
0206 child->thread.debug.iac2 = bp_info->addr;
0207 child->thread.debug.dbcr0 |= DBCR0_IAC2;
0208 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
0209 } else if (!slot3_in_use) {
0210 slot = 3;
0211 child->thread.debug.iac3 = bp_info->addr;
0212 child->thread.debug.dbcr0 |= DBCR0_IAC3;
0213 } else if (!slot4_in_use) {
0214 slot = 4;
0215 child->thread.debug.iac4 = bp_info->addr;
0216 child->thread.debug.dbcr0 |= DBCR0_IAC4;
0217 #endif
0218 } else {
0219 return -ENOSPC;
0220 }
0221 }
0222 out:
0223 child->thread.debug.dbcr0 |= DBCR0_IDM;
0224 regs_set_return_msr(child->thread.regs, child->thread.regs->msr | MSR_DE);
0225
0226 return slot;
0227 }
0228
0229 static int del_instruction_bp(struct task_struct *child, int slot)
0230 {
0231 switch (slot) {
0232 case 1:
0233 if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0)
0234 return -ENOENT;
0235
0236 if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
0237
0238 child->thread.debug.iac2 = 0;
0239 dbcr_iac_range(child) &= ~DBCR_IAC12MODE;
0240 }
0241 child->thread.debug.iac1 = 0;
0242 child->thread.debug.dbcr0 &= ~DBCR0_IAC1;
0243 break;
0244 case 2:
0245 if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0)
0246 return -ENOENT;
0247
0248 if (dbcr_iac_range(child) & DBCR_IAC12MODE)
0249
0250 return -EINVAL;
0251 child->thread.debug.iac2 = 0;
0252 child->thread.debug.dbcr0 &= ~DBCR0_IAC2;
0253 break;
0254 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
0255 case 3:
0256 if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0)
0257 return -ENOENT;
0258
0259 if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
0260
0261 child->thread.debug.iac4 = 0;
0262 dbcr_iac_range(child) &= ~DBCR_IAC34MODE;
0263 }
0264 child->thread.debug.iac3 = 0;
0265 child->thread.debug.dbcr0 &= ~DBCR0_IAC3;
0266 break;
0267 case 4:
0268 if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0)
0269 return -ENOENT;
0270
0271 if (dbcr_iac_range(child) & DBCR_IAC34MODE)
0272
0273 return -EINVAL;
0274 child->thread.debug.iac4 = 0;
0275 child->thread.debug.dbcr0 &= ~DBCR0_IAC4;
0276 break;
0277 #endif
0278 default:
0279 return -EINVAL;
0280 }
0281 return 0;
0282 }
0283
0284 static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
0285 {
0286 int byte_enable =
0287 (bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT)
0288 & 0xf;
0289 int condition_mode =
0290 bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE;
0291 int slot;
0292
0293 if (byte_enable && condition_mode == 0)
0294 return -EINVAL;
0295
0296 if (bp_info->addr >= TASK_SIZE)
0297 return -EIO;
0298
0299 if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) {
0300 slot = 1;
0301 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
0302 dbcr_dac(child) |= DBCR_DAC1R;
0303 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
0304 dbcr_dac(child) |= DBCR_DAC1W;
0305 child->thread.debug.dac1 = (unsigned long)bp_info->addr;
0306 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
0307 if (byte_enable) {
0308 child->thread.debug.dvc1 =
0309 (unsigned long)bp_info->condition_value;
0310 child->thread.debug.dbcr2 |=
0311 ((byte_enable << DBCR2_DVC1BE_SHIFT) |
0312 (condition_mode << DBCR2_DVC1M_SHIFT));
0313 }
0314 #endif
0315 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
0316 } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
0317
0318 return -ENOSPC;
0319 #endif
0320 } else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) {
0321 slot = 2;
0322 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
0323 dbcr_dac(child) |= DBCR_DAC2R;
0324 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
0325 dbcr_dac(child) |= DBCR_DAC2W;
0326 child->thread.debug.dac2 = (unsigned long)bp_info->addr;
0327 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
0328 if (byte_enable) {
0329 child->thread.debug.dvc2 =
0330 (unsigned long)bp_info->condition_value;
0331 child->thread.debug.dbcr2 |=
0332 ((byte_enable << DBCR2_DVC2BE_SHIFT) |
0333 (condition_mode << DBCR2_DVC2M_SHIFT));
0334 }
0335 #endif
0336 } else {
0337 return -ENOSPC;
0338 }
0339 child->thread.debug.dbcr0 |= DBCR0_IDM;
0340 regs_set_return_msr(child->thread.regs, child->thread.regs->msr | MSR_DE);
0341
0342 return slot + 4;
0343 }
0344
0345 static int del_dac(struct task_struct *child, int slot)
0346 {
0347 if (slot == 1) {
0348 if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
0349 return -ENOENT;
0350
0351 child->thread.debug.dac1 = 0;
0352 dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
0353 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
0354 if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
0355 child->thread.debug.dac2 = 0;
0356 child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE;
0357 }
0358 child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
0359 #endif
0360 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
0361 child->thread.debug.dvc1 = 0;
0362 #endif
0363 } else if (slot == 2) {
0364 if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
0365 return -ENOENT;
0366
0367 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
0368 if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE)
0369
0370 return -EINVAL;
0371 child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
0372 #endif
0373 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
0374 child->thread.debug.dvc2 = 0;
0375 #endif
0376 child->thread.debug.dac2 = 0;
0377 dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
0378 } else {
0379 return -EINVAL;
0380 }
0381
0382 return 0;
0383 }
0384
0385 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
0386 static int set_dac_range(struct task_struct *child,
0387 struct ppc_hw_breakpoint *bp_info)
0388 {
0389 int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK;
0390
0391
0392 if (bp_info->condition_mode)
0393 return -EINVAL;
0394
0395
0396
0397
0398
0399
0400
0401 if (bp_info->addr >= TASK_SIZE)
0402 return -EIO;
0403 if (mode == PPC_BREAKPOINT_MODE_MASK) {
0404
0405
0406
0407
0408 if (~((unsigned long)bp_info->addr2) >= TASK_SIZE)
0409 return -EIO;
0410 } else {
0411
0412
0413
0414 if (bp_info->addr2 >= TASK_SIZE)
0415 return -EIO;
0416 }
0417
0418 if (child->thread.debug.dbcr0 &
0419 (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
0420 return -ENOSPC;
0421
0422 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
0423 child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
0424 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
0425 child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
0426 child->thread.debug.dac1 = bp_info->addr;
0427 child->thread.debug.dac2 = bp_info->addr2;
0428 if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
0429 child->thread.debug.dbcr2 |= DBCR2_DAC12M;
0430 else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
0431 child->thread.debug.dbcr2 |= DBCR2_DAC12MX;
0432 else
0433 child->thread.debug.dbcr2 |= DBCR2_DAC12MM;
0434 regs_set_return_msr(child->thread.regs, child->thread.regs->msr | MSR_DE);
0435
0436 return 5;
0437 }
0438 #endif
0439
0440 long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
0441 {
0442 if (bp_info->version != 1)
0443 return -ENOTSUPP;
0444
0445
0446
0447 if (bp_info->trigger_type == 0 ||
0448 (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE |
0449 PPC_BREAKPOINT_TRIGGER_RW)) ||
0450 (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) ||
0451 (bp_info->condition_mode &
0452 ~(PPC_BREAKPOINT_CONDITION_MODE |
0453 PPC_BREAKPOINT_CONDITION_BE_ALL)))
0454 return -EINVAL;
0455 #if CONFIG_PPC_ADV_DEBUG_DVCS == 0
0456 if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
0457 return -EINVAL;
0458 #endif
0459
0460 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) {
0461 if (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE ||
0462 bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
0463 return -EINVAL;
0464 return set_instruction_bp(child, bp_info);
0465 }
0466 if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
0467 return set_dac(child, bp_info);
0468
0469 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
0470 return set_dac_range(child, bp_info);
0471 #else
0472 return -EINVAL;
0473 #endif
0474 }
0475
0476 long ppc_del_hwdebug(struct task_struct *child, long data)
0477 {
0478 int rc;
0479
0480 if (data <= 4)
0481 rc = del_instruction_bp(child, (int)data);
0482 else
0483 rc = del_dac(child, (int)data - 4);
0484
0485 if (!rc) {
0486 if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0,
0487 child->thread.debug.dbcr1)) {
0488 child->thread.debug.dbcr0 &= ~DBCR0_IDM;
0489 regs_set_return_msr(child->thread.regs,
0490 child->thread.regs->msr & ~MSR_DE);
0491 }
0492 }
0493 return rc;
0494 }