diff options
author | Mike Pagano <mpagano@gentoo.org> | 2017-08-25 06:53:06 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2018-11-21 09:57:21 -0500 |
commit | 07618d99beee5ff1657bed13752ff0a339762885 (patch) | |
tree | 3fc28d1e4578b6613c141ba47a33db342c201607 /1083_linux-4.4.84.patch | |
parent | Linux patch 4.4.83 (diff) | |
download | linux-patches-07618d99beee5ff1657bed13752ff0a339762885.tar.gz linux-patches-07618d99beee5ff1657bed13752ff0a339762885.tar.bz2 linux-patches-07618d99beee5ff1657bed13752ff0a339762885.zip |
Linux patch 4.4.84
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
Diffstat (limited to '1083_linux-4.4.84.patch')
-rw-r--r-- | 1083_linux-4.4.84.patch | 761 |
1 files changed, 761 insertions, 0 deletions
diff --git a/1083_linux-4.4.84.patch b/1083_linux-4.4.84.patch new file mode 100644 index 00000000..74a42d33 --- /dev/null +++ b/1083_linux-4.4.84.patch @@ -0,0 +1,761 @@ +diff --git a/Makefile b/Makefile +index 7f67b35caf99..9d77ac063ec0 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 83 ++SUBLEVEL = 84 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index 9e11dbe1cec3..329c127e13dc 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -121,10 +121,10 @@ typedef struct user_fpsimd_state elf_fpregset_t; + + /* + * This is the base location for PIE (ET_DYN with INTERP) loads. On +- * 64-bit, this is raised to 4GB to leave the entire 32-bit address ++ * 64-bit, this is above 4GB to leave the entire 32-bit address + * space open for things that want to use the area for 32-bit pointers. + */ +-#define ELF_ET_DYN_BASE 0x100000000UL ++#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) + + /* + * When the program starts, a1 contains a pointer to a function to be +diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S +index 1cd792db15ef..1eab79c9ac48 100644 +--- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S ++++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S +@@ -117,11 +117,10 @@ + .set T1, REG_T1 + .endm + +-#define K_BASE %r8 + #define HASH_PTR %r9 ++#define BLOCKS_CTR %r8 + #define BUFFER_PTR %r10 + #define BUFFER_PTR2 %r13 +-#define BUFFER_END %r11 + + #define PRECALC_BUF %r14 + #define WK_BUF %r15 +@@ -205,14 +204,14 @@ + * blended AVX2 and ALU instruction scheduling + * 1 vector iteration per 8 rounds + */ +- vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP ++ vmovdqu (i * 2)(BUFFER_PTR), W_TMP + .elseif ((i & 7) == 1) +- vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\ ++ vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\ + WY_TMP, WY_TMP + .elseif ((i & 7) == 2) + vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY + .elseif ((i & 7) == 4) +- vpaddd K_XMM(K_BASE), WY, WY_TMP ++ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP + .elseif ((i & 7) == 7) + vmovdqu WY_TMP, PRECALC_WK(i&~7) + +@@ -255,7 +254,7 @@ + vpxor WY, WY_TMP, WY_TMP + .elseif ((i & 7) == 7) + vpxor WY_TMP2, WY_TMP, WY +- vpaddd K_XMM(K_BASE), WY, WY_TMP ++ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP + vmovdqu WY_TMP, PRECALC_WK(i&~7) + + PRECALC_ROTATE_WY +@@ -291,7 +290,7 @@ + vpsrld $30, WY, WY + vpor WY, WY_TMP, WY + .elseif ((i & 7) == 7) +- vpaddd K_XMM(K_BASE), WY, WY_TMP ++ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP + vmovdqu WY_TMP, PRECALC_WK(i&~7) + + PRECALC_ROTATE_WY +@@ -446,6 +445,16 @@ + + .endm + ++/* Add constant only if (%2 > %3) condition met (uses RTA as temp) ++ * %1 + %2 >= %3 ? %4 : 0 ++ */ ++.macro ADD_IF_GE a, b, c, d ++ mov \a, RTA ++ add $\d, RTA ++ cmp $\c, \b ++ cmovge RTA, \a ++.endm ++ + /* + * macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining + */ +@@ -463,13 +472,16 @@ + lea (2*4*80+32)(%rsp), WK_BUF + + # Precalc WK for first 2 blocks +- PRECALC_OFFSET = 0 ++ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64 + .set i, 0 + .rept 160 + PRECALC i + .set i, i + 1 + .endr +- PRECALC_OFFSET = 128 ++ ++ /* Go to next block if needed */ ++ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128 ++ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 + xchg WK_BUF, PRECALC_BUF + + .align 32 +@@ -479,8 +491,8 @@ _loop: + * we use K_BASE value as a signal of a last block, + * it is set below by: cmovae BUFFER_PTR, K_BASE + */ +- cmp K_BASE, BUFFER_PTR +- jne _begin ++ test BLOCKS_CTR, BLOCKS_CTR ++ jnz _begin + .align 32 + jmp _end + .align 32 +@@ -512,10 +524,10 @@ _loop0: + .set j, j+2 + .endr + +- add $(2*64), BUFFER_PTR /* move to next odd-64-byte block */ +- cmp BUFFER_END, BUFFER_PTR /* is current block the last one? */ +- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ +- ++ /* Update Counter */ ++ sub $1, BLOCKS_CTR ++ /* Move to the next block only if needed*/ ++ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128 + /* + * rounds + * 60,62,64,66,68 +@@ -532,8 +544,8 @@ _loop0: + UPDATE_HASH 12(HASH_PTR), D + UPDATE_HASH 16(HASH_PTR), E + +- cmp K_BASE, BUFFER_PTR /* is current block the last one? */ +- je _loop ++ test BLOCKS_CTR, BLOCKS_CTR ++ jz _loop + + mov TB, B + +@@ -575,10 +587,10 @@ _loop2: + .set j, j+2 + .endr + +- add $(2*64), BUFFER_PTR2 /* move to next even-64-byte block */ +- +- cmp BUFFER_END, BUFFER_PTR2 /* is current block the last one */ +- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ ++ /* update counter */ ++ sub $1, BLOCKS_CTR ++ /* Move to the next block only if needed*/ ++ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 + + jmp _loop3 + _loop3: +@@ -641,19 +653,12 @@ _loop3: + + avx2_zeroupper + +- lea K_XMM_AR(%rip), K_BASE +- ++ /* Setup initial values */ + mov CTX, HASH_PTR + mov BUF, BUFFER_PTR +- lea 64(BUF), BUFFER_PTR2 +- +- shl $6, CNT /* mul by 64 */ +- add BUF, CNT +- add $64, CNT +- mov CNT, BUFFER_END + +- cmp BUFFER_END, BUFFER_PTR2 +- cmovae K_BASE, BUFFER_PTR2 ++ mov BUF, BUFFER_PTR2 ++ mov CNT, BLOCKS_CTR + + xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP + +diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c +index 7de207a11014..dd14616b7739 100644 +--- a/arch/x86/crypto/sha1_ssse3_glue.c ++++ b/arch/x86/crypto/sha1_ssse3_glue.c +@@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32 *digest, const char *data, + + static bool avx2_usable(void) + { +- if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) ++ if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) + && boot_cpu_has(X86_FEATURE_BMI1) + && boot_cpu_has(X86_FEATURE_BMI2)) + return true; +diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S +index a55697d19824..cc0f2f5da19b 100644 +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -1190,6 +1190,8 @@ ENTRY(nmi) + * other IST entries. + */ + ++ ASM_CLAC ++ + /* Use %rdx as our temp variable throughout */ + pushq %rdx + +diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h +index 07cf288b692e..bcd3d6199464 100644 +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -247,11 +247,11 @@ extern int force_personality32; + + /* + * This is the base location for PIE (ET_DYN with INTERP) loads. On +- * 64-bit, this is raised to 4GB to leave the entire 32-bit address ++ * 64-bit, this is above 4GB to leave the entire 32-bit address + * space open for things that want to use the area for 32-bit pointers. + */ + #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ +- 0x100000000UL) ++ (TASK_SIZE / 3 * 2)) + + /* This yields a mask that user programs can use to figure out what + instruction set this CPU supports. This could be done in user space, +diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +index 8900400230c6..2cdae69d7e0b 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +@@ -153,7 +153,7 @@ static void __intel_pmu_lbr_enable(bool pmi) + */ + if (cpuc->lbr_sel) + lbr_select = cpuc->lbr_sel->config; +- if (!pmi) ++ if (!pmi && cpuc->lbr_sel) + wrmsrl(MSR_LBR_SELECT, lbr_select); + + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); +@@ -432,8 +432,10 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) + int out = 0; + int num = x86_pmu.lbr_nr; + +- if (cpuc->lbr_sel->config & LBR_CALL_STACK) +- num = tos; ++ if (cpuc->lbr_sel) { ++ if (cpuc->lbr_sel->config & LBR_CALL_STACK) ++ num = tos; ++ } + + for (i = 0; i < num; i++) { + unsigned long lbr_idx = (tos - i) & mask; +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index da5458dfb1e3..98d4e515587a 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1235,6 +1235,10 @@ static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN0100", 0 }, + { "ELAN0600", 0 }, + { "ELAN0605", 0 }, ++ { "ELAN0608", 0 }, ++ { "ELAN0605", 0 }, ++ { "ELAN0609", 0 }, ++ { "ELAN060B", 0 }, + { "ELAN1000", 0 }, + { } + }; +diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c +index 37199b9b2cfa..831a195cb806 100644 +--- a/drivers/irqchip/irq-atmel-aic-common.c ++++ b/drivers/irqchip/irq-atmel-aic-common.c +@@ -148,9 +148,9 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root) + struct device_node *np; + void __iomem *regs; + +- np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc"); ++ np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc"); + if (!np) +- np = of_find_compatible_node(root, NULL, ++ np = of_find_compatible_node(NULL, NULL, + "atmel,at91sam9x5-rtc"); + + if (!np) +@@ -202,7 +202,6 @@ void __init aic_common_irq_fixup(const struct of_device_id *matches) + return; + + match = of_match_node(matches, root); +- of_node_put(root); + + if (match) { + void (*fixup)(struct device_node *) = match->data; +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 582d8f0c6266..958af3b1af7f 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -707,6 +707,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ + {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ + {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ ++ {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ + {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ + {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ + {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ +diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c +index 7b0ca1551d7b..005ea632ba53 100644 +--- a/drivers/parisc/dino.c ++++ b/drivers/parisc/dino.c +@@ -954,7 +954,7 @@ static int __init dino_probe(struct parisc_device *dev) + + dino_dev->hba.dev = dev; + dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); +- dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ ++ dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND; + spin_lock_init(&dino_dev->dinosaur_pen); + dino_dev->hba.iommu = ccio_get_iommu(dev); + +diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c +index 2776cfe64c09..ef9cf4a21afe 100644 +--- a/drivers/usb/core/usb-acpi.c ++++ b/drivers/usb/core/usb-acpi.c +@@ -127,6 +127,22 @@ out: + */ + #define USB_ACPI_LOCATION_VALID (1 << 31) + ++static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent, ++ int raw) ++{ ++ struct acpi_device *adev; ++ ++ if (!parent) ++ return NULL; ++ ++ list_for_each_entry(adev, &parent->children, node) { ++ if (acpi_device_adr(adev) == raw) ++ return adev; ++ } ++ ++ return acpi_find_child_device(parent, raw, false); ++} ++ + static struct acpi_device *usb_acpi_find_companion(struct device *dev) + { + struct usb_device *udev; +@@ -174,8 +190,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) + int raw; + + raw = usb_hcd_find_raw_port_number(hcd, port1); +- adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev), +- raw, false); ++ ++ adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev), ++ raw); ++ + if (!adev) + return NULL; + } else { +@@ -186,7 +204,9 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) + return NULL; + + acpi_bus_get_device(parent_handle, &adev); +- adev = acpi_find_child_device(adev, port1, false); ++ ++ adev = usb_acpi_find_port(adev, port1); ++ + if (!adev) + return NULL; + } +diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c +index 4da69dbf7dca..1bdd02a6d6ac 100644 +--- a/drivers/xen/biomerge.c ++++ b/drivers/xen/biomerge.c +@@ -10,8 +10,7 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, + unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page)); + unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page)); + +- return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && +- ((bfn1 == bfn2) || ((bfn1+1) == bfn2)); ++ return bfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == bfn2; + #else + /* + * XXX: Add support for merging bio_vec when using different page +diff --git a/include/linux/pid.h b/include/linux/pid.h +index 23705a53abba..97b745ddece5 100644 +--- a/include/linux/pid.h ++++ b/include/linux/pid.h +@@ -8,7 +8,9 @@ enum pid_type + PIDTYPE_PID, + PIDTYPE_PGID, + PIDTYPE_SID, +- PIDTYPE_MAX ++ PIDTYPE_MAX, ++ /* only valid to __task_pid_nr_ns() */ ++ __PIDTYPE_TGID + }; + + /* +diff --git a/include/linux/sched.h b/include/linux/sched.h +index eff7c1fad26f..e887c8d6f395 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1949,31 +1949,8 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) + return tsk->tgid; + } + +-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); +- +-static inline pid_t task_tgid_vnr(struct task_struct *tsk) +-{ +- return pid_vnr(task_tgid(tsk)); +-} +- + + static inline int pid_alive(const struct task_struct *p); +-static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) +-{ +- pid_t pid = 0; +- +- rcu_read_lock(); +- if (pid_alive(tsk)) +- pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); +- rcu_read_unlock(); +- +- return pid; +-} +- +-static inline pid_t task_ppid_nr(const struct task_struct *tsk) +-{ +- return task_ppid_nr_ns(tsk, &init_pid_ns); +-} + + static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, + struct pid_namespace *ns) +@@ -1998,6 +1975,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk) + return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); + } + ++static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) ++{ ++ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); ++} ++ ++static inline pid_t task_tgid_vnr(struct task_struct *tsk) ++{ ++ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); ++} ++ ++static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) ++{ ++ pid_t pid = 0; ++ ++ rcu_read_lock(); ++ if (pid_alive(tsk)) ++ pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); ++ rcu_read_unlock(); ++ ++ return pid; ++} ++ ++static inline pid_t task_ppid_nr(const struct task_struct *tsk) ++{ ++ return task_ppid_nr_ns(tsk, &init_pid_ns); ++} ++ + /* obsolete, do not use */ + static inline pid_t task_pgrp_nr(struct task_struct *tsk) + { +diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c +index 939945a5649c..a162661c9d60 100644 +--- a/kernel/audit_watch.c ++++ b/kernel/audit_watch.c +@@ -457,13 +457,15 @@ void audit_remove_watch_rule(struct audit_krule *krule) + list_del(&krule->rlist); + + if (list_empty(&watch->rules)) { ++ /* ++ * audit_remove_watch() drops our reference to 'parent' which ++ * can get freed. Grab our own reference to be safe. ++ */ ++ audit_get_parent(parent); + audit_remove_watch(watch); +- +- if (list_empty(&parent->watches)) { +- audit_get_parent(parent); ++ if (list_empty(&parent->watches)) + fsnotify_destroy_mark(&parent->mark, audit_watch_group); +- audit_put_parent(parent); +- } ++ audit_put_parent(parent); + } + } + +diff --git a/kernel/pid.c b/kernel/pid.c +index 78b3d9f80d44..b17263be9082 100644 +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -526,8 +526,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, + if (!ns) + ns = task_active_pid_ns(current); + if (likely(pid_alive(task))) { +- if (type != PIDTYPE_PID) ++ if (type != PIDTYPE_PID) { ++ if (type == __PIDTYPE_TGID) ++ type = PIDTYPE_PID; + task = task->group_leader; ++ } + nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); + } + rcu_read_unlock(); +@@ -536,12 +539,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, + } + EXPORT_SYMBOL(__task_pid_nr_ns); + +-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +-{ +- return pid_nr_ns(task_tgid(tsk), ns); +-} +-EXPORT_SYMBOL(task_tgid_nr_ns); +- + struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) + { + return ns_of_pid(task_pid(tsk)); +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index e09b1a0e2cfe..c947014d128a 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -894,11 +894,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, + *policy |= (pol->flags & MPOL_MODE_FLAGS); + } + +- if (vma) { +- up_read(¤t->mm->mmap_sem); +- vma = NULL; +- } +- + err = 0; + if (nmask) { + if (mpol_store_user_nodemask(pol)) { +diff --git a/mm/migrate.c b/mm/migrate.c +index 72c09dea6526..afedcfab60e2 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -38,6 +38,7 @@ + #include <linux/balloon_compaction.h> + #include <linux/mmu_notifier.h> + #include <linux/page_idle.h> ++#include <linux/ptrace.h> + + #include <asm/tlbflush.h> + +@@ -1483,7 +1484,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, + const int __user *, nodes, + int __user *, status, int, flags) + { +- const struct cred *cred = current_cred(), *tcred; + struct task_struct *task; + struct mm_struct *mm; + int err; +@@ -1507,14 +1507,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, + + /* + * Check if this process has the right to modify the specified +- * process. The right exists if the process has administrative +- * capabilities, superuser privileges or the same +- * userid as the target process. ++ * process. Use the regular "ptrace_may_access()" checks. + */ +- tcred = __task_cred(task); +- if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) && +- !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) && +- !capable(CAP_SYS_NICE)) { ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) { + rcu_read_unlock(); + err = -EPERM; + goto out; +diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c +index 1a9545965c0d..531ca55f1af6 100644 +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -53,7 +53,11 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, + + rcu_read_lock(); + t = rcu_dereference(nf_ct_ext_types[id]); +- BUG_ON(t == NULL); ++ if (!t) { ++ rcu_read_unlock(); ++ return NULL; ++ } ++ + off = ALIGN(sizeof(struct nf_ct_ext), t->align); + len = off + t->len + var_alloc_len; + alloc_size = t->alloc_size + var_alloc_len; +@@ -88,7 +92,10 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, + + rcu_read_lock(); + t = rcu_dereference(nf_ct_ext_types[id]); +- BUG_ON(t == NULL); ++ if (!t) { ++ rcu_read_unlock(); ++ return NULL; ++ } + + newoff = ALIGN(old->len, t->align); + newlen = newoff + t->len + var_alloc_len; +@@ -186,6 +193,6 @@ void nf_ct_extend_unregister(struct nf_ct_ext_type *type) + RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); + update_alloc_size(type); + mutex_unlock(&nf_ct_ext_type_mutex); +- rcu_barrier(); /* Wait for completion of call_rcu()'s */ ++ synchronize_rcu(); + } + EXPORT_SYMBOL_GPL(nf_ct_extend_unregister); +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index c67f9c212dd1..e326c1d80416 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1530,19 +1530,14 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, + void __user *arg) + { + struct snd_seq_queue_info info; +- int result; + struct snd_seq_queue *q; + + if (copy_from_user(&info, arg, sizeof(info))) + return -EFAULT; + +- result = snd_seq_queue_alloc(client->number, info.locked, info.flags); +- if (result < 0) +- return result; +- +- q = queueptr(result); +- if (q == NULL) +- return -EINVAL; ++ q = snd_seq_queue_alloc(client->number, info.locked, info.flags); ++ if (IS_ERR(q)) ++ return PTR_ERR(q); + + info.queue = q->queue; + info.locked = q->locked; +@@ -1552,7 +1547,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, + if (! info.name[0]) + snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue); + strlcpy(q->name, info.name, sizeof(q->name)); +- queuefree(q); ++ snd_use_lock_free(&q->use_lock); + + if (copy_to_user(arg, &info, sizeof(info))) + return -EFAULT; +diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c +index 450c5187eecb..79e0c5604ef8 100644 +--- a/sound/core/seq/seq_queue.c ++++ b/sound/core/seq/seq_queue.c +@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void) + static void queue_use(struct snd_seq_queue *queue, int client, int use); + + /* allocate a new queue - +- * return queue index value or negative value for error ++ * return pointer to new queue or ERR_PTR(-errno) for error ++ * The new queue's use_lock is set to 1. It is the caller's responsibility to ++ * call snd_use_lock_free(&q->use_lock). + */ +-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) ++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) + { + struct snd_seq_queue *q; + + q = queue_new(client, locked); + if (q == NULL) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + q->info_flags = info_flags; + queue_use(q, client, 1); ++ snd_use_lock_use(&q->use_lock); + if (queue_list_add(q) < 0) { ++ snd_use_lock_free(&q->use_lock); + queue_delete(q); +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + } +- return q->queue; ++ return q; + } + + /* delete a queue - queue must be owned by the client */ +diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h +index 30c8111477f6..719093489a2c 100644 +--- a/sound/core/seq/seq_queue.h ++++ b/sound/core/seq/seq_queue.h +@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void); + + + /* create new queue (constructor) */ +-int snd_seq_queue_alloc(int client, int locked, unsigned int flags); ++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags); + + /* delete queue (destructor) */ + int snd_seq_queue_delete(int client, int queueid); +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 499b03c8281d..696de5ac69be 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -541,6 +541,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, + + if (size < sizeof(scale)) + return -ENOMEM; ++ if (cval->min_mute) ++ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE; + scale[2] = cval->dBmin; + scale[3] = cval->dBmax; + if (copy_to_user(_tlv, scale, sizeof(scale))) +diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h +index 3417ef347e40..2b4b067646ab 100644 +--- a/sound/usb/mixer.h ++++ b/sound/usb/mixer.h +@@ -64,6 +64,7 @@ struct usb_mixer_elem_info { + int cached; + int cache_val[MAX_CHANNELS]; + u8 initialized; ++ u8 min_mute; + void *private_data; + }; + +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 04991b009132..5d2fc5f58bfe 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, + if (unitid == 7 && cval->control == UAC_FU_VOLUME) + snd_dragonfly_quirk_db_scale(mixer, cval, kctl); + break; ++ /* lowest playback value is muted on C-Media devices */ ++ case USB_ID(0x0d8c, 0x000c): ++ case USB_ID(0x0d8c, 0x0014): ++ if (strstr(kctl->id.name, "Playback")) ++ cval->min_mute = 1; ++ break; + } + } + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 29f38e2b4ca9..1cc20d138dae 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1143,6 +1143,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) + case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ + case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ + case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ ++ case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ + case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ + case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */ + case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ |