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 arch_show_interrupt_context(const void *reg);
|
||||||
void set_signal(int, void *);
|
void set_signal(int, void *, int);
|
||||||
void check_signal(long, void *);
|
void check_signal(long, void *);
|
||||||
|
|
||||||
void handle_interrupt(int vector, struct x86_regs *regs)
|
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",
|
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);
|
||||||
set_signal(SIGILL, regs);
|
set_signal(SIGILL, regs, 1);
|
||||||
check_signal(0, regs);
|
check_signal(0, regs);
|
||||||
// panic("GPF");
|
// panic("GPF");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,19 @@
|
|||||||
#define _NSIG_BPW 64
|
#define _NSIG_BPW 64
|
||||||
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
|
#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 {
|
typedef struct {
|
||||||
unsigned long sig[_NSIG_WORDS];
|
__sigset_t __val[_SIGSET_NWORDS];
|
||||||
} sigset_t;
|
} sigset_t;
|
||||||
|
|
||||||
|
#define SIG_BLOCK 0
|
||||||
|
#define SIG_UNBLOCK 1
|
||||||
|
#define SIG_SETMASK 2
|
||||||
|
|
||||||
struct sigaction {
|
struct sigaction {
|
||||||
void (*sa_handler)(int);
|
void (*sa_handler)(int);
|
||||||
unsigned long sa_flags;
|
unsigned long sa_flags;
|
||||||
@@ -30,6 +39,76 @@ struct k_sigaction {
|
|||||||
struct sigaction sa;
|
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 SIGHUP 1
|
||||||
#define SIGINT 2
|
#define SIGINT 2
|
||||||
#define SIGQUIT 3
|
#define SIGQUIT 3
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ SYSCALL_HANDLED(129, rt_sigqueueinfo)
|
|||||||
SYSCALL_HANDLED(130, rt_sigsuspend)
|
SYSCALL_HANDLED(130, rt_sigsuspend)
|
||||||
SYSCALL_HANDLED(131, sigaltstack)
|
SYSCALL_HANDLED(131, sigaltstack)
|
||||||
SYSCALL_HANDLED(158, arch_prctl)
|
SYSCALL_HANDLED(158, arch_prctl)
|
||||||
|
SYSCALL_HANDLED(186, gettid)
|
||||||
SYSCALL_DELEGATED(201, time)
|
SYSCALL_DELEGATED(201, time)
|
||||||
SYSCALL_HANDLED(202, futex)
|
SYSCALL_HANDLED(202, futex)
|
||||||
SYSCALL_HANDLED(203, sched_setaffinity)
|
SYSCALL_HANDLED(203, sched_setaffinity)
|
||||||
|
|||||||
@@ -98,8 +98,9 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern struct cpu_local_var *clv;
|
extern struct cpu_local_var *clv;
|
||||||
extern unsigned long do_kill(int pid, int sig);
|
extern unsigned long do_kill(int pid, int tid, int sig);
|
||||||
extern void interrupt_syscall();
|
extern void interrupt_syscall(int all);
|
||||||
|
extern int num_processors;
|
||||||
|
|
||||||
void
|
void
|
||||||
check_signal(unsigned long rc, unsigned long *regs)
|
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
|
if(regs[14] & 0x8000000000000000){ // kernel addr
|
||||||
proc->signal = sig;
|
proc->signal = sig;
|
||||||
interrupt_syscall();
|
|
||||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -162,36 +162,76 @@ check_signal(unsigned long rc, unsigned long *regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
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 *proc = cpu_local_var(current);
|
||||||
|
struct process *tproc = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
if(proc == NULL || proc->pid == 0){
|
if(proc == NULL || proc->pid == 0){
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
}
|
}
|
||||||
if(proc->pid == pid){
|
|
||||||
proc->signal = sig;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pid <= 0){
|
if(sig > 64 || sig < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if(tid == -1){
|
||||||
|
if(pid == proc->pid || pid <= 0){
|
||||||
|
tproc = proc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(sig == 0){
|
else if(pid == -1){
|
||||||
return 0;
|
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{
|
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
|
void
|
||||||
set_signal(int sig, unsigned long *regs)
|
set_signal(int sig, unsigned long *regs, int nonmaskable)
|
||||||
{
|
{
|
||||||
struct process *proc = cpu_local_var(current);
|
struct process *proc = cpu_local_var(current);
|
||||||
|
|
||||||
if(proc == NULL || proc->pid == 0)
|
if(proc == NULL || proc->pid == 0)
|
||||||
return;
|
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;
|
proc->signal = sig;
|
||||||
interrupt_syscall();
|
interrupt_syscall(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ static void *main_loop_thread_func(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sendsig(int sig)
|
sendsig(int sig, siginfo_t *siginfo, void *context)
|
||||||
{
|
{
|
||||||
unsigned long param;
|
unsigned long param;
|
||||||
|
|
||||||
@@ -782,8 +782,9 @@ int main(int argc, char **argv)
|
|||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
sigaction(i, NULL, &act);
|
sigaction(i, NULL, &act);
|
||||||
act.sa_handler = sendsig;
|
act.sa_sigaction = sendsig;
|
||||||
act.sa_flags &= ~(SA_RESTART);
|
act.sa_flags &= ~(SA_RESTART);
|
||||||
|
act.sa_flags |= SA_SIGINFO;
|
||||||
sigaction(i, &act, NULL);
|
sigaction(i, &act, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
proc->pid = pn->pid;
|
proc->pid = pn->pid;
|
||||||
|
proc->tid = pn->pid;
|
||||||
proc->vm->region.user_start = pn->user_start;
|
proc->vm->region.user_start = pn->user_start;
|
||||||
proc->vm->region.user_end = pn->user_end;
|
proc->vm->region.user_end = pn->user_end;
|
||||||
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
||||||
@@ -394,7 +395,7 @@ static void syscall_channel_send(struct ihk_ikc_channel_desc *c,
|
|||||||
ihk_ikc_send(c, packet, 0);
|
ihk_ikc_send(c, packet, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned long do_kill(int, int);
|
extern unsigned long do_kill(int, int, int);
|
||||||
|
|
||||||
static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||||
void *__packet, void *ihk_os)
|
void *__packet, void *ihk_os)
|
||||||
@@ -433,7 +434,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
//cpu_local_var(next) = (struct process *)packet->arg;
|
//cpu_local_var(next) = (struct process *)packet->arg;
|
||||||
return 0;
|
return 0;
|
||||||
case SCD_MSG_SEND_SIGNAL:
|
case SCD_MSG_SEND_SIGNAL:
|
||||||
rc = do_kill((int)packet->arg, (int)(packet->arg >> 32));
|
rc = do_kill((int)packet->arg, -1, (int)(packet->arg >> 32));
|
||||||
kprintf("SCD_MSG_SEND_SIGNAL: %lx, rc=%d\n", packet->arg, rc);
|
kprintf("SCD_MSG_SEND_SIGNAL: %lx, rc=%d\n", packet->arg, rc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,14 +108,16 @@ struct process {
|
|||||||
unsigned long tlsblock_base, tlsblock_limit;
|
unsigned long tlsblock_base, tlsblock_limit;
|
||||||
} thread;
|
} thread;
|
||||||
|
|
||||||
int signal;
|
int tid;
|
||||||
sigset_t sigpend;
|
|
||||||
sigset_t sigmask;
|
sigset_t sigmask;
|
||||||
|
int signal;
|
||||||
|
// sigset_t sigpend;
|
||||||
struct sig_handler *sighandler;
|
struct sig_handler *sighandler;
|
||||||
ihk_mc_kernel_context_t sigctx;
|
// ihk_mc_kernel_context_t sigctx;
|
||||||
char sigstack[512];
|
char sigstack[512]; // TODO: 1. move to user stack
|
||||||
// TODO: backup FR and MMX regs
|
// TODO: 2. backup FR and MMX regs
|
||||||
unsigned long sigrc; // return code of rt_sigreturn (x86_64: rax reg.)
|
unsigned long sigrc; // return code of rt_sigreturn (x86_64: rax reg.)
|
||||||
|
|
||||||
struct rlimit rlimit_stack;
|
struct rlimit rlimit_stack;
|
||||||
pgio_func_t *pgio_fp;
|
pgio_func_t *pgio_fp;
|
||||||
void *pgio_arg;
|
void *pgio_arg;
|
||||||
|
|||||||
@@ -203,9 +203,9 @@ struct syscall_params {
|
|||||||
SYSCALL_ARG_##a2(2); SYSCALL_ARG_##a3(3); \
|
SYSCALL_ARG_##a2(2); SYSCALL_ARG_##a3(3); \
|
||||||
SYSCALL_ARG_##a4(4); SYSCALL_ARG_##a5(5);
|
SYSCALL_ARG_##a4(4); SYSCALL_ARG_##a5(5);
|
||||||
|
|
||||||
#define SYSCALL_FOOTER return do_syscall(&request, ctx)
|
#define SYSCALL_FOOTER return do_syscall(&request, ctx, ihk_mc_get_processor_id())
|
||||||
|
|
||||||
extern int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx);
|
extern int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu);
|
||||||
extern int obtain_clone_cpuid();
|
extern int obtain_clone_cpuid();
|
||||||
extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx);
|
extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
|||||||
.priv = NULL,
|
.priv = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_signal(int, unsigned long *);
|
void set_signal(int, unsigned long *, int);
|
||||||
void check_signal(long, unsigned long *);
|
void check_signal(long, unsigned long *);
|
||||||
|
|
||||||
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
||||||
@@ -234,10 +234,10 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
|||||||
reason, regs, error);
|
reason, regs, error);
|
||||||
unhandled_page_fault(proc, fault_addr, regs);
|
unhandled_page_fault(proc, fault_addr, regs);
|
||||||
if (error == -ERANGE) {
|
if (error == -ERANGE) {
|
||||||
set_signal(SIGBUS, regs);
|
set_signal(SIGBUS, regs, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_signal(SIGSEGV, regs);
|
set_signal(SIGSEGV, regs, 1);
|
||||||
}
|
}
|
||||||
check_signal(0, regs);
|
check_signal(0, regs);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -1379,7 +1379,8 @@ void sched_init(void)
|
|||||||
idle_process->vm = &cpu_local_var(idle_vm);
|
idle_process->vm = &cpu_local_var(idle_vm);
|
||||||
|
|
||||||
ihk_mc_init_context(&idle_process->ctx, NULL, idle);
|
ihk_mc_init_context(&idle_process->ctx, NULL, idle);
|
||||||
idle_process->pid = ihk_mc_get_processor_id();
|
idle_process->pid = 0;
|
||||||
|
idle_process->tid = ihk_mc_get_processor_id();
|
||||||
|
|
||||||
INIT_LIST_HEAD(&cpu_local_var(runq));
|
INIT_LIST_HEAD(&cpu_local_var(runq));
|
||||||
cpu_local_var(runq_len) = 0;
|
cpu_local_var(runq_len) = 0;
|
||||||
@@ -1443,7 +1444,7 @@ void schedule(void)
|
|||||||
if (switch_ctx) {
|
if (switch_ctx) {
|
||||||
dkprintf("[%d] schedule: %d => %d \n",
|
dkprintf("[%d] schedule: %d => %d \n",
|
||||||
ihk_mc_get_processor_id(),
|
ihk_mc_get_processor_id(),
|
||||||
prev ? prev->pid : 0, next ? next->pid : 0);
|
prev ? prev->tid : 0, next ? next->tid : 0);
|
||||||
|
|
||||||
ihk_mc_load_page_table(next->vm->page_table);
|
ihk_mc_load_page_table(next->vm->page_table);
|
||||||
|
|
||||||
@@ -1526,8 +1527,8 @@ void __runq_add_proc(struct process *proc, int cpu_id)
|
|||||||
proc->status = PS_RUNNING;
|
proc->status = PS_RUNNING;
|
||||||
get_cpu_local_var(cpu_id)->status = CPU_STATUS_RUNNING;
|
get_cpu_local_var(cpu_id)->status = CPU_STATUS_RUNNING;
|
||||||
|
|
||||||
dkprintf("runq_add_proc(): pid %d added to CPU[%d]'s runq\n",
|
dkprintf("runq_add_proc(): tid %d added to CPU[%d]'s runq\n",
|
||||||
proc->pid, cpu_id);
|
proc->tid, cpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void runq_add_proc(struct process *proc, int cpu_id)
|
void runq_add_proc(struct process *proc, int cpu_id)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
#define ekprintf(...) kprintf(__VA_ARGS__)
|
#define ekprintf(...) kprintf(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ihk_atomic_t pid_cnt = IHK_ATOMIC_INIT(1024);
|
//static ihk_atomic_t pid_cnt = IHK_ATOMIC_INIT(1024);
|
||||||
|
|
||||||
/* generate system call handler's prototypes */
|
/* generate system call handler's prototypes */
|
||||||
#define SYSCALL_HANDLED(number,name) extern long sys_##name(int n, ihk_mc_user_context_t *ctx);
|
#define SYSCALL_HANDLED(number,name) extern long sys_##name(int n, ihk_mc_user_context_t *ctx);
|
||||||
@@ -98,7 +98,7 @@ void check_signal(long rc, unsigned long *regs);
|
|||||||
static void do_mod_exit(int status);
|
static void do_mod_exit(int status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void send_syscall(struct syscall_request *req)
|
static void send_syscall(struct syscall_request *req, int cpu)
|
||||||
{
|
{
|
||||||
struct ikc_scd_packet packet;
|
struct ikc_scd_packet packet;
|
||||||
struct syscall_response *res;
|
struct syscall_response *res;
|
||||||
@@ -106,7 +106,6 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
int w;
|
int w;
|
||||||
struct syscall_params *scp;
|
struct syscall_params *scp;
|
||||||
struct ihk_ikc_channel_desc *syscall_channel;
|
struct ihk_ikc_channel_desc *syscall_channel;
|
||||||
int cpu;
|
|
||||||
|
|
||||||
if(req->number == __NR_exit_group ||
|
if(req->number == __NR_exit_group ||
|
||||||
req->number == __NR_kill){ // interrupt syscall
|
req->number == __NR_kill){ // interrupt syscall
|
||||||
@@ -117,9 +116,8 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
cpu = num_processors;
|
cpu = num_processors;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
scp = &cpu_local_var(scp);
|
scp = &get_cpu_local_var(cpu)->scp;
|
||||||
syscall_channel = cpu_local_var(syscall_channel);
|
syscall_channel = get_cpu_local_var(cpu)->syscall_channel;
|
||||||
cpu = ihk_mc_get_processor_id();
|
|
||||||
}
|
}
|
||||||
res = scp->response_va;
|
res = scp->response_va;
|
||||||
|
|
||||||
@@ -150,7 +148,7 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu)
|
||||||
{
|
{
|
||||||
struct syscall_response *res;
|
struct syscall_response *res;
|
||||||
struct syscall_request req2 IHK_DMA_ALIGN;
|
struct syscall_request req2 IHK_DMA_ALIGN;
|
||||||
@@ -166,11 +164,11 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
|||||||
scp = &get_cpu_local_var(0)->scp2;
|
scp = &get_cpu_local_var(0)->scp2;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
scp = &cpu_local_var(scp);
|
scp = &get_cpu_local_var(cpu)->scp;
|
||||||
}
|
}
|
||||||
res = scp->response_va;
|
res = scp->response_va;
|
||||||
|
|
||||||
send_syscall(req);
|
send_syscall(req, cpu);
|
||||||
|
|
||||||
dkprintf("SC(%d)[%3d] waiting for host.. \n",
|
dkprintf("SC(%d)[%3d] waiting for host.. \n",
|
||||||
ihk_mc_get_processor_id(),
|
ihk_mc_get_processor_id(),
|
||||||
@@ -185,7 +183,7 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res->status == STATUS_PAGE_FAULT) {
|
if (res->status == STATUS_PAGE_FAULT) {
|
||||||
error = page_fault_process(cpu_local_var(current),
|
error = page_fault_process(get_cpu_local_var(cpu)->current,
|
||||||
(void *)res->fault_address,
|
(void *)res->fault_address,
|
||||||
res->fault_reason);
|
res->fault_reason);
|
||||||
|
|
||||||
@@ -195,7 +193,7 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
|||||||
req2.args[0] = PAGER_RESUME_PAGE_FAULT;
|
req2.args[0] = PAGER_RESUME_PAGE_FAULT;
|
||||||
req2.args[1] = error;
|
req2.args[1] = error;
|
||||||
|
|
||||||
send_syscall(&req2);
|
send_syscall(&req2, cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +237,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
|
|||||||
/* XXX: send SIGKILL to all threads in this process */
|
/* XXX: send SIGKILL to all threads in this process */
|
||||||
|
|
||||||
flush_process_memory(proc); /* temporary hack */
|
flush_process_memory(proc); /* temporary hack */
|
||||||
do_syscall(&request, ctx);
|
do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||||
|
|
||||||
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
||||||
proc->status = PS_ZOMBIE;
|
proc->status = PS_ZOMBIE;
|
||||||
@@ -253,12 +251,12 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
interrupt_syscall()
|
interrupt_syscall(int all)
|
||||||
{
|
{
|
||||||
ihk_mc_user_context_t ctx;
|
ihk_mc_user_context_t ctx;
|
||||||
long lerror;
|
long lerror;
|
||||||
|
|
||||||
ihk_mc_syscall_arg0(&ctx) = ihk_mc_get_processor_id();
|
ihk_mc_syscall_arg0(&ctx) = all? -1: ihk_mc_get_processor_id();
|
||||||
ihk_mc_syscall_arg1(&ctx) = 0;
|
ihk_mc_syscall_arg1(&ctx) = 0;
|
||||||
|
|
||||||
lerror = syscall_generic_forwarding(__NR_kill, &ctx);
|
lerror = syscall_generic_forwarding(__NR_kill, &ctx);
|
||||||
@@ -284,7 +282,7 @@ SYSCALL_DECLARE(exit_group)
|
|||||||
|
|
||||||
/* XXX: send SIGKILL to all threads in this process */
|
/* XXX: send SIGKILL to all threads in this process */
|
||||||
|
|
||||||
do_syscall(&request, ctx);
|
do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||||
|
|
||||||
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
||||||
proc->status = PS_ZOMBIE;
|
proc->status = PS_ZOMBIE;
|
||||||
@@ -874,6 +872,11 @@ SYSCALL_DECLARE(getpid)
|
|||||||
return cpu_local_var(current)->pid;
|
return cpu_local_var(current)->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(gettid)
|
||||||
|
{
|
||||||
|
return cpu_local_var(current)->tid;
|
||||||
|
}
|
||||||
|
|
||||||
long do_arch_prctl(unsigned long code, unsigned long address)
|
long do_arch_prctl(unsigned long code, unsigned long address)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@@ -932,6 +935,8 @@ SYSCALL_DECLARE(clone)
|
|||||||
int cpuid;
|
int cpuid;
|
||||||
int clone_flags = ihk_mc_syscall_arg0(ctx);
|
int clone_flags = ihk_mc_syscall_arg0(ctx);
|
||||||
struct process *new;
|
struct process *new;
|
||||||
|
ihk_mc_user_context_t ctx1;
|
||||||
|
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||||
|
|
||||||
if(clone_flags == 0x1200011){
|
if(clone_flags == 0x1200011){
|
||||||
// fork()
|
// fork()
|
||||||
@@ -942,7 +947,7 @@ SYSCALL_DECLARE(clone)
|
|||||||
ihk_mc_get_processor_id(),
|
ihk_mc_get_processor_id(),
|
||||||
(unsigned long)ihk_mc_syscall_arg1(ctx));
|
(unsigned long)ihk_mc_syscall_arg1(ctx));
|
||||||
|
|
||||||
cpuid = obtain_clone_cpuid();
|
cpuid = obtain_clone_cpuid();
|
||||||
|
|
||||||
new = clone_process(cpu_local_var(current), ihk_mc_syscall_pc(ctx),
|
new = clone_process(cpu_local_var(current), ihk_mc_syscall_pc(ctx),
|
||||||
ihk_mc_syscall_arg1(ctx));
|
ihk_mc_syscall_arg1(ctx));
|
||||||
@@ -951,8 +956,12 @@ SYSCALL_DECLARE(clone)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new pid */
|
// /* Allocate new pid */
|
||||||
new->pid = ihk_atomic_inc_return(&pid_cnt);
|
// new->pid = ihk_atomic_inc_return(&pid_cnt);
|
||||||
|
|
||||||
|
new->pid = cpu_local_var(current)->pid;
|
||||||
|
request1.number = __NR_gettid;
|
||||||
|
new->tid = do_syscall(&request1, &ctx1, cpuid);
|
||||||
|
|
||||||
if (clone_flags & CLONE_PARENT_SETTID) {
|
if (clone_flags & CLONE_PARENT_SETTID) {
|
||||||
dkprintf("clone_flags & CLONE_PARENT_SETTID: 0x%lX\n",
|
dkprintf("clone_flags & CLONE_PARENT_SETTID: 0x%lX\n",
|
||||||
@@ -982,10 +991,10 @@ SYSCALL_DECLARE(clone)
|
|||||||
|
|
||||||
ihk_mc_syscall_ret(new->uctx) = 0;
|
ihk_mc_syscall_ret(new->uctx) = 0;
|
||||||
|
|
||||||
dkprintf("clone: kicking scheduler!,cpuid=%d\n", cpuid);
|
dkprintf("clone: kicking scheduler!,cpuid=%d pid=%d tid=%d\n", cpuid, new->pid, new->tid);
|
||||||
runq_add_proc(new, cpuid);
|
runq_add_proc(new, cpuid);
|
||||||
|
|
||||||
return new->pid;
|
return new->tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(set_tid_address)
|
SYSCALL_DECLARE(set_tid_address)
|
||||||
@@ -996,31 +1005,24 @@ SYSCALL_DECLARE(set_tid_address)
|
|||||||
return cpu_local_var(current)->pid;
|
return cpu_local_var(current)->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned long do_kill(int pid, int sig);
|
extern unsigned long do_kill(int pid, int tid, int sig);
|
||||||
|
|
||||||
SYSCALL_DECLARE(kill)
|
SYSCALL_DECLARE(kill)
|
||||||
{
|
{
|
||||||
int pid = ihk_mc_syscall_arg0(ctx);
|
int pid = ihk_mc_syscall_arg0(ctx);
|
||||||
int sig = ihk_mc_syscall_arg1(ctx);
|
int sig = ihk_mc_syscall_arg1(ctx);
|
||||||
|
|
||||||
return do_kill(pid, sig);
|
return do_kill(pid, -1, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// see linux-2.6.34.13/kernel/signal.c
|
// see linux-2.6.34.13/kernel/signal.c
|
||||||
SYSCALL_DECLARE(tgkill)
|
SYSCALL_DECLARE(tgkill)
|
||||||
{
|
{
|
||||||
int tgid = ihk_mc_syscall_arg0(ctx);
|
int tgid = ihk_mc_syscall_arg0(ctx);
|
||||||
int pid = ihk_mc_syscall_arg1(ctx);
|
int pid = ihk_mc_syscall_arg1(ctx);
|
||||||
int sig = ihk_mc_syscall_arg2(ctx);
|
int sig = ihk_mc_syscall_arg2(ctx);
|
||||||
|
|
||||||
if(pid <= 0 || tgid <= 0) { return -EINVAL; }
|
return do_kill(tgid, pid, sig);
|
||||||
// search pid
|
|
||||||
// check kill permission
|
|
||||||
if(sig == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(set_robust_list)
|
SYSCALL_DECLARE(set_robust_list)
|
||||||
@@ -1072,7 +1074,32 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
|||||||
int how = ihk_mc_syscall_arg0(ctx);
|
int how = ihk_mc_syscall_arg0(ctx);
|
||||||
const sigset_t *set = (const sigset_t *)ihk_mc_syscall_arg1(ctx);
|
const sigset_t *set = (const sigset_t *)ihk_mc_syscall_arg1(ctx);
|
||||||
sigset_t *oldset = (sigset_t *)ihk_mc_syscall_arg2(ctx);
|
sigset_t *oldset = (sigset_t *)ihk_mc_syscall_arg2(ctx);
|
||||||
// kprintf("sys_rt_sigprocmask called. returning zero...\n");
|
struct process *proc = cpu_local_var(current);
|
||||||
|
int irqstate;
|
||||||
|
|
||||||
|
if(set &&
|
||||||
|
how != SIG_BLOCK &&
|
||||||
|
how != SIG_UNBLOCK &&
|
||||||
|
how != SIG_SETMASK)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
||||||
|
if(oldset)
|
||||||
|
oldset->__val[0] = proc->sigmask.__val[0];
|
||||||
|
if(set){
|
||||||
|
switch(how){
|
||||||
|
case SIG_BLOCK:
|
||||||
|
proc->sigmask.__val[0] |= set->__val[0];
|
||||||
|
break;
|
||||||
|
case SIG_UNBLOCK:
|
||||||
|
proc->sigmask.__val[0] &= ~set->__val[0];
|
||||||
|
break;
|
||||||
|
case SIG_SETMASK:
|
||||||
|
proc->sigmask.__val[0] = set->__val[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,7 +1176,7 @@ SYSCALL_DECLARE(futex)
|
|||||||
|
|
||||||
request.args[0] = __phys;
|
request.args[0] = __phys;
|
||||||
|
|
||||||
int r = do_syscall(&request, ctx);
|
int r = do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|||||||
Reference in New Issue
Block a user