Merge branch 'fixes'
* fixes: v4l1: fix 32-bit compat microcode loading translation De-pessimize rds_page_copy_user
This commit is contained in:
Коммит
822a2e4524
|
@ -193,17 +193,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
|
||||||
struct video_code32 {
|
struct video_code32 {
|
||||||
char loadwhat[16]; /* name or tag of file being passed */
|
char loadwhat[16]; /* name or tag of file being passed */
|
||||||
compat_int_t datasize;
|
compat_int_t datasize;
|
||||||
unsigned char *data;
|
compat_uptr_t data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int get_microcode32(struct video_code *kp, struct video_code32 __user *up)
|
static struct video_code __user *get_microcode32(struct video_code32 *kp)
|
||||||
{
|
{
|
||||||
if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
|
struct video_code __user *up;
|
||||||
copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) ||
|
|
||||||
get_user(kp->datasize, &up->datasize) ||
|
up = compat_alloc_user_space(sizeof(*up));
|
||||||
copy_from_user(kp->data, up->data, up->datasize))
|
|
||||||
return -EFAULT;
|
/*
|
||||||
return 0;
|
* NOTE! We don't actually care if these fail. If the
|
||||||
|
* user address is invalid, the native ioctl will do
|
||||||
|
* the error handling for us
|
||||||
|
*/
|
||||||
|
(void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat));
|
||||||
|
(void) put_user(kp->datasize, &up->datasize);
|
||||||
|
(void) put_user(compat_ptr(kp->data), &up->data);
|
||||||
|
return up;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
|
#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
|
||||||
|
@ -739,7 +746,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
|
||||||
struct video_tuner vt;
|
struct video_tuner vt;
|
||||||
struct video_buffer vb;
|
struct video_buffer vb;
|
||||||
struct video_window vw;
|
struct video_window vw;
|
||||||
struct video_code vc;
|
struct video_code32 vc;
|
||||||
struct video_audio va;
|
struct video_audio va;
|
||||||
#endif
|
#endif
|
||||||
struct v4l2_format v2f;
|
struct v4l2_format v2f;
|
||||||
|
@ -818,8 +825,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIDIOCSMICROCODE:
|
case VIDIOCSMICROCODE:
|
||||||
err = get_microcode32(&karg.vc, up);
|
/* Copy the 32-bit "video_code32" to kernel space */
|
||||||
compatible_arg = 0;
|
if (copy_from_user(&karg.vc, up, sizeof(karg.vc)))
|
||||||
|
return -EFAULT;
|
||||||
|
/* Convert the 32-bit version to a 64-bit version in user space */
|
||||||
|
up = get_microcode32(&karg.vc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIDIOCSFREQ:
|
case VIDIOCSFREQ:
|
||||||
|
|
|
@ -57,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset,
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
if (to_user)
|
addr = kmap(page);
|
||||||
|
if (to_user) {
|
||||||
rds_stats_add(s_copy_to_user, bytes);
|
rds_stats_add(s_copy_to_user, bytes);
|
||||||
else
|
ret = copy_to_user(ptr, addr + offset, bytes);
|
||||||
|
} else {
|
||||||
rds_stats_add(s_copy_from_user, bytes);
|
rds_stats_add(s_copy_from_user, bytes);
|
||||||
|
ret = copy_from_user(addr + offset, ptr, bytes);
|
||||||
addr = kmap_atomic(page, KM_USER0);
|
|
||||||
if (to_user)
|
|
||||||
ret = __copy_to_user_inatomic(ptr, addr + offset, bytes);
|
|
||||||
else
|
|
||||||
ret = __copy_from_user_inatomic(addr + offset, ptr, bytes);
|
|
||||||
kunmap_atomic(addr, KM_USER0);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
addr = kmap(page);
|
|
||||||
if (to_user)
|
|
||||||
ret = copy_to_user(ptr, addr + offset, bytes);
|
|
||||||
else
|
|
||||||
ret = copy_from_user(addr + offset, ptr, bytes);
|
|
||||||
kunmap(page);
|
|
||||||
if (ret)
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
|
kunmap(page);
|
||||||
|
|
||||||
return 0;
|
return ret ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rds_page_copy_user);
|
EXPORT_SYMBOL_GPL(rds_page_copy_user);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче