0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #define _GNU_SOURCE
0020 #include <stdio.h>
0021 #include <stdlib.h>
0022 #include <signal.h>
0023 #include <string.h>
0024 #include <ucontext.h>
0025 #include <unistd.h>
0026 #include <sys/mman.h>
0027
0028 #include "tm.h"
0029 #include "utils.h"
0030 #include "reg.h"
0031
0032 #define COUNT_MAX 5000
0033
0034
0035
0036
0037
0038
0039 #ifndef __powerpc64__
0040 #undef MSR_TS_S
0041 #define MSR_TS_S 0
0042 #endif
0043
0044
0045 ucontext_t init_context;
0046
0047
0048 static volatile int count;
0049
0050 void usr_signal_handler(int signo, siginfo_t *si, void *uc)
0051 {
0052 ucontext_t *ucp = uc;
0053 int ret;
0054
0055
0056
0057
0058
0059
0060 ucp->uc_link = mmap(NULL, sizeof(ucontext_t),
0061 PROT_READ | PROT_WRITE,
0062 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
0063 if (ucp->uc_link == (void *)-1) {
0064 perror("Mmap failed");
0065 exit(-1);
0066 }
0067
0068
0069 ret = madvise(ucp->uc_link, sizeof(ucontext_t), MADV_DONTNEED);
0070 if (ret) {
0071 perror("madvise failed");
0072 exit(-1);
0073 }
0074
0075 memcpy(&ucp->uc_link->uc_mcontext, &ucp->uc_mcontext,
0076 sizeof(ucp->uc_mcontext));
0077
0078
0079 UCONTEXT_MSR(ucp) |= MSR_TS_S;
0080
0081
0082
0083
0084
0085 if (fork() == 0) {
0086
0087
0088
0089
0090
0091 count = COUNT_MAX;
0092 }
0093
0094
0095
0096
0097
0098 }
0099
0100 void seg_signal_handler(int signo, siginfo_t *si, void *uc)
0101 {
0102 count++;
0103
0104
0105 setcontext(&init_context);
0106 }
0107
0108 void tm_trap_test(void)
0109 {
0110 struct sigaction usr_sa, seg_sa;
0111 stack_t ss;
0112
0113 usr_sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
0114 usr_sa.sa_sigaction = usr_signal_handler;
0115
0116 seg_sa.sa_flags = SA_SIGINFO;
0117 seg_sa.sa_sigaction = seg_signal_handler;
0118
0119
0120
0121
0122
0123 getcontext(&init_context);
0124
0125 while (count < COUNT_MAX) {
0126
0127 ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
0128 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
0129 ss.ss_size = SIGSTKSZ;
0130 ss.ss_flags = 0;
0131
0132 if (ss.ss_sp == (void *)-1) {
0133 perror("mmap error\n");
0134 exit(-1);
0135 }
0136
0137
0138 if (madvise(ss.ss_sp, SIGSTKSZ, MADV_DONTNEED)) {
0139 perror("madvise\n");
0140 exit(-1);
0141 }
0142
0143
0144
0145
0146
0147 if (sigaltstack(&ss, NULL)) {
0148 perror("sigaltstack\n");
0149 exit(-1);
0150 }
0151
0152
0153 sigaction(SIGUSR1, &usr_sa, NULL);
0154
0155 sigaction(SIGSEGV, &seg_sa, NULL);
0156
0157 raise(SIGUSR1);
0158 count++;
0159 }
0160 }
0161
0162 int tm_signal_context_force_tm(void)
0163 {
0164 SKIP_IF(!have_htm());
0165
0166
0167
0168
0169
0170 SKIP_IF(!is_ppc64le());
0171
0172 tm_trap_test();
0173
0174 return EXIT_SUCCESS;
0175 }
0176
0177 int main(int argc, char **argv)
0178 {
0179 test_harness(tm_signal_context_force_tm, "tm_signal_context_force_tm");
0180 }