diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/x86.c | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a97157cc42ae..87d434228fe2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1869,6 +1869,15 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1869 | struct kvm *kvm = filp->private_data; | 1869 | struct kvm *kvm = filp->private_data; |
1870 | void __user *argp = (void __user *)arg; | 1870 | void __user *argp = (void __user *)arg; |
1871 | int r = -EINVAL; | 1871 | int r = -EINVAL; |
1872 | /* | ||
1873 | * This union makes it completely explicit to gcc-3.x | ||
1874 | * that these two variables' stack usage should be | ||
1875 | * combined, not added together. | ||
1876 | */ | ||
1877 | union { | ||
1878 | struct kvm_pit_state ps; | ||
1879 | struct kvm_memory_alias alias; | ||
1880 | } u; | ||
1872 | 1881 | ||
1873 | switch (ioctl) { | 1882 | switch (ioctl) { |
1874 | case KVM_SET_TSS_ADDR: | 1883 | case KVM_SET_TSS_ADDR: |
@@ -1900,17 +1909,14 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1900 | case KVM_GET_NR_MMU_PAGES: | 1909 | case KVM_GET_NR_MMU_PAGES: |
1901 | r = kvm_vm_ioctl_get_nr_mmu_pages(kvm); | 1910 | r = kvm_vm_ioctl_get_nr_mmu_pages(kvm); |
1902 | break; | 1911 | break; |
1903 | case KVM_SET_MEMORY_ALIAS: { | 1912 | case KVM_SET_MEMORY_ALIAS: |
1904 | struct kvm_memory_alias alias; | ||
1905 | |||
1906 | r = -EFAULT; | 1913 | r = -EFAULT; |
1907 | if (copy_from_user(&alias, argp, sizeof alias)) | 1914 | if (copy_from_user(&u.alias, argp, sizeof(struct kvm_memory_alias))) |
1908 | goto out; | 1915 | goto out; |
1909 | r = kvm_vm_ioctl_set_memory_alias(kvm, &alias); | 1916 | r = kvm_vm_ioctl_set_memory_alias(kvm, &u.alias); |
1910 | if (r) | 1917 | if (r) |
1911 | goto out; | 1918 | goto out; |
1912 | break; | 1919 | break; |
1913 | } | ||
1914 | case KVM_CREATE_IRQCHIP: | 1920 | case KVM_CREATE_IRQCHIP: |
1915 | r = -ENOMEM; | 1921 | r = -ENOMEM; |
1916 | kvm->arch.vpic = kvm_create_pic(kvm); | 1922 | kvm->arch.vpic = kvm_create_pic(kvm); |
@@ -1952,37 +1958,51 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1952 | } | 1958 | } |
1953 | case KVM_GET_IRQCHIP: { | 1959 | case KVM_GET_IRQCHIP: { |
1954 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ | 1960 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ |
1955 | struct kvm_irqchip chip; | 1961 | struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); |
1956 | 1962 | ||
1957 | r = -EFAULT; | 1963 | r = -ENOMEM; |
1958 | if (copy_from_user(&chip, argp, sizeof chip)) | 1964 | if (!chip) |
1959 | goto out; | 1965 | goto out; |
1966 | r = -EFAULT; | ||
1967 | if (copy_from_user(chip, argp, sizeof *chip)) | ||
1968 | goto get_irqchip_out; | ||
1960 | r = -ENXIO; | 1969 | r = -ENXIO; |
1961 | if (!irqchip_in_kernel(kvm)) | 1970 | if (!irqchip_in_kernel(kvm)) |
1962 | goto out; | 1971 | goto get_irqchip_out; |
1963 | r = kvm_vm_ioctl_get_irqchip(kvm, &chip); | 1972 | r = kvm_vm_ioctl_get_irqchip(kvm, chip); |
1964 | if (r) | 1973 | if (r) |
1965 | goto out; | 1974 | goto get_irqchip_out; |
1966 | r = -EFAULT; | 1975 | r = -EFAULT; |
1967 | if (copy_to_user(argp, &chip, sizeof chip)) | 1976 | if (copy_to_user(argp, chip, sizeof *chip)) |
1968 | goto out; | 1977 | goto get_irqchip_out; |
1969 | r = 0; | 1978 | r = 0; |
1979 | get_irqchip_out: | ||
1980 | kfree(chip); | ||
1981 | if (r) | ||
1982 | goto out; | ||
1970 | break; | 1983 | break; |
1971 | } | 1984 | } |
1972 | case KVM_SET_IRQCHIP: { | 1985 | case KVM_SET_IRQCHIP: { |
1973 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ | 1986 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ |
1974 | struct kvm_irqchip chip; | 1987 | struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); |
1975 | 1988 | ||
1976 | r = -EFAULT; | 1989 | r = -ENOMEM; |
1977 | if (copy_from_user(&chip, argp, sizeof chip)) | 1990 | if (!chip) |
1978 | goto out; | 1991 | goto out; |
1992 | r = -EFAULT; | ||
1993 | if (copy_from_user(chip, argp, sizeof *chip)) | ||
1994 | goto set_irqchip_out; | ||
1979 | r = -ENXIO; | 1995 | r = -ENXIO; |
1980 | if (!irqchip_in_kernel(kvm)) | 1996 | if (!irqchip_in_kernel(kvm)) |
1981 | goto out; | 1997 | goto set_irqchip_out; |
1982 | r = kvm_vm_ioctl_set_irqchip(kvm, &chip); | 1998 | r = kvm_vm_ioctl_set_irqchip(kvm, chip); |
1983 | if (r) | 1999 | if (r) |
1984 | goto out; | 2000 | goto set_irqchip_out; |
1985 | r = 0; | 2001 | r = 0; |
2002 | set_irqchip_out: | ||
2003 | kfree(chip); | ||
2004 | if (r) | ||
2005 | goto out; | ||
1986 | break; | 2006 | break; |
1987 | } | 2007 | } |
1988 | case KVM_ASSIGN_PCI_DEVICE: { | 2008 | case KVM_ASSIGN_PCI_DEVICE: { |
@@ -2008,31 +2028,29 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
2008 | break; | 2028 | break; |
2009 | } | 2029 | } |
2010 | case KVM_GET_PIT: { | 2030 | case KVM_GET_PIT: { |
2011 | struct kvm_pit_state ps; | ||
2012 | r = -EFAULT; | 2031 | r = -EFAULT; |
2013 | if (copy_from_user(&ps, argp, sizeof ps)) | 2032 | if (copy_from_user(&u.ps, argp, sizeof(struct kvm_pit_state))) |
2014 | goto out; | 2033 | goto out; |
2015 | r = -ENXIO; | 2034 | r = -ENXIO; |
2016 | if (!kvm->arch.vpit) | 2035 | if (!kvm->arch.vpit) |
2017 | goto out; | 2036 | goto out; |
2018 | r = kvm_vm_ioctl_get_pit(kvm, &ps); | 2037 | r = kvm_vm_ioctl_get_pit(kvm, &u.ps); |
2019 | if (r) | 2038 | if (r) |
2020 | goto out; | 2039 | goto out; |
2021 | r = -EFAULT; | 2040 | r = -EFAULT; |
2022 | if (copy_to_user(argp, &ps, sizeof ps)) | 2041 | if (copy_to_user(argp, &u.ps, sizeof(struct kvm_pit_state))) |
2023 | goto out; | 2042 | goto out; |
2024 | r = 0; | 2043 | r = 0; |
2025 | break; | 2044 | break; |
2026 | } | 2045 | } |
2027 | case KVM_SET_PIT: { | 2046 | case KVM_SET_PIT: { |
2028 | struct kvm_pit_state ps; | ||
2029 | r = -EFAULT; | 2047 | r = -EFAULT; |
2030 | if (copy_from_user(&ps, argp, sizeof ps)) | 2048 | if (copy_from_user(&u.ps, argp, sizeof u.ps)) |
2031 | goto out; | 2049 | goto out; |
2032 | r = -ENXIO; | 2050 | r = -ENXIO; |
2033 | if (!kvm->arch.vpit) | 2051 | if (!kvm->arch.vpit) |
2034 | goto out; | 2052 | goto out; |
2035 | r = kvm_vm_ioctl_set_pit(kvm, &ps); | 2053 | r = kvm_vm_ioctl_set_pit(kvm, &u.ps); |
2036 | if (r) | 2054 | if (r) |
2037 | goto out; | 2055 | goto out; |
2038 | r = 0; | 2056 | r = 0; |