add MCEXEC_UP_STRNCPY_FROM_USER

It allows a mcexec to execute the strncpy_from_user().
This commit is contained in:
NAKAMURA Gou
2014-01-08 12:47:41 +09:00
parent e86ffb0b57
commit afc38718a0
4 changed files with 83 additions and 0 deletions

View File

@ -37,6 +37,7 @@
#define MCEXEC_UP_LOAD_SYSCALL 0x30a02905
#define MCEXEC_UP_SEND_SIGNAL 0x30a02906
#define MCEXEC_UP_GET_CPU 0x30a02907
#define MCEXEC_UP_STRNCPY_FROM_USER 0x30a02908
#define MCEXEC_UP_PREPARE_DMA 0x30a02910
#define MCEXEC_UP_FREE_DMA 0x30a02911
@ -115,6 +116,13 @@ struct syscall_ret_desc {
unsigned long size;
};
struct strncpy_from_user_desc {
void *dest;
void *src;
unsigned long n;
long result;
};
struct prepare_dma_desc {
unsigned long size;
unsigned long pa;

View File

@ -573,6 +573,58 @@ long mcexec_ret_syscall(ihk_os_t os, struct syscall_ret_desc *__user arg)
return 0;
}
long mcexec_strncpy_from_user(ihk_os_t os, struct strncpy_from_user_desc * __user arg)
{
struct strncpy_from_user_desc desc;
void *buf;
void *dest;
void *src;
unsigned long remain;
long want;
long copied;
if (copy_from_user(&desc, arg, sizeof(desc))) {
return -EFAULT;
}
buf = (void *)__get_free_page(GFP_KERNEL);
if (!buf) {
return -ENOMEM;
}
dest = desc.dest;
src = desc.src;
remain = desc.n;
want = 0;
copied = 0;
while ((remain > 0) && (want == copied)) {
want = (remain > PAGE_SIZE)? PAGE_SIZE: remain;
copied = strncpy_from_user(buf, src, want);
if (copied == want) {
if (copy_to_user(dest, buf, copied)) {
copied = -EFAULT;
}
}
else if (copied >= 0) {
if (copy_to_user(dest, buf, copied+1)) {
copied = -EFAULT;
}
}
dest += copied;
src += copied;
remain -= copied;
}
desc.result = (copied >= 0)? (desc.n - remain): copied;
free_page((unsigned long)buf);
if (copy_to_user(arg, &desc, sizeof(*arg))) {
return -EFAULT;
}
return 0;
}
long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg)
{
switch (req) {
@ -600,6 +652,9 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg)
case MCEXEC_UP_GET_CPU:
return mcexec_get_cpu(os);
case MCEXEC_UP_STRNCPY_FROM_USER:
return mcexec_strncpy_from_user(os, (struct strncpy_from_user_desc *)arg);
case MCEXEC_UP_PREPARE_DMA:
return mcexec_pin_region(os, (unsigned long *)arg);

View File

@ -51,6 +51,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = {
{ .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_GET_CPU, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_STRNCPY_FROM_USER, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl },
};

View File

@ -883,6 +883,25 @@ kill_thread(unsigned long cpu)
}
}
static long do_strncpy_from_user(int fd, void *dest, void *src, unsigned long n)
{
struct strncpy_from_user_desc desc;
int ret;
desc.dest = dest;
desc.src = src;
desc.n = n;
ret = ioctl(fd, MCEXEC_UP_STRNCPY_FROM_USER, (unsigned long)&desc);
if (ret) {
ret = -errno;
perror("strncpy_from_user:ioctl");
return ret;
}
return desc.result;
}
#define SET_ERR(ret) if (ret == -1) ret = -errno
int main_loop(int fd, int cpu, pthread_mutex_t *lock)