aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDave Hansen <dave@linux.vnet.ibm.com>2008-08-11 13:01:45 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:18 -0400
commitf0d662759a2465babdba1160749c446648c9d159 (patch)
treed98d36f37df91bab55e2cb74cd5647fbf2bfb13e /arch
parent4d5c5d0fe89c921336b95f5e7e4f529a9df92f53 (diff)
KVM: Reduce kvm stack usage in kvm_arch_vm_ioctl()
On my machine with gcc 3.4, kvm uses ~2k of stack in a few select functions. This is mostly because gcc fails to notice that the different case: statements could have their stack usage combined. It overflows very nicely if interrupts happen during one of these large uses. This patch uses two methods for reducing stack usage. 1. dynamically allocate large objects instead of putting on the stack. 2. Use a union{} member for all of the case variables. This tricks gcc into combining them all into a single stack allocation. (There's also a comment on this) Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/x86.c72
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;