mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-22 06:41:23 +00:00
1488 lines
49 KiB
Diff
1488 lines
49 KiB
Diff
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;
|
|
}
|