diff options
author | Mike Pagano <mpagano@gentoo.org> | 2016-12-15 18:41:14 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2016-12-15 18:41:14 -0500 |
commit | ba8283a81206007982898ff1867ce119c3c8bba6 (patch) | |
tree | 74d0b3a827967d1d14c5567ae31f7aa2860288e8 | |
parent | Linux patch 4.4.38 (diff) | |
download | linux-patches-ba8283a81206007982898ff1867ce119c3c8bba6.tar.gz linux-patches-ba8283a81206007982898ff1867ce119c3c8bba6.tar.bz2 linux-patches-ba8283a81206007982898ff1867ce119c3c8bba6.zip |
Linux patch 4.4.394.4-43
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1038_linux-4.4.39.patch | 513 |
2 files changed, 517 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 5f964363..27da6792 100644 --- a/0000_README +++ b/0000_README @@ -195,6 +195,10 @@ Patch: 1037_linux-4.4.38.patch From: http://www.kernel.org Desc: Linux 4.4.38 +Patch: 1038_linux-4.4.39.patch +From: http://www.kernel.org +Desc: Linux 4.4.39 + 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/1038_linux-4.4.39.patch b/1038_linux-4.4.39.patch new file mode 100644 index 00000000..5b3ea9d8 --- /dev/null +++ b/1038_linux-4.4.39.patch @@ -0,0 +1,513 @@ +diff --git a/Makefile b/Makefile +index 6876efe0d735..88d26a632bef 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 38 ++SUBLEVEL = 39 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h +index 007a69fc4f40..5f3ab8c1db55 100644 +--- a/arch/arm64/include/asm/futex.h ++++ b/arch/arm64/include/asm/futex.h +@@ -121,6 +121,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + return -EFAULT; + + asm volatile("// futex_atomic_cmpxchg_inatomic\n" ++ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN) + " prfm pstl1strm, %2\n" + "1: ldxr %w1, %2\n" + " sub %w3, %w1, %w4\n" +@@ -137,6 +138,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + " .align 3\n" + " .quad 1b, 4b, 2b, 4b\n" + " .popsection\n" ++ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN) + : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp) + : "r" (oldval), "r" (newval), "Ir" (-EFAULT) + : "memory"); +diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h +index d28fa8fe26fe..c598d847d56b 100644 +--- a/arch/m68k/include/asm/delay.h ++++ b/arch/m68k/include/asm/delay.h +@@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs) + */ + #define HZSCALE (268435456 / (1000000 / HZ)) + +-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000)); ++#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000)) + + #endif /* defined(_M68K_DELAY_H) */ +diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h +index c2c43f714684..3a4ed9f91d57 100644 +--- a/arch/parisc/include/asm/pgtable.h ++++ b/arch/parisc/include/asm/pgtable.h +@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) + unsigned long flags; \ + spin_lock_irqsave(&pa_tlb_lock, flags); \ + old_pte = *ptep; \ +- set_pte(ptep, pteval); \ + if (pte_inserted(old_pte)) \ + purge_tlb_entries(mm, addr); \ ++ set_pte(ptep, pteval); \ + spin_unlock_irqrestore(&pa_tlb_lock, flags); \ + } while (0) + +@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned + spin_unlock_irqrestore(&pa_tlb_lock, flags); + return 0; + } +- set_pte(ptep, pte_mkold(pte)); + purge_tlb_entries(vma->vm_mm, addr); ++ set_pte(ptep, pte_mkold(pte)); + spin_unlock_irqrestore(&pa_tlb_lock, flags); + return 1; + } +@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + + spin_lock_irqsave(&pa_tlb_lock, flags); + old_pte = *ptep; +- set_pte(ptep, __pte(0)); + if (pte_inserted(old_pte)) + purge_tlb_entries(mm, addr); ++ set_pte(ptep, __pte(0)); + spin_unlock_irqrestore(&pa_tlb_lock, flags); + + return old_pte; +@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, + { + unsigned long flags; + spin_lock_irqsave(&pa_tlb_lock, flags); +- set_pte(ptep, pte_wrprotect(*ptep)); + purge_tlb_entries(mm, addr); ++ set_pte(ptep, pte_wrprotect(*ptep)); + spin_unlock_irqrestore(&pa_tlb_lock, flags); + } + +diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c +index fd5979f28ada..6857a104b2f9 100644 +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -375,6 +375,15 @@ void __init parisc_setup_cache_timing(void) + + /* calculate TLB flush threshold */ + ++ /* On SMP machines, skip the TLB measure of kernel text which ++ * has been mapped as huge pages. */ ++ if (num_online_cpus() > 1 && !parisc_requires_coherency()) { ++ threshold = max(cache_info.it_size, cache_info.dt_size); ++ threshold *= PAGE_SIZE; ++ threshold /= num_online_cpus(); ++ goto set_tlb_threshold; ++ } ++ + alltime = mfctl(16); + flush_tlb_all(); + alltime = mfctl(16) - alltime; +@@ -393,6 +402,8 @@ void __init parisc_setup_cache_timing(void) + alltime, size, rangetime); + + threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime); ++ ++set_tlb_threshold: + if (threshold) + parisc_tlb_flush_threshold = threshold; + printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", +diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S +index 675521919229..a4761b772406 100644 +--- a/arch/parisc/kernel/pacache.S ++++ b/arch/parisc/kernel/pacache.S +@@ -886,19 +886,10 @@ ENTRY(flush_dcache_page_asm) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) +- cmpb,COND(<<) %r28, %r25,1b ++ cmpb,COND(<<) %r28, %r25,1b + fdc,m r31(%r28) + + sync +- +-#ifdef CONFIG_PA20 +- pdtlb,l %r0(%r25) +-#else +- tlb_lock %r20,%r21,%r22 +- pdtlb %r0(%r25) +- tlb_unlock %r20,%r21,%r22 +-#endif +- + bv %r0(%r2) + nop + .exit +@@ -973,17 +964,6 @@ ENTRY(flush_icache_page_asm) + fic,m %r31(%sr4,%r28) + + sync +- +-#ifdef CONFIG_PA20 +- pdtlb,l %r0(%r28) +- pitlb,l %r0(%sr4,%r25) +-#else +- tlb_lock %r20,%r21,%r22 +- pdtlb %r0(%r28) +- pitlb %r0(%sr4,%r25) +- tlb_unlock %r20,%r21,%r22 +-#endif +- + bv %r0(%r2) + nop + .exit +diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c +index c07bfb52275e..300382e5a2cc 100644 +--- a/arch/powerpc/kernel/eeh_driver.c ++++ b/arch/powerpc/kernel/eeh_driver.c +@@ -612,8 +612,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) + + /* Clear frozen state */ + rc = eeh_clear_pe_frozen_state(pe, false); +- if (rc) ++ if (rc) { ++ pci_unlock_rescan_remove(); + return rc; ++ } + + /* Give the system 5 seconds to finish running the user-space + * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, +diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c +index a3aeb2cc361e..1a8256dd6729 100644 +--- a/arch/x86/kernel/cpu/perf_event.c ++++ b/arch/x86/kernel/cpu/perf_event.c +@@ -67,7 +67,7 @@ u64 x86_perf_event_update(struct perf_event *event) + int shift = 64 - x86_pmu.cntval_bits; + u64 prev_raw_count, new_raw_count; + int idx = hwc->idx; +- s64 delta; ++ u64 delta; + + if (idx == INTEL_PMC_IDX_FIXED_BTS) + return 0; +diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c +index 5f82cd59f0e5..5cc2242d77c6 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel.c ++++ b/arch/x86/kernel/cpu/perf_event_intel.c +@@ -3636,7 +3636,7 @@ __init int intel_pmu_init(void) + + /* Support full width counters using alternative MSR range */ + if (x86_pmu.intel_cap.full_width_write) { +- x86_pmu.max_period = x86_pmu.cntval_mask; ++ x86_pmu.max_period = x86_pmu.cntval_mask >> 1; + x86_pmu.perfctr = MSR_IA32_PMC0; + pr_cont("full-width counters, "); + } +diff --git a/crypto/Makefile b/crypto/Makefile +index f7aba923458d..82fbff180ad3 100644 +--- a/crypto/Makefile ++++ b/crypto/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o + + $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h + $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h ++$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h + clean-files += rsapubkey-asn1.c rsapubkey-asn1.h + clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h + +diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c +index fe5b495a434d..a0ceb41d5ccc 100644 +--- a/crypto/mcryptd.c ++++ b/crypto/mcryptd.c +@@ -258,18 +258,22 @@ out_free_inst: + goto out; + } + +-static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type, ++static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type, + u32 *mask) + { + struct crypto_attr_type *algt; + + algt = crypto_get_attr_type(tb); + if (IS_ERR(algt)) +- return; +- if ((algt->type & CRYPTO_ALG_INTERNAL)) +- *type |= CRYPTO_ALG_INTERNAL; +- if ((algt->mask & CRYPTO_ALG_INTERNAL)) +- *mask |= CRYPTO_ALG_INTERNAL; ++ return false; ++ ++ *type |= algt->type & CRYPTO_ALG_INTERNAL; ++ *mask |= algt->mask & CRYPTO_ALG_INTERNAL; ++ ++ if (*type & *mask & CRYPTO_ALG_INTERNAL) ++ return true; ++ else ++ return false; + } + + static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm) +@@ -498,7 +502,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, + u32 mask = 0; + int err; + +- mcryptd_check_internal(tb, &type, &mask); ++ if (!mcryptd_check_internal(tb, &type, &mask)) ++ return -EINVAL; + + salg = shash_attr_alg(tb[1], type, mask); + if (IS_ERR(salg)) +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 1770c455dfdd..1648de80e230 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1378,8 +1378,14 @@ static ssize_t hot_remove_store(struct class *class, + return ret ? ret : count; + } + ++/* ++ * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a ++ * sense that reading from this file does alter the state of your system -- it ++ * creates a new un-initialized zram device and returns back this device's ++ * device_id (or an error code if it fails to create a new device). ++ */ + static struct class_attribute zram_control_class_attrs[] = { +- __ATTR_RO(hot_add), ++ __ATTR(hot_add, 0400, hot_add_show, NULL), + __ATTR_WO(hot_remove), + __ATTR_NULL, + }; +diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c +index 5a2e341a6d1e..91be4575b524 100644 +--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c +@@ -872,23 +872,25 @@ lbl_free_candev: + static void peak_usb_disconnect(struct usb_interface *intf) + { + struct peak_usb_device *dev; ++ struct peak_usb_device *dev_prev_siblings; + + /* unregister as many netdev devices as siblings */ +- for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) { ++ for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) { + struct net_device *netdev = dev->netdev; + char name[IFNAMSIZ]; + ++ dev_prev_siblings = dev->prev_siblings; + dev->state &= ~PCAN_USB_STATE_CONNECTED; + strncpy(name, netdev->name, IFNAMSIZ); + + unregister_netdev(netdev); +- free_candev(netdev); + + kfree(dev->cmd_buf); + dev->next_siblings = NULL; + if (dev->adapter->dev_free) + dev->adapter->dev_free(dev); + ++ free_candev(netdev); + dev_info(&intf->dev, "%s removed\n", name); + } + +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index d2ca8c38f9c4..3ea9aae2387d 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -131,22 +131,16 @@ enum { + { .notifier_call = fn, .priority = pri }; \ + __register_cpu_notifier(&fn##_nb); \ + } +-#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ +-#define cpu_notifier(fn, pri) do { (void)(fn); } while (0) +-#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0) +-#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ + +-#ifdef CONFIG_HOTPLUG_CPU + extern int register_cpu_notifier(struct notifier_block *nb); + extern int __register_cpu_notifier(struct notifier_block *nb); + extern void unregister_cpu_notifier(struct notifier_block *nb); + extern void __unregister_cpu_notifier(struct notifier_block *nb); +-#else + +-#ifndef MODULE +-extern int register_cpu_notifier(struct notifier_block *nb); +-extern int __register_cpu_notifier(struct notifier_block *nb); +-#else ++#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ ++#define cpu_notifier(fn, pri) do { (void)(fn); } while (0) ++#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0) ++ + static inline int register_cpu_notifier(struct notifier_block *nb) + { + return 0; +@@ -156,7 +150,6 @@ static inline int __register_cpu_notifier(struct notifier_block *nb) + { + return 0; + } +-#endif + + static inline void unregister_cpu_notifier(struct notifier_block *nb) + { +diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h +index 9692cda5f8fc..c48d93a28d1a 100644 +--- a/include/uapi/linux/can.h ++++ b/include/uapi/linux/can.h +@@ -196,5 +196,6 @@ struct can_filter { + }; + + #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */ ++#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */ + + #endif /* !_UAPI_CAN_H */ +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 85ff5e26e23b..cd6d1258554e 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -223,8 +223,6 @@ static int cpu_notify(unsigned long val, void *v) + return __cpu_notify(val, v, -1, NULL); + } + +-#ifdef CONFIG_HOTPLUG_CPU +- + static void cpu_notify_nofail(unsigned long val, void *v) + { + BUG_ON(cpu_notify(val, v)); +@@ -246,6 +244,7 @@ void __unregister_cpu_notifier(struct notifier_block *nb) + } + EXPORT_SYMBOL(__unregister_cpu_notifier); + ++#ifdef CONFIG_HOTPLUG_CPU + /** + * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU + * @cpu: a CPU id +diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c +index 8251e75dd9c0..b066724d7a5b 100644 +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiters(struct rt_mutex *lock) + + static void fixup_rt_mutex_waiters(struct rt_mutex *lock) + { +- if (!rt_mutex_has_waiters(lock)) +- clear_rt_mutex_waiters(lock); ++ unsigned long owner, *p = (unsigned long *) &lock->owner; ++ ++ if (rt_mutex_has_waiters(lock)) ++ return; ++ ++ /* ++ * The rbtree has no waiters enqueued, now make sure that the ++ * lock->owner still has the waiters bit set, otherwise the ++ * following can happen: ++ * ++ * CPU 0 CPU 1 CPU2 ++ * l->owner=T1 ++ * rt_mutex_lock(l) ++ * lock(l->lock) ++ * l->owner = T1 | HAS_WAITERS; ++ * enqueue(T2) ++ * boost() ++ * unlock(l->lock) ++ * block() ++ * ++ * rt_mutex_lock(l) ++ * lock(l->lock) ++ * l->owner = T1 | HAS_WAITERS; ++ * enqueue(T3) ++ * boost() ++ * unlock(l->lock) ++ * block() ++ * signal(->T2) signal(->T3) ++ * lock(l->lock) ++ * dequeue(T2) ++ * deboost() ++ * unlock(l->lock) ++ * lock(l->lock) ++ * dequeue(T3) ++ * ==> wait list is empty ++ * deboost() ++ * unlock(l->lock) ++ * lock(l->lock) ++ * fixup_rt_mutex_waiters() ++ * if (wait_list_empty(l) { ++ * l->owner = owner ++ * owner = l->owner & ~HAS_WAITERS; ++ * ==> l->owner = T1 ++ * } ++ * lock(l->lock) ++ * rt_mutex_unlock(l) fixup_rt_mutex_waiters() ++ * if (wait_list_empty(l) { ++ * owner = l->owner & ~HAS_WAITERS; ++ * cmpxchg(l->owner, T1, NULL) ++ * ===> Success (l->owner = NULL) ++ * ++ * l->owner = owner ++ * ==> l->owner = T1 ++ * } ++ * ++ * With the check for the waiter bit in place T3 on CPU2 will not ++ * overwrite. All tasks fiddling with the waiters bit are ++ * serialized by l->lock, so nothing else can modify the waiters ++ * bit. If the bit is set then nothing can change l->owner either ++ * so the simple RMW is safe. The cmpxchg() will simply fail if it ++ * happens in the middle of the RMW because the waiters bit is ++ * still set. ++ */ ++ owner = READ_ONCE(*p); ++ if (owner & RT_MUTEX_HAS_WAITERS) ++ WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS); + } + + /* +diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h +index 4f5f83c7d2d3..e317e1cbb3eb 100644 +--- a/kernel/locking/rtmutex_common.h ++++ b/kernel/locking/rtmutex_common.h +@@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p) + + static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock) + { +- return (struct task_struct *) +- ((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL); ++ unsigned long owner = (unsigned long) READ_ONCE(lock->owner); ++ ++ return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL); + } + + /* +diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c +index 83b0ca27a45e..f2079acb555d 100644 +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -2764,7 +2764,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv, + &tvlv_tt_data, + &tt_change, + &tt_len); +- if (!tt_len) ++ if (!tt_len || !tvlv_len) + goto unlock; + + /* Copy the last orig_node's OGM buffer */ +@@ -2782,7 +2782,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv, + &tvlv_tt_data, + &tt_change, + &tt_len); +- if (!tt_len) ++ if (!tt_len || !tvlv_len) + goto out; + + /* fill the rest of the tvlv with the real TT entries */ +diff --git a/net/can/raw.c b/net/can/raw.c +index 2e67b1423cd3..56af689ca999 100644 +--- a/net/can/raw.c ++++ b/net/can/raw.c +@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, + if (optlen % sizeof(struct can_filter) != 0) + return -EINVAL; + ++ if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter)) ++ return -EINVAL; ++ + count = optlen / sizeof(struct can_filter); + + if (count > 1) { |