bp_signal.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Inspired by breakpoint overflow test done by
  3. * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests
  4. * (git://github.com/deater/perf_event_tests)
  5. */
  6. /*
  7. * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
  8. * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
  9. */
  10. #define __SANE_USERSPACE_TYPES__
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <sys/ioctl.h>
  16. #include <time.h>
  17. #include <fcntl.h>
  18. #include <signal.h>
  19. #include <sys/mman.h>
  20. #include <linux/compiler.h>
  21. #include <linux/hw_breakpoint.h>
  22. #include "tests.h"
  23. #include "debug.h"
  24. #include "perf.h"
  25. static int fd1;
  26. static int fd2;
  27. static int overflows;
  28. __attribute__ ((noinline))
  29. static int test_function(void)
  30. {
  31. return time(NULL);
  32. }
  33. static void sig_handler(int signum __maybe_unused,
  34. siginfo_t *oh __maybe_unused,
  35. void *uc __maybe_unused)
  36. {
  37. overflows++;
  38. if (overflows > 10) {
  39. /*
  40. * This should be executed only once during
  41. * this test, if we are here for the 10th
  42. * time, consider this the recursive issue.
  43. *
  44. * We can get out of here by disable events,
  45. * so no new SIGIO is delivered.
  46. */
  47. ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
  48. ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
  49. }
  50. }
  51. static int bp_event(void *fn, int setup_signal)
  52. {
  53. struct perf_event_attr pe;
  54. int fd;
  55. memset(&pe, 0, sizeof(struct perf_event_attr));
  56. pe.type = PERF_TYPE_BREAKPOINT;
  57. pe.size = sizeof(struct perf_event_attr);
  58. pe.config = 0;
  59. pe.bp_type = HW_BREAKPOINT_X;
  60. pe.bp_addr = (unsigned long) fn;
  61. pe.bp_len = sizeof(long);
  62. pe.sample_period = 1;
  63. pe.sample_type = PERF_SAMPLE_IP;
  64. pe.wakeup_events = 1;
  65. pe.disabled = 1;
  66. pe.exclude_kernel = 1;
  67. pe.exclude_hv = 1;
  68. fd = sys_perf_event_open(&pe, 0, -1, -1, 0);
  69. if (fd < 0) {
  70. pr_debug("failed opening event %llx\n", pe.config);
  71. return TEST_FAIL;
  72. }
  73. if (setup_signal) {
  74. fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
  75. fcntl(fd, F_SETSIG, SIGIO);
  76. fcntl(fd, F_SETOWN, getpid());
  77. }
  78. ioctl(fd, PERF_EVENT_IOC_RESET, 0);
  79. return fd;
  80. }
  81. static long long bp_count(int fd)
  82. {
  83. long long count;
  84. int ret;
  85. ret = read(fd, &count, sizeof(long long));
  86. if (ret != sizeof(long long)) {
  87. pr_debug("failed to read: %d\n", ret);
  88. return TEST_FAIL;
  89. }
  90. return count;
  91. }
  92. int test__bp_signal(void)
  93. {
  94. struct sigaction sa;
  95. long long count1, count2;
  96. /* setup SIGIO signal handler */
  97. memset(&sa, 0, sizeof(struct sigaction));
  98. sa.sa_sigaction = (void *) sig_handler;
  99. sa.sa_flags = SA_SIGINFO;
  100. if (sigaction(SIGIO, &sa, NULL) < 0) {
  101. pr_debug("failed setting up signal handler\n");
  102. return TEST_FAIL;
  103. }
  104. /*
  105. * We create following events:
  106. *
  107. * fd1 - breakpoint event on test_function with SIGIO
  108. * signal configured. We should get signal
  109. * notification each time the breakpoint is hit
  110. *
  111. * fd2 - breakpoint event on sig_handler without SIGIO
  112. * configured.
  113. *
  114. * Following processing should happen:
  115. * - execute test_function
  116. * - fd1 event breakpoint hit -> count1 == 1
  117. * - SIGIO is delivered -> overflows == 1
  118. * - fd2 event breakpoint hit -> count2 == 1
  119. *
  120. * The test case check following error conditions:
  121. * - we get stuck in signal handler because of debug
  122. * exception being triggered receursively due to
  123. * the wrong RF EFLAG management
  124. *
  125. * - we never trigger the sig_handler breakpoint due
  126. * to the rong RF EFLAG management
  127. *
  128. */
  129. fd1 = bp_event(test_function, 1);
  130. fd2 = bp_event(sig_handler, 0);
  131. ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
  132. ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
  133. /*
  134. * Kick off the test by trigering 'fd1'
  135. * breakpoint.
  136. */
  137. test_function();
  138. ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
  139. ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
  140. count1 = bp_count(fd1);
  141. count2 = bp_count(fd2);
  142. close(fd1);
  143. close(fd2);
  144. pr_debug("count1 %lld, count2 %lld, overflow %d\n",
  145. count1, count2, overflows);
  146. if (count1 != 1) {
  147. if (count1 == 11)
  148. pr_debug("failed: RF EFLAG recursion issue detected\n");
  149. else
  150. pr_debug("failed: wrong count for bp1%lld\n", count1);
  151. }
  152. if (overflows != 1)
  153. pr_debug("failed: wrong overflow hit\n");
  154. if (count2 != 1)
  155. pr_debug("failed: wrong count for bp2\n");
  156. return count1 == 1 && overflows == 1 && count2 == 1 ?
  157. TEST_OK : TEST_FAIL;
  158. }