support SIGSEGV(page fault) and SIGILL(general protection error)

This commit is contained in:
Tomoki Shirasawa
2013-07-26 11:53:00 +09:00
parent b6d25861e5
commit 221f2c0517
5 changed files with 163 additions and 49 deletions

View File

@ -373,12 +373,15 @@ void handle_interrupt(int vector, struct x86_regs *regs)
} }
} }
void sigill(void *);
void gpe_handler(struct x86_regs *regs) void gpe_handler(struct x86_regs *regs)
{ {
kprintf("General protection fault (err: %lx, %lx:%lx)\n", kprintf("General protection fault (err: %lx, %lx:%lx)\n",
regs->error, regs->cs, regs->rip); regs->error, regs->cs, regs->rip);
arch_show_interrupt_context(regs); arch_show_interrupt_context(regs);
panic("GPF"); sigill(regs);
// panic("GPF");
} }
void x86_issue_ipi(unsigned int apicid, unsigned int low) void x86_issue_ipi(unsigned int apicid, unsigned int low)

View File

@ -16,3 +16,39 @@ struct sigaction {
struct k_sigaction { struct k_sigaction {
struct sigaction sa; struct sigaction sa;
}; };
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGBUS 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGURG 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGIO 29
#define SIGPOLL SIGIO
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED 31
#define SIGRTMIN 32

View File

@ -6,6 +6,10 @@
#include <ihk/debug.h> #include <ihk/debug.h>
#include <cls.h> #include <cls.h>
#include <syscall.h> #include <syscall.h>
#include <process.h>
#include <string.h>
void terminate(int, int, ihk_mc_user_context_t *);
//#define DEBUG_PRINT_SC //#define DEBUG_PRINT_SC
@ -67,3 +71,80 @@ int obtain_clone_cpuid() {
ihk_mc_spinlock_unlock_noirq(&cpuid_head_lock); ihk_mc_spinlock_unlock_noirq(&cpuid_head_lock);
return cpuid; return cpuid;
} }
SYSCALL_DECLARE(rt_sigreturn)
{
struct process *proc = cpu_local_var(current);
char *kspbottom;
asm volatile ("movq %%gs:132,%0" : "=r" (kspbottom));
memcpy(kspbottom - 120, proc->sigstack, 120);
return proc->sigrc;
}
void
check_signal(unsigned long rc, unsigned long *regs)
{
struct process *proc = cpu_local_var(current);
struct k_sigaction *k;
int sig = proc->signal;
proc->signal = 0;
if(sig){
if(regs == NULL){ /* call from syscall */
asm volatile ("movq %%gs:132,%0" : "=r" (regs));
regs -= 16;
}
else{
rc = regs[9]; /* rax */
}
k = proc->sighandler->action + sig - 1;
if(k->sa.sa_handler == (void *)1){
return;
}
else if(k->sa.sa_handler){
unsigned long *usp; /* user stack */
long w;
usp = (void *)regs[14];
memcpy(proc->sigstack, regs, 128);
proc->sigrc = rc;
usp--;
*usp = (unsigned long)k->sa.sa_restorer;
w = 56 + 3;
asm volatile ("pushq %0" :: "r" (w));
asm volatile ("pushq %0" :: "r" (usp));
w = 1 << 9;
asm volatile ("pushq %0" :: "r" (w));
w = 48 + 3;
asm volatile ("pushq %0" :: "r" (w));
asm volatile ("pushq %0" :: "r" (k->sa.sa_handler));
asm volatile ("iretq");
}
else{
if(sig == SIGCHLD || sig == SIGURG)
return;
terminate(0, sig, (ihk_mc_user_context_t *)regs[14]);
}
}
}
void
sigsegv(unsigned long *regs)
{
struct process *proc = cpu_local_var(current);
proc->signal = SIGSEGV;
check_signal(0, regs);
}
void
sigill(unsigned long *regs)
{
struct process *proc = cpu_local_var(current);
proc->signal = SIGILL;
check_signal(0, regs);
}

View File

@ -141,7 +141,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
.priv = NULL, .priv = NULL,
}; };
void sigsegv(void *);
static void page_fault_handler(unsigned long address, void *regs, static void page_fault_handler(unsigned long address, void *regs,
unsigned long rbp) unsigned long rbp)
@ -226,7 +226,9 @@ static void page_fault_handler(unsigned long address, void *regs,
} }
#endif #endif
panic(""); sigsegv(regs);
//panic("mem fault");
} }
static void page_allocator_init(void) static void page_allocator_init(void)

