aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2011-06-07 20:45:37 -0400
committerAvi Kivity <avi@redhat.com>2011-07-12 06:16:17 -0400
commit1dda606c5f94b14a8f36c220d1d8844bab68a720 (patch)
treecf78b5aa3d499d239079c392491bcf656fbe05e6 /virt/kvm
parent91e3d71db29d9b3b67b64e2a08e724a7ff538b4c (diff)
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>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/kvm_main.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fa2321ac77cc..11d2783eb9df 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -84,6 +84,10 @@ struct dentry *kvm_debugfs_dir;
84 84
85static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, 85static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
86 unsigned long arg); 86 unsigned long arg);
87#ifdef CONFIG_COMPAT
88static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl,
89 unsigned long arg);
90#endif
87static int hardware_enable_all(void); 91static int hardware_enable_all(void);
88static void hardware_disable_all(void); 92static void hardware_disable_all(void);
89 93
@@ -1586,7 +1590,9 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
1586static struct file_operations kvm_vcpu_fops = { 1590static struct file_operations kvm_vcpu_fops = {
1587 .release = kvm_vcpu_release, 1591 .release = kvm_vcpu_release,
1588 .unlocked_ioctl = kvm_vcpu_ioctl, 1592 .unlocked_ioctl = kvm_vcpu_ioctl,
1589 .compat_ioctl = kvm_vcpu_ioctl, 1593#ifdef CONFIG_COMPAT
1594 .compat_ioctl = kvm_vcpu_compat_ioctl,
1595#endif
1590 .mmap = kvm_vcpu_mmap, 1596 .mmap = kvm_vcpu_mmap,
1591 .llseek = noop_llseek, 1597 .llseek = noop_llseek,
1592}; 1598};
@@ -1875,6 +1881,50 @@ out:
1875 return r; 1881 return r;
1876} 1882}
1877 1883
1884#ifdef CONFIG_COMPAT
1885static long kvm_vcpu_compat_ioctl(struct file *filp,
1886 unsigned int ioctl, unsigned long arg)
1887{
1888 struct kvm_vcpu *vcpu = filp->private_data;
1889 void __user *argp = compat_ptr(arg);
1890 int r;
1891
1892 if (vcpu->kvm->mm != current->mm)
1893 return -EIO;
1894
1895 switch (ioctl) {
1896 case KVM_SET_SIGNAL_MASK: {
1897 struct kvm_signal_mask __user *sigmask_arg = argp;
1898 struct kvm_signal_mask kvm_sigmask;
1899 compat_sigset_t csigset;
1900 sigset_t sigset;
1901
1902 if (argp) {
1903 r = -EFAULT;
1904 if (copy_from_user(&kvm_sigmask, argp,
1905 sizeof kvm_sigmask))
1906 goto out;
1907 r = -EINVAL;
1908 if (kvm_sigmask.len != sizeof csigset)
1909 goto out;
1910 r = -EFAULT;
1911 if (copy_from_user(&csigset, sigmask_arg->sigset,
1912 sizeof csigset))
1913 goto out;
1914 }
1915 sigset_from_compat(&sigset, &csigset);
1916 r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
1917 break;
1918 }
1919 default:
1920 r = kvm_vcpu_ioctl(filp, ioctl, arg);
1921 }
1922
1923out:
1924 return r;
1925}
1926#endif
1927
1878static long kvm_vm_ioctl(struct file *filp, 1928static long kvm_vm_ioctl(struct file *filp,
1879 unsigned int ioctl, unsigned long arg) 1929 unsigned int ioctl, unsigned long arg)
1880{ 1930{