signal (part 1)
This commit is contained in:
@ -368,7 +368,7 @@ void setup_x86_ap(void (*next_func)(void))
|
||||
}
|
||||
|
||||
void arch_show_interrupt_context(const void *reg);
|
||||
void set_signal(int, void *);
|
||||
void set_signal(int, void *, int);
|
||||
void check_signal(long, void *);
|
||||
|
||||
void handle_interrupt(int vector, struct x86_regs *regs)
|
||||
@ -409,7 +409,7 @@ void gpe_handler(struct x86_regs *regs)
|
||||
kprintf("General protection fault (err: %lx, %lx:%lx)\n",
|
||||
regs->error, regs->cs, regs->rip);
|
||||
arch_show_interrupt_context(regs);
|
||||
set_signal(SIGILL, regs);
|
||||
set_signal(SIGILL, regs, 1);
|
||||
check_signal(0, regs);
|
||||
// panic("GPF");
|
||||
}
|
||||
|
||||
@ -15,10 +15,19 @@
|
||||
#define _NSIG_BPW 64
|
||||
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
|
||||
|
||||
typedef unsigned long int __sigset_t;
|
||||
#define __sigmask(sig) (((__sigset_t) 1) << ((sig) - 1))
|
||||
|
||||
# define _SIGSET_NWORDS (1024 / (8 * sizeof (__sigset_t)))
|
||||
|
||||
typedef struct {
|
||||
unsigned long sig[_NSIG_WORDS];
|
||||
__sigset_t __val[_SIGSET_NWORDS];
|
||||
} sigset_t;
|
||||
|
||||
#define SIG_BLOCK 0
|
||||
#define SIG_UNBLOCK 1
|
||||
#define SIG_SETMASK 2
|
||||
|
||||
struct sigaction {
|
||||
void (*sa_handler)(int);
|
||||
unsigned long sa_flags;
|
||||
@ -30,6 +39,76 @@ struct k_sigaction {
|
||||
struct sigaction sa;
|
||||
};
|
||||
|
||||
struct sigstack {
|
||||
void *ss_sp;
|
||||
int ss_onstack;
|
||||
};
|
||||
|
||||
typedef struct sigaltstack {
|
||||
void *ss_sp;
|
||||
int ss_flags;
|
||||
size_t ss_size;
|
||||
} stack_t;
|
||||
|
||||
typedef union sigval {
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
|
||||
#define __SI_MAX_SIZE 128
|
||||
#define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
|
||||
|
||||
typedef struct siginfo {
|
||||
int si_signo; /* Signal number. */
|
||||
int si_errno; /* If non-zero, an errno value associated with
|
||||
this signal, as defined in <errno.h>. */
|
||||
int si_code; /* Signal code. */
|
||||
|
||||
union {
|
||||
int _pad[__SI_PAD_SIZE];
|
||||
|
||||
/* kill(). */
|
||||
struct {
|
||||
int si_pid;/* Sending process ID. */
|
||||
int si_uid;/* Real user ID of sending process. */
|
||||
} _kill;
|
||||
|
||||
/* POSIX.1b timers. */
|
||||
struct {
|
||||
int si_tid; /* Timer ID. */
|
||||
int si_overrun; /* Overrun count. */
|
||||
sigval_t si_sigval; /* Signal value. */
|
||||
} _timer;
|
||||
|
||||
/* POSIX.1b signals. */
|
||||
struct {
|
||||
int si_pid; /* Sending process ID. */
|
||||
int si_uid; /* Real user ID of sending process. */
|
||||
sigval_t si_sigval; /* Signal value. */
|
||||
} _rt;
|
||||
|
||||
/* SIGCHLD. */
|
||||
struct {
|
||||
int si_pid; /* Which child. */
|
||||
int si_uid; /* Real user ID of sending process. */
|
||||
int si_status; /* Exit value or signal. */
|
||||
long si_utime;
|
||||
long si_stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
|
||||
struct {
|
||||
void *si_addr; /* Faulting insn/memory ref. */
|
||||
} _sigfault;
|
||||
|
||||
/* SIGPOLL. */
|
||||
struct {
|
||||
long int si_band; /* Band event for SIGPOLL. */
|
||||
int si_fd;
|
||||
} _sigpoll;
|
||||
} _sifields;
|
||||
} siginfo_t;
|
||||
|
||||
#define SIGHUP 1
|
||||
#define SIGINT 2
|
||||
#define SIGQUIT 3
|
||||
|
||||
@ -64,6 +64,7 @@ SYSCALL_HANDLED(129, rt_sigqueueinfo)
|
||||
SYSCALL_HANDLED(130, rt_sigsuspend)
|
||||
SYSCALL_HANDLED(131, sigaltstack)
|
||||
SYSCALL_HANDLED(158, arch_prctl)
|
||||
SYSCALL_HANDLED(186, gettid)
|
||||
SYSCALL_DELEGATED(201, time)
|
||||
SYSCALL_HANDLED(202, futex)
|
||||
SYSCALL_HANDLED(203, sched_setaffinity)
|
||||
|
||||
@ -98,8 +98,9 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
}
|
||||
|
||||
extern struct cpu_local_var *clv;
|
||||
extern unsigned long do_kill(int pid, int sig);
|
||||
extern void interrupt_syscall();
|
||||
extern unsigned long do_kill(int pid, int tid, int sig);
|
||||
extern void interrupt_syscall(int all);
|
||||
extern int num_processors;
|
||||
|
||||
void
|
||||
check_signal(unsigned long rc, unsigned long *regs)
|
||||
@ -136,7 +137,6 @@ check_signal(unsigned long rc, unsigned long *regs)
|
||||
|
||||
if(regs[14] & 0x8000000000000000){ // kernel addr
|
||||
proc->signal = sig;
|
||||
interrupt_syscall();
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||
return;
|
||||
}
|
||||
@ -162,36 +162,76 @@ check_signal(unsigned long rc, unsigned long *regs)
|
||||
}
|
||||
|
||||
unsigned long
|
||||
do_kill(int pid, int sig)
|
||||
do_kill(int pid, int tid, int sig)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct process *tproc = NULL;
|
||||
int i;
|
||||
|
||||
if(proc == NULL || proc->pid == 0){
|
||||
return -ESRCH;
|
||||
}
|
||||
if(proc->pid == pid){
|
||||
proc->signal = sig;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pid <= 0){
|
||||
if(sig > 64 || sig < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if(tid == -1){
|
||||
if(pid == proc->pid || pid <= 0){
|
||||
tproc = proc;
|
||||
}
|
||||
}
|
||||
if(sig == 0){
|
||||
return 0;
|
||||
else if(pid == -1){
|
||||
for(i = 0; i < num_processors; i++)
|
||||
if(get_cpu_local_var(i)->current &&
|
||||
get_cpu_local_var(i)->current->pid > 0 &&
|
||||
get_cpu_local_var(i)->current->tid == tid){
|
||||
tproc = get_cpu_local_var(i)->current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
return -EPERM;
|
||||
if(pid == 0)
|
||||
return -ESRCH;
|
||||
for(i = 0; i < num_processors; i++)
|
||||
if(get_cpu_local_var(i)->current &&
|
||||
get_cpu_local_var(i)->current->pid == pid &&
|
||||
get_cpu_local_var(i)->current->tid == tid){
|
||||
tproc = get_cpu_local_var(i)->current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!tproc)
|
||||
return -ESRCH;
|
||||
if(sig == 0)
|
||||
return 0;
|
||||
|
||||
if(__sigmask(sig) & proc->sigmask.__val[0]){
|
||||
// TODO: masked signal: ignore -> pending
|
||||
return 0;
|
||||
}
|
||||
proc->signal = sig;
|
||||
interrupt_syscall(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_signal(int sig, unsigned long *regs)
|
||||
set_signal(int sig, unsigned long *regs, int nonmaskable)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
|
||||
if(proc == NULL || proc->pid == 0)
|
||||
return;
|
||||
|
||||
if(__sigmask(sig) & proc->sigmask.__val[0]){
|
||||
if(nonmaskable){
|
||||
terminate(0, sig, (ihk_mc_user_context_t *)regs[14]);
|
||||
}
|
||||
else{
|
||||
// TODO: masked signal: ignore -> pending
|
||||
return;
|
||||
}
|
||||
}
|
||||
proc->signal = sig;
|
||||
interrupt_syscall();
|
||||
interrupt_syscall(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user