Commit bbec2a2d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm-5.7-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
 "Rework compat ioctl handling in the user space hibernation interface
  (Christoph Hellwig) and fix a typo in a function name in the cpuidle
  haltpoll driver (Yihao Wu)"

* tag 'pm-5.7-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpuidle-haltpoll: Fix small typo
  PM / sleep: handle the compat case in snapshot_set_swap_area()
  PM / sleep: move SNAPSHOT_SET_SWAP_AREA handling into a helper
parents 523a05fc a31434bc
...@@ -94,7 +94,7 @@ static void haltpoll_uninit(void) ...@@ -94,7 +94,7 @@ static void haltpoll_uninit(void)
haltpoll_cpuidle_devices = NULL; haltpoll_cpuidle_devices = NULL;
} }
static bool haltpool_want(void) static bool haltpoll_want(void)
{ {
return kvm_para_has_hint(KVM_HINTS_REALTIME) || force; return kvm_para_has_hint(KVM_HINTS_REALTIME) || force;
} }
...@@ -110,7 +110,7 @@ static int __init haltpoll_init(void) ...@@ -110,7 +110,7 @@ static int __init haltpoll_init(void)
cpuidle_poll_state_init(drv); cpuidle_poll_state_init(drv);
if (!kvm_para_available() || !haltpool_want()) if (!kvm_para_available() || !haltpoll_want())
return -ENODEV; return -ENODEV;
ret = cpuidle_register_driver(drv); ret = cpuidle_register_driver(drv);
......
...@@ -196,6 +196,50 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, ...@@ -196,6 +196,50 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
return res; return res;
} }
struct compat_resume_swap_area {
compat_loff_t offset;
u32 dev;
} __packed;
static int snapshot_set_swap_area(struct snapshot_data *data,
void __user *argp)
{
sector_t offset;
dev_t swdev;
if (swsusp_swap_in_use())
return -EPERM;
if (in_compat_syscall()) {
struct compat_resume_swap_area swap_area;
if (copy_from_user(&swap_area, argp, sizeof(swap_area)))
return -EFAULT;
swdev = new_decode_dev(swap_area.dev);
offset = swap_area.offset;
} else {
struct resume_swap_area swap_area;
if (copy_from_user(&swap_area, argp, sizeof(swap_area)))
return -EFAULT;
swdev = new_decode_dev(swap_area.dev);
offset = swap_area.offset;
}
/*
* User space encodes device types as two-byte values,
* so we need to recode them
*/
if (!swdev) {
data->swap = -1;
return -EINVAL;
}
data->swap = swap_type_of(swdev, offset, NULL);
if (data->swap < 0)
return -ENODEV;
return 0;
}
static long snapshot_ioctl(struct file *filp, unsigned int cmd, static long snapshot_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -351,34 +395,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, ...@@ -351,34 +395,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
break; break;
case SNAPSHOT_SET_SWAP_AREA: case SNAPSHOT_SET_SWAP_AREA:
if (swsusp_swap_in_use()) { error = snapshot_set_swap_area(data, (void __user *)arg);
error = -EPERM;
} else {
struct resume_swap_area swap_area;
dev_t swdev;
error = copy_from_user(&swap_area, (void __user *)arg,
sizeof(struct resume_swap_area));
if (error) {
error = -EFAULT;
break;
}
/*
* User space encodes device types as two-byte values,
* so we need to recode them
*/
swdev = new_decode_dev(swap_area.dev);
if (swdev) {
offset = swap_area.offset;
data->swap = swap_type_of(swdev, offset, NULL);
if (data->swap < 0)
error = -ENODEV;
} else {
data->swap = -1;
error = -EINVAL;
}
}
break; break;
default: default:
...@@ -393,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, ...@@ -393,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct compat_resume_swap_area {
compat_loff_t offset;
u32 dev;
} __packed;
static long static long
snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
...@@ -409,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -409,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case SNAPSHOT_AVAIL_SWAP_SIZE: case SNAPSHOT_AVAIL_SWAP_SIZE:
case SNAPSHOT_ALLOC_SWAP_PAGE: case SNAPSHOT_ALLOC_SWAP_PAGE:
case SNAPSHOT_CREATE_IMAGE: case SNAPSHOT_CREATE_IMAGE:
case SNAPSHOT_SET_SWAP_AREA:
return snapshot_ioctl(file, cmd, return snapshot_ioctl(file, cmd,
(unsigned long) compat_ptr(arg)); (unsigned long) compat_ptr(arg));
case SNAPSHOT_SET_SWAP_AREA: {
struct compat_resume_swap_area __user *u_swap_area =
compat_ptr(arg);
struct resume_swap_area swap_area;
mm_segment_t old_fs;
int err;
err = get_user(swap_area.offset, &u_swap_area->offset);
err |= get_user(swap_area.dev, &u_swap_area->dev);
if (err)
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA,
(unsigned long) &swap_area);
set_fs(old_fs);
return err;
}
default: default:
return snapshot_ioctl(file, cmd, arg); return snapshot_ioctl(file, cmd, arg);
} }
} }
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
static const struct file_operations snapshot_fops = { static const struct file_operations snapshot_fops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment