mcctrl: Add mcexec_terminate_thread_unsafe()
Change-Id: I6ca54cdac2ab9449d40b22f7329f1a215e5aa33b
This commit is contained in:
@ -250,6 +250,13 @@ struct release_user_space_desc {
|
||||
unsigned long user_end;
|
||||
};
|
||||
|
||||
struct terminate_thread_desc {
|
||||
int pid;
|
||||
int tid;
|
||||
long sig;
|
||||
unsigned long tsk; /* struct task_struct * */
|
||||
};
|
||||
|
||||
enum perf_ctrl_type {
|
||||
PERF_CTRL_SET,
|
||||
PERF_CTRL_GET,
|
||||
|
||||
@ -2442,84 +2442,93 @@ mcexec_sig_thread(ihk_os_t os, unsigned long arg, struct file *file)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
long
|
||||
mcexec_terminate_thread(ihk_os_t os, unsigned long __user *arg, struct file *file)
|
||||
static long
|
||||
mcexec_terminate_thread_unsafe(ihk_os_t os, int pid, int tid, long sig, struct task_struct *tsk)
|
||||
{
|
||||
unsigned long param[4];
|
||||
int rc;
|
||||
int pid;
|
||||
int tid;
|
||||
long sig;
|
||||
struct task_struct *tsk;
|
||||
struct host_thread *thread;
|
||||
struct ikc_scd_packet *packet;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd;
|
||||
|
||||
if (copy_from_user(param, arg, sizeof(unsigned long) * 4)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
pid = param[0];
|
||||
tid = param[1];
|
||||
sig = param[2];
|
||||
tsk = (struct task_struct *)param[3];
|
||||
|
||||
//printk("%s: pid=%d,tid=%d,sig=%lx,task=%p\n", __FUNCTION__, pid, tid, sig, tsk);
|
||||
|
||||
list_for_each_entry(thread, &host_threads, list) {
|
||||
if(thread->pid == pid && thread->tid == tid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!thread) {
|
||||
printk("%s: thread not found in host_threads list\n", __FUNCTION__);
|
||||
write_unlock_irqrestore(&host_thread_lock, flags);
|
||||
return -ESRCH;
|
||||
}
|
||||
dprintk("%s: target pid=%d,tid=%d,sig=%lx,task=%p\n", __FUNCTION__, pid, tid, sig, tsk);
|
||||
|
||||
ppd = mcctrl_get_per_proc_data(usrdata, pid);
|
||||
if (!ppd) {
|
||||
kprintf("%s: ERROR: no per-process structure for PID %d??\n",
|
||||
__FUNCTION__, pid);
|
||||
goto err;
|
||||
__FUNCTION__, pid);
|
||||
goto no_ppd;
|
||||
}
|
||||
packet = (struct ikc_scd_packet *)mcctrl_get_per_thread_data(ppd, tsk);
|
||||
if (!packet) {
|
||||
kprintf("%s: ERROR: no packet registered for TID %d\n",
|
||||
__FUNCTION__, tid);
|
||||
goto err;
|
||||
__FUNCTION__, tid);
|
||||
goto no_ptd;
|
||||
}
|
||||
|
||||
if ((rc = mcctrl_delete_per_thread_data(ppd, tsk))) {
|
||||
kprintf("%s: ERROR: mcctrl_delete_per_thread_data failed (%d)\n", __FUNCTION__, rc);
|
||||
goto err;
|
||||
goto no_ptd;
|
||||
}
|
||||
|
||||
__return_syscall(usrdata->os, packet, sig, tid);
|
||||
printk("%s: packet=%p,channels=%p,ref=%d,desc=%p\n", __FUNCTION__, packet, usrdata->channels, packet->ref, (usrdata->channels + packet->ref)->c);
|
||||
|
||||
ihk_ikc_release_packet((struct ihk_ikc_free_packet *)packet,
|
||||
(usrdata->ikc2linux[smp_processor_id()] ?
|
||||
usrdata->ikc2linux[smp_processor_id()] :
|
||||
usrdata->ikc2linux[0]));
|
||||
|
||||
no_ptd:
|
||||
/* Destroy per_proc_data with the following two puts. Note that
|
||||
it survived the signal-kill of tracee thanks to the additional put
|
||||
done in mcexec_util_thread2 */
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
|
||||
err:
|
||||
if(ppd)
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
no_ppd:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
mcexec_terminate_thread(ihk_os_t os, struct terminate_thread_desc * __user arg)
|
||||
{
|
||||
long rc;
|
||||
unsigned long flags;
|
||||
struct terminate_thread_desc desc;
|
||||
struct host_thread *thread;
|
||||
|
||||
if (copy_from_user(&desc, arg, sizeof(struct terminate_thread_desc))) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dprintk("%s: target pid=%d,tid=%d\n", __FUNCTION__, desc.pid, desc.tid);
|
||||
|
||||
/* Stop switching FS registers for uti thread */
|
||||
write_lock_irqsave(&host_thread_lock, flags);
|
||||
list_for_each_entry(thread, &host_threads, list) {
|
||||
if(thread->tid == desc.tid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!thread) {
|
||||
printk("%s: ERROR: thread (pid=%d,tid=%d) not found in host_threads\n", __FUNCTION__, desc.pid, desc.tid);
|
||||
rc = -ESRCH;
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
list_del(&thread->list);
|
||||
kfree(thread);
|
||||
|
||||
return 0;
|
||||
write_unlock_irqrestore(&host_thread_lock, flags);
|
||||
|
||||
rc = mcexec_terminate_thread_unsafe(os, desc.pid, desc.tid, desc.sig, (struct task_struct *)desc.tsk);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
|
||||
unlock_out:
|
||||
write_unlock_irqrestore(&host_thread_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
static long mcexec_release_user_space(struct release_user_space_desc *__user arg)
|
||||
{
|
||||
struct release_user_space_desc desc;
|
||||
@ -3033,7 +3042,7 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
|
||||
return mcexec_syscall_thread(os, arg, file);
|
||||
|
||||
case MCEXEC_UP_TERMINATE_THREAD:
|
||||
return mcexec_terminate_thread(os, (unsigned long __user *)arg, file);
|
||||
return mcexec_terminate_thread(os, (struct terminate_thread_desc *)arg);
|
||||
|
||||
case MCEXEC_UP_RELEASE_USER_SPACE:
|
||||
return mcexec_release_user_space((struct release_user_space_desc *)arg);
|
||||
|
||||
@ -3036,17 +3036,17 @@ create_tracer(unsigned long user_start, unsigned long user_end)
|
||||
sig = 0;
|
||||
waitpid(-1, &st, __WALL);
|
||||
if (WIFEXITED(st) || WIFSIGNALED(st)) {
|
||||
unsigned long term_param[4];
|
||||
struct terminate_thread_desc term_desc;
|
||||
|
||||
term_param[0] = uti_desc->pid;
|
||||
term_param[1] = uti_desc->tid;
|
||||
term_param[3] = uti_desc->key;
|
||||
term_desc.pid = uti_desc->pid;
|
||||
term_desc.tid = uti_desc->tid;
|
||||
term_desc.tsk = uti_desc->key;
|
||||
code = st;
|
||||
|
||||
if (exited == 2) { /* exit_group */
|
||||
code |= 0x0000000100000000;
|
||||
}
|
||||
term_param[2] = code;
|
||||
term_desc.sig = code;
|
||||
|
||||
/* How return_syscall() is called depends on how utility thread exits:
|
||||
exit:
|
||||
@ -3063,7 +3063,7 @@ create_tracer(unsigned long user_start, unsigned long user_end)
|
||||
*/
|
||||
if (exited == 1 || exited == 2) {
|
||||
__dprintf("calling MCEXEC_UP_TERMINATE_THREAD,exited=%d,code=%lx\n", exited, code);
|
||||
if (ioctl(fd, MCEXEC_UP_TERMINATE_THREAD, term_param) != 0) {
|
||||
if (ioctl(fd, MCEXEC_UP_TERMINATE_THREAD, &term_desc) != 0) {
|
||||
fprintf(stderr, "%s: INFO: MCEXEC_UP_TERMINATE_THREAD returned %d\n", __FUNCTION__, errno);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user