mirror of https://gitee.com/openkylin/linux.git
[MIPS] RTLX: Handle copy_*_user return values.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
bc4809e939
commit
46230aa6ea
|
@ -191,6 +191,8 @@ void sp_work_handle_request(void)
|
|||
struct mtsp_syscall_generic generic;
|
||||
struct mtsp_syscall_ret ret;
|
||||
struct kspd_notifications *n;
|
||||
unsigned long written;
|
||||
mm_segment_t old_fs;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
int cmd;
|
||||
|
@ -201,7 +203,11 @@ void sp_work_handle_request(void)
|
|||
|
||||
ret.retval = -1;
|
||||
|
||||
if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) {
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
|
||||
if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
|
||||
set_fs(old_fs);
|
||||
printk(KERN_ERR "Expected request but nothing to read\n");
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +215,8 @@ void sp_work_handle_request(void)
|
|||
size = sc.size;
|
||||
|
||||
if (size) {
|
||||
if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) {
|
||||
if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
|
||||
set_fs(old_fs);
|
||||
printk(KERN_ERR "Expected request but nothing to read\n");
|
||||
return;
|
||||
}
|
||||
|
@ -282,8 +289,11 @@ void sp_work_handle_request(void)
|
|||
if (vpe_getuid(SP_VPE))
|
||||
sp_setfsuidgid( 0, 0);
|
||||
|
||||
if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0))
|
||||
< sizeof(struct mtsp_syscall_ret))
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
|
||||
set_fs(old_fs);
|
||||
if (written < sizeof(ret))
|
||||
printk("KSPD: sp_work_handle_request failed to send to SP\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -289,26 +289,11 @@ unsigned int rtlx_write_poll(int index)
|
|||
return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
|
||||
}
|
||||
|
||||
static inline void copy_to(void *dst, void *src, size_t count, int user)
|
||||
{
|
||||
if (user)
|
||||
copy_to_user(dst, src, count);
|
||||
else
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
static inline void copy_from(void *dst, void *src, size_t count, int user)
|
||||
{
|
||||
if (user)
|
||||
copy_from_user(dst, src, count);
|
||||
else
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
||||
ssize_t rtlx_read(int index, void __user *buff, size_t count, int user)
|
||||
{
|
||||
size_t lx_write, fl = 0L;
|
||||
struct rtlx_channel *lx;
|
||||
unsigned long failed;
|
||||
|
||||
if (rtlx == NULL)
|
||||
return -ENOSYS;
|
||||
|
@ -327,11 +312,16 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
|||
/* then how much from the read pointer onwards */
|
||||
fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
|
||||
|
||||
copy_to(buff, lx->lx_buffer + lx->lx_read, fl, user);
|
||||
failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl);
|
||||
if (failed)
|
||||
goto out;
|
||||
|
||||
/* and if there is anything left at the beginning of the buffer */
|
||||
if (count - fl)
|
||||
copy_to(buff + fl, lx->lx_buffer, count - fl, user);
|
||||
failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl);
|
||||
|
||||
out:
|
||||
count -= failed;
|
||||
|
||||
smp_wmb();
|
||||
lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
|
||||
|
@ -341,7 +331,7 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
|||
return count;
|
||||
}
|
||||
|
||||
ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
|
||||
ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user)
|
||||
{
|
||||
struct rtlx_channel *rt;
|
||||
size_t rt_read;
|
||||
|
@ -363,11 +353,17 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
|
|||
/* first bit from write pointer to the end of the buffer, or count */
|
||||
fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
|
||||
|
||||
copy_from(rt->rt_buffer + rt->rt_write, buffer, fl, user);
|
||||
failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl);
|
||||
if (failed)
|
||||
goto out;
|
||||
|
||||
/* if there's any left copy to the beginning of the buffer */
|
||||
if (count - fl)
|
||||
copy_from(rt->rt_buffer, buffer + fl, count - fl, user);
|
||||
if (count - fl) {
|
||||
failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
|
||||
}
|
||||
|
||||
out:
|
||||
count -= cailed;
|
||||
|
||||
smp_wmb();
|
||||
rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
|
||||
|
@ -426,7 +422,7 @@ static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
|
|||
return 0; // -EAGAIN makes cat whinge
|
||||
}
|
||||
|
||||
return rtlx_read(minor, buffer, count, 1);
|
||||
return rtlx_read(minor, buffer, count);
|
||||
}
|
||||
|
||||
static ssize_t file_write(struct file *file, const char __user * buffer,
|
||||
|
@ -452,7 +448,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
|
|||
return ret;
|
||||
}
|
||||
|
||||
return rtlx_write(minor, (void *)buffer, count, 1);
|
||||
return rtlx_write(minor, buffer, count);
|
||||
}
|
||||
|
||||
static const struct file_operations rtlx_fops = {
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
extern int rtlx_open(int index, int can_sleep);
|
||||
extern int rtlx_release(int index);
|
||||
extern ssize_t rtlx_read(int index, void *buff, size_t count, int user);
|
||||
extern ssize_t rtlx_write(int index, void *buffer, size_t count, int user);
|
||||
extern ssize_t rtlx_read(int index, void __user *buff, size_t count);
|
||||
extern ssize_t rtlx_write(int index, const void __user *buffer, size_t count);
|
||||
extern unsigned int rtlx_read_poll(int index, int can_sleep);
|
||||
extern unsigned int rtlx_write_poll(int index);
|
||||
|
||||
|
|
Loading…
Reference in New Issue