View File

@ -66,6 +66,8 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
#undef SYSCALL_DELEGATED #undef SYSCALL_DELEGATED
}; };
void check_signal(unsigned long rc, unsigned long *regs);
#ifdef DCFA_KMOD #ifdef DCFA_KMOD
static void do_mod_exit(int status); static void do_mod_exit(int status);
#endif #endif
@ -145,9 +147,41 @@ SYSCALL_DECLARE(open)
SYSCALL_FOOTER; SYSCALL_FOOTER;
} }
void
terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
{
struct syscall_request request IHK_DMA_ALIGN;
struct process *proc = cpu_local_var(current);
request.number = __NR_exit_group;
#ifdef DCFA_KMOD
do_mod_exit(rc);
#endif
/* XXX: send SIGKILL to all threads in this process */
do_syscall(&request, ctx);
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
proc->status = PS_ZOMBIE;
if (IS_DETACHED_PROCESS(proc)) {
/* release a reference for wait(2) */
proc->status = PS_EXITED;
free_process(proc);
}
schedule();
}
SYSCALL_DECLARE(exit_group) SYSCALL_DECLARE(exit_group)
{ {
#if 0
SYSCALL_HEADER; SYSCALL_HEADER;
#endif
terminate((int)ihk_mc_syscall_arg0(ctx), 0, ctx);
#if 0
struct process *proc = cpu_local_var(current); struct process *proc = cpu_local_var(current);
#ifdef DCFA_KMOD #ifdef DCFA_KMOD
@ -168,6 +202,8 @@ SYSCALL_DECLARE(exit_group)
schedule(); schedule();
#endif
return 0; return 0;
} }
@ -806,7 +842,7 @@ SYSCALL_DECLARE(rt_sigaction)
int sig = ihk_mc_syscall_arg0(ctx); int sig = ihk_mc_syscall_arg0(ctx);
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx); const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx); struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
size_t sigsetsize = ihk_mc_syscall_arg3(ctx); //size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
struct k_sigaction new_sa, old_sa; struct k_sigaction new_sa, old_sa;
int rc; int rc;
@ -822,50 +858,6 @@ SYSCALL_DECLARE(rt_sigaction)
return rc; return rc;
} }
static void
check_signal(unsigned long rc)
{
struct process *proc = cpu_local_var(current);
struct k_sigaction *k;
int sig = proc->signal;
proc->signal = 0;
if(sig){
k = proc->sighandler->action + sig - 1;
if(k->sa.sa_handler){
unsigned long *usp; /* user stack */
char *kspbottom;
long w;
asm volatile ("movq %%gs:24,%0" : "=r" (usp));
asm volatile ("movq %%gs:132,%0" : "=r" (kspbottom));
memcpy(proc->sigstack, kspbottom - 120, 120);
proc->sigrc = rc;
usp--;
*usp = (unsigned long)k->sa.sa_restorer;
w = 56 + 3;
asm volatile ("pushq %0" :: "r" (w));
asm volatile ("pushq %0" :: "r" (usp));
w = 1 << 9;
asm volatile ("pushq %0" :: "r" (w));
w = 48 + 3;
asm volatile ("pushq %0" :: "r" (w));
asm volatile ("pushq %0" :: "r" (k->sa.sa_handler));
asm volatile ("iretq");
}
}
}
SYSCALL_DECLARE(rt_sigreturn)
{
struct process *proc = cpu_local_var(current);
char *kspbottom;
asm volatile ("movq %%gs:132,%0" : "=r" (kspbottom));
memcpy(kspbottom - 120, proc->sigstack, 120);
return proc->sigrc;
}
SYSCALL_DECLARE(rt_sigprocmask) SYSCALL_DECLARE(rt_sigprocmask)
{ {
// kprintf("sys_rt_sigprocmask called. returning zero...\n"); // kprintf("sys_rt_sigprocmask called. returning zero...\n");
@ -1198,7 +1190,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
l = syscall_generic_forwarding(num, ctx); l = syscall_generic_forwarding(num, ctx);
} }
check_signal(l); check_signal(l, NULL);
return l; return l;
} }