Lines Matching +full:entry +full:- +full:address

1 // SPDX-License-Identifier: GPL-2.0
38 #include <asm/asm-extable.h>
39 #include <asm/asm-offsets.h>
47 #include "../kernel/entry.h"
66 * Find out which address space caused the exception.
70 union teid teid = { .val = regs->int_parm_long }; in get_fault_type()
78 gmap = (struct gmap *)get_lowcore()->gmap; in get_fault_type()
79 if (gmap && gmap->asce == regs->cr1) in get_fault_type()
88 /* Home space -> access via kernel ASCE */ in get_fault_type()
94 union teid teid = { .val = regs->int_parm_long }; in get_fault_address()
101 union teid teid = { .val = regs->int_parm_long }; in fault_is_write()
108 static void dump_pagetable(unsigned long asce, unsigned long address) in dump_pagetable() argument
110 unsigned long entry, *table = __va(asce & _ASCE_ORIGIN); in dump_pagetable() local
115 table += (address & _REGION1_INDEX) >> _REGION1_SHIFT; in dump_pagetable()
116 if (get_kernel_nofault(entry, table)) in dump_pagetable()
118 pr_cont("R1:%016lx ", entry); in dump_pagetable()
119 if (entry & _REGION_ENTRY_INVALID) in dump_pagetable()
121 table = __va(entry & _REGION_ENTRY_ORIGIN); in dump_pagetable()
124 table += (address & _REGION2_INDEX) >> _REGION2_SHIFT; in dump_pagetable()
125 if (get_kernel_nofault(entry, table)) in dump_pagetable()
127 pr_cont("R2:%016lx ", entry); in dump_pagetable()
128 if (entry & _REGION_ENTRY_INVALID) in dump_pagetable()
130 table = __va(entry & _REGION_ENTRY_ORIGIN); in dump_pagetable()
133 table += (address & _REGION3_INDEX) >> _REGION3_SHIFT; in dump_pagetable()
134 if (get_kernel_nofault(entry, table)) in dump_pagetable()
136 pr_cont("R3:%016lx ", entry); in dump_pagetable()
137 if (entry & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE)) in dump_pagetable()
139 table = __va(entry & _REGION_ENTRY_ORIGIN); in dump_pagetable()
142 table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; in dump_pagetable()
143 if (get_kernel_nofault(entry, table)) in dump_pagetable()
145 pr_cont("S:%016lx ", entry); in dump_pagetable()
146 if (entry & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) in dump_pagetable()
148 table = __va(entry & _SEGMENT_ENTRY_ORIGIN); in dump_pagetable()
150 table += (address & _PAGE_INDEX) >> _PAGE_SHIFT; in dump_pagetable()
151 if (get_kernel_nofault(entry, table)) in dump_pagetable()
153 pr_cont("P:%016lx ", entry); in dump_pagetable()
163 union teid teid = { .val = regs->int_parm_long }; in dump_fault_info()
166 pr_alert("Failing address: %016lx TEID: %016lx\n", in dump_fault_info()
186 asce = get_lowcore()->user_asce.val; in dump_fault_info()
190 asce = ((struct gmap *)get_lowcore()->gmap)->asce; in dump_fault_info()
194 asce = get_lowcore()->kernel_asce.val; in dump_fault_info()
217 regs->int_code & 0xffff, regs->int_code >> 17); in report_user_fault()
218 print_vma_addr(KERN_CONT "in ", regs->psw.addr); in report_user_fault()
234 unsigned long address; in handle_fault_error_nolock() local
246 address = get_fault_address(regs); in handle_fault_error_nolock()
248 if (kfence_handle_page_fault(address, is_write, regs)) in handle_fault_error_nolock()
252 pr_alert("Unable to handle kernel pointer dereference in virtual kernel address space\n"); in handle_fault_error_nolock()
254 pr_alert("Unable to handle kernel paging request in virtual user address space\n"); in handle_fault_error_nolock()
261 struct mm_struct *mm = current->mm; in handle_fault_error()
273 * This routine handles page faults. It determines the address,
278 * 04 Protection -> Write-Protection (suppression)
279 * 10 Segment translation -> Not present (nullification)
280 * 11 Page translation -> Not present (nullification)
281 * 3b Region third trans. -> Not present (nullification)
286 unsigned long address; in do_exception() local
301 mm = current->mm; in do_exception()
302 address = get_fault_address(regs); in do_exception()
314 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); in do_exception()
324 vma = lock_vma_under_rcu(mm, address); in do_exception()
327 if (!(vma->vm_flags & access)) { in do_exception()
332 fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs); in do_exception()
355 gmap = (struct gmap *)get_lowcore()->gmap; in do_exception()
356 current->thread.gmap_addr = address; in do_exception()
357 current->thread.gmap_write_flag = !!(flags & FAULT_FLAG_WRITE); in do_exception()
358 current->thread.gmap_int_code = regs->int_code & 0xffff; in do_exception()
359 address = __gmap_translate(gmap, address); in do_exception()
360 if (address == -EFAULT) in do_exception()
362 if (gmap->pfault_enabled) in do_exception()
366 vma = find_vma(mm, address); in do_exception()
369 if (unlikely(vma->vm_start > address)) { in do_exception()
370 if (!(vma->vm_flags & VM_GROWSDOWN)) in do_exception()
372 vma = expand_stack(mm, address); in do_exception()
376 if (unlikely(!(vma->vm_flags & access))) in do_exception()
378 fault = handle_mm_fault(vma, address, flags, regs); in do_exception()
404 current->thread.gmap_pfault = 1; in do_exception()
414 address = __gmap_link(gmap, current->thread.gmap_addr, in do_exception()
415 address); in do_exception()
416 if (address == -EFAULT) in do_exception()
418 if (address == -ENOMEM) { in do_exception()
450 union teid teid = { .val = regs->int_parm_long }; in do_protection_exception()
453 * Protection exceptions are suppressing, decrement psw address. in do_protection_exception()
457 if (!(regs->int_code & 0x200)) in do_protection_exception()
458 regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); in do_protection_exception()
460 * Check for low-address protection. This needs to be treated in do_protection_exception()
466 /* Low-address protection in user mode: cannot happen */ in do_protection_exception()
467 die(regs, "Low-address protection"); in do_protection_exception()
470 * Low-address protection in kernel mode means in do_protection_exception()
476 regs->int_parm_long = (teid.addr * PAGE_SIZE) | (regs->psw.addr & PAGE_MASK); in do_protection_exception()
493 union teid teid = { .val = regs->int_parm_long }; in do_secure_storage_access()
503 * Bit 61 indicates if the address is valid, if it is not the in do_secure_storage_access()
526 mm = current->mm; in do_secure_storage_access()
527 gmap = (struct gmap *)get_lowcore()->gmap; in do_secure_storage_access()
535 mm = current->mm; in do_secure_storage_access()
571 struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; in do_non_secure_storage_access()
576 if (gmap_convert_to_secure(gmap, gaddr) == -EINVAL) in do_non_secure_storage_access()
583 struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; in do_secure_storage_violation()
587 * If the VM has been rebooted, its address space might still contain in do_secure_storage_violation()
601 current->comm, current->pid); in do_secure_storage_violation()