support sigqueue
This commit is contained in:
@ -405,7 +405,7 @@ void setup_x86_ap(void (*next_func)(void))
|
||||
}
|
||||
|
||||
void arch_show_interrupt_context(const void *reg);
|
||||
void set_signal(int sig, void *regs);
|
||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
extern void tlb_flush_handler(int vector);
|
||||
|
||||
@ -452,10 +452,13 @@ void handle_interrupt(int vector, struct x86_regs *regs)
|
||||
|
||||
void gpe_handler(struct x86_regs *regs)
|
||||
{
|
||||
struct siginfo info;
|
||||
|
||||
kprintf("General protection fault (err: %lx, %lx:%lx)\n",
|
||||
regs->error, regs->cs, regs->rip);
|
||||
arch_show_interrupt_context(regs);
|
||||
set_signal(SIGILL, regs);
|
||||
memset(&info, '\0', sizeof info);
|
||||
set_signal(SIGILL, regs, &info);
|
||||
check_signal(0, regs);
|
||||
check_need_resched();
|
||||
// panic("GPF");
|
||||
|
||||
@ -36,13 +36,13 @@ struct sigaction {
|
||||
sigset_t sa_mask;
|
||||
};
|
||||
|
||||
#define SA_NOCLDSTOP 0x00000001u
|
||||
#define SA_NOCLDWAIT 0x00000002u
|
||||
#define SA_NODEFER 0x40000000u
|
||||
#define SA_ONSTACK 0x08000000u
|
||||
#define SA_RESETHAND 0x80000000u
|
||||
#define SA_RESTART 0x10000000u
|
||||
#define SA_SIGINFO 0x00000004u
|
||||
#define SA_NOCLDSTOP 0x00000001U
|
||||
#define SA_NOCLDWAIT 0x00000002U
|
||||
#define SA_NODEFER 0x40000000U
|
||||
#define SA_ONSTACK 0x08000000U
|
||||
#define SA_RESETHAND 0x80000000U
|
||||
#define SA_RESTART 0x10000000U
|
||||
#define SA_SIGINFO 0x00000004U
|
||||
|
||||
struct k_sigaction {
|
||||
struct sigaction sa;
|
||||
@ -71,6 +71,16 @@ typedef struct siginfo {
|
||||
int si_errno; /* If non-zero, an errno value associated with
|
||||
this signal, as defined in <errno.h>. */
|
||||
int si_code; /* Signal code. */
|
||||
#define SI_USER 0 /* sent by kill, sigsend, raise */
|
||||
#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
|
||||
#define SI_QUEUE -1 /* sent by sigqueue */
|
||||
#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
|
||||
#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change
|
||||
*/
|
||||
#define SI_ASYNCIO -4 /* sent by AIO completion */
|
||||
#define SI_SIGIO -5 /* sent by queued SIGIO */
|
||||
#define SI_TKILL -6 /* sent by tkill system call */
|
||||
#define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */
|
||||
|
||||
union {
|
||||
int _pad[__SI_PAD_SIZE];
|
||||
@ -117,6 +127,29 @@ typedef struct siginfo {
|
||||
} _sifields;
|
||||
} siginfo_t;
|
||||
|
||||
struct signalfd_siginfo {
|
||||
unsigned int ssi_signo;
|
||||
int ssi_errno;
|
||||
int ssi_code;
|
||||
unsigned int ssi_pid;
|
||||
unsigned int ssi_uid;
|
||||
int ssi_fd;
|
||||
unsigned int ssi_tid;
|
||||
unsigned int ssi_band;
|
||||
unsigned int ssi_overrun;
|
||||
unsigned int ssi_trapno;
|
||||
int ssi_status;
|
||||
int ssi_int;
|
||||
unsigned long ssi_ptr;
|
||||
unsigned long ssi_utime;
|
||||
unsigned long ssi_stime;
|
||||
unsigned long ssi_addr;
|
||||
unsigned short ssi_addr_lsb;
|
||||
|
||||
char __pad[46];
|
||||
};
|
||||
|
||||
|
||||
#define SIGHUP 1
|
||||
#define SIGINT 2
|
||||
#define SIGQUIT 3
|
||||
|
||||
@ -84,6 +84,8 @@ SYSCALL_HANDLED(218, set_tid_address)
|
||||
SYSCALL_HANDLED(231, exit_group)
|
||||
SYSCALL_HANDLED(234, tgkill)
|
||||
SYSCALL_HANDLED(273, set_robust_list)
|
||||
SYSCALL_HANDLED(282, signalfd)
|
||||
SYSCALL_HANDLED(289, signalfd4)
|
||||
#ifdef DCFA_KMOD
|
||||
SYSCALL_HANDLED(303, mod_call)
|
||||
#endif
|
||||
|
||||
@ -135,6 +135,7 @@ struct sigsp {
|
||||
unsigned long sigrc;
|
||||
unsigned long sigmask;
|
||||
int ssflags;
|
||||
siginfo_t info;
|
||||
};
|
||||
|
||||
SYSCALL_DECLARE(rt_sigreturn)
|
||||
@ -157,7 +158,7 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
}
|
||||
|
||||
extern struct cpu_local_var *clv;
|
||||
extern unsigned long do_kill(int pid, int tid, int sig);
|
||||
extern unsigned long do_kill(int pid, int tid, int sig, struct siginfo *info);
|
||||
extern void interrupt_syscall(int all, int pid);
|
||||
extern int num_processors;
|
||||
|
||||
@ -253,12 +254,17 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
||||
}
|
||||
sigsp->sigmask = mask;
|
||||
sigsp->ssflags = ssflags;
|
||||
memcpy(&sigsp->info, &pending->info, sizeof(siginfo_t));
|
||||
|
||||
usp = (unsigned long *)sigsp;
|
||||
usp--;
|
||||
*usp = (unsigned long)k->sa.sa_restorer;
|
||||
|
||||
regs->rdi = (unsigned long)sig;
|
||||
if(k->sa.sa_flags & SA_SIGINFO){
|
||||
regs->rsi = (unsigned long)&sigsp->info;
|
||||
regs->rdx = 0;
|
||||
}
|
||||
regs->rip = (unsigned long)k->sa.sa_handler;
|
||||
regs->rsp = (unsigned long)usp;
|
||||
|
||||
@ -374,7 +380,7 @@ check_signal(unsigned long rc, void *regs0)
|
||||
}
|
||||
|
||||
unsigned long
|
||||
do_kill(int pid, int tid, int sig)
|
||||
do_kill(int pid, int tid, int sig, siginfo_t *info)
|
||||
{
|
||||
struct cpu_local_var *v;
|
||||
struct process *p;
|
||||
@ -435,9 +441,9 @@ do_kill(int pid, int tid, int sig)
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
}
|
||||
for(i = 0; i < n; i++)
|
||||
rc = do_kill(pids[i], -1, sig);
|
||||
rc = do_kill(pids[i], -1, sig, info);
|
||||
if(sendme)
|
||||
rc = do_kill(proc->pid, -1, sig);
|
||||
rc = do_kill(proc->pid, -1, sig, info);
|
||||
|
||||
kfree(pids);
|
||||
return rc;
|
||||
@ -563,11 +569,12 @@ do_kill(int pid, int tid, int sig)
|
||||
if(pending == NULL){
|
||||
doint = 1;
|
||||
pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT);
|
||||
pending->sigmask.__val[0] = mask;
|
||||
if(!pending){
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
else{
|
||||
pending->sigmask.__val[0] = mask;
|
||||
memcpy(&pending->info, info, sizeof(siginfo_t));
|
||||
list_add_tail(&pending->list, head);
|
||||
tproc->sigevent = 1;
|
||||
}
|
||||
@ -625,7 +632,7 @@ do_kill(int pid, int tid, int sig)
|
||||
}
|
||||
|
||||
void
|
||||
set_signal(int sig, void *regs0)
|
||||
set_signal(int sig, void *regs0, siginfo_t *info)
|
||||
{
|
||||
struct x86_regs *regs = regs0;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
@ -639,5 +646,5 @@ set_signal(int sig, void *regs0)
|
||||
terminate(0, sig | 0x80, (ihk_mc_user_context_t *)regs->rsp);
|
||||
}
|
||||
else
|
||||
do_kill(proc->pid, proc->tid, sig);
|
||||
do_kill(proc->pid, proc->tid, sig, info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user