optprobes_head.S 2.8 KB

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