aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/kprobes.c89
1 files changed, 45 insertions, 44 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 169ec3a7156c..9c9c8fcdfbdc 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
90 p->ainsn.target_br_reg = 0; 90 p->ainsn.target_br_reg = 0;
91 91
92 /* Check for Break instruction 92 /* Check for Break instruction
93 * Bits 37:40 Major opcode to be zero 93 * Bits 37:40 Major opcode to be zero
94 * Bits 27:32 X6 to be zero 94 * Bits 27:32 X6 to be zero
95 * Bits 32:35 X3 to be zero 95 * Bits 32:35 X3 to be zero
96 */ 96 */
@@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
104 switch (major_opcode) { 104 switch (major_opcode) {
105 case INDIRECT_CALL_OPCODE: 105 case INDIRECT_CALL_OPCODE:
106 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; 106 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
107 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); 107 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
108 break; 108 break;
109 case IP_RELATIVE_PREDICT_OPCODE: 109 case IP_RELATIVE_PREDICT_OPCODE:
110 case IP_RELATIVE_BRANCH_OPCODE: 110 case IP_RELATIVE_BRANCH_OPCODE:
111 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; 111 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
112 break; 112 break;
113 case IP_RELATIVE_CALL_OPCODE: 113 case IP_RELATIVE_CALL_OPCODE:
114 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; 114 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
115 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; 115 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
116 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); 116 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
117 break; 117 break;
118 } 118 }
119 } else if (bundle_encoding[template][slot] == X) { 119 } else if (bundle_encoding[template][slot] == X) {
120 switch (major_opcode) { 120 switch (major_opcode) {
121 case LONG_CALL_OPCODE: 121 case LONG_CALL_OPCODE:
122 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; 122 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
@@ -258,18 +258,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
258 258
259 switch (slot) { 259 switch (slot) {
260 case 0: 260 case 0:
261 *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); 261 *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
262 *kprobe_inst = bundle->quad0.slot0; 262 *kprobe_inst = bundle->quad0.slot0;
263 break; 263 break;
264 case 1: 264 case 1:
265 *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); 265 *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
266 kprobe_inst_p0 = bundle->quad0.slot1_p0; 266 kprobe_inst_p0 = bundle->quad0.slot1_p0;
267 kprobe_inst_p1 = bundle->quad1.slot1_p1; 267 kprobe_inst_p1 = bundle->quad1.slot1_p1;
268 *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); 268 *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
269 break; 269 break;
270 case 2: 270 case 2:
271 *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); 271 *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
272 *kprobe_inst = bundle->quad1.slot2; 272 *kprobe_inst = bundle->quad1.slot2;
273 break; 273 break;
274 } 274 }
275} 275}
@@ -290,11 +290,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
290 return -EINVAL; 290 return -EINVAL;
291 } 291 }
292 292
293 if (in_ivt_functions(addr)) { 293 if (in_ivt_functions(addr)) {
294 printk(KERN_WARNING "Kprobes can't be inserted inside " 294 printk(KERN_WARNING "Kprobes can't be inserted inside "
295 "IVT functions at 0x%lx\n", addr); 295 "IVT functions at 0x%lx\n", addr);
296 return -EINVAL; 296 return -EINVAL;
297 } 297 }
298 298
299 if (slot == 1 && bundle_encoding[template][1] != L) { 299 if (slot == 1 && bundle_encoding[template][1] != L) {
300 printk(KERN_WARNING "Inserting kprobes on slot #1 " 300 printk(KERN_WARNING "Inserting kprobes on slot #1 "
@@ -424,14 +424,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
424 bundle_t *bundle; 424 bundle_t *bundle;
425 425
426 bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle; 426 bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
427 template = bundle->quad0.template; 427 template = bundle->quad0.template;
428 428
429 if(valid_kprobe_addr(template, slot, addr)) 429 if(valid_kprobe_addr(template, slot, addr))
430 return -EINVAL; 430 return -EINVAL;
431 431
432 /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ 432 /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
433 if (slot == 1 && bundle_encoding[template][1] == L) 433 if (slot == 1 && bundle_encoding[template][1] == L)
434 slot++; 434 slot++;
435 435
436 /* Get kprobe_inst and major_opcode from the bundle */ 436 /* Get kprobe_inst and major_opcode from the bundle */
437 get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); 437 get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
@@ -489,21 +489,22 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
489 */ 489 */
490static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 490static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
491{ 491{
492 unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); 492 unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
493 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; 493 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
494 unsigned long template; 494 unsigned long template;
495 int slot = ((unsigned long)p->addr & 0xf); 495 int slot = ((unsigned long)p->addr & 0xf);
496 496
497 template = p->ainsn.insn->bundle.quad0.template; 497 template = p->ainsn.insn->bundle.quad0.template;
498 498
499 if (slot == 1 && bundle_encoding[template][1] == L) 499 if (slot == 1 && bundle_encoding[template][1] == L)
500 slot = 2; 500 slot = 2;
501 501
502 if (p->ainsn.inst_flag) { 502 if (p->ainsn.inst_flag) {
503 503
504 if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) { 504 if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
505 /* Fix relative IP address */ 505 /* Fix relative IP address */
506 regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr; 506 regs->cr_iip = (regs->cr_iip - bundle_addr) +
507 resume_addr;
507 } 508 }
508 509
509 if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) { 510 if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
@@ -540,18 +541,18 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
540 } 541 }
541 542
542 if (slot == 2) { 543 if (slot == 2) {
543 if (regs->cr_iip == bundle_addr + 0x10) { 544 if (regs->cr_iip == bundle_addr + 0x10) {
544 regs->cr_iip = resume_addr + 0x10; 545 regs->cr_iip = resume_addr + 0x10;
545 } 546 }
546 } else { 547 } else {
547 if (regs->cr_iip == bundle_addr) { 548 if (regs->cr_iip == bundle_addr) {
548 regs->cr_iip = resume_addr; 549 regs->cr_iip = resume_addr;
549 } 550 }
550 } 551 }
551 552
552turn_ss_off: 553turn_ss_off:
553 /* Turn off Single Step bit */ 554 /* Turn off Single Step bit */
554 ia64_psr(regs)->ss = 0; 555 ia64_psr(regs)->ss = 0;
555} 556}
556 557
557static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) 558static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
@@ -587,7 +588,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
587 588
588 /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ 589 /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
589 if (slot == 1 && bundle_encoding[template][1] == L) 590 if (slot == 1 && bundle_encoding[template][1] == L)
590 slot++; 591 slot++;
591 592
592 /* Get Kprobe probe instruction at given slot*/ 593 /* Get Kprobe probe instruction at given slot*/
593 get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode); 594 get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode);
@@ -627,7 +628,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
627 if (p) { 628 if (p) {
628 if ((kcb->kprobe_status == KPROBE_HIT_SS) && 629 if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
629 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { 630 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
630 ia64_psr(regs)->ss = 0; 631 ia64_psr(regs)->ss = 0;
631 goto no_kprobe; 632 goto no_kprobe;
632 } 633 }
633 /* We have reentered the pre_kprobe_handler(), since 634 /* We have reentered the pre_kprobe_handler(), since
@@ -887,7 +888,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
887 * fix the return address to our jprobe_inst_return() function 888 * fix the return address to our jprobe_inst_return() function
888 * in the jprobes.S file 889 * in the jprobes.S file
889 */ 890 */
890 regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; 891 regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
891 892
892 return 1; 893 return 1;
893} 894}