1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * EDAT test. 4 * 5 * Copyright (c) 2021 IBM Corp 6 * 7 * Authors: 8 * Claudio Imbrenda <imbrenda@linux.ibm.com> 9 */ 10 #include <libcflat.h> 11 #include <vmalloc.h> 12 #include <asm/facility.h> 13 #include <asm/interrupt.h> 14 #include <mmu.h> 15 #include <asm/pgtable.h> 16 #include <asm-generic/barrier.h> 17 18 #define PGD_PAGE_SHIFT (REGION1_SHIFT - PAGE_SHIFT) 19 20 #define LC_SIZE (2 * PAGE_SIZE) 21 #define VIRT(x) ((void *)((unsigned long)(x) + (unsigned long)mem)) 22 23 static uint8_t prefix_buf[LC_SIZE] __attribute__((aligned(LC_SIZE))); 24 static unsigned int tmp[1024] __attribute__((aligned(PAGE_SIZE))); 25 static void *root, *mem, *m; 26 volatile unsigned int *p; 27 28 /* 29 * Check if a non-access-list protection exception happened for the given 30 * address, in the primary address space. 31 */ 32 static bool check_pgm_prot(void *ptr) 33 { 34 union teid teid; 35 36 if (lowcore.pgm_int_code != PGM_INT_CODE_PROTECTION) 37 return false; 38 39 teid.val = lowcore.trans_exc_id; 40 41 /* 42 * depending on the presence of the ESOP feature, the rest of the 43 * field might or might not be meaningful when the m field is 0. 44 */ 45 if (!teid.m) 46 return true; 47 return (!teid.acc_list_prot && !teid.asce_id && 48 (teid.addr == ((unsigned long)ptr >> PAGE_SHIFT))); 49 } 50 51 static void test_dat(void) 52 { 53 report_prefix_push("edat off"); 54 /* disable EDAT */ 55 ctl_clear_bit(0, CTL0_EDAT); 56 57 /* Check some basics */ 58 p[0] = 42; 59 report(p[0] == 42, "pte, r/w"); 60 p[0] = 0; 61 62 /* Write protect the page and try to write, expect a fault */ 63 protect_page(m, PAGE_ENTRY_P); 64 expect_pgm_int(); 65 p[0] = 42; 66 unprotect_page(m, PAGE_ENTRY_P); 67 report(!p[0] && check_pgm_prot(m), "pte, ro"); 68 69 /* 70 * The FC bit (for large pages) should be ignored because EDAT is 71 * off. We set a value and then we try to read it back again after 72 * setting the FC bit. This way we can check if large pages were 73 * erroneously enabled despite EDAT being off. 74 */ 75 p[0] = 42; 76 protect_dat_entry(m, SEGMENT_ENTRY_FC, pgtable_level_pmd); 77 report(p[0] == 42, "pmd, fc=1, r/w"); 78 unprotect_dat_entry(m, SEGMENT_ENTRY_FC, pgtable_level_pmd); 79 p[0] = 0; 80 81 /* 82 * Segment protection should work even with EDAT off, try to write 83 * anyway and expect a fault 84 */ 85 protect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 86 expect_pgm_int(); 87 p[0] = 42; 88 report(!p[0] && check_pgm_prot(m), "pmd, ro"); 89 unprotect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 90 91 /* The FC bit should be ignored because EDAT is off, like above */ 92 p[0] = 42; 93 protect_dat_entry(m, REGION3_ENTRY_FC, pgtable_level_pud); 94 report(p[0] == 42, "pud, fc=1, r/w"); 95 unprotect_dat_entry(m, REGION3_ENTRY_FC, pgtable_level_pud); 96 p[0] = 0; 97 98 /* 99 * Region1/2/3 protection should not work, because EDAT is off. 100 * Protect the various region1/2/3 entries and write, expect the 101 * write to be successful. 102 */ 103 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 104 p[0] = 42; 105 report(p[0] == 42, "pud, ro"); 106 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 107 p[0] = 0; 108 109 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 110 p[0] = 42; 111 report(p[0] == 42, "p4d, ro"); 112 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 113 p[0] = 0; 114 115 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 116 p[0] = 42; 117 report(p[0] == 42, "pgd, ro"); 118 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 119 p[0] = 0; 120 121 report_prefix_pop(); 122 } 123 124 static void test_edat1(void) 125 { 126 report_prefix_push("edat1"); 127 /* Enable EDAT */ 128 ctl_set_bit(0, CTL0_EDAT); 129 p[0] = 0; 130 131 /* 132 * Segment protection should work normally, try to write and expect 133 * a fault. 134 */ 135 expect_pgm_int(); 136 protect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 137 p[0] = 42; 138 report(!p[0] && check_pgm_prot(m), "pmd, ro"); 139 unprotect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 140 141 /* 142 * Region1/2/3 protection should work now, because EDAT is on. Try 143 * to write anyway and expect a fault. 144 */ 145 expect_pgm_int(); 146 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 147 p[0] = 42; 148 report(!p[0] && check_pgm_prot(m), "pud, ro"); 149 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 150 151 expect_pgm_int(); 152 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 153 p[0] = 42; 154 report(!p[0] && check_pgm_prot(m), "p4d, ro"); 155 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 156 157 expect_pgm_int(); 158 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 159 p[0] = 42; 160 report(!p[0] && check_pgm_prot(m), "pgd, ro"); 161 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 162 163 /* Large pages should work */ 164 p[0] = 42; 165 install_large_page(root, 0, mem); 166 report(p[0] == 42, "pmd, large"); 167 168 /* 169 * Prefixing should not work with large pages. Since the lower 170 * addresses are mapped with small pages, which are subject to 171 * prefixing, and the pages mapped with large pages are not subject 172 * to prefixing, this is the resulting scenario: 173 * 174 * virtual 0 = real 0 -> absolute prefix_buf 175 * virtual prefix_buf = real prefix_buf -> absolute 0 176 * VIRT(0) -> absolute 0 177 * VIRT(prefix_buf) -> absolute prefix_buf 178 * 179 * The testcase checks if the memory at virtual 0 has the same 180 * content as the memory at VIRT(prefix_buf) and the memory at 181 * VIRT(0) has the same content as the memory at virtual prefix_buf. 182 * If prefixing is erroneously applied for large pages, the testcase 183 * will therefore fail. 184 */ 185 report(!memcmp(0, VIRT(prefix_buf), LC_SIZE) && 186 !memcmp(prefix_buf, VIRT(0), LC_SIZE), 187 "pmd, large, prefixing"); 188 189 report_prefix_pop(); 190 } 191 192 static void test_edat2(void) 193 { 194 report_prefix_push("edat2"); 195 p[0] = 42; 196 197 /* Huge pages should work */ 198 install_huge_page(root, 0, mem); 199 report(p[0] == 42, "pud, huge"); 200 201 /* Prefixing should not work with huge pages, just like large pages */ 202 report(!memcmp(0, VIRT(prefix_buf), LC_SIZE) && 203 !memcmp(prefix_buf, VIRT(0), LC_SIZE), 204 "pmd, large, prefixing"); 205 206 report_prefix_pop(); 207 } 208 209 static unsigned int setup(void) 210 { 211 bool has_edat1 = test_facility(8); 212 bool has_edat2 = test_facility(78); 213 unsigned long pa, va; 214 215 if (has_edat2 && !has_edat1) 216 report_abort("EDAT2 available, but EDAT1 not available"); 217 218 /* Setup DAT 1:1 mapping and memory management */ 219 setup_vm(); 220 root = (void *)(stctg(1) & PAGE_MASK); 221 222 /* 223 * Get a pgd worth of virtual memory, so we can test things later 224 * without interfering with the test code or the interrupt handler 225 */ 226 mem = alloc_vpages_aligned(BIT_ULL(PGD_PAGE_SHIFT), PGD_PAGE_SHIFT); 227 assert(mem); 228 va = (unsigned long)mem; 229 230 /* Map the first 1GB of real memory */ 231 for (pa = 0; pa < SZ_1G; pa += PAGE_SIZE, va += PAGE_SIZE) 232 install_page(root, pa, (void *)va); 233 234 /* 235 * Move the lowcore to a known non-zero location. This is needed 236 * later to check whether prefixing is working with large pages. 237 */ 238 assert((unsigned long)&prefix_buf < SZ_2G); 239 memcpy(prefix_buf, 0, LC_SIZE); 240 set_prefix((uint32_t)(uintptr_t)prefix_buf); 241 /* Clear the old copy */ 242 memset(prefix_buf, 0, LC_SIZE); 243 244 /* m will point to tmp through the new virtual mapping */ 245 m = VIRT(&tmp); 246 /* p is the same as m but volatile */ 247 p = (volatile unsigned int *)m; 248 249 return has_edat1 + has_edat2; 250 } 251 252 int main(void) 253 { 254 unsigned int edat; 255 256 report_prefix_push("edat"); 257 edat = setup(); 258 259 test_dat(); 260 261 if (edat) 262 test_edat1(); 263 else 264 report_skip("EDAT not available"); 265 266 if (edat >= 2) 267 test_edat2(); 268 else 269 report_skip("EDAT2 not available"); 270 271 report_prefix_pop(); 272 return report_summary(); 273 } 274