KVM: Add compat ioctl for KVM_SET_SIGNAL_MASK
KVM has an ioctl to define which signal mask should be used while running inside VCPU_RUN. At least for big endian systems, this mask is different on 32-bit and 64-bit systems (though the size is identical). Add a compat wrapper that converts the mask to whatever the kernel accepts, allowing 32-bit kvm user space to set signal masks. This patch fixes qemu with --enable-io-thread on ppc64 hosts when running 32-bit user land. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
91e3d71db2
commit
1dda606c5f
|
@ -890,6 +890,7 @@ sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
|
|||
case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sigset_from_compat);
|
||||
|
||||
asmlinkage long
|
||||
compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
|
||||
|
|
|
@ -84,6 +84,10 @@ struct dentry *kvm_debugfs_dir;
|
|||
|
||||
static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
|
||||
unsigned long arg);
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
static int hardware_enable_all(void);
|
||||
static void hardware_disable_all(void);
|
||||
|
||||
|
@ -1586,7 +1590,9 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
|
|||
static struct file_operations kvm_vcpu_fops = {
|
||||
.release = kvm_vcpu_release,
|
||||
.unlocked_ioctl = kvm_vcpu_ioctl,
|
||||
.compat_ioctl = kvm_vcpu_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = kvm_vcpu_compat_ioctl,
|
||||
#endif
|
||||
.mmap = kvm_vcpu_mmap,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
@ -1875,6 +1881,50 @@ out:
|
|||
return r;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long kvm_vcpu_compat_ioctl(struct file *filp,
|
||||
unsigned int ioctl, unsigned long arg)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = filp->private_data;
|
||||
void __user *argp = compat_ptr(arg);
|
||||
int r;
|
||||
|
||||
if (vcpu->kvm->mm != current->mm)
|
||||
return -EIO;
|
||||
|
||||
switch (ioctl) {
|
||||
case KVM_SET_SIGNAL_MASK: {
|
||||
struct kvm_signal_mask __user *sigmask_arg = argp;
|
||||
struct kvm_signal_mask kvm_sigmask;
|
||||
compat_sigset_t csigset;
|
||||
sigset_t sigset;
|
||||
|
||||
if (argp) {
|
||||
r = -EFAULT;
|
||||
if (copy_from_user(&kvm_sigmask, argp,
|
||||
sizeof kvm_sigmask))
|
||||
goto out;
|
||||
r = -EINVAL;
|
||||
if (kvm_sigmask.len != sizeof csigset)
|
||||
goto out;
|
||||
r = -EFAULT;
|
||||
if (copy_from_user(&csigset, sigmask_arg->sigset,
|
||||
sizeof csigset))
|
||||
goto out;
|
||||
}
|
||||
sigset_from_compat(&sigset, &csigset);
|
||||
r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
r = kvm_vcpu_ioctl(filp, ioctl, arg);
|
||||
}
|
||||
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static long kvm_vm_ioctl(struct file *filp,
|
||||
unsigned int ioctl, unsigned long arg)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue