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 the exception is consistent with DAT protection and has the correct 30 * address and 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 switch (get_supp_on_prot_facility()) { 41 case SOP_NONE: 42 case SOP_BASIC: 43 assert(false); /* let's ignore ancient/irrelevant machines */ 44 case SOP_ENHANCED_1: 45 if (!teid.sop_teid_predictable) /* implies key or low addr */ 46 return false; 47 break; 48 case SOP_ENHANCED_2: 49 if (teid_esop2_prot_code(teid) != PROT_DAT) 50 return false; 51 } 52 return (!teid.sop_acc_list && !teid.asce_id && 53 (teid.addr == ((unsigned long)ptr >> PAGE_SHIFT))); 54 } 55 56 static void test_dat(void) 57 { 58 report_prefix_push("edat off"); 59 /* disable EDAT */ 60 ctl_clear_bit(0, CTL0_EDAT); 61 62 /* Check some basics */ 63 p[0] = 42; 64 report(p[0] == 42, "pte, r/w"); 65 p[0] = 0; 66 67 /* Write protect the page and try to write, expect a fault */ 68 protect_page(m, PAGE_ENTRY_P); 69 expect_pgm_int(); 70 p[0] = 42; 71 unprotect_page(m, PAGE_ENTRY_P); 72 report(!p[0] && check_pgm_prot(m), "pte, ro"); 73 74 /* 75 * The FC bit (for large pages) should be ignored because EDAT is 76 * off. We set a value and then we try to read it back again after 77 * setting the FC bit. This way we can check if large pages were 78 * erroneously enabled despite EDAT being off. 79 */ 80 p[0] = 42; 81 protect_dat_entry(m, SEGMENT_ENTRY_FC, pgtable_level_pmd); 82 report(p[0] == 42, "pmd, fc=1, r/w"); 83 unprotect_dat_entry(m, SEGMENT_ENTRY_FC, pgtable_level_pmd); 84 p[0] = 0; 85 86 /* 87 * Segment protection should work even with EDAT off, try to write 88 * anyway and expect a fault 89 */ 90 protect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 91 expect_pgm_int(); 92 p[0] = 42; 93 report(!p[0] && check_pgm_prot(m), "pmd, ro"); 94 unprotect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 95 96 /* The FC bit should be ignored because EDAT is off, like above */ 97 p[0] = 42; 98 protect_dat_entry(m, REGION3_ENTRY_FC, pgtable_level_pud); 99 report(p[0] == 42, "pud, fc=1, r/w"); 100 unprotect_dat_entry(m, REGION3_ENTRY_FC, pgtable_level_pud); 101 p[0] = 0; 102 103 /* 104 * Region1/2/3 protection should not work, because EDAT is off. 105 * Protect the various region1/2/3 entries and write, expect the 106 * write to be successful. 107 */ 108 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 109 p[0] = 42; 110 report(p[0] == 42, "pud, ro"); 111 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 112 p[0] = 0; 113 114 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 115 p[0] = 42; 116 report(p[0] == 42, "p4d, ro"); 117 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 118 p[0] = 0; 119 120 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 121 p[0] = 42; 122 report(p[0] == 42, "pgd, ro"); 123 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 124 p[0] = 0; 125 126 report_prefix_pop(); 127 } 128 129 static void test_edat1(void) 130 { 131 report_prefix_push("edat1"); 132 /* Enable EDAT */ 133 ctl_set_bit(0, CTL0_EDAT); 134 p[0] = 0; 135 136 /* 137 * Segment protection should work normally, try to write and expect 138 * a fault. 139 */ 140 expect_pgm_int(); 141 protect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 142 p[0] = 42; 143 report(!p[0] && check_pgm_prot(m), "pmd, ro"); 144 unprotect_dat_entry(m, SEGMENT_ENTRY_P, pgtable_level_pmd); 145 146 /* 147 * Region1/2/3 protection should work now, because EDAT is on. Try 148 * to write anyway and expect a fault. 149 */ 150 expect_pgm_int(); 151 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 152 p[0] = 42; 153 report(!p[0] && check_pgm_prot(m), "pud, ro"); 154 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pud); 155 156 expect_pgm_int(); 157 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 158 p[0] = 42; 159 report(!p[0] && check_pgm_prot(m), "p4d, ro"); 160 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_p4d); 161 162 expect_pgm_int(); 163 protect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 164 p[0] = 42; 165 report(!p[0] && check_pgm_prot(m), "pgd, ro"); 166 unprotect_dat_entry(m, REGION_ENTRY_P, pgtable_level_pgd); 167 168 /* Large pages should work */ 169 p[0] = 42; 170 install_large_page(root, 0, mem); 171 report(p[0] == 42, "pmd, large"); 172 173 /* 174 * Prefixing should not work with large pages. Since the lower 175 * addresses are mapped with small pages, which are subject to 176 * prefixing, and the pages mapped with large pages are not subject 177 * to prefixing, this is the resulting scenario: 178 * 179 * virtual 0 = real 0 -> absolute prefix_buf 180 * virtual prefix_buf = real prefix_buf -> absolute 0 181 * VIRT(0) -> absolute 0 182 * VIRT(prefix_buf) -> absolute prefix_buf 183 * 184 * The testcase checks if the memory at virtual 0 has the same 185 * content as the memory at VIRT(prefix_buf) and the memory at 186 * VIRT(0) has the same content as the memory at virtual prefix_buf. 187 * If prefixing is erroneously applied for large pages, the testcase 188 * will therefore fail. 189 */ 190 report(!memcmp(0, VIRT(prefix_buf), LC_SIZE) && 191 !memcmp(prefix_buf, VIRT(0), LC_SIZE), 192 "pmd, large, prefixing"); 193 194 report_prefix_pop(); 195 } 196 197 static void test_edat2(void) 198 { 199 report_prefix_push("edat2"); 200 p[0] = 42; 201 202 /* Huge pages should work */ 203 install_huge_page(root, 0, mem); 204 report(p[0] == 42, "pud, huge"); 205 206 /* Prefixing should not work with huge pages, just like large pages */ 207 report(!memcmp(0, VIRT(prefix_buf), LC_SIZE) && 208 !memcmp(prefix_buf, VIRT(0), LC_SIZE), 209 "pmd, large, prefixing"); 210 211 report_prefix_pop(); 212 } 213 214 static unsigned int setup(void) 215 { 216 bool has_edat1 = test_facility(8); 217 bool has_edat2 = test_facility(78); 218 unsigned long pa, va; 219 220 if (has_edat2 && !has_edat1) 221 report_abort("EDAT2 available, but EDAT1 not available"); 222 223 /* Setup DAT 1:1 mapping and memory management */ 224 setup_vm(); 225 root = (void *)(stctg(1) & PAGE_MASK); 226 227 /* 228 * Get a pgd worth of virtual memory, so we can test things later 229 * without interfering with the test code or the interrupt handler 230 */ 231 mem = alloc_vpages_aligned(BIT_ULL(PGD_PAGE_SHIFT), PGD_PAGE_SHIFT); 232 assert(mem); 233 va = (unsigned long)mem; 234 235 /* Map the first 1GB of real memory */ 236 for (pa = 0; pa < SZ_1G; pa += PAGE_SIZE, va += PAGE_SIZE) 237 install_page(root, pa, (void *)va); 238 239 /* 240 * Move the lowcore to a known non-zero location. This is needed 241 * later to check whether prefixing is working with large pages. 242 */ 243 assert((unsigned long)&prefix_buf < SZ_2G); 244 memcpy(prefix_buf, 0, LC_SIZE); 245 set_prefix((uint32_t)(uintptr_t)prefix_buf); 246 /* Clear the old copy */ 247 memset(prefix_buf, 0, LC_SIZE); 248 249 /* m will point to tmp through the new virtual mapping */ 250 m = VIRT(&tmp); 251 /* p is the same as m but volatile */ 252 p = (volatile unsigned int *)m; 253 254 return has_edat1 + has_edat2; 255 } 256 257 int main(void) 258 { 259 unsigned int edat; 260 261 report_prefix_push("edat"); 262 edat = setup(); 263 264 test_dat(); 265 266 if (edat) 267 test_edat1(); 268 else 269 report_skip("EDAT not available"); 270 271 if (edat >= 2) 272 test_edat2(); 273 else 274 report_skip("EDAT2 not available"); 275 276 report_prefix_pop(); 277 return report_summary(); 278 } 279