From c0cc6ac6db14abe97ef3f0c4559e1a6070892dc9 Mon Sep 17 00:00:00 2001 From: Ken Sato Date: Tue, 9 Feb 2016 14:54:53 +0900 Subject: [PATCH] Add skeleton for perf_event_open. --- arch/x86/kernel/include/syscall_list.h | 5 +- executer/user/mcexec.c | 5 + kernel/include/process.h | 14 ++- kernel/process.c | 1 + kernel/syscall.c | 159 ++++++++++++++++++++----- 5 files changed, 148 insertions(+), 36 deletions(-) diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index 04bc1e8f..2f955348 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -20,7 +20,7 @@ * syscall_name[] only, no handler exists. */ -SYSCALL_DELEGATED(0, read) +SYSCALL_HANDLED(0, read) SYSCALL_DELEGATED(1, write) SYSCALL_DELEGATED(2, open) SYSCALL_HANDLED(3, close) @@ -35,7 +35,7 @@ SYSCALL_HANDLED(12, brk) SYSCALL_HANDLED(13, rt_sigaction) SYSCALL_HANDLED(14, rt_sigprocmask) SYSCALL_HANDLED(15, rt_sigreturn) -SYSCALL_DELEGATED(16, ioctl) +SYSCALL_HANDLED(16, ioctl) SYSCALL_DELEGATED(17, pread64) SYSCALL_DELEGATED(18, pwrite64) SYSCALL_DELEGATED(20, writev) @@ -133,6 +133,7 @@ SYSCALL_HANDLED(279, move_pages) SYSCALL_DELEGATED(281, epoll_pwait) SYSCALL_HANDLED(282, signalfd) SYSCALL_HANDLED(289, signalfd4) +SYSCALL_HANDLED(298, perf_event_open) #ifdef DCFA_KMOD SYSCALL_HANDLED(303, mod_call) #endif diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 2da3ed03..1992a449 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -2198,6 +2198,11 @@ return_execve2: do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); break; + case __NR_perf_event_open: + ret = open("/dev/null", O_RDONLY); + do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + break; + case __NR_rt_sigaction: act_sigaction(&w); do_syscall_return(fd, cpu, 0, 0, 0, 0, 0); diff --git a/kernel/include/process.h b/kernel/include/process.h index 44d0d83b..4ad8b8d6 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -312,18 +312,22 @@ struct vm_regions { struct process_vm; -struct sigfd { - struct sigfd *next; +struct mckfd { + struct mckfd *next; int fd; - __sigset_t mask; + long data; + void *opt; + long (*read_cb)(struct mckfd *, ihk_mc_user_context_t *); + int (*ioctl_cb)(struct mckfd *, ihk_mc_user_context_t *); + int (*close_cb)(struct mckfd *, ihk_mc_user_context_t *); }; + #define SFD_CLOEXEC 02000000 #define SFD_NONBLOCK 04000 struct sig_common { ihk_spinlock_t lock; ihk_atomic_t use; - struct sigfd *sigfd; struct k_sigaction action[_NSIG]; struct list_head sigpending; }; @@ -425,6 +429,8 @@ struct process { /* Store signal sent to parent when the process terminates. */ int termsig; + ihk_spinlock_t mckfd_lock; + struct mckfd *mckfd; }; void hold_thread(struct thread *ftn); diff --git a/kernel/process.c b/kernel/process.c index 2889c528..3b0e0a07 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -96,6 +96,7 @@ init_process(struct process *proc, struct process *parent) INIT_LIST_HEAD(&proc->ptraced_children_list); mcs_rwlock_init(&proc->threads_lock); mcs_rwlock_init(&proc->children_lock); + ihk_mc_spinlock_init(&proc->mckfd_lock); waitq_init(&proc->waitpid_q); ihk_atomic_set(&proc->refcount, 2); } diff --git a/kernel/syscall.c b/kernel/syscall.c index a60afd41..41e5639f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2359,34 +2359,85 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) return 0; } +SYSCALL_DECLARE(read) +{ + int fd = ihk_mc_syscall_arg0(ctx); + long rc; + struct thread *thread = cpu_local_var(current); + struct process *proc = thread->proc; + struct mckfd *fdp; + long irqstate; + + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + for(fdp = proc->mckfd; fdp; fdp = fdp->next) + if(fdp->fd == fd) + break; + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); + + if(fdp && fdp->read_cb){ +kprintf("read: found system fd %d\n", fd); + rc = fdp->read_cb(fdp, ctx); + } + else{ + rc = syscall_generic_forwarding(__NR_read, ctx); + } + return rc; +} + +SYSCALL_DECLARE(ioctl) +{ + int fd = ihk_mc_syscall_arg0(ctx); + long rc; + struct thread *thread = cpu_local_var(current); + struct process *proc = thread->proc; + struct mckfd *fdp; + long irqstate; + + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + for(fdp = proc->mckfd; fdp; fdp = fdp->next) + if(fdp->fd == fd) + break; + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); + + if(fdp && fdp->ioctl_cb){ +kprintf("ioctl: found system fd %d\n", fd); + rc = fdp->ioctl_cb(fdp, ctx); + } + else{ + rc = syscall_generic_forwarding(__NR_ioctl, ctx); + } + return rc; +} + SYSCALL_DECLARE(close) { int fd = ihk_mc_syscall_arg0(ctx); - int rc; + long rc; struct thread *thread = cpu_local_var(current); - struct sigfd *sfd; - struct sigfd *sb; - long irqstate; + struct process *proc = thread->proc; + struct mckfd *fdp; + struct mckfd *fdq; + long irqstate; - irqstate = ihk_mc_spinlock_lock(&thread->sigcommon->lock); - for(sfd = thread->sigcommon->sigfd, sb = NULL; sfd; sb = sfd, sfd = sfd->next) - if(sfd->fd == fd) + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + for(fdp = proc->mckfd, fdq = NULL; fdp; fdq = fdp, fdp = fdp->next) + if(fdp->fd == fd) break; - if(sfd){ - struct syscall_request request IHK_DMA_ALIGN; - if(sb) - sb->next = sfd->next; + + if(fdp){ +kprintf("close: found system fd %d pid=%d\n", fd, proc->pid); + if(fdq) + fdq->next = fdp->next; else - thread->sigcommon->sigfd = sfd->next; - ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); - request.number = __NR_signalfd4; - request.args[0] = 1; - request.args[1] = sfd->fd; - kfree(sfd); - rc = do_syscall(&request, ihk_mc_get_processor_id(), 0); + proc->mckfd = fdp->next; + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); + if(fdp->close_cb) + fdp->close_cb(fdp, ctx); + kfree(fdp); + rc = syscall_generic_forwarding(__NR_close, ctx); } else{ - ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); rc = syscall_generic_forwarding(__NR_close, ctx); } return rc; @@ -2487,7 +2538,8 @@ SYSCALL_DECLARE(signalfd4) { int fd = ihk_mc_syscall_arg0(ctx); struct thread *thread = cpu_local_var(current); - struct sigfd *sfd; + struct process *proc = thread->proc; + struct mckfd *sfd; long irqstate; sigset_t *maskp = (sigset_t *)ihk_mc_syscall_arg1(ctx);; __sigset_t mask; @@ -2501,10 +2553,9 @@ SYSCALL_DECLARE(signalfd4) if(flags & ~(SFD_NONBLOCK | SFD_CLOEXEC)) return -EINVAL; - irqstate = ihk_mc_spinlock_lock(&thread->sigcommon->lock); if(fd == -1){ struct syscall_request request IHK_DMA_ALIGN; - ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); + request.number = __NR_signalfd4; request.args[0] = 0; request.args[1] = flags; @@ -2512,25 +2563,73 @@ SYSCALL_DECLARE(signalfd4) if(fd < 0){ return fd; } - sfd = kmalloc(sizeof(struct sigfd), IHK_MC_AP_NOWAIT); + sfd = kmalloc(sizeof(struct mckfd), IHK_MC_AP_NOWAIT); if(!sfd) return -ENOMEM; sfd->fd = fd; - irqstate = ihk_mc_spinlock_lock(&thread->sigcommon->lock); - sfd->next = thread->sigcommon->sigfd; - thread->sigcommon->sigfd = sfd; + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + sfd->next = proc->mckfd; + proc->mckfd = sfd; } else{ - for(sfd = thread->sigcommon->sigfd; sfd; sfd = sfd->next) + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + for(sfd = proc->mckfd; sfd; sfd = sfd->next) if(sfd->fd == fd) break; if(!sfd){ - ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); return -EINVAL; } } - memcpy(&sfd->mask, &mask, sizeof mask); - ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); + memcpy(&sfd->data, &mask, sizeof mask); + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); + return sfd->fd; +} + +static long +perf_event_read(struct mckfd *sfd, ihk_mc_user_context_t *ctx) +{ + return 0; +} + +static int +perf_event_ioctl(struct mckfd *sfd, ihk_mc_user_context_t *ctx) +{ + return 0; +} + +static int +perf_event_close(struct mckfd *sfd, ihk_mc_user_context_t *ctx) +{ + return 0; +} + +SYSCALL_DECLARE(perf_event_open) +{ + struct syscall_request request IHK_DMA_ALIGN; + struct thread *thread = cpu_local_var(current); + struct process *proc = thread->proc; + struct mckfd *sfd; + int fd; + long irqstate; + + request.number = __NR_perf_event_open; + request.args[0] = 0; + fd = do_syscall(&request, ihk_mc_get_processor_id(), 0); + if(fd < 0){ + return fd; + } + sfd = kmalloc(sizeof(struct mckfd), IHK_MC_AP_NOWAIT); + if(!sfd) + return -ENOMEM; + sfd->fd = fd; + sfd->read_cb = perf_event_read; + sfd->ioctl_cb = perf_event_ioctl; + sfd->close_cb = perf_event_close; + irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock); + sfd->next = proc->mckfd; + proc->mckfd = sfd; + ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate); return sfd->fd; }