diff options
author | Alice Ferrazzi <alicef@gentoo.org> | 2017-06-26 10:14:34 +0000 |
---|---|---|
committer | Alice Ferrazzi <alicef@gentoo.org> | 2017-06-26 10:14:34 +0000 |
commit | b9b2027386c3789be10544130ad07f4425763a2c (patch) | |
tree | 87b9c5a4e5e26c549b1865c379d3451d093ab203 | |
parent | Linux kernel 4.4.73 (diff) | |
download | linux-patches-4.4-77.tar.gz linux-patches-4.4-77.tar.bz2 linux-patches-4.4-77.zip |
linux kernel 4.4.744.4-77
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1073_linux-4.4.74.patch | 1488 |
2 files changed, 1492 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 24aadfd2..bcacfeab 100644 --- a/0000_README +++ b/0000_README @@ -335,6 +335,10 @@ Patch: 1072_linux-4.4.73.patch From: http://www.kernel.org Desc: Linux 4.4.73 +Patch: 1073_linux-4.4.74.patch +From: http://www.kernel.org +Desc: Linux 4.4.74 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1073_linux-4.4.74.patch b/1073_linux-4.4.74.patch new file mode 100644 index 00000000..4c15d4de --- /dev/null +++ b/1073_linux-4.4.74.patch @@ -0,0 +1,1488 @@ +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index ca64ca566099..7c77d7edb851 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -3580,6 +3580,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + spia_pedr= + spia_peddr= + ++ stack_guard_gap= [MM] ++ override the default stack gap protection. The value ++ is in page units and it defines how many pages prior ++ to (for stacks growing down) resp. after (for stacks ++ growing up) the main stack are reserved for no other ++ mapping. Default value is 256 pages. ++ + stacktrace [FTRACE] + Enabled the stack tracer on boot up. + +diff --git a/Makefile b/Makefile +index ba5a70b6e32c..1f75507acbf4 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 73 ++SUBLEVEL = 74 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c +index 2e06d56e987b..cf4ae6958240 100644 +--- a/arch/arc/mm/mmap.c ++++ b/arch/arc/mm/mmap.c +@@ -64,7 +64,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c +index 407dc786583a..c469c0665752 100644 +--- a/arch/arm/mm/mmap.c ++++ b/arch/arm/mm/mmap.c +@@ -89,7 +89,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +@@ -140,7 +140,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c +index 836f14707a62..efa59f1f8022 100644 +--- a/arch/frv/mm/elf-fdpic.c ++++ b/arch/frv/mm/elf-fdpic.c +@@ -74,7 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi + addr = PAGE_ALIGN(addr); + vma = find_vma(current->mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + goto success; + } + +diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c +index d8f9b357b222..e9fed8ca9b42 100644 +--- a/arch/mips/kernel/branch.c ++++ b/arch/mips/kernel/branch.c +@@ -816,8 +816,10 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, + break; + } + /* Compact branch: BNEZC || JIALC */ +- if (insn.i_format.rs) ++ if (!insn.i_format.rs) { ++ /* JIALC: set $31/ra */ + regs->regs[31] = epc + 4; ++ } + regs->cp0_epc += 8; + break; + #endif +diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c +index 5c81fdd032c3..025cb31aa0a2 100644 +--- a/arch/mips/mm/mmap.c ++++ b/arch/mips/mm/mmap.c +@@ -92,7 +92,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c +index 5aba01ac457f..4dda73c44fee 100644 +--- a/arch/parisc/kernel/sys_parisc.c ++++ b/arch/parisc/kernel/sys_parisc.c +@@ -88,7 +88,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) + { + struct mm_struct *mm = current->mm; +- struct vm_area_struct *vma; ++ struct vm_area_struct *vma, *prev; + unsigned long task_size = TASK_SIZE; + int do_color_align, last_mmap; + struct vm_unmapped_area_info info; +@@ -115,9 +115,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + else + addr = PAGE_ALIGN(addr); + +- vma = find_vma(mm, addr); ++ vma = find_vma_prev(mm, addr, &prev); + if (task_size - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma)) && ++ (!prev || addr >= vm_end_gap(prev))) + goto found_addr; + } + +@@ -141,7 +142,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + const unsigned long len, const unsigned long pgoff, + const unsigned long flags) + { +- struct vm_area_struct *vma; ++ struct vm_area_struct *vma, *prev; + struct mm_struct *mm = current->mm; + unsigned long addr = addr0; + int do_color_align, last_mmap; +@@ -175,9 +176,11 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + addr = COLOR_ALIGN(addr, last_mmap, pgoff); + else + addr = PAGE_ALIGN(addr); +- vma = find_vma(mm, addr); ++ ++ vma = find_vma_prev(mm, addr, &prev); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma)) && ++ (!prev || addr >= vm_end_gap(prev))) + goto found_addr; + } + +diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c +index 0f432a702870..6ad12b244770 100644 +--- a/arch/powerpc/mm/slice.c ++++ b/arch/powerpc/mm/slice.c +@@ -105,7 +105,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr, + if ((mm->task_size - len) < addr) + return 0; + vma = find_vma(mm, addr); +- return (!vma || (addr + len) <= vma->vm_start); ++ return (!vma || (addr + len) <= vm_start_gap(vma)); + } + + static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice) +diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c +index f2b6b1d9c804..126c4a9b9bf9 100644 +--- a/arch/s390/mm/mmap.c ++++ b/arch/s390/mm/mmap.c +@@ -97,7 +97,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +@@ -135,7 +135,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c +index 6777177807c2..7df7d5944188 100644 +--- a/arch/sh/mm/mmap.c ++++ b/arch/sh/mm/mmap.c +@@ -63,7 +63,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +@@ -113,7 +113,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c +index c690c8e16a96..7f0f7c01b297 100644 +--- a/arch/sparc/kernel/sys_sparc_64.c ++++ b/arch/sparc/kernel/sys_sparc_64.c +@@ -118,7 +118,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi + + vma = find_vma(mm, addr); + if (task_size - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +@@ -181,7 +181,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + + vma = find_vma(mm, addr); + if (task_size - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c +index da1142401bf4..ffa842b4d7d4 100644 +--- a/arch/sparc/mm/hugetlbpage.c ++++ b/arch/sparc/mm/hugetlbpage.c +@@ -115,7 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + addr = ALIGN(addr, HPAGE_SIZE); + vma = find_vma(mm, addr); + if (task_size - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + if (mm->get_unmapped_area == arch_get_unmapped_area) +diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c +index c034dc3fe2d4..c97ee6c7f949 100644 +--- a/arch/tile/mm/hugetlbpage.c ++++ b/arch/tile/mm/hugetlbpage.c +@@ -232,7 +232,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + if (current->mm->get_unmapped_area == arch_get_unmapped_area) +diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c +index 10e0272d789a..136ad7c1ce7b 100644 +--- a/arch/x86/kernel/sys_x86_64.c ++++ b/arch/x86/kernel/sys_x86_64.c +@@ -143,7 +143,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (end - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +@@ -186,7 +186,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c +index 42982b26e32b..39bdaf3ac44a 100644 +--- a/arch/x86/mm/hugetlbpage.c ++++ b/arch/x86/mm/hugetlbpage.c +@@ -144,7 +144,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + if (mm->get_unmapped_area == arch_get_unmapped_area) +diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c +index 47b6436e41c2..3686a1db25b2 100644 +--- a/arch/x86/mm/numa_32.c ++++ b/arch/x86/mm/numa_32.c +@@ -100,5 +100,6 @@ void __init initmem_init(void) + printk(KERN_DEBUG "High memory starts at vaddr %08lx\n", + (ulong) pfn_to_kaddr(highstart_pfn)); + ++ __vmalloc_start_set = true; + setup_bootmem_allocator(); + } +diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c +index 83cf49685373..3aaaae18417c 100644 +--- a/arch/xtensa/kernel/syscall.c ++++ b/arch/xtensa/kernel/syscall.c +@@ -87,7 +87,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; +- if (!vmm || addr + len <= vmm->vm_start) ++ if (!vmm || addr + len <= vm_start_gap(vmm)) + return addr; + addr = vmm->vm_end; + if (flags & MAP_SHARED) +diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c +index 1fa1deb6e91f..c395f9198fd2 100644 +--- a/drivers/cpufreq/cpufreq_conservative.c ++++ b/drivers/cpufreq/cpufreq_conservative.c +@@ -212,8 +212,8 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, + int ret; + ret = sscanf(buf, "%u", &input); + +- /* cannot be lower than 11 otherwise freq will not fall */ +- if (ret != 1 || input < 11 || input > 100 || ++ /* cannot be lower than 1 otherwise freq will not fall */ ++ if (ret != 1 || input < 1 || input > 100 || + input >= cs_tuners->up_threshold) + return -EINVAL; + +diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c +index 9e6d1cdb7fcd..420478924a0c 100644 +--- a/drivers/iio/proximity/as3935.c ++++ b/drivers/iio/proximity/as3935.c +@@ -263,8 +263,6 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private) + + static void calibrate_as3935(struct as3935_state *st) + { +- mutex_lock(&st->lock); +- + /* mask disturber interrupt bit */ + as3935_write(st, AS3935_INT, BIT(5)); + +@@ -274,8 +272,6 @@ static void calibrate_as3935(struct as3935_state *st) + + mdelay(2); + as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV)); +- +- mutex_unlock(&st->lock); + } + + #ifdef CONFIG_PM_SLEEP +@@ -312,6 +308,8 @@ static int as3935_resume(struct device *dev) + val &= ~AS3935_AFE_PWR_BIT; + ret = as3935_write(st, AS3935_AFE_GAIN, val); + ++ calibrate_as3935(st); ++ + err_resume: + mutex_unlock(&st->lock); + +diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c +index e1907cd0c3b7..7613d1fee104 100644 +--- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c +@@ -123,15 +123,10 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) + memset(&tvdata,0,sizeof(tvdata)); + + eeprom = pvr2_eeprom_fetch(hdw); +- if (!eeprom) return -EINVAL; +- +- { +- struct i2c_client fake_client; +- /* Newer version expects a useless client interface */ +- fake_client.addr = hdw->eeprom_addr; +- fake_client.adapter = &hdw->i2c_adap; +- tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); +- } ++ if (!eeprom) ++ return -EINVAL; ++ ++ tveeprom_hauppauge_analog(NULL, &tvdata, eeprom); + + trace_eeprom("eeprom assumed v4l tveeprom module"); + trace_eeprom("eeprom direct call results:"); +diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c +index 47f37683893a..3dc9ed2e0774 100644 +--- a/drivers/media/v4l2-core/videobuf2-core.c ++++ b/drivers/media/v4l2-core/videobuf2-core.c +@@ -793,7 +793,7 @@ EXPORT_SYMBOL_GPL(vb2_core_create_bufs); + */ + void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) + { +- if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) ++ if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) + return NULL; + + return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv); +diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c +index c30290f33430..fe51e9709210 100644 +--- a/drivers/mfd/omap-usb-tll.c ++++ b/drivers/mfd/omap-usb-tll.c +@@ -375,8 +375,8 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata) + * and use SDR Mode + */ + reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE +- | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF + | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); ++ reg |= OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF; + } else if (pdata->port_mode[i] == + OMAP_EHCI_PORT_MODE_HSIC) { + /* +diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c +index 5484301d57d9..3dc61ea7dc64 100644 +--- a/drivers/misc/c2port/c2port-duramar2150.c ++++ b/drivers/misc/c2port/c2port-duramar2150.c +@@ -129,8 +129,8 @@ static int __init duramar2150_c2port_init(void) + + duramar2150_c2port_dev = c2port_device_register("uc", + &duramar2150_c2port_ops, NULL); +- if (!duramar2150_c2port_dev) { +- ret = -ENODEV; ++ if (IS_ERR(duramar2150_c2port_dev)) { ++ ret = PTR_ERR(duramar2150_c2port_dev); + goto free_region; + } + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index cbc99d5649af..ae5709354546 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -246,6 +246,8 @@ static int gs_cmd_reset(struct gs_usb *gsusb, struct gs_can *gsdev) + sizeof(*dm), + 1000); + ++ kfree(dm); ++ + return rc; + } + +diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c +index 3cdb40fea5ee..f5cedbbc552a 100644 +--- a/drivers/staging/rtl8188eu/core/rtw_ap.c ++++ b/drivers/staging/rtl8188eu/core/rtw_ap.c +@@ -894,7 +894,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + return _FAIL; + + +- if (len > MAX_IE_SZ) ++ if (len < 0 || len > MAX_IE_SZ) + return _FAIL; + + pbss_network->IELength = len; +diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c +index 195acc868763..5d476916191b 100644 +--- a/drivers/tty/serial/efm32-uart.c ++++ b/drivers/tty/serial/efm32-uart.c +@@ -27,6 +27,7 @@ + #define UARTn_FRAME 0x04 + #define UARTn_FRAME_DATABITS__MASK 0x000f + #define UARTn_FRAME_DATABITS(n) ((n) - 3) ++#define UARTn_FRAME_PARITY__MASK 0x0300 + #define UARTn_FRAME_PARITY_NONE 0x0000 + #define UARTn_FRAME_PARITY_EVEN 0x0200 + #define UARTn_FRAME_PARITY_ODD 0x0300 +@@ -572,12 +573,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, + 16 * (4 + (clkdiv >> 6))); + + frame = efm32_uart_read32(efm_port, UARTn_FRAME); +- if (frame & UARTn_FRAME_PARITY_ODD) ++ switch (frame & UARTn_FRAME_PARITY__MASK) { ++ case UARTn_FRAME_PARITY_ODD: + *parity = 'o'; +- else if (frame & UARTn_FRAME_PARITY_EVEN) ++ break; ++ case UARTn_FRAME_PARITY_EVEN: + *parity = 'e'; +- else ++ break; ++ default: + *parity = 'n'; ++ } + + *bits = (frame & UARTn_FRAME_DATABITS__MASK) - + UARTn_FRAME_DATABITS(4) + 4; +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index c3f4f2ab7b33..b403596818db 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2511,6 +2511,7 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, + hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), + GFP_KERNEL); + if (!hcd->bandwidth_mutex) { ++ kfree(hcd->address0_mutex); + kfree(hcd); + dev_dbg(dev, "hcd bandwidth mutex alloc failed\n"); + return NULL; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index b627392ad52a..1d59d489a1ad 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1318,7 +1318,13 @@ static int hub_configure(struct usb_hub *hub, + if (ret < 0) { + message = "can't read hub descriptor"; + goto fail; +- } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) { ++ } ++ ++ maxchild = USB_MAXCHILDREN; ++ if (hub_is_superspeed(hdev)) ++ maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS); ++ ++ if (hub->descriptor->bNbrPorts > maxchild) { + message = "hub has too many ports!"; + ret = -ENODEV; + goto fail; +diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c +index 2f1fb7e7aa54..9eba51b92f72 100644 +--- a/drivers/usb/dwc3/dwc3-exynos.c ++++ b/drivers/usb/dwc3/dwc3-exynos.c +@@ -148,7 +148,8 @@ static int dwc3_exynos_probe(struct platform_device *pdev) + exynos->axius_clk = devm_clk_get(dev, "usbdrd30_axius_clk"); + if (IS_ERR(exynos->axius_clk)) { + dev_err(dev, "no AXI UpScaler clk specified\n"); +- return -ENODEV; ++ ret = -ENODEV; ++ goto axius_clk_err; + } + clk_prepare_enable(exynos->axius_clk); + } else { +@@ -206,6 +207,7 @@ err3: + regulator_disable(exynos->vdd33); + err2: + clk_disable_unprepare(exynos->axius_clk); ++axius_clk_err: + clk_disable_unprepare(exynos->susp_clk); + clk_disable_unprepare(exynos->clk); + return ret; +diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c +index de014436fb22..43ce2cfcdb4d 100644 +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1676,9 +1676,10 @@ static void + gadgetfs_suspend (struct usb_gadget *gadget) + { + struct dev_data *dev = get_gadget_data (gadget); ++ unsigned long flags; + + INFO (dev, "suspended from state %d\n", dev->state); +- spin_lock (&dev->lock); ++ spin_lock_irqsave(&dev->lock, flags); + switch (dev->state) { + case STATE_DEV_SETUP: // VERY odd... host died?? + case STATE_DEV_CONNECTED: +@@ -1689,7 +1690,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) + default: + break; + } +- spin_unlock (&dev->lock); ++ spin_unlock_irqrestore(&dev->lock, flags); + } + + static struct usb_gadget_driver gadgetfs_driver = { +diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c +index 6610f7a023d3..64f404a1a072 100644 +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_hcd *dum_hcd) + /* Report reset and disconnect events to the driver */ + if (dum->driver && (disconnect || reset)) { + stop_activity(dum); +- spin_unlock(&dum->lock); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); + else + dum->driver->disconnect(&dum->gadget); +- spin_lock(&dum->lock); + } + } else if (dum_hcd->active != dum_hcd->old_active) { +- if (dum_hcd->old_active && dum->driver->suspend) { +- spin_unlock(&dum->lock); ++ if (dum_hcd->old_active && dum->driver->suspend) + dum->driver->suspend(&dum->gadget); +- spin_lock(&dum->lock); +- } else if (!dum_hcd->old_active && dum->driver->resume) { +- spin_unlock(&dum->lock); ++ else if (!dum_hcd->old_active && dum->driver->resume) + dum->driver->resume(&dum->gadget); +- spin_lock(&dum->lock); +- } + } + + dum_hcd->old_status = dum_hcd->port_status; +@@ -985,7 +978,9 @@ static int dummy_udc_stop(struct usb_gadget *g) + struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); + struct dummy *dum = dum_hcd->dum; + ++ spin_lock_irq(&dum->lock); + dum->driver = NULL; ++ spin_unlock_irq(&dum->lock); + + return 0; + } +@@ -2011,7 +2006,7 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc) + HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = 1; + desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ +- desc->u.ss.DeviceRemovable = 0xffff; ++ desc->u.ss.DeviceRemovable = 0; + } + + static inline void hub_descriptor(struct usb_hub_descriptor *desc) +@@ -2023,8 +2018,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) + HUB_CHAR_INDV_PORT_LPSM | + HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = 1; +- desc->u.hs.DeviceRemovable[0] = 0xff; +- desc->u.hs.DeviceRemovable[1] = 0xff; ++ desc->u.hs.DeviceRemovable[0] = 0; ++ desc->u.hs.DeviceRemovable[1] = 0xff; /* PortPwrCtrlMask */ + } + + static int dummy_hub_control( +diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c +index 6706aef907f4..a47de8c31ce9 100644 +--- a/drivers/usb/gadget/udc/net2280.c ++++ b/drivers/usb/gadget/udc/net2280.c +@@ -2425,11 +2425,8 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) + nuke(&dev->ep[i]); + + /* report disconnect; the driver is already quiesced */ +- if (driver) { +- spin_unlock(&dev->lock); ++ if (driver) + driver->disconnect(&dev->gadget); +- spin_lock(&dev->lock); +- } + + usb_reinit(dev); + } +@@ -3275,8 +3272,6 @@ next_endpoints: + BIT(PCI_RETRY_ABORT_INTERRUPT)) + + static void handle_stat1_irqs(struct net2280 *dev, u32 stat) +-__releases(dev->lock) +-__acquires(dev->lock) + { + struct net2280_ep *ep; + u32 tmp, num, mask, scratch; +@@ -3317,14 +3312,12 @@ __acquires(dev->lock) + if (disconnect || reset) { + stop_activity(dev, dev->driver); + ep0_start(dev); +- spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); +- spin_lock(&dev->lock); + return; + } + } +diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c +index 4cbd0633c5c2..a11c2c8bda53 100644 +--- a/drivers/usb/host/r8a66597-hcd.c ++++ b/drivers/usb/host/r8a66597-hcd.c +@@ -1269,7 +1269,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td) + time = 30; + break; + default: +- time = 300; ++ time = 50; + break; + } + +@@ -1785,6 +1785,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597) + pipe = td->pipe; + pipe_stop(r8a66597, pipe); + ++ /* Select a different address or endpoint */ + new_td = td; + do { + list_move_tail(&new_td->queue, +@@ -1794,7 +1795,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597) + new_td = td; + break; + } +- } while (td != new_td && td->address == new_td->address); ++ } while (td != new_td && td->address == new_td->address && ++ td->pipe->info.epnum == new_td->pipe->info.epnum); + + start_transfer(r8a66597, new_td); + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 30c4ae80c8f9..e8f990642281 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -198,6 +198,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == 0x1042) + xhci->quirks |= XHCI_BROKEN_STREAMS; ++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && ++ pdev->device == 0x1142) ++ xhci->quirks |= XHCI_TRUST_TX_LENGTH; + + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c +index ec5c8325b503..0525ebc3aea2 100644 +--- a/fs/configfs/symlink.c ++++ b/fs/configfs/symlink.c +@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item, + ret = -ENOMEM; + sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); + if (sl) { +- sl->sl_target = config_item_get(item); + spin_lock(&configfs_dirent_lock); + if (target_sd->s_type & CONFIGFS_USET_DROPPING) { + spin_unlock(&configfs_dirent_lock); +- config_item_put(item); + kfree(sl); + return -ENOENT; + } ++ sl->sl_target = config_item_get(item); + list_add(&sl->sl_list, &target_sd->s_links); + spin_unlock(&configfs_dirent_lock); + ret = configfs_create_link(sl, parent_item->ci_dentry, +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index 595ebdb41846..a17da8b57fc6 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -191,7 +191,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma))) + return addr; + } + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index db1a1427c27a..07ef85e19fbc 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -295,11 +295,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) + + /* We don't show the stack guard page in /proc/maps */ + start = vma->vm_start; +- if (stack_guard_page_start(vma, start)) +- start += PAGE_SIZE; + end = vma->vm_end; +- if (stack_guard_page_end(vma, end)) +- end -= PAGE_SIZE; + + seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", +diff --git a/include/linux/mm.h b/include/linux/mm.h +index f0ffa01c90d9..55f950afb60d 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1278,39 +1278,11 @@ int clear_page_dirty_for_io(struct page *page); + + int get_cmdline(struct task_struct *task, char *buffer, int buflen); + +-/* Is the vma a continuation of the stack vma above it? */ +-static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr) +-{ +- return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); +-} +- + static inline bool vma_is_anonymous(struct vm_area_struct *vma) + { + return !vma->vm_ops; + } + +-static inline int stack_guard_page_start(struct vm_area_struct *vma, +- unsigned long addr) +-{ +- return (vma->vm_flags & VM_GROWSDOWN) && +- (vma->vm_start == addr) && +- !vma_growsdown(vma->vm_prev, addr); +-} +- +-/* Is the vma a continuation of the stack vma below it? */ +-static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr) +-{ +- return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP); +-} +- +-static inline int stack_guard_page_end(struct vm_area_struct *vma, +- unsigned long addr) +-{ +- return (vma->vm_flags & VM_GROWSUP) && +- (vma->vm_end == addr) && +- !vma_growsup(vma->vm_next, addr); +-} +- + int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t); + + extern unsigned long move_page_tables(struct vm_area_struct *vma, +@@ -2012,6 +1984,7 @@ void page_cache_async_readahead(struct address_space *mapping, + pgoff_t offset, + unsigned long size); + ++extern unsigned long stack_guard_gap; + /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ + extern int expand_stack(struct vm_area_struct *vma, unsigned long address); + +@@ -2040,6 +2013,30 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m + return vma; + } + ++static inline unsigned long vm_start_gap(struct vm_area_struct *vma) ++{ ++ unsigned long vm_start = vma->vm_start; ++ ++ if (vma->vm_flags & VM_GROWSDOWN) { ++ vm_start -= stack_guard_gap; ++ if (vm_start > vma->vm_start) ++ vm_start = 0; ++ } ++ return vm_start; ++} ++ ++static inline unsigned long vm_end_gap(struct vm_area_struct *vma) ++{ ++ unsigned long vm_end = vma->vm_end; ++ ++ if (vma->vm_flags & VM_GROWSUP) { ++ vm_end += stack_guard_gap; ++ if (vm_end < vma->vm_end) ++ vm_end = -PAGE_SIZE; ++ } ++ return vm_end; ++} ++ + static inline unsigned long vma_pages(struct vm_area_struct *vma) + { + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; +diff --git a/include/uapi/linux/usb/ch11.h b/include/uapi/linux/usb/ch11.h +index 331499d597fa..9ce10d4a0245 100644 +--- a/include/uapi/linux/usb/ch11.h ++++ b/include/uapi/linux/usb/ch11.h +@@ -22,6 +22,9 @@ + */ + #define USB_MAXCHILDREN 31 + ++/* See USB 3.1 spec Table 10-5 */ ++#define USB_SS_MAXPORTS 15 ++ + /* + * Hub request types + */ +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 6ead200370da..a079ed14f230 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -1287,8 +1287,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) + ret = __irq_set_trigger(desc, + new->flags & IRQF_TRIGGER_MASK); + +- if (ret) ++ if (ret) { ++ irq_release_resources(desc); + goto out_mask; ++ } + } + + desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ +diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c +index 7fbba635a549..2c3a23d77704 100644 +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -339,7 +339,7 @@ void alarm_start_relative(struct alarm *alarm, ktime_t start) + { + struct alarm_base *base = &alarm_bases[alarm->type]; + +- start = ktime_add(start, base->gettime()); ++ start = ktime_add_safe(start, base->gettime()); + alarm_start(alarm, start); + } + EXPORT_SYMBOL_GPL(alarm_start_relative); +@@ -425,7 +425,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval) + overrun++; + } + +- alarm->node.expires = ktime_add(alarm->node.expires, interval); ++ alarm->node.expires = ktime_add_safe(alarm->node.expires, interval); + return overrun; + } + EXPORT_SYMBOL_GPL(alarm_forward); +@@ -611,13 +611,21 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, + + /* start the timer */ + timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval); ++ ++ /* ++ * Rate limit to the tick as a hot fix to prevent DOS. Will be ++ * mopped up later. ++ */ ++ if (ktime_to_ns(timr->it.alarm.interval) < TICK_NSEC) ++ timr->it.alarm.interval = ktime_set(0, TICK_NSEC); ++ + exp = timespec_to_ktime(new_setting->it_value); + /* Convert (if necessary) to absolute time */ + if (flags != TIMER_ABSTIME) { + ktime_t now; + + now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime(); +- exp = ktime_add(now, exp); ++ exp = ktime_add_safe(now, exp); + } + + alarm_start(&timr->it.alarm.alarmtimer, exp); +diff --git a/mm/gup.c b/mm/gup.c +index 4b0b7e7d1136..b599526db9f7 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -312,11 +312,6 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, + /* mlock all present pages, but do not fault in new pages */ + if ((*flags & (FOLL_POPULATE | FOLL_MLOCK)) == FOLL_MLOCK) + return -ENOENT; +- /* For mm_populate(), just skip the stack guard page. */ +- if ((*flags & FOLL_POPULATE) && +- (stack_guard_page_start(vma, address) || +- stack_guard_page_end(vma, address + PAGE_SIZE))) +- return -ENOENT; + if (*flags & FOLL_WRITE) + fault_flags |= FAULT_FLAG_WRITE; + if (nonblocking) +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 43aee7ab143e..091fe9b06663 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1208,7 +1208,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags) + * page_remove_rmap() in try_to_unmap_one(). So to determine page status + * correctly, we save a copy of the page flags at this time. + */ +- page_flags = p->flags; ++ if (PageHuge(p)) ++ page_flags = hpage->flags; ++ else ++ page_flags = p->flags; + + /* + * unpoison always clear PG_hwpoison inside page lock +diff --git a/mm/memory.c b/mm/memory.c +index 76dcee317714..e6fa13484447 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2662,40 +2662,6 @@ out_release: + } + + /* +- * This is like a special single-page "expand_{down|up}wards()", +- * except we must first make sure that 'address{-|+}PAGE_SIZE' +- * doesn't hit another vma. +- */ +-static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) +-{ +- address &= PAGE_MASK; +- if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { +- struct vm_area_struct *prev = vma->vm_prev; +- +- /* +- * Is there a mapping abutting this one below? +- * +- * That's only ok if it's the same stack mapping +- * that has gotten split.. +- */ +- if (prev && prev->vm_end == address) +- return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; +- +- return expand_downwards(vma, address - PAGE_SIZE); +- } +- if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { +- struct vm_area_struct *next = vma->vm_next; +- +- /* As VM_GROWSDOWN but s/below/above/ */ +- if (next && next->vm_start == address + PAGE_SIZE) +- return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; +- +- return expand_upwards(vma, address + PAGE_SIZE); +- } +- return 0; +-} +- +-/* + * We enter with non-exclusive mmap_sem (to exclude vma changes, + * but allow concurrent faults), and pte mapped but not yet locked. + * We return with mmap_sem still held, but pte unmapped and unlocked. +@@ -2715,10 +2681,6 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, + if (vma->vm_flags & VM_SHARED) + return VM_FAULT_SIGBUS; + +- /* Check if we need to add a guard page to the stack */ +- if (check_stack_guard_page(vma, address) < 0) +- return VM_FAULT_SIGSEGV; +- + /* Use the zero-page for reads */ + if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) { + entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), +diff --git a/mm/mmap.c b/mm/mmap.c +index 455772a05e54..0990f8bc0fbe 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -288,6 +288,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) + unsigned long retval; + unsigned long newbrk, oldbrk; + struct mm_struct *mm = current->mm; ++ struct vm_area_struct *next; + unsigned long min_brk; + bool populate; + +@@ -332,7 +333,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) + } + + /* Check against existing mmap mappings. */ +- if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) ++ next = find_vma(mm, oldbrk); ++ if (next && newbrk + PAGE_SIZE > vm_start_gap(next)) + goto out; + + /* Ok, looks good - let it rip. */ +@@ -355,10 +357,22 @@ out: + + static long vma_compute_subtree_gap(struct vm_area_struct *vma) + { +- unsigned long max, subtree_gap; +- max = vma->vm_start; +- if (vma->vm_prev) +- max -= vma->vm_prev->vm_end; ++ unsigned long max, prev_end, subtree_gap; ++ ++ /* ++ * Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we ++ * allow two stack_guard_gaps between them here, and when choosing ++ * an unmapped area; whereas when expanding we only require one. ++ * That's a little inconsistent, but keeps the code here simpler. ++ */ ++ max = vm_start_gap(vma); ++ if (vma->vm_prev) { ++ prev_end = vm_end_gap(vma->vm_prev); ++ if (max > prev_end) ++ max -= prev_end; ++ else ++ max = 0; ++ } + if (vma->vm_rb.rb_left) { + subtree_gap = rb_entry(vma->vm_rb.rb_left, + struct vm_area_struct, vm_rb)->rb_subtree_gap; +@@ -451,7 +465,7 @@ static void validate_mm(struct mm_struct *mm) + anon_vma_unlock_read(anon_vma); + } + +- highest_address = vma->vm_end; ++ highest_address = vm_end_gap(vma); + vma = vma->vm_next; + i++; + } +@@ -620,7 +634,7 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, + if (vma->vm_next) + vma_gap_update(vma->vm_next); + else +- mm->highest_vm_end = vma->vm_end; ++ mm->highest_vm_end = vm_end_gap(vma); + + /* + * vma->vm_prev wasn't known when we followed the rbtree to find the +@@ -866,7 +880,7 @@ again: remove_next = 1 + (end > next->vm_end); + vma_gap_update(vma); + if (end_changed) { + if (!next) +- mm->highest_vm_end = end; ++ mm->highest_vm_end = vm_end_gap(vma); + else if (!adjust_next) + vma_gap_update(next); + } +@@ -909,7 +923,7 @@ again: remove_next = 1 + (end > next->vm_end); + else if (next) + vma_gap_update(next); + else +- mm->highest_vm_end = end; ++ VM_WARN_ON(mm->highest_vm_end != vm_end_gap(vma)); + } + if (insert && file) + uprobe_mmap(insert); +@@ -1741,7 +1755,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) + + while (true) { + /* Visit left subtree if it looks promising */ +- gap_end = vma->vm_start; ++ gap_end = vm_start_gap(vma); + if (gap_end >= low_limit && vma->vm_rb.rb_left) { + struct vm_area_struct *left = + rb_entry(vma->vm_rb.rb_left, +@@ -1752,12 +1766,13 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) + } + } + +- gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0; ++ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0; + check_current: + /* Check if current node has a suitable gap */ + if (gap_start > high_limit) + return -ENOMEM; +- if (gap_end >= low_limit && gap_end - gap_start >= length) ++ if (gap_end >= low_limit && ++ gap_end > gap_start && gap_end - gap_start >= length) + goto found; + + /* Visit right subtree if it looks promising */ +@@ -1779,8 +1794,8 @@ check_current: + vma = rb_entry(rb_parent(prev), + struct vm_area_struct, vm_rb); + if (prev == vma->vm_rb.rb_left) { +- gap_start = vma->vm_prev->vm_end; +- gap_end = vma->vm_start; ++ gap_start = vm_end_gap(vma->vm_prev); ++ gap_end = vm_start_gap(vma); + goto check_current; + } + } +@@ -1844,7 +1859,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) + + while (true) { + /* Visit right subtree if it looks promising */ +- gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0; ++ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0; + if (gap_start <= high_limit && vma->vm_rb.rb_right) { + struct vm_area_struct *right = + rb_entry(vma->vm_rb.rb_right, +@@ -1857,10 +1872,11 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) + + check_current: + /* Check if current node has a suitable gap */ +- gap_end = vma->vm_start; ++ gap_end = vm_start_gap(vma); + if (gap_end < low_limit) + return -ENOMEM; +- if (gap_start <= high_limit && gap_end - gap_start >= length) ++ if (gap_start <= high_limit && ++ gap_end > gap_start && gap_end - gap_start >= length) + goto found; + + /* Visit left subtree if it looks promising */ +@@ -1883,7 +1899,7 @@ check_current: + struct vm_area_struct, vm_rb); + if (prev == vma->vm_rb.rb_right) { + gap_start = vma->vm_prev ? +- vma->vm_prev->vm_end : 0; ++ vm_end_gap(vma->vm_prev) : 0; + goto check_current; + } + } +@@ -1921,7 +1937,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) + { + struct mm_struct *mm = current->mm; +- struct vm_area_struct *vma; ++ struct vm_area_struct *vma, *prev; + struct vm_unmapped_area_info info; + + if (len > TASK_SIZE - mmap_min_addr) +@@ -1932,9 +1948,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + + if (addr) { + addr = PAGE_ALIGN(addr); +- vma = find_vma(mm, addr); ++ vma = find_vma_prev(mm, addr, &prev); + if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma)) && ++ (!prev || addr >= vm_end_gap(prev))) + return addr; + } + +@@ -1957,7 +1974,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + const unsigned long len, const unsigned long pgoff, + const unsigned long flags) + { +- struct vm_area_struct *vma; ++ struct vm_area_struct *vma, *prev; + struct mm_struct *mm = current->mm; + unsigned long addr = addr0; + struct vm_unmapped_area_info info; +@@ -1972,9 +1989,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + /* requesting a specific address */ + if (addr) { + addr = PAGE_ALIGN(addr); +- vma = find_vma(mm, addr); ++ vma = find_vma_prev(mm, addr, &prev); + if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && +- (!vma || addr + len <= vma->vm_start)) ++ (!vma || addr + len <= vm_start_gap(vma)) && ++ (!prev || addr >= vm_end_gap(prev))) + return addr; + } + +@@ -2099,21 +2117,19 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, + * update accounting. This is shared with both the + * grow-up and grow-down cases. + */ +-static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, unsigned long grow) ++static int acct_stack_growth(struct vm_area_struct *vma, ++ unsigned long size, unsigned long grow) + { + struct mm_struct *mm = vma->vm_mm; + struct rlimit *rlim = current->signal->rlim; +- unsigned long new_start, actual_size; ++ unsigned long new_start; + + /* address space limit tests */ + if (!may_expand_vm(mm, grow)) + return -ENOMEM; + + /* Stack limit test */ +- actual_size = size; +- if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN))) +- actual_size -= PAGE_SIZE; +- if (actual_size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur)) ++ if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur)) + return -ENOMEM; + + /* mlock limit tests */ +@@ -2151,16 +2167,32 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns + int expand_upwards(struct vm_area_struct *vma, unsigned long address) + { + struct mm_struct *mm = vma->vm_mm; ++ struct vm_area_struct *next; ++ unsigned long gap_addr; + int error = 0; + + if (!(vma->vm_flags & VM_GROWSUP)) + return -EFAULT; + +- /* Guard against wrapping around to address 0. */ +- if (address < PAGE_ALIGN(address+4)) +- address = PAGE_ALIGN(address+4); +- else ++ /* Guard against exceeding limits of the address space. */ ++ address &= PAGE_MASK; ++ if (address >= TASK_SIZE) + return -ENOMEM; ++ address += PAGE_SIZE; ++ ++ /* Enforce stack_guard_gap */ ++ gap_addr = address + stack_guard_gap; ++ ++ /* Guard against overflow */ ++ if (gap_addr < address || gap_addr > TASK_SIZE) ++ gap_addr = TASK_SIZE; ++ ++ next = vma->vm_next; ++ if (next && next->vm_start < gap_addr) { ++ if (!(next->vm_flags & VM_GROWSUP)) ++ return -ENOMEM; ++ /* Check that both stack segments have the same anon_vma? */ ++ } + + /* We must make sure the anon_vma is allocated. */ + if (unlikely(anon_vma_prepare(vma))) +@@ -2206,7 +2238,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) + if (vma->vm_next) + vma_gap_update(vma->vm_next); + else +- mm->highest_vm_end = address; ++ mm->highest_vm_end = vm_end_gap(vma); + spin_unlock(&mm->page_table_lock); + + perf_event_mmap(vma); +@@ -2227,6 +2259,8 @@ int expand_downwards(struct vm_area_struct *vma, + unsigned long address) + { + struct mm_struct *mm = vma->vm_mm; ++ struct vm_area_struct *prev; ++ unsigned long gap_addr; + int error; + + address &= PAGE_MASK; +@@ -2234,6 +2268,17 @@ int expand_downwards(struct vm_area_struct *vma, + if (error) + return error; + ++ /* Enforce stack_guard_gap */ ++ gap_addr = address - stack_guard_gap; ++ if (gap_addr > address) ++ return -ENOMEM; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end > gap_addr) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ /* Check that both stack segments have the same anon_vma? */ ++ } ++ + /* We must make sure the anon_vma is allocated. */ + if (unlikely(anon_vma_prepare(vma))) + return -ENOMEM; +@@ -2289,28 +2334,25 @@ int expand_downwards(struct vm_area_struct *vma, + return error; + } + +-/* +- * Note how expand_stack() refuses to expand the stack all the way to +- * abut the next virtual mapping, *unless* that mapping itself is also +- * a stack mapping. We want to leave room for a guard page, after all +- * (the guard page itself is not added here, that is done by the +- * actual page faulting logic) +- * +- * This matches the behavior of the guard page logic (see mm/memory.c: +- * check_stack_guard_page()), which only allows the guard page to be +- * removed under these circumstances. +- */ ++/* enforced gap between the expanding stack and other mappings. */ ++unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT; ++ ++static int __init cmdline_parse_stack_guard_gap(char *p) ++{ ++ unsigned long val; ++ char *endptr; ++ ++ val = simple_strtoul(p, &endptr, 10); ++ if (!*endptr) ++ stack_guard_gap = val << PAGE_SHIFT; ++ ++ return 0; ++} ++__setup("stack_guard_gap=", cmdline_parse_stack_guard_gap); ++ + #ifdef CONFIG_STACK_GROWSUP + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { +- struct vm_area_struct *next; +- +- address &= PAGE_MASK; +- next = vma->vm_next; +- if (next && next->vm_start == address + PAGE_SIZE) { +- if (!(next->vm_flags & VM_GROWSUP)) +- return -ENOMEM; +- } + return expand_upwards(vma, address); + } + +@@ -2332,14 +2374,6 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) + #else + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { +- struct vm_area_struct *prev; +- +- address &= PAGE_MASK; +- prev = vma->vm_prev; +- if (prev && prev->vm_end == address) { +- if (!(prev->vm_flags & VM_GROWSDOWN)) +- return -ENOMEM; +- } + return expand_downwards(vma, address); + } + +@@ -2437,7 +2471,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, + vma->vm_prev = prev; + vma_gap_update(vma); + } else +- mm->highest_vm_end = prev ? prev->vm_end : 0; ++ mm->highest_vm_end = prev ? vm_end_gap(prev) : 0; + tail_vma->vm_next = NULL; + + /* Kill the cache */ +diff --git a/mm/swap_cgroup.c b/mm/swap_cgroup.c +index b5f7f24b8dd1..40dd0f9b00d6 100644 +--- a/mm/swap_cgroup.c ++++ b/mm/swap_cgroup.c +@@ -48,6 +48,9 @@ static int swap_cgroup_prepare(int type) + if (!page) + goto not_enough_page; + ctrl->map[idx] = page; ++ ++ if (!(idx % SWAP_CLUSTER_MAX)) ++ cond_resched(); + } + return 0; + not_enough_page: +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 980e9e9b6684..24ba31601fc9 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -66,6 +66,8 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata, + 2 + (IEEE80211_MAX_SUPP_RATES - 8) + + 2 + sizeof(struct ieee80211_ht_cap) + + 2 + sizeof(struct ieee80211_ht_operation) + ++ 2 + sizeof(struct ieee80211_vht_cap) + ++ 2 + sizeof(struct ieee80211_vht_operation) + + ifibss->ie_len; + presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); + if (!presp) +@@ -486,14 +488,14 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, + struct beacon_data *presp, *old_presp; + struct cfg80211_bss *cbss; + const struct cfg80211_bss_ies *ies; +- u16 capability = 0; ++ u16 capability = WLAN_CAPABILITY_IBSS; + u64 tsf; + int ret = 0; + + sdata_assert_lock(sdata); + + if (ifibss->privacy) +- capability = WLAN_CAPABILITY_PRIVACY; ++ capability |= WLAN_CAPABILITY_PRIVACY; + + cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan, + ifibss->bssid, ifibss->ssid, +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 9f0915f72702..3bcabc2ba4a6 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1455,12 +1455,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) + */ + if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) && + !ieee80211_has_morefrags(hdr->frame_control) && ++ !ieee80211_is_back_req(hdr->frame_control) && + !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && + (rx->sdata->vif.type == NL80211_IFTYPE_AP || + rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && +- /* PM bit is only checked in frames where it isn't reserved, ++ /* ++ * PM bit is only checked in frames where it isn't reserved, + * in AP mode it's reserved in non-bufferable management frames + * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field) ++ * BAR frames should be ignored as specified in ++ * IEEE 802.11-2012 10.2.1.2. + */ + (!ieee80211_is_mgmt(hdr->frame_control) || + ieee80211_is_bufferable_mmpdu(hdr->frame_control))) { +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index d824c38971ed..e19ea1c53afa 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -16,6 +16,7 @@ + #include <asm/unaligned.h> + #include <net/mac80211.h> + #include <crypto/aes.h> ++#include <crypto/algapi.h> + + #include "ieee80211_i.h" + #include "michael.h" +@@ -152,7 +153,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; + key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; + michael_mic(key, hdr, data, data_len, mic); +- if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) ++ if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN)) + goto mic_fail; + + /* remove Michael MIC from payload */ +@@ -1044,7 +1045,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + bip_aad(skb, aad); + ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mic); +- if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { ++ if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_UNUSABLE; + } +@@ -1094,7 +1095,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + bip_aad(skb, aad); + ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mic); +- if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { ++ if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_UNUSABLE; + } +@@ -1198,7 +1199,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) + if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, + skb->data + 24, skb->len - 24, + mic) < 0 || +- memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { ++ crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_gmac.icverrors++; + return RX_DROP_UNUSABLE; + } |