Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/watchpoints: Don't track info persistently

info is cheap to retrieve, and is likely optimised by the compiler
anyway. On the other hand, propagating it across the functions makes it
possible to be inconsistent and adds needless complexity.

Remove it, and invoke counter_arch_bp() when we need to work with it.

As we don't persist it, we just use the local bp array to track whether
we are ignoring a breakpoint.

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20230801011744.153973-3-bgray@linux.ibm.com

authored by

Benjamin Gray and committed by
Michael Ellerman
668a6ec6 8f8f1cd6

+32 -28
+32 -28
arch/powerpc/kernel/hw_breakpoint.c
··· 538 538 * We've failed in reliably handling the hw-breakpoint. Unregister 539 539 * it and throw a warning message to let the user know about it. 540 540 */ 541 - static void handler_error(struct perf_event *bp, struct arch_hw_breakpoint *info) 541 + static void handler_error(struct perf_event *bp) 542 542 { 543 543 WARN(1, "Unable to handle hardware breakpoint. Breakpoint at 0x%lx will be disabled.", 544 - info->address); 544 + counter_arch_bp(bp)->address); 545 545 perf_event_disable_inatomic(bp); 546 546 } 547 547 548 - static void larx_stcx_err(struct perf_event *bp, struct arch_hw_breakpoint *info) 548 + static void larx_stcx_err(struct perf_event *bp) 549 549 { 550 550 printk_ratelimited("Breakpoint hit on instruction that can't be emulated. Breakpoint at 0x%lx will be disabled.\n", 551 - info->address); 551 + counter_arch_bp(bp)->address); 552 552 perf_event_disable_inatomic(bp); 553 553 } 554 554 555 555 static bool stepping_handler(struct pt_regs *regs, struct perf_event **bp, 556 - struct arch_hw_breakpoint **info, int *hit, 557 - ppc_inst_t instr) 556 + int *hit, ppc_inst_t instr) 558 557 { 559 558 int i; 560 559 int stepped; ··· 564 565 if (!hit[i]) 565 566 continue; 566 567 current->thread.last_hit_ubp[i] = bp[i]; 567 - info[i] = NULL; 568 + bp[i] = NULL; 568 569 } 569 570 regs_set_return_msr(regs, regs->msr | MSR_SE); 570 571 return false; ··· 575 576 for (i = 0; i < nr_wp_slots(); i++) { 576 577 if (!hit[i]) 577 578 continue; 578 - handler_error(bp[i], info[i]); 579 - info[i] = NULL; 579 + handler_error(bp[i]); 580 + bp[i] = NULL; 580 581 } 581 582 return false; 582 583 } 583 584 return true; 584 585 } 585 586 586 - static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info, 587 + static void handle_p10dd1_spurious_exception(struct perf_event **bp, 587 588 int *hit, unsigned long ea) 588 589 { 589 590 int i; ··· 595 596 * spurious exception. 596 597 */ 597 598 for (i = 0; i < nr_wp_slots(); i++) { 598 - if (!info[i]) 599 + struct arch_hw_breakpoint *info; 600 + 601 + if (!bp[i]) 599 602 continue; 600 603 601 - hw_end_addr = ALIGN(info[i]->address + info[i]->len, HW_BREAKPOINT_SIZE); 604 + info = counter_arch_bp(bp[i]); 605 + 606 + hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE); 602 607 603 608 /* 604 609 * Ending address of DAWR range is less than starting ··· 632 629 return; 633 630 634 631 for (i = 0; i < nr_wp_slots(); i++) { 635 - if (info[i]) { 632 + if (bp[i]) { 636 633 hit[i] = 1; 637 - info[i]->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; 634 + counter_arch_bp(bp[i])->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; 638 635 } 639 636 } 640 637 } ··· 645 642 int rc = NOTIFY_STOP; 646 643 struct perf_event *bp[HBP_NUM_MAX] = { NULL }; 647 644 struct pt_regs *regs = args->regs; 648 - struct arch_hw_breakpoint *info[HBP_NUM_MAX] = { NULL }; 649 645 int i; 650 646 int hit[HBP_NUM_MAX] = {0}; 651 647 int nr_hit = 0; ··· 669 667 wp_get_instr_detail(regs, &instr, &type, &size, &ea); 670 668 671 669 for (i = 0; i < nr_wp_slots(); i++) { 670 + struct arch_hw_breakpoint *info; 671 + 672 672 bp[i] = __this_cpu_read(bp_per_reg[i]); 673 673 if (!bp[i]) 674 674 continue; 675 675 676 - info[i] = counter_arch_bp(bp[i]); 677 - info[i]->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ; 676 + info = counter_arch_bp(bp[i]); 677 + info->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ; 678 678 679 - if (wp_check_constraints(regs, instr, ea, type, size, info[i])) { 679 + if (wp_check_constraints(regs, instr, ea, type, size, info)) { 680 680 if (!IS_ENABLED(CONFIG_PPC_8xx) && 681 681 ppc_inst_equal(instr, ppc_inst(0))) { 682 - handler_error(bp[i], info[i]); 683 - info[i] = NULL; 682 + handler_error(bp[i]); 683 + bp[i] = NULL; 684 684 err = 1; 685 685 continue; 686 686 } ··· 701 697 /* Workaround for Power10 DD1 */ 702 698 if (!IS_ENABLED(CONFIG_PPC_8xx) && mfspr(SPRN_PVR) == 0x800100 && 703 699 is_octword_vsx_instr(type, size)) { 704 - handle_p10dd1_spurious_exception(info, hit, ea); 700 + handle_p10dd1_spurious_exception(bp, hit, ea); 705 701 } else { 706 702 rc = NOTIFY_DONE; 707 703 goto out; ··· 719 715 if (!hit[i]) 720 716 continue; 721 717 perf_bp_event(bp[i], regs); 722 - info[i] = NULL; 718 + bp[i] = NULL; 723 719 } 724 720 rc = NOTIFY_DONE; 725 721 goto reset; ··· 730 726 for (i = 0; i < nr_wp_slots(); i++) { 731 727 if (!hit[i]) 732 728 continue; 733 - larx_stcx_err(bp[i], info[i]); 734 - info[i] = NULL; 729 + larx_stcx_err(bp[i]); 730 + bp[i] = NULL; 735 731 } 736 732 goto reset; 737 733 } 738 734 739 - if (!stepping_handler(regs, bp, info, hit, instr)) 735 + if (!stepping_handler(regs, bp, hit, instr)) 740 736 goto reset; 741 737 } 742 738 ··· 747 743 for (i = 0; i < nr_wp_slots(); i++) { 748 744 if (!hit[i]) 749 745 continue; 750 - if (!(info[i]->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) 746 + if (!(counter_arch_bp(bp[i])->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) 751 747 perf_bp_event(bp[i], regs); 752 748 } 753 749 754 750 reset: 755 751 for (i = 0; i < nr_wp_slots(); i++) { 756 - if (!info[i]) 752 + if (!bp[i]) 757 753 continue; 758 - __set_breakpoint(i, info[i]); 754 + __set_breakpoint(i, counter_arch_bp(bp[i])); 759 755 } 760 756 761 757 out: