From fb24dcea2e10025e67e3133bd735426e6092ff78 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Tue, 2 Oct 2018 13:01:16 +0900 Subject: [PATCH] unhandled_page_fault: Refactor architecture dependent parts Fujitsu: REQ-12 Refs: #1012 Change-Id: I3c61f9cd3f514bdcd4a7f26e7c15043529269cf5 --- arch/arm64/kernel/cpu.c | 59 ---------------------------------------- arch/x86_64/kernel/cpu.c | 59 ---------------------------------------- kernel/mem.c | 56 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 120 deletions(-) diff --git a/arch/arm64/kernel/cpu.c b/arch/arm64/kernel/cpu.c index 59318655..7832f9dc 100644 --- a/arch/arm64/kernel/cpu.c +++ b/arch/arm64/kernel/cpu.c @@ -53,7 +53,6 @@ void assign_processor_id(void); void arch_delay(int); int gettime_local_support = 0; -extern int ihk_mc_pt_print_pte(struct page_table *pt, void *virt); extern int interrupt_from_user(void *); extern unsigned long ihk_param_gic_dist_base_pa; @@ -1559,64 +1558,6 @@ restore_fp_regs(struct thread *thread) } } -void -unhandled_page_fault(struct thread *thread, void *fault_addr, void *regs) -{ - const uintptr_t address = (uintptr_t)fault_addr; - struct process_vm *vm; - struct vm_range *range; - unsigned long irqflags; - unsigned long error = 0; - - irqflags = kprintf_lock(); - __kprintf("Page fault for 0x%lx\n", address); - __kprintf("%s for %s access in %s mode (reserved bit %s set), " - "it %s an instruction fetch\n", - (error & PF_PROT ? "protection fault" : "no page found"), - (error & PF_WRITE ? "write" : "read"), - (error & PF_USER ? "user" : "kernel"), - (error & PF_RSVD ? "was" : "wasn't"), - (error & PF_INSTR ? "was" : "wasn't")); - - if (!thread) - goto skipvm; - - vm = thread->vm; - - range = lookup_process_memory_range(vm, address, address+1); - if (range) { - __kprintf("address is in range, flag: 0x%lx\n", - range->flag); - ihk_mc_pt_print_pte(vm->address_space->page_table, (void*)address); - } else { - __kprintf("address is out of range! \n"); - } - -skipvm: - kprintf_unlock(irqflags); - - /* TODO */ - ihk_mc_debug_show_interrupt_context(regs); - - if (!interrupt_from_user(regs)) { - panic("panic: kernel mode PF"); - } - - //dkprintf("now dump a core file\n"); - //coredump(proc, regs); - - #ifdef DEBUG_PRINT_MEM - { - uint64_t *sp = (void *)REGS_GET_STACK_POINTER(regs); - - kprintf("*rsp:%lx,*rsp+8:%lx,*rsp+16:%lx,*rsp+24:%lx,\n", - sp[0], sp[1], sp[2], sp[3]); - } - #endif - - return; -} - void init_tick(void) { dkprintf("init_tick():\n"); diff --git a/arch/x86_64/kernel/cpu.c b/arch/x86_64/kernel/cpu.c index dce674fb..1fbcdf9d 100644 --- a/arch/x86_64/kernel/cpu.c +++ b/arch/x86_64/kernel/cpu.c @@ -92,7 +92,6 @@ void x86_set_warm_reset(unsigned long ip, char *first_page_va); void x86_init_perfctr(void); int gettime_local_support = 0; -extern int ihk_mc_pt_print_pte(struct page_table *pt, void *virt); extern int kprintf(const char *format, ...); extern int interrupt_from_user(void *); extern void perf_start(struct mc_perf_event *event); @@ -1085,64 +1084,6 @@ void int3_handler(struct x86_user_context *regs) CPUTIME_MODE_K2U : CPUTIME_MODE_K2K_OUT); } -void -unhandled_page_fault(struct thread *thread, void *fault_addr, void *regs) -{ - const uintptr_t address = (uintptr_t)fault_addr; - struct process_vm *vm; - struct vm_range *range; - unsigned long irqflags; - unsigned long error = ((struct x86_user_context *)regs)->gpr.error; - - irqflags = kprintf_lock(); - __kprintf("Page fault for 0x%lx\n", address); - __kprintf("%s for %s access in %s mode (reserved bit %s set), " - "it %s an instruction fetch\n", - (error & PF_PROT ? "protection fault" : "no page found"), - (error & PF_WRITE ? "write" : "read"), - (error & PF_USER ? "user" : "kernel"), - (error & PF_RSVD ? "was" : "wasn't"), - (error & PF_INSTR ? "was" : "wasn't")); - - if (!thread) - goto skipvm; - - vm = thread->vm; - - range = lookup_process_memory_range(vm, address, address+1); - if (range) { - __kprintf("address is in range, flag: 0x%lx\n", - range->flag); - ihk_mc_pt_print_pte(vm->address_space->page_table, (void*)address); - } else { - __kprintf("address is out of range! \n"); - } - -skipvm: - kprintf_unlock(irqflags); - - /* TODO */ - ihk_mc_debug_show_interrupt_context(regs); - - if (!(error & PF_USER)) { - panic("panic: kernel mode PF"); - } - - //dkprintf("now dump a core file\n"); - //coredump(proc, regs); - -#ifdef DEBUG_PRINT_MEM - { - uint64_t *sp = (void *)REGS_GET_STACK_POINTER(regs); - - kprintf("*rsp:%lx,*rsp+8:%lx,*rsp+16:%lx,*rsp+24:%lx,\n", - sp[0], sp[1], sp[2], sp[3]); - } -#endif - - return; -} - static void outb(uint8_t v, uint16_t port) { asm volatile("outb %0, %1" : : "a" (v), "d" (port)); diff --git a/kernel/mem.c b/kernel/mem.c index 774e4eb0..a7f058cf 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -56,7 +56,7 @@ static unsigned long pa_start, pa_end; static struct ihk_mc_numa_node memory_nodes[512]; -extern void unhandled_page_fault(struct thread *, void *, void *); +extern int ihk_mc_pt_print_pte(struct page_table *pt, void *virt); extern int interrupt_from_user(void *); struct tlb_flush_entry tlb_flush_vector[IHK_TLB_FLUSH_IRQ_VECTOR_SIZE]; @@ -1144,6 +1144,58 @@ void tlb_flush_handler(int vector) #endif // PROFILE_ENABLE } +static void unhandled_page_fault(struct thread *thread, void *fault_addr, + uint64_t reason, void *regs) +{ + const uintptr_t address = (uintptr_t)fault_addr; + struct process_vm *vm = thread->vm; + struct vm_range *range; + unsigned long irqflags; + + irqflags = kprintf_lock(); + __kprintf("Page fault for 0x%lx\n", address); + __kprintf("%s for %s access in %s mode (reserved bit %s set), " + "it %s an instruction fetch\n", + (reason & PF_PROT ? "protection fault" : + "no page found"), + (reason & PF_WRITE ? "write" : "read"), + (reason & PF_USER ? "user" : "kernel"), + (reason & PF_RSVD ? "was" : "wasn't"), + (reason & PF_INSTR ? "was" : "wasn't")); + + range = lookup_process_memory_range(vm, address, address+1); + if (range) { + __kprintf("address is in range, flag: 0x%lx\n", + range->flag); + ihk_mc_pt_print_pte(vm->address_space->page_table, + (void *)address); + } else { + __kprintf("address is out of range!\n"); + } + + kprintf_unlock(irqflags); + + /* TODO */ + ihk_mc_debug_show_interrupt_context(regs); + + if (!(reason & PF_USER)) { + panic("panic: kernel mode PF"); + } + + //dkprintf("now dump a core file\n"); + //coredump(proc, regs); + +#ifdef DEBUG_PRINT_MEM + { + uint64_t *sp = (void *)REGS_GET_STACK_POINTER(regs); + + kprintf("*rsp:%lx,*rsp+8:%lx,*rsp+16:%lx,*rsp+24:%lx,\n", + sp[0], sp[1], sp[2], sp[3]); + } +#endif +} + + static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs) { struct thread *thread = cpu_local_var(current); @@ -1182,7 +1234,7 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs) kprintf("%s fault VM failed for TID: %d, addr: 0x%lx, reason: %d, error: %d\n", __func__, thread ? thread->tid : -1, fault_addr, reason, error); - unhandled_page_fault(thread, fault_addr, regs); + unhandled_page_fault(thread, fault_addr, reason, regs); preempt_enable(); memset(&info, '\0', sizeof info); if (error == -ERANGE) {