1/* 2 * Copyright 2019, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include <autoconf.h> 14/* test_registers (below) runs in a context without a valid SP. At the end it 15 * needs to call into a C function and needs a valid stack to do this. We 16 * provide it a stack it can switch to here. 17 */ 18.section .bss 19.align 4 20.space 4096 21_safe_stack: 22.section .text 23#if defined(CONFIG_ARCH_AARCH32) 24 25/* Trampoline for providing the thread a valid stack before entering 26 * reply_to_parent. No blx required because reply_to_parent does not 27 * return. 28 */ 29reply_trampoline: 30 ldr sp, =_safe_stack 31 b reply_to_parent 32 33.global test_registers 34test_registers: 35 /* Assume the PC and CPSR are correct because there's no good way of 36 * testing them. Test each of the registers against the magic numbers our 37 * parent set. 38 */ 39 cmp sp, #13 40 bne test_registers_fail 41 cmp r0, #15 42 bne test_registers_fail 43 cmp r1, #1 44 bne test_registers_fail 45 cmp r2, #2 46 bne test_registers_fail 47 cmp r3, #3 48 bne test_registers_fail 49 cmp r4, #4 50 bne test_registers_fail 51 cmp r5, #5 52 bne test_registers_fail 53 cmp r6, #6 54 bne test_registers_fail 55 cmp r7, #7 56 bne test_registers_fail 57 cmp r8, #8 58 bne test_registers_fail 59 cmp r9, #9 60 bne test_registers_fail 61 cmp r10, #10 62 bne test_registers_fail 63 cmp r11, #11 64 bne test_registers_fail 65 cmp r12, #12 66 bne test_registers_fail 67 cmp r14, #14 68 bne test_registers_fail 69 70 /* Return success. Note that we don't bother saving registers or bl because 71 * we're not planning to return here and we don't have a valid stack. 72 */ 73 mov r0, #0 74 b reply_trampoline 75 76 /* Return failure. */ 77test_registers_fail: 78 mov r0, #1 79 b reply_trampoline 80 81#elif defined(CONFIG_ARCH_AARCH64) 82 /* Trampoline for providing the thread a valid stack before entering 83 * reply_to_parent. No blx required because reply_to_parent does not 84 * return. 85 */ 86reply_trampoline: 87 ldr x1, =_safe_stack 88 mov sp, x1 89 b reply_to_parent 90 91.global test_registers 92test_registers: 93 cmp sp, #1 94 bne test_registers_fail 95 cmp x0, #2 96 bne test_registers_fail 97 cmp x1, #3 98 bne test_registers_fail 99 cmp x2, #4 100 bne test_registers_fail 101 cmp x3, #5 102 bne test_registers_fail 103 cmp x4, #6 104 bne test_registers_fail 105 cmp x5, #7 106 bne test_registers_fail 107 cmp x6, #8 108 bne test_registers_fail 109 cmp x7, #9 110 bne test_registers_fail 111 cmp x8, #10 112 bne test_registers_fail 113 cmp x9, #11 114 bne test_registers_fail 115 cmp x10, #12 116 bne test_registers_fail 117 cmp x11, #13 118 bne test_registers_fail 119 cmp x12, #14 120 bne test_registers_fail 121 cmp x13, #15 122 bne test_registers_fail 123 cmp x14, #16 124 bne test_registers_fail 125 cmp x15, #17 126 bne test_registers_fail 127 cmp x16, #18 128 bne test_registers_fail 129 cmp x17, #19 130 bne test_registers_fail 131 cmp x18, #20 132 bne test_registers_fail 133 cmp x19, #21 134 bne test_registers_fail 135 cmp x20, #22 136 bne test_registers_fail 137 cmp x21, #23 138 bne test_registers_fail 139 cmp x22, #24 140 bne test_registers_fail 141 cmp x23, #25 142 bne test_registers_fail 143 cmp x24, #26 144 bne test_registers_fail 145 cmp x25, #27 146 bne test_registers_fail 147 cmp x26, #28 148 bne test_registers_fail 149 cmp x27, #29 150 bne test_registers_fail 151 cmp x28, #30 152 bne test_registers_fail 153 cmp x29, #31 154 bne test_registers_fail 155 cmp x30, #32 156 bne test_registers_fail 157 158 /* Return success. Note that we don't bother saving registers or bl because 159 * we're not planning to return here and we don't have a valid stack. 160 */ 161 mov x0, #0 162 b reply_trampoline 163 164/* Return failure. */ 165test_registers_fail: 166 mov x0, #1 167 b reply_trampoline 168 169#elif defined(CONFIG_ARCH_X86_64) 170reply_trampoline: 171 leaq _safe_stack, %rsp 172 movq %rax, %rdi 173 call reply_to_parent 174.global test_registers 175test_registers: 176 jb rflags_ok 177 jmp test_registers_fail 178 rflags_ok: 179 cmpq $0x0000000a, %rax 180 jne test_registers_fail 181 movq $2, %rax 182 cmpq $0x0000000b, %rbx 183 jne test_registers_fail 184 movq $3, %rax 185 cmpq $0x0000000c, %rcx 186 jne test_registers_fail 187 movq $4, %rax 188 cmpq $0x0000000d, %rdx 189 jne test_registers_fail 190 movq $5, %rax 191 cmpq $0x00000005, %rsi 192 jne test_registers_fail 193 movq $6, %rax 194 cmpq $0x00000002, %rdi 195 jne test_registers_fail 196 movq $7, %rax 197 cmpq $0x00000003, %rbp 198 jne test_registers_fail 199 movq $8, %rax 200 cmpq $0x00000004, %rsp 201 jne test_registers_fail 202 movq $9, %rax 203 cmpq $0x00000088, %r8 204 jne test_registers_fail 205 movq $100, %rax 206 cmpq $0x00000099, %r9 207 jne test_registers_fail 208 movq $11, %rax 209 cmpq $0x00000010, %r10 210 jne test_registers_fail 211 movq $12, %rax 212 cmpq $0x00000011, %r11 213 jne test_registers_fail 214 movq $13, %rax 215 cmpq $0x00000012, %r12 216 jne test_registers_fail 217 movq $14, %rax 218 cmpq $0x00000013, %r13 219 jne test_registers_fail 220 movq $15, %rax 221 cmpq $0x00000014, %r14 222 jne test_registers_fail 223 movq $16, %rax 224 cmpq $0x00000015, %r15 225 jne test_registers_fail 226 movq $0, %rax 227 jmp reply_trampoline 228 test_registers_fail: 229 movq $1, %rax 230 jmp reply_trampoline 231 232#elif defined(CONFIG_ARCH_X86) 233 /* As for the ARM implementation above, but we also need to massage the 234 * calling convention by taking the value test_registers passed us in EAX 235 * and put it on the stack where reply_to_parent expects it. 236 */ 237reply_trampoline: 238 leal _safe_stack, %esp 239 pushl %eax 240 call reply_to_parent 241 242.global test_registers 243test_registers: 244 /* Assume EIP, GS and FS are correct. Is there a good way to 245 * test these? 246 * EIP - If this is incorrect we'll never arrive at this function. 247 * GS - With an incorrect GDT selector we fault and die immediately. 248 * FS - Overwritten by the kernel before we jump here. 249 */ 250 251 /* We need to test EFLAGS indirectly because we can't cmp it. The jb 252 * should only be taken if CF (bit 0) is set. 253 */ 254 jb eflags_ok 255 jmp test_registers_fail 256 eflags_ok: 257 cmpl $0x0000000a, %eax 258 jne test_registers_fail 259 cmpl $0x0000000b, %ebx 260 jne test_registers_fail 261 cmpl $0x0000000c, %ecx 262 jne test_registers_fail 263 cmpl $0x0000000d, %edx 264 jne test_registers_fail 265 cmpl $0x00000005, %esi 266 jne test_registers_fail 267 cmpl $0x00000002, %edi 268 jne test_registers_fail 269 cmpl $0x00000003, %ebp 270 jne test_registers_fail 271 cmpl $0x00000004, %esp 272 jne test_registers_fail 273 274 /* Return success. Note we use a custom calling convention because we 275 * don't have a valid stack. 276 */ 277 movl $0, %eax 278 jmp reply_trampoline 279 280 /* Return failure. */ 281test_registers_fail: 282 movl $1, %eax 283 jmp reply_trampoline 284#elif defined(CONFIG_ARCH_RISCV) 285/* Trampoline for providing the thread a valid stack before entering 286 * reply_to_parent. No jal required because reply_to_parent does not 287 * return. 288 */ 289reply_trampoline: 290 la a1, _safe_stack 291 mv sp, a1 292 j reply_to_parent 293 294.global test_registers 295test_registers: 296 297 li a0, 1 298 bne ra, a0, test_registers_fail 299 li a0, 2 300 bne sp, a0, test_registers_fail 301 li a0, 4 302 bne t0, a0, test_registers_fail 303 li a0, 5 304 bne t1, a0, test_registers_fail 305 li a0, 6 306 bne t2, a0, test_registers_fail 307 li a0, 7 308 bne s0, a0, test_registers_fail 309 li a0, 8 310 bne s1, a0, test_registers_fail 311 li a0, 10 312 bne a1, a0, test_registers_fail 313 li a0, 11 314 bne a2, a0, test_registers_fail 315 li a0, 12 316 bne a0, a3, test_registers_fail 317 li a0, 13 318 bne a0, a4, test_registers_fail 319 li a0, 14 320 bne a0, a5, test_registers_fail 321 li a0, 15 322 bne a0, a6, test_registers_fail 323#if 0 324 /* skip x3, see below */ 325 context.x4 = 3; 326#endif 327 328 /* Return success. Note that we don't bother saving registers or bl because 329 * we're not planning to return here and we don't have a valid stack. 330 */ 331 mv a0, x0 332 j reply_trampoline 333 334 /* Return failure. */ 335test_registers_fail: 336 li a0, 1 337 j reply_trampoline 338 339#else 340#error Unsupported architecture 341#endif 342 343