0001
0002
0003
0004
0005
0006 #include <linux/hugetlb.h>
0007 #include <linux/mm.h>
0008 #include <asm/cacheflush.h>
0009 #include <asm/facility.h>
0010 #include <asm/pgalloc.h>
0011 #include <asm/kfence.h>
0012 #include <asm/page.h>
0013 #include <asm/set_memory.h>
0014
0015 static inline unsigned long sske_frame(unsigned long addr, unsigned char skey)
0016 {
0017 asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0"
0018 : [addr] "+a" (addr) : [skey] "d" (skey));
0019 return addr;
0020 }
0021
0022 void __storage_key_init_range(unsigned long start, unsigned long end)
0023 {
0024 unsigned long boundary, size;
0025
0026 while (start < end) {
0027 if (MACHINE_HAS_EDAT1) {
0028
0029 size = 1UL << 20;
0030 boundary = (start + size) & ~(size - 1);
0031 if (boundary <= end) {
0032 do {
0033 start = sske_frame(start, PAGE_DEFAULT_KEY);
0034 } while (start < boundary);
0035 continue;
0036 }
0037 }
0038 page_set_storage_key(start, PAGE_DEFAULT_KEY, 1);
0039 start += PAGE_SIZE;
0040 }
0041 }
0042
0043 #ifdef CONFIG_PROC_FS
0044 atomic_long_t direct_pages_count[PG_DIRECT_MAP_MAX];
0045
0046 void arch_report_meminfo(struct seq_file *m)
0047 {
0048 seq_printf(m, "DirectMap4k: %8lu kB\n",
0049 atomic_long_read(&direct_pages_count[PG_DIRECT_MAP_4K]) << 2);
0050 seq_printf(m, "DirectMap1M: %8lu kB\n",
0051 atomic_long_read(&direct_pages_count[PG_DIRECT_MAP_1M]) << 10);
0052 seq_printf(m, "DirectMap2G: %8lu kB\n",
0053 atomic_long_read(&direct_pages_count[PG_DIRECT_MAP_2G]) << 21);
0054 }
0055 #endif
0056
0057 static void pgt_set(unsigned long *old, unsigned long new, unsigned long addr,
0058 unsigned long dtt)
0059 {
0060 unsigned long *table, mask;
0061
0062 mask = 0;
0063 if (MACHINE_HAS_EDAT2) {
0064 switch (dtt) {
0065 case CRDTE_DTT_REGION3:
0066 mask = ~(PTRS_PER_PUD * sizeof(pud_t) - 1);
0067 break;
0068 case CRDTE_DTT_SEGMENT:
0069 mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
0070 break;
0071 case CRDTE_DTT_PAGE:
0072 mask = ~(PTRS_PER_PTE * sizeof(pte_t) - 1);
0073 break;
0074 }
0075 table = (unsigned long *)((unsigned long)old & mask);
0076 crdte(*old, new, table, dtt, addr, S390_lowcore.kernel_asce);
0077 } else if (MACHINE_HAS_IDTE) {
0078 cspg(old, *old, new);
0079 } else {
0080 csp((unsigned int *)old + 1, *old, new);
0081 }
0082 }
0083
0084 static int walk_pte_level(pmd_t *pmdp, unsigned long addr, unsigned long end,
0085 unsigned long flags)
0086 {
0087 pte_t *ptep, new;
0088
0089 if (flags == SET_MEMORY_4K)
0090 return 0;
0091 ptep = pte_offset_kernel(pmdp, addr);
0092 do {
0093 new = *ptep;
0094 if (pte_none(new))
0095 return -EINVAL;
0096 if (flags & SET_MEMORY_RO)
0097 new = pte_wrprotect(new);
0098 else if (flags & SET_MEMORY_RW)
0099 new = pte_mkwrite(pte_mkdirty(new));
0100 if (flags & SET_MEMORY_NX)
0101 new = set_pte_bit(new, __pgprot(_PAGE_NOEXEC));
0102 else if (flags & SET_MEMORY_X)
0103 new = clear_pte_bit(new, __pgprot(_PAGE_NOEXEC));
0104 pgt_set((unsigned long *)ptep, pte_val(new), addr, CRDTE_DTT_PAGE);
0105 ptep++;
0106 addr += PAGE_SIZE;
0107 cond_resched();
0108 } while (addr < end);
0109 return 0;
0110 }
0111
0112 static int split_pmd_page(pmd_t *pmdp, unsigned long addr)
0113 {
0114 unsigned long pte_addr, prot;
0115 pte_t *pt_dir, *ptep;
0116 pmd_t new;
0117 int i, ro, nx;
0118
0119 pt_dir = vmem_pte_alloc();
0120 if (!pt_dir)
0121 return -ENOMEM;
0122 pte_addr = pmd_pfn(*pmdp) << PAGE_SHIFT;
0123 ro = !!(pmd_val(*pmdp) & _SEGMENT_ENTRY_PROTECT);
0124 nx = !!(pmd_val(*pmdp) & _SEGMENT_ENTRY_NOEXEC);
0125 prot = pgprot_val(ro ? PAGE_KERNEL_RO : PAGE_KERNEL);
0126 if (!nx)
0127 prot &= ~_PAGE_NOEXEC;
0128 ptep = pt_dir;
0129 for (i = 0; i < PTRS_PER_PTE; i++) {
0130 set_pte(ptep, __pte(pte_addr | prot));
0131 pte_addr += PAGE_SIZE;
0132 ptep++;
0133 }
0134 new = __pmd(__pa(pt_dir) | _SEGMENT_ENTRY);
0135 pgt_set((unsigned long *)pmdp, pmd_val(new), addr, CRDTE_DTT_SEGMENT);
0136 update_page_count(PG_DIRECT_MAP_4K, PTRS_PER_PTE);
0137 update_page_count(PG_DIRECT_MAP_1M, -1);
0138 return 0;
0139 }
0140
0141 static void modify_pmd_page(pmd_t *pmdp, unsigned long addr,
0142 unsigned long flags)
0143 {
0144 pmd_t new = *pmdp;
0145
0146 if (flags & SET_MEMORY_RO)
0147 new = pmd_wrprotect(new);
0148 else if (flags & SET_MEMORY_RW)
0149 new = pmd_mkwrite(pmd_mkdirty(new));
0150 if (flags & SET_MEMORY_NX)
0151 new = set_pmd_bit(new, __pgprot(_SEGMENT_ENTRY_NOEXEC));
0152 else if (flags & SET_MEMORY_X)
0153 new = clear_pmd_bit(new, __pgprot(_SEGMENT_ENTRY_NOEXEC));
0154 pgt_set((unsigned long *)pmdp, pmd_val(new), addr, CRDTE_DTT_SEGMENT);
0155 }
0156
0157 static int walk_pmd_level(pud_t *pudp, unsigned long addr, unsigned long end,
0158 unsigned long flags)
0159 {
0160 unsigned long next;
0161 int need_split;
0162 pmd_t *pmdp;
0163 int rc = 0;
0164
0165 pmdp = pmd_offset(pudp, addr);
0166 do {
0167 if (pmd_none(*pmdp))
0168 return -EINVAL;
0169 next = pmd_addr_end(addr, end);
0170 if (pmd_large(*pmdp)) {
0171 need_split = !!(flags & SET_MEMORY_4K);
0172 need_split |= !!(addr & ~PMD_MASK);
0173 need_split |= !!(addr + PMD_SIZE > next);
0174 if (need_split) {
0175 rc = split_pmd_page(pmdp, addr);
0176 if (rc)
0177 return rc;
0178 continue;
0179 }
0180 modify_pmd_page(pmdp, addr, flags);
0181 } else {
0182 rc = walk_pte_level(pmdp, addr, next, flags);
0183 if (rc)
0184 return rc;
0185 }
0186 pmdp++;
0187 addr = next;
0188 cond_resched();
0189 } while (addr < end);
0190 return rc;
0191 }
0192
0193 static int split_pud_page(pud_t *pudp, unsigned long addr)
0194 {
0195 unsigned long pmd_addr, prot;
0196 pmd_t *pm_dir, *pmdp;
0197 pud_t new;
0198 int i, ro, nx;
0199
0200 pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY);
0201 if (!pm_dir)
0202 return -ENOMEM;
0203 pmd_addr = pud_pfn(*pudp) << PAGE_SHIFT;
0204 ro = !!(pud_val(*pudp) & _REGION_ENTRY_PROTECT);
0205 nx = !!(pud_val(*pudp) & _REGION_ENTRY_NOEXEC);
0206 prot = pgprot_val(ro ? SEGMENT_KERNEL_RO : SEGMENT_KERNEL);
0207 if (!nx)
0208 prot &= ~_SEGMENT_ENTRY_NOEXEC;
0209 pmdp = pm_dir;
0210 for (i = 0; i < PTRS_PER_PMD; i++) {
0211 set_pmd(pmdp, __pmd(pmd_addr | prot));
0212 pmd_addr += PMD_SIZE;
0213 pmdp++;
0214 }
0215 new = __pud(__pa(pm_dir) | _REGION3_ENTRY);
0216 pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3);
0217 update_page_count(PG_DIRECT_MAP_1M, PTRS_PER_PMD);
0218 update_page_count(PG_DIRECT_MAP_2G, -1);
0219 return 0;
0220 }
0221
0222 static void modify_pud_page(pud_t *pudp, unsigned long addr,
0223 unsigned long flags)
0224 {
0225 pud_t new = *pudp;
0226
0227 if (flags & SET_MEMORY_RO)
0228 new = pud_wrprotect(new);
0229 else if (flags & SET_MEMORY_RW)
0230 new = pud_mkwrite(pud_mkdirty(new));
0231 if (flags & SET_MEMORY_NX)
0232 new = set_pud_bit(new, __pgprot(_REGION_ENTRY_NOEXEC));
0233 else if (flags & SET_MEMORY_X)
0234 new = clear_pud_bit(new, __pgprot(_REGION_ENTRY_NOEXEC));
0235 pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3);
0236 }
0237
0238 static int walk_pud_level(p4d_t *p4d, unsigned long addr, unsigned long end,
0239 unsigned long flags)
0240 {
0241 unsigned long next;
0242 int need_split;
0243 pud_t *pudp;
0244 int rc = 0;
0245
0246 pudp = pud_offset(p4d, addr);
0247 do {
0248 if (pud_none(*pudp))
0249 return -EINVAL;
0250 next = pud_addr_end(addr, end);
0251 if (pud_large(*pudp)) {
0252 need_split = !!(flags & SET_MEMORY_4K);
0253 need_split |= !!(addr & ~PUD_MASK);
0254 need_split |= !!(addr + PUD_SIZE > next);
0255 if (need_split) {
0256 rc = split_pud_page(pudp, addr);
0257 if (rc)
0258 break;
0259 continue;
0260 }
0261 modify_pud_page(pudp, addr, flags);
0262 } else {
0263 rc = walk_pmd_level(pudp, addr, next, flags);
0264 }
0265 pudp++;
0266 addr = next;
0267 cond_resched();
0268 } while (addr < end && !rc);
0269 return rc;
0270 }
0271
0272 static int walk_p4d_level(pgd_t *pgd, unsigned long addr, unsigned long end,
0273 unsigned long flags)
0274 {
0275 unsigned long next;
0276 p4d_t *p4dp;
0277 int rc = 0;
0278
0279 p4dp = p4d_offset(pgd, addr);
0280 do {
0281 if (p4d_none(*p4dp))
0282 return -EINVAL;
0283 next = p4d_addr_end(addr, end);
0284 rc = walk_pud_level(p4dp, addr, next, flags);
0285 p4dp++;
0286 addr = next;
0287 cond_resched();
0288 } while (addr < end && !rc);
0289 return rc;
0290 }
0291
0292 DEFINE_MUTEX(cpa_mutex);
0293
0294 static int change_page_attr(unsigned long addr, unsigned long end,
0295 unsigned long flags)
0296 {
0297 unsigned long next;
0298 int rc = -EINVAL;
0299 pgd_t *pgdp;
0300
0301 if (addr == end)
0302 return 0;
0303 if (end >= MODULES_END)
0304 return -EINVAL;
0305 mutex_lock(&cpa_mutex);
0306 pgdp = pgd_offset_k(addr);
0307 do {
0308 if (pgd_none(*pgdp))
0309 break;
0310 next = pgd_addr_end(addr, end);
0311 rc = walk_p4d_level(pgdp, addr, next, flags);
0312 if (rc)
0313 break;
0314 cond_resched();
0315 } while (pgdp++, addr = next, addr < end && !rc);
0316 mutex_unlock(&cpa_mutex);
0317 return rc;
0318 }
0319
0320 int __set_memory(unsigned long addr, int numpages, unsigned long flags)
0321 {
0322 if (!MACHINE_HAS_NX)
0323 flags &= ~(SET_MEMORY_NX | SET_MEMORY_X);
0324 if (!flags)
0325 return 0;
0326 addr &= PAGE_MASK;
0327 return change_page_attr(addr, addr + numpages * PAGE_SIZE, flags);
0328 }
0329
0330 #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
0331
0332 static void ipte_range(pte_t *pte, unsigned long address, int nr)
0333 {
0334 int i;
0335
0336 if (test_facility(13)) {
0337 __ptep_ipte_range(address, nr - 1, pte, IPTE_GLOBAL);
0338 return;
0339 }
0340 for (i = 0; i < nr; i++) {
0341 __ptep_ipte(address, pte, 0, 0, IPTE_GLOBAL);
0342 address += PAGE_SIZE;
0343 pte++;
0344 }
0345 }
0346
0347 void __kernel_map_pages(struct page *page, int numpages, int enable)
0348 {
0349 unsigned long address;
0350 pte_t *ptep, pte;
0351 int nr, i, j;
0352
0353 for (i = 0; i < numpages;) {
0354 address = (unsigned long)page_to_virt(page + i);
0355 ptep = virt_to_kpte(address);
0356 nr = (unsigned long)ptep >> ilog2(sizeof(long));
0357 nr = PTRS_PER_PTE - (nr & (PTRS_PER_PTE - 1));
0358 nr = min(numpages - i, nr);
0359 if (enable) {
0360 for (j = 0; j < nr; j++) {
0361 pte = clear_pte_bit(*ptep, __pgprot(_PAGE_INVALID));
0362 set_pte(ptep, pte);
0363 address += PAGE_SIZE;
0364 ptep++;
0365 }
0366 } else {
0367 ipte_range(ptep, address, nr);
0368 }
0369 i += nr;
0370 }
0371 }
0372
0373 #endif