unhandled_page_fault: Refactor architecture dependent parts

Fujitsu: REQ-12
Refs: #1012
Change-Id: I3c61f9cd3f514bdcd4a7f26e7c15043529269cf5
This commit is contained in:
Masamichi Takagi
2018-10-02 13:01:16 +09:00
committed by Dominique Martinet
parent 207d653b41
commit fb24dcea2e
3 changed files with 54 additions and 120 deletions

View File

@ -53,7 +53,6 @@ void assign_processor_id(void);
void arch_delay(int); void arch_delay(int);
int gettime_local_support = 0; 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 int interrupt_from_user(void *);
extern unsigned long ihk_param_gic_dist_base_pa; 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) void init_tick(void)
{ {
dkprintf("init_tick():\n"); dkprintf("init_tick():\n");

View File

@ -92,7 +92,6 @@ void x86_set_warm_reset(unsigned long ip, char *first_page_va);
void x86_init_perfctr(void); void x86_init_perfctr(void);
int gettime_local_support = 0; 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 kprintf(const char *format, ...);
extern int interrupt_from_user(void *); extern int interrupt_from_user(void *);
extern void perf_start(struct mc_perf_event *event); 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); 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) static void outb(uint8_t v, uint16_t port)
{ {
asm volatile("outb %0, %1" : : "a" (v), "d" (port)); asm volatile("outb %0, %1" : : "a" (v), "d" (port));

View File

@ -56,7 +56,7 @@
static unsigned long pa_start, pa_end; static unsigned long pa_start, pa_end;
static struct ihk_mc_numa_node memory_nodes[512]; 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 *); extern int interrupt_from_user(void *);
struct tlb_flush_entry tlb_flush_vector[IHK_TLB_FLUSH_IRQ_VECTOR_SIZE]; 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 #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) static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
{ {
struct thread *thread = cpu_local_var(current); 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", kprintf("%s fault VM failed for TID: %d, addr: 0x%lx, reason: %d, error: %d\n",
__func__, thread ? thread->tid : -1, fault_addr, __func__, thread ? thread->tid : -1, fault_addr,
reason, error); reason, error);
unhandled_page_fault(thread, fault_addr, regs); unhandled_page_fault(thread, fault_addr, reason, regs);
preempt_enable(); preempt_enable();
memset(&info, '\0', sizeof info); memset(&info, '\0', sizeof info);
if (error == -ERANGE) { if (error == -ERANGE) {