optprobes_head.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Code to prepare detour buffer for optprobes in Kernel.
  4. *
  5. * Copyright 2017, Anju T, IBM Corp.
  6. */
  7. #include <asm/ppc_asm.h>
  8. #include <asm/ptrace.h>
  9. #include <asm/asm-offsets.h>
  10. #ifdef CONFIG_PPC64
  11. #define SAVE_30GPRS(base) SAVE_GPRS(2, 31, base)
  12. #define REST_30GPRS(base) REST_GPRS(2, 31, base)
  13. #define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop; nop; nop
  14. #else
  15. #define SAVE_30GPRS(base) stmw r2, GPR2(base)
  16. #define REST_30GPRS(base) lmw r2, GPR2(base)
  17. #define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop
  18. #endif
  19. #define OPT_SLOT_SIZE 65536
  20. .balign 4
  21. /*
  22. * Reserve an area to allocate slots for detour buffer.
  23. * This is part of .text section (rather than vmalloc area)
  24. * as this needs to be within 32MB of the probed address.
  25. */
  26. .global optinsn_slot
  27. optinsn_slot:
  28. .space OPT_SLOT_SIZE
  29. /*
  30. * Optprobe template:
  31. * This template gets copied into one of the slots in optinsn_slot
  32. * and gets fixed up with real optprobe structures et al.
  33. */
  34. .global optprobe_template_entry
  35. optprobe_template_entry:
  36. /* Create an in-memory pt_regs */
  37. PPC_STLU r1,-INT_FRAME_SIZE(r1)
  38. SAVE_GPR(0,r1)
  39. /* Save the previous SP into stack */
  40. addi r0,r1,INT_FRAME_SIZE
  41. PPC_STL r0,GPR1(r1)
  42. SAVE_30GPRS(r1)
  43. /* Save SPRS */
  44. mfmsr r5
  45. PPC_STL r5,_MSR(r1)
  46. li r5,0x700
  47. PPC_STL r5,_TRAP(r1)
  48. li r5,0
  49. PPC_STL r5,ORIG_GPR3(r1)
  50. PPC_STL r5,RESULT(r1)
  51. mfctr r5
  52. PPC_STL r5,_CTR(r1)
  53. mflr r5
  54. PPC_STL r5,_LINK(r1)
  55. mfspr r5,SPRN_XER
  56. PPC_STL r5,_XER(r1)
  57. mfcr r5
  58. PPC_STL r5,_CCR(r1)
  59. #ifdef CONFIG_PPC64
  60. lbz r5,PACAIRQSOFTMASK(r13)
  61. std r5,SOFTE(r1)
  62. #endif
  63. /*
  64. * We may get here from a module, so load the kernel TOC in r2.
  65. * The original TOC gets restored when pt_regs is restored
  66. * further below.
  67. */
  68. #ifdef CONFIG_PPC64
  69. LOAD_PACA_TOC()
  70. #endif
  71. .global optprobe_template_op_address
  72. optprobe_template_op_address:
  73. /*
  74. * Parameters to optimized_callback():
  75. * 1. optimized_kprobe structure in r3
  76. */
  77. TEMPLATE_FOR_IMM_LOAD_INSNS
  78. /* 2. pt_regs pointer in r4 */
  79. addi r4,r1,STACK_FRAME_OVERHEAD
  80. .global optprobe_template_call_handler
  81. optprobe_template_call_handler:
  82. /* Branch to optimized_callback() */
  83. nop
  84. /*
  85. * Parameters for instruction emulation:
  86. * 1. Pass SP in register r3.
  87. */
  88. addi r3,r1,STACK_FRAME_OVERHEAD
  89. .global optprobe_template_insn
  90. optprobe_template_insn:
  91. /* 2, Pass instruction to be emulated in r4 */
  92. TEMPLATE_FOR_IMM_LOAD_INSNS
  93. .global optprobe_template_call_emulate
  94. optprobe_template_call_emulate:
  95. /* Branch to emulate_step() */
  96. nop
  97. /*
  98. * All done.
  99. * Now, restore the registers...
  100. */
  101. PPC_LL r5,_MSR(r1)
  102. mtmsr r5
  103. PPC_LL r5,_CTR(r1)
  104. mtctr r5
  105. PPC_LL r5,_LINK(r1)
  106. mtlr r5
  107. PPC_LL r5,_XER(r1)
  108. mtxer r5
  109. PPC_LL r5,_CCR(r1)
  110. mtcr r5
  111. REST_GPR(0,r1)
  112. REST_30GPRS(r1)
  113. /* Restore the previous SP */
  114. addi r1,r1,INT_FRAME_SIZE
  115. .global optprobe_template_ret
  116. optprobe_template_ret:
  117. /* ... and jump back from trampoline */
  118. nop
  119. .global optprobe_template_end
  120. optprobe_template_end: