1// SPDX-License-Identifier: GPL-2.0+ 2// 3// Copyright 2022, Michael Ellerman, IBM Corp. 4// 5// Test that the 4PB address space SLB handling doesn't corrupt userspace registers 6// (r9-r13) due to a SLB fault while saving the PPR. 7// 8// The bug was introduced in f384796c4 ("powerpc/mm: Add support for handling > 512TB 9// address in SLB miss") and fixed in 4c2de74cc869 ("powerpc/64: Interrupts save PPR on 10// stack rather than thread_struct"). 11// 12// To hit the bug requires the task struct and kernel stack to be in different segments. 13// Usually that requires more than 1TB of RAM, or if that's not practical, boot the kernel 14// with "disable_1tb_segments". 15// 16// The test works by creating mappings above 512TB, to trigger the large address space 17// support. It creates 64 mappings, double the size of the SLB, to cause SLB faults on 18// each access (assuming naive replacement). It then loops over those mappings touching 19// each, and checks that r9-r13 aren't corrupted. 20// 21// It then forks another child and tries again, because a new child process will get a new 22// kernel stack and thread struct allocated, which may be more optimally placed to trigger 23// the bug. It would probably be better to leave the previous child processes hanging 24// around, so that kernel stack & thread struct allocations are not reused, but that would 25// amount to a 30 second fork bomb. The current design reliably triggers the bug on 26// unpatched kernels. 27 28#include <signal.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <sys/mman.h> 32#include <sys/types.h> 33#include <sys/wait.h> 34#include <unistd.h> 35 36#include "utils.h" 37 38#ifndef MAP_FIXED_NOREPLACE 39#define MAP_FIXED_NOREPLACE MAP_FIXED // "Should be safe" above 512TB 40#endif 41 42#define BASE_ADDRESS (1ul << 50) // 1PB 43#define STRIDE (2ul << 40) // 2TB 44#define SLB_SIZE 32 45#define NR_MAPPINGS (SLB_SIZE * 2) 46 47static volatile sig_atomic_t signaled; 48 49static void signal_handler(int sig) 50{ 51 signaled = 1; 52} 53 54#define CHECK_REG(_reg) \ 55 if (_reg != _reg##_orig) { \ 56 printf(str(_reg) " corrupted! Expected 0x%lx != 0x%lx\n", _reg##_orig, \ 57 _reg); \ 58 _exit(1); \ 59 } 60 61static int touch_mappings(void) 62{ 63 unsigned long r9_orig, r10_orig, r11_orig, r12_orig, r13_orig; 64 unsigned long r9, r10, r11, r12, r13; 65 unsigned long addr, *p; 66 int i; 67 68 for (i = 0; i < NR_MAPPINGS; i++) { 69 addr = BASE_ADDRESS + (i * STRIDE); 70 p = (unsigned long *)addr; 71 72 asm volatile("mr %0, %%r9 ;" // Read original GPR values 73 "mr %1, %%r10 ;" 74 "mr %2, %%r11 ;" 75 "mr %3, %%r12 ;" 76 "mr %4, %%r13 ;" 77 "std %10, 0(%11) ;" // Trigger SLB fault 78 "mr %5, %%r9 ;" // Save possibly corrupted values 79 "mr %6, %%r10 ;" 80 "mr %7, %%r11 ;" 81 "mr %8, %%r12 ;" 82 "mr %9, %%r13 ;" 83 "mr %%r9, %0 ;" // Restore original values 84 "mr %%r10, %1 ;" 85 "mr %%r11, %2 ;" 86 "mr %%r12, %3 ;" 87 "mr %%r13, %4 ;" 88 : "=&b"(r9_orig), "=&b"(r10_orig), "=&b"(r11_orig), 89 "=&b"(r12_orig), "=&b"(r13_orig), "=&b"(r9), "=&b"(r10), 90 "=&b"(r11), "=&b"(r12), "=&b"(r13) 91 : "b"(i), "b"(p) 92 : "r9", "r10", "r11", "r12", "r13"); 93 94 CHECK_REG(r9); 95 CHECK_REG(r10); 96 CHECK_REG(r11); 97 CHECK_REG(r12); 98 CHECK_REG(r13); 99 } 100 101 return 0; 102} 103 104static int test(void) 105{ 106 unsigned long page_size, addr, *p; 107 struct sigaction action; 108 bool hash_mmu; 109 int i, status; 110 pid_t pid; 111 112 // This tests a hash MMU specific bug. 113 FAIL_IF(using_hash_mmu(&hash_mmu)); 114 SKIP_IF(!hash_mmu); 115 // 4K kernels don't support 4PB address space 116 SKIP_IF(sysconf(_SC_PAGESIZE) < 65536); 117 118 page_size = sysconf(_SC_PAGESIZE); 119 120 for (i = 0; i < NR_MAPPINGS; i++) { 121 addr = BASE_ADDRESS + (i * STRIDE); 122 123 p = mmap((void *)addr, page_size, PROT_READ | PROT_WRITE, 124 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0); 125 if (p == MAP_FAILED) { 126 perror("mmap"); 127 printf("Error: couldn't mmap(), confirm kernel has 4PB support?\n"); 128 return 1; 129 } 130 } 131 132 action.sa_handler = signal_handler; 133 action.sa_flags = SA_RESTART; 134 FAIL_IF(sigaction(SIGALRM, &action, NULL) < 0); 135 136 // Seen to always crash in under ~10s on affected kernels. 137 alarm(30); 138 139 while (!signaled) { 140 // Fork new processes, to increase the chance that we hit the case where 141 // the kernel stack and task struct are in different segments. 142 pid = fork(); 143 if (pid == 0) 144 exit(touch_mappings()); 145 146 FAIL_IF(waitpid(-1, &status, 0) == -1); 147 FAIL_IF(WIFSIGNALED(status)); 148 FAIL_IF(!WIFEXITED(status)); 149 FAIL_IF(WEXITSTATUS(status)); 150 } 151 152 return 0; 153} 154 155int main(void) 156{ 157 return test_harness(test, "large_vm_gpr_corruption"); 158} 159