signal: interrupt_syscall is called by the core executing the thread that recieved the signal.
refs #999
This commit is contained in:
@ -849,6 +849,7 @@ void setup_x86_ap(void (*next_func)(void))
|
|||||||
void arch_show_interrupt_context(const void *reg);
|
void arch_show_interrupt_context(const void *reg);
|
||||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||||
void check_signal(unsigned long, void *, int);
|
void check_signal(unsigned long, void *, int);
|
||||||
|
void check_sig_pending();
|
||||||
extern void tlb_flush_handler(int vector);
|
extern void tlb_flush_handler(int vector);
|
||||||
|
|
||||||
void __show_stack(uintptr_t *sp) {
|
void __show_stack(uintptr_t *sp) {
|
||||||
@ -870,6 +871,18 @@ void show_context_stack(uintptr_t *rbp) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void interrupt_exit(struct x86_user_context *regs)
|
||||||
|
{
|
||||||
|
if (interrupt_from_user(regs)) {
|
||||||
|
cpu_enable_interrupt();
|
||||||
|
check_signal(0, regs, 0);
|
||||||
|
check_need_resched();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
check_sig_pending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle_interrupt(int vector, struct x86_user_context *regs)
|
void handle_interrupt(int vector, struct x86_user_context *regs)
|
||||||
{
|
{
|
||||||
struct ihk_mc_interrupt_handler *h;
|
struct ihk_mc_interrupt_handler *h;
|
||||||
@ -992,11 +1005,7 @@ void handle_interrupt(int vector, struct x86_user_context *regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(interrupt_from_user(regs)){
|
interrupt_exit(regs);
|
||||||
cpu_enable_interrupt();
|
|
||||||
check_signal(0, regs, 0);
|
|
||||||
check_need_resched();
|
|
||||||
}
|
|
||||||
set_cputime(0);
|
set_cputime(0);
|
||||||
|
|
||||||
--v->in_interrupt;
|
--v->in_interrupt;
|
||||||
@ -1012,11 +1021,7 @@ void gpe_handler(struct x86_user_context *regs)
|
|||||||
panic("gpe_handler");
|
panic("gpe_handler");
|
||||||
}
|
}
|
||||||
set_signal(SIGSEGV, regs, NULL);
|
set_signal(SIGSEGV, regs, NULL);
|
||||||
if(interrupt_from_user(regs)){
|
interrupt_exit(regs);
|
||||||
cpu_enable_interrupt();
|
|
||||||
check_signal(0, regs, 0);
|
|
||||||
check_need_resched();
|
|
||||||
}
|
|
||||||
set_cputime(0);
|
set_cputime(0);
|
||||||
panic("GPF");
|
panic("GPF");
|
||||||
}
|
}
|
||||||
@ -1045,11 +1050,7 @@ void debug_handler(struct x86_user_context *regs)
|
|||||||
memset(&info, '\0', sizeof info);
|
memset(&info, '\0', sizeof info);
|
||||||
info.si_code = si_code;
|
info.si_code = si_code;
|
||||||
set_signal(SIGTRAP, regs, &info);
|
set_signal(SIGTRAP, regs, &info);
|
||||||
if(interrupt_from_user(regs)){
|
interrupt_exit(regs);
|
||||||
cpu_enable_interrupt();
|
|
||||||
check_signal(0, regs, 0);
|
|
||||||
check_need_resched();
|
|
||||||
}
|
|
||||||
set_cputime(0);
|
set_cputime(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,11 +1068,7 @@ void int3_handler(struct x86_user_context *regs)
|
|||||||
memset(&info, '\0', sizeof info);
|
memset(&info, '\0', sizeof info);
|
||||||
info.si_code = TRAP_BRKPT;
|
info.si_code = TRAP_BRKPT;
|
||||||
set_signal(SIGTRAP, regs, &info);
|
set_signal(SIGTRAP, regs, &info);
|
||||||
if(interrupt_from_user(regs)){
|
interrupt_exit(regs);
|
||||||
cpu_enable_interrupt();
|
|
||||||
check_signal(0, regs, 0);
|
|
||||||
check_need_resched();
|
|
||||||
}
|
|
||||||
set_cputime(0);
|
set_cputime(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
|
||||||
void terminate(int, int);
|
|
||||||
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||||
long syscall(int num, ihk_mc_user_context_t *ctx);
|
long syscall(int num, ihk_mc_user_context_t *ctx);
|
||||||
void set_signal(int sig, void *regs0, siginfo_t *info);
|
void set_signal(int sig, void *regs0, siginfo_t *info);
|
||||||
@ -280,6 +279,7 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
extern struct cpu_local_var *clv;
|
extern struct cpu_local_var *clv;
|
||||||
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
||||||
extern void interrupt_syscall(struct thread *, int sig);
|
extern void interrupt_syscall(struct thread *, int sig);
|
||||||
|
extern void terminate(int, int);
|
||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
|
|
||||||
#define RFLAGS_MASK (RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | \
|
#define RFLAGS_MASK (RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | \
|
||||||
@ -1054,6 +1054,72 @@ out:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
check_sig_pending()
|
||||||
|
{
|
||||||
|
struct thread *thread;
|
||||||
|
int found = 0;
|
||||||
|
struct list_head *head;
|
||||||
|
mcs_rwlock_lock_t *lock;
|
||||||
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
|
struct sig_pending *next;
|
||||||
|
struct sig_pending *pending;
|
||||||
|
__sigset_t w;
|
||||||
|
__sigset_t x;
|
||||||
|
int sig;
|
||||||
|
struct k_sigaction *k;
|
||||||
|
|
||||||
|
|
||||||
|
if(clv == NULL)
|
||||||
|
return;
|
||||||
|
thread = cpu_local_var(current);
|
||||||
|
|
||||||
|
if (thread == NULL || thread == &cpu_local_var(idle)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->in_syscall_offload == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = thread->sigmask.__val[0];
|
||||||
|
|
||||||
|
lock = &thread->sigcommon->lock;
|
||||||
|
head = &thread->sigcommon->sigpending;
|
||||||
|
for (;;) {
|
||||||
|
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(pending, next, head, list){
|
||||||
|
for (x = pending->sigmask.__val[0], sig = 0; x;
|
||||||
|
sig++, x >>= 1);
|
||||||
|
k = thread->sigcommon->action + sig - 1;
|
||||||
|
if ((sig != SIGCHLD && sig != SIGURG) ||
|
||||||
|
(k->sa.sa_handler != (void *)1 &&
|
||||||
|
k->sa.sa_handler != NULL)) {
|
||||||
|
if (!(pending->sigmask.__val[0] & w)) {
|
||||||
|
if (pending->interrupted == 0) {
|
||||||
|
pending->interrupted = 1;
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
|
if (lock == &thread->sigpendinglock) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = &thread->sigpendinglock;
|
||||||
|
head = &thread->sigpending;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
interrupt_syscall(thread, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
||||||
int ptracecont)
|
int ptracecont)
|
||||||
@ -1308,9 +1374,6 @@ done:
|
|||||||
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tthread->cpu_id)->apic_id, 0xd0);
|
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tthread->cpu_id)->apic_id, 0xd0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tthread->proc->nohost)
|
|
||||||
interrupt_syscall(tthread, 0);
|
|
||||||
|
|
||||||
if (status != PS_RUNNING) {
|
if (status != PS_RUNNING) {
|
||||||
if(sig == SIGKILL){
|
if(sig == SIGKILL){
|
||||||
/* Wake up the target only when stopped by ptrace-reporting */
|
/* Wake up the target only when stopped by ptrace-reporting */
|
||||||
|
|||||||
@ -437,6 +437,7 @@ struct sig_pending {
|
|||||||
sigset_t sigmask;
|
sigset_t sigmask;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
int ptracecont;
|
int ptracecont;
|
||||||
|
int interrupted;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void pgio_func_t(void *arg);
|
typedef void pgio_func_t(void *arg);
|
||||||
|
|||||||
Reference in New Issue
Block a user