~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/mm/wild_bctr.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0+
  2 /*
  3  * Copyright 2018, Michael Ellerman, IBM Corp.
  4  *
  5  * Test that an out-of-bounds branch to counter behaves as expected.
  6  */
  7 
  8 #include <setjmp.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <sys/mman.h>
 13 #include <sys/types.h>
 14 #include <sys/wait.h>
 15 #include <ucontext.h>
 16 #include <unistd.h>
 17 
 18 #include "utils.h"
 19 
 20 
 21 #define BAD_NIP 0x788c545a18000000ull
 22 
 23 static struct pt_regs signal_regs;
 24 static jmp_buf setjmp_env;
 25 
 26 static void save_regs(ucontext_t *ctxt)
 27 {
 28         struct pt_regs *regs = ctxt->uc_mcontext.regs;
 29 
 30         memcpy(&signal_regs, regs, sizeof(signal_regs));
 31 }
 32 
 33 static void segv_handler(int signum, siginfo_t *info, void *ctxt_v)
 34 {
 35         save_regs(ctxt_v);
 36         longjmp(setjmp_env, 1);
 37 }
 38 
 39 static void usr2_handler(int signum, siginfo_t *info, void *ctxt_v)
 40 {
 41         save_regs(ctxt_v);
 42 }
 43 
 44 static int ok(void)
 45 {
 46         printf("Everything is OK in here.\n");
 47         return 0;
 48 }
 49 
 50 #define REG_POISON      0x5a5a
 51 #define POISONED_REG(n) ((((unsigned long)REG_POISON) << 48) | ((n) << 32) | \
 52                          (((unsigned long)REG_POISON) << 16) | (n))
 53 
 54 static inline void poison_regs(void)
 55 {
 56         #define POISON_REG(n)   \
 57           "lis  " __stringify(n) "," __stringify(REG_POISON) ";" \
 58           "addi " __stringify(n) "," __stringify(n) "," __stringify(n) ";" \
 59           "sldi " __stringify(n) "," __stringify(n) ", 32 ;" \
 60           "oris " __stringify(n) "," __stringify(n) "," __stringify(REG_POISON) ";" \
 61           "addi " __stringify(n) "," __stringify(n) "," __stringify(n) ";"
 62 
 63         asm (POISON_REG(15)
 64              POISON_REG(16)
 65              POISON_REG(17)
 66              POISON_REG(18)
 67              POISON_REG(19)
 68              POISON_REG(20)
 69              POISON_REG(21)
 70              POISON_REG(22)
 71              POISON_REG(23)
 72              POISON_REG(24)
 73              POISON_REG(25)
 74              POISON_REG(26)
 75              POISON_REG(27)
 76              POISON_REG(28)
 77              POISON_REG(29)
 78              : // inputs
 79              : // outputs
 80              : "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25",
 81                "26", "27", "28", "29"
 82         );
 83         #undef POISON_REG
 84 }
 85 
 86 static int check_regs(void)
 87 {
 88         unsigned long i;
 89 
 90         for (i = 15; i <= 29; i++)
 91                 FAIL_IF(signal_regs.gpr[i] != POISONED_REG(i));
 92 
 93         printf("Regs OK\n");
 94         return 0;
 95 }
 96 
 97 static void dump_regs(void)
 98 {
 99         for (int i = 0; i < 32; i += 4) {
100                 printf("r%02d 0x%016lx  r%02d 0x%016lx  " \
101                        "r%02d 0x%016lx  r%02d 0x%016lx\n",
102                        i, signal_regs.gpr[i],
103                        i+1, signal_regs.gpr[i+1],
104                        i+2, signal_regs.gpr[i+2],
105                        i+3, signal_regs.gpr[i+3]);
106         }
107 }
108 
109 #ifdef _CALL_AIXDESC
110 struct opd {
111         unsigned long ip;
112         unsigned long toc;
113         unsigned long env;
114 };
115 static struct opd bad_opd = {
116         .ip = BAD_NIP,
117 };
118 #define BAD_FUNC (&bad_opd)
119 #else
120 #define BAD_FUNC BAD_NIP
121 #endif
122 
123 int test_wild_bctr(void)
124 {
125         int (*func_ptr)(void);
126         struct sigaction segv = {
127                 .sa_sigaction = segv_handler,
128                 .sa_flags = SA_SIGINFO
129         };
130         struct sigaction usr2 = {
131                 .sa_sigaction = usr2_handler,
132                 .sa_flags = SA_SIGINFO
133         };
134 
135         FAIL_IF(sigaction(SIGSEGV, &segv, NULL));
136         FAIL_IF(sigaction(SIGUSR2, &usr2, NULL));
137 
138         bzero(&signal_regs, sizeof(signal_regs));
139 
140         if (setjmp(setjmp_env) == 0) {
141                 func_ptr = ok;
142                 func_ptr();
143 
144                 kill(getpid(), SIGUSR2);
145                 printf("Regs before:\n");
146                 dump_regs();
147                 bzero(&signal_regs, sizeof(signal_regs));
148 
149                 poison_regs();
150 
151                 func_ptr = (int (*)(void))BAD_FUNC;
152                 func_ptr();
153 
154                 FAIL_IF(1); /* we didn't segv? */
155         }
156 
157         FAIL_IF(signal_regs.nip != BAD_NIP);
158 
159         printf("All good - took SEGV as expected branching to 0x%llx\n", BAD_NIP);
160 
161         dump_regs();
162         FAIL_IF(check_regs());
163 
164         return 0;
165 }
166 
167 int main(void)
168 {
169         return test_harness(test_wild_bctr, "wild_bctr");
170 }
171 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php