mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 00:31:47 +00:00
1497 lines
49 KiB
Diff
1497 lines
49 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index eb120001bc12..c88ea5d8d19c 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 10
|
|
-SUBLEVEL = 95
|
|
+SUBLEVEL = 96
|
|
EXTRAVERSION =
|
|
NAME = TOSSUG Baby Fish
|
|
|
|
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
|
|
index 33a74fc45959..dfad98fda4f8 100644
|
|
--- a/arch/arm64/kernel/ptrace.c
|
|
+++ b/arch/arm64/kernel/ptrace.c
|
|
@@ -51,6 +51,12 @@
|
|
*/
|
|
void ptrace_disable(struct task_struct *child)
|
|
{
|
|
+ /*
|
|
+ * This would be better off in core code, but PTRACE_DETACH has
|
|
+ * grown its fair share of arch-specific worts and changing it
|
|
+ * is likely to cause regressions on obscure architectures.
|
|
+ */
|
|
+ user_disable_single_step(child);
|
|
}
|
|
|
|
/*
|
|
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
|
|
index ba7477efad5c..5b77586ef0af 100644
|
|
--- a/arch/arm64/mm/mmu.c
|
|
+++ b/arch/arm64/mm/mmu.c
|
|
@@ -348,6 +348,9 @@ void __init paging_init(void)
|
|
|
|
empty_zero_page = virt_to_page(zero_page);
|
|
|
|
+ /* Ensure the zero page is visible to the page table walker */
|
|
+ dsb();
|
|
+
|
|
/*
|
|
* TTBR0 is only used for the identity mapping at this stage. Make it
|
|
* point to zero page to avoid speculatively fetching new entries.
|
|
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
|
|
index 428da175d073..31b91602f055 100644
|
|
--- a/arch/mn10300/Kconfig
|
|
+++ b/arch/mn10300/Kconfig
|
|
@@ -2,6 +2,7 @@ config MN10300
|
|
def_bool y
|
|
select HAVE_OPROFILE
|
|
select HAVE_GENERIC_HARDIRQS
|
|
+ select HAVE_UID16
|
|
select GENERIC_IRQ_SHOW
|
|
select ARCH_WANT_IPC_PARSE_VERSION
|
|
select HAVE_ARCH_TRACEHOOK
|
|
@@ -37,9 +38,6 @@ config HIGHMEM
|
|
config NUMA
|
|
def_bool n
|
|
|
|
-config UID16
|
|
- def_bool y
|
|
-
|
|
config RWSEM_GENERIC_SPINLOCK
|
|
def_bool y
|
|
|
|
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
|
|
index 1072bfd18c50..f4dd44a7118f 100644
|
|
--- a/arch/openrisc/Kconfig
|
|
+++ b/arch/openrisc/Kconfig
|
|
@@ -17,6 +17,7 @@ config OPENRISC
|
|
select GENERIC_IRQ_SHOW
|
|
select GENERIC_IOMAP
|
|
select GENERIC_CPU_DEVICES
|
|
+ select HAVE_UID16
|
|
select GENERIC_ATOMIC64
|
|
select GENERIC_CLOCKEVENTS
|
|
select GENERIC_STRNCPY_FROM_USER
|
|
@@ -29,9 +30,6 @@ config MMU
|
|
config HAVE_DMA_ATTRS
|
|
def_bool y
|
|
|
|
-config UID16
|
|
- def_bool y
|
|
-
|
|
config RWSEM_GENERIC_SPINLOCK
|
|
def_bool y
|
|
|
|
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
|
|
index e245aab7f191..95b515113186 100644
|
|
--- a/arch/powerpc/include/asm/cmpxchg.h
|
|
+++ b/arch/powerpc/include/asm/cmpxchg.h
|
|
@@ -18,12 +18,12 @@ __xchg_u32(volatile void *p, unsigned long val)
|
|
unsigned long prev;
|
|
|
|
__asm__ __volatile__(
|
|
- PPC_RELEASE_BARRIER
|
|
+ PPC_ATOMIC_ENTRY_BARRIER
|
|
"1: lwarx %0,0,%2 \n"
|
|
PPC405_ERR77(0,%2)
|
|
" stwcx. %3,0,%2 \n\
|
|
bne- 1b"
|
|
- PPC_ACQUIRE_BARRIER
|
|
+ PPC_ATOMIC_EXIT_BARRIER
|
|
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
|
|
: "r" (p), "r" (val)
|
|
: "cc", "memory");
|
|
@@ -61,12 +61,12 @@ __xchg_u64(volatile void *p, unsigned long val)
|
|
unsigned long prev;
|
|
|
|
__asm__ __volatile__(
|
|
- PPC_RELEASE_BARRIER
|
|
+ PPC_ATOMIC_ENTRY_BARRIER
|
|
"1: ldarx %0,0,%2 \n"
|
|
PPC405_ERR77(0,%2)
|
|
" stdcx. %3,0,%2 \n\
|
|
bne- 1b"
|
|
- PPC_ACQUIRE_BARRIER
|
|
+ PPC_ATOMIC_EXIT_BARRIER
|
|
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
|
|
: "r" (p), "r" (val)
|
|
: "cc", "memory");
|
|
@@ -152,14 +152,14 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
|
|
unsigned int prev;
|
|
|
|
__asm__ __volatile__ (
|
|
- PPC_RELEASE_BARRIER
|
|
+ PPC_ATOMIC_ENTRY_BARRIER
|
|
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
|
|
cmpw 0,%0,%3\n\
|
|
bne- 2f\n"
|
|
PPC405_ERR77(0,%2)
|
|
" stwcx. %4,0,%2\n\
|
|
bne- 1b"
|
|
- PPC_ACQUIRE_BARRIER
|
|
+ PPC_ATOMIC_EXIT_BARRIER
|
|
"\n\
|
|
2:"
|
|
: "=&r" (prev), "+m" (*p)
|
|
@@ -198,13 +198,13 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
|
|
unsigned long prev;
|
|
|
|
__asm__ __volatile__ (
|
|
- PPC_RELEASE_BARRIER
|
|
+ PPC_ATOMIC_ENTRY_BARRIER
|
|
"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
|
|
cmpd 0,%0,%3\n\
|
|
bne- 2f\n\
|
|
stdcx. %4,0,%2\n\
|
|
bne- 1b"
|
|
- PPC_ACQUIRE_BARRIER
|
|
+ PPC_ATOMIC_EXIT_BARRIER
|
|
"\n\
|
|
2:"
|
|
: "=&r" (prev), "+m" (*p)
|
|
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
|
|
index 795f67792ea9..60c31698f7d5 100644
|
|
--- a/arch/powerpc/include/asm/reg.h
|
|
+++ b/arch/powerpc/include/asm/reg.h
|
|
@@ -108,6 +108,7 @@
|
|
#define MSR_TS_T __MASK(MSR_TS_T_LG) /* Transaction Transactional */
|
|
#define MSR_TS_MASK (MSR_TS_T | MSR_TS_S) /* Transaction State bits */
|
|
#define MSR_TM_ACTIVE(x) (((x) & MSR_TS_MASK) != 0) /* Transaction active? */
|
|
+#define MSR_TM_RESV(x) (((x) & MSR_TS_MASK) == MSR_TS_MASK) /* Reserved */
|
|
#define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T)
|
|
#define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S)
|
|
|
|
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
|
|
index e682a7143edb..c50868681f9e 100644
|
|
--- a/arch/powerpc/include/asm/synch.h
|
|
+++ b/arch/powerpc/include/asm/synch.h
|
|
@@ -44,7 +44,7 @@ static inline void isync(void)
|
|
MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
|
|
#define PPC_ACQUIRE_BARRIER "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
|
|
#define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n"
|
|
-#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
|
|
+#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n"
|
|
#define PPC_ATOMIC_EXIT_BARRIER "\n" stringify_in_c(sync) "\n"
|
|
#else
|
|
#define PPC_ACQUIRE_BARRIER
|
|
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
|
|
index d9b673b06757..8220ae86252c 100644
|
|
--- a/arch/powerpc/kernel/signal_32.c
|
|
+++ b/arch/powerpc/kernel/signal_32.c
|
|
@@ -858,6 +858,15 @@ static long restore_tm_user_regs(struct pt_regs *regs,
|
|
return 1;
|
|
#endif /* CONFIG_SPE */
|
|
|
|
+ /* Get the top half of the MSR from the user context */
|
|
+ if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
|
|
+ return 1;
|
|
+ msr_hi <<= 32;
|
|
+ /* If TM bits are set to the reserved value, it's an invalid context */
|
|
+ if (MSR_TM_RESV(msr_hi))
|
|
+ return 1;
|
|
+ /* Pull in the MSR TM bits from the user context */
|
|
+ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
|
|
/* Now, recheckpoint. This loads up all of the checkpointed (older)
|
|
* registers, including FP and V[S]Rs. After recheckpointing, the
|
|
* transactional versions should be loaded.
|
|
@@ -867,11 +876,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
|
|
current->thread.tm_texasr |= TEXASR_FS;
|
|
/* This loads the checkpointed FP/VEC state, if used */
|
|
tm_recheckpoint(¤t->thread, msr);
|
|
- /* Get the top half of the MSR */
|
|
- if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
|
|
- return 1;
|
|
- /* Pull in MSR TM from user context */
|
|
- regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
|
|
|
|
/* This loads the speculative FP/VEC state, if used */
|
|
if (msr & MSR_FP) {
|
|
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
|
|
index 74d9615a6bb6..2419c17538e2 100644
|
|
--- a/arch/powerpc/kernel/signal_64.c
|
|
+++ b/arch/powerpc/kernel/signal_64.c
|
|
@@ -416,6 +416,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
|
|
|
|
/* get MSR separately, transfer the LE bit if doing signal return */
|
|
err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
|
|
+ /* Don't allow reserved mode. */
|
|
+ if (MSR_TM_RESV(msr))
|
|
+ return -EINVAL;
|
|
+
|
|
/* pull in MSR TM from user context */
|
|
regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
|
|
|
|
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
|
|
index 102ad8a255f3..466fbd54e7f8 100644
|
|
--- a/arch/powerpc/kvm/book3s_hv.c
|
|
+++ b/arch/powerpc/kvm/book3s_hv.c
|
|
@@ -160,6 +160,12 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
|
|
|
|
void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
|
|
{
|
|
+ /*
|
|
+ * Check for illegal transactional state bit combination
|
|
+ * and if we find it, force the TS field to a safe state.
|
|
+ */
|
|
+ if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
|
|
+ msr &= ~MSR_TS_MASK;
|
|
vcpu->arch.shregs.msr = msr;
|
|
kvmppc_end_cede(vcpu);
|
|
}
|
|
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
|
|
index 4fa687a47a62..6b8d6e8cd449 100644
|
|
--- a/arch/x86/include/asm/boot.h
|
|
+++ b/arch/x86/include/asm/boot.h
|
|
@@ -27,7 +27,7 @@
|
|
#define BOOT_HEAP_SIZE 0x400000
|
|
#else /* !CONFIG_KERNEL_BZIP2 */
|
|
|
|
-#define BOOT_HEAP_SIZE 0x8000
|
|
+#define BOOT_HEAP_SIZE 0x10000
|
|
|
|
#endif /* !CONFIG_KERNEL_BZIP2 */
|
|
|
|
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
|
|
index 90fd1195f276..abfc89b3b55a 100644
|
|
--- a/arch/x86/kernel/reboot.c
|
|
+++ b/arch/x86/kernel/reboot.c
|
|
@@ -366,6 +366,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
|
DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
|
|
},
|
|
},
|
|
+ { /* Handle problems with rebooting on the iMac10,1. */
|
|
+ .callback = set_pci_reboot,
|
|
+ .ident = "Apple iMac10,1",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"),
|
|
+ },
|
|
+ },
|
|
|
|
{ /* Handle reboot issue on Acer Aspire one */
|
|
.callback = set_kbd_reboot,
|
|
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
|
|
index 66deef41512f..f11fd597c5b6 100644
|
|
--- a/arch/x86/kernel/signal.c
|
|
+++ b/arch/x86/kernel/signal.c
|
|
@@ -686,12 +686,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
|
signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
|
|
}
|
|
|
|
-#ifdef CONFIG_X86_32
|
|
-#define NR_restart_syscall __NR_restart_syscall
|
|
-#else /* !CONFIG_X86_32 */
|
|
-#define NR_restart_syscall \
|
|
- test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
|
|
-#endif /* CONFIG_X86_32 */
|
|
+static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
|
|
+{
|
|
+#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64)
|
|
+ return __NR_restart_syscall;
|
|
+#else /* !CONFIG_X86_32 && CONFIG_X86_64 */
|
|
+ return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall :
|
|
+ __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
|
|
+#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */
|
|
+}
|
|
|
|
/*
|
|
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
|
@@ -720,7 +723,7 @@ static void do_signal(struct pt_regs *regs)
|
|
break;
|
|
|
|
case -ERESTART_RESTARTBLOCK:
|
|
- regs->ax = NR_restart_syscall;
|
|
+ regs->ax = get_nr_restart_syscall(regs);
|
|
regs->ip -= 2;
|
|
break;
|
|
}
|
|
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
|
|
index 45329c8c226e..39e12c10b931 100644
|
|
--- a/arch/x86/xen/suspend.c
|
|
+++ b/arch/x86/xen/suspend.c
|
|
@@ -30,7 +30,8 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled)
|
|
{
|
|
#ifdef CONFIG_XEN_PVHVM
|
|
int cpu;
|
|
- xen_hvm_init_shared_info();
|
|
+ if (!suspend_cancelled)
|
|
+ xen_hvm_init_shared_info();
|
|
xen_callback_vector();
|
|
xen_unplug_emulated_devices();
|
|
if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
|
|
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
|
|
index 02cc352d8bcc..a67ac2a71155 100644
|
|
--- a/drivers/char/ipmi/ipmi_si_intf.c
|
|
+++ b/drivers/char/ipmi/ipmi_si_intf.c
|
|
@@ -1144,14 +1144,14 @@ static int smi_start_processing(void *send_info,
|
|
|
|
new_smi->intf = intf;
|
|
|
|
- /* Try to claim any interrupts. */
|
|
- if (new_smi->irq_setup)
|
|
- new_smi->irq_setup(new_smi);
|
|
-
|
|
/* Set up the timer that drives the interface. */
|
|
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
|
|
smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
|
|
|
|
+ /* Try to claim any interrupts. */
|
|
+ if (new_smi->irq_setup)
|
|
+ new_smi->irq_setup(new_smi);
|
|
+
|
|
/*
|
|
* Check if the user forcefully enabled the daemon.
|
|
*/
|
|
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
|
|
index 0daa11e418b1..bdbd80415908 100644
|
|
--- a/drivers/connector/connector.c
|
|
+++ b/drivers/connector/connector.c
|
|
@@ -154,26 +154,21 @@ static int cn_call_callback(struct sk_buff *skb)
|
|
*
|
|
* It checks skb, netlink header and msg sizes, and calls callback helper.
|
|
*/
|
|
-static void cn_rx_skb(struct sk_buff *__skb)
|
|
+static void cn_rx_skb(struct sk_buff *skb)
|
|
{
|
|
struct nlmsghdr *nlh;
|
|
- struct sk_buff *skb;
|
|
int len, err;
|
|
|
|
- skb = skb_get(__skb);
|
|
-
|
|
if (skb->len >= NLMSG_HDRLEN) {
|
|
nlh = nlmsg_hdr(skb);
|
|
len = nlmsg_len(nlh);
|
|
|
|
if (len < (int)sizeof(struct cn_msg) ||
|
|
skb->len < nlh->nlmsg_len ||
|
|
- len > CONNECTOR_MAX_MSG_SIZE) {
|
|
- kfree_skb(skb);
|
|
+ len > CONNECTOR_MAX_MSG_SIZE)
|
|
return;
|
|
- }
|
|
|
|
- err = cn_call_callback(skb);
|
|
+ err = cn_call_callback(skb_get(skb));
|
|
if (err < 0)
|
|
kfree_skb(skb);
|
|
}
|
|
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
|
index 2bd798a7d9aa..c1a8cf2d490b 100644
|
|
--- a/drivers/hid/hid-core.c
|
|
+++ b/drivers/hid/hid-core.c
|
|
@@ -1462,7 +1462,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
|
|
"Multi-Axis Controller"
|
|
};
|
|
const char *type, *bus;
|
|
- char buf[64];
|
|
+ char buf[64] = "";
|
|
unsigned int i;
|
|
int len;
|
|
int ret;
|
|
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
|
|
index 38ceac5053a0..0ed6731396ef 100644
|
|
--- a/drivers/isdn/i4l/isdn_ppp.c
|
|
+++ b/drivers/isdn/i4l/isdn_ppp.c
|
|
@@ -301,6 +301,8 @@ isdn_ppp_open(int min, struct file *file)
|
|
is->compflags = 0;
|
|
|
|
is->reset = isdn_ppp_ccp_reset_alloc(is);
|
|
+ if (!is->reset)
|
|
+ return -ENOMEM;
|
|
|
|
is->lp = NULL;
|
|
is->mp_seqno = 0; /* MP sequence number */
|
|
@@ -320,6 +322,10 @@ isdn_ppp_open(int min, struct file *file)
|
|
* VJ header compression init
|
|
*/
|
|
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
|
|
+ if (IS_ERR(is->slcomp)) {
|
|
+ isdn_ppp_ccp_reset_free(is);
|
|
+ return PTR_ERR(is->slcomp);
|
|
+ }
|
|
#endif
|
|
#ifdef CONFIG_IPPP_FILTER
|
|
is->pass_filter = NULL;
|
|
@@ -568,10 +574,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
|
|
is->maxcid = val;
|
|
#ifdef CONFIG_ISDN_PPP_VJ
|
|
sltmp = slhc_init(16, val);
|
|
- if (!sltmp) {
|
|
- printk(KERN_ERR "ippp, can't realloc slhc struct\n");
|
|
- return -ENOMEM;
|
|
- }
|
|
+ if (IS_ERR(sltmp))
|
|
+ return PTR_ERR(sltmp);
|
|
if (is->slcomp)
|
|
slhc_free(is->slcomp);
|
|
is->slcomp = sltmp;
|
|
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
|
|
index 5a1897d86e94..a2d7d5f066f1 100644
|
|
--- a/drivers/net/ppp/ppp_generic.c
|
|
+++ b/drivers/net/ppp/ppp_generic.c
|
|
@@ -716,10 +716,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
val &= 0xffff;
|
|
}
|
|
vj = slhc_init(val2+1, val+1);
|
|
- if (!vj) {
|
|
- netdev_err(ppp->dev,
|
|
- "PPP: no memory (VJ compressor)\n");
|
|
- err = -ENOMEM;
|
|
+ if (IS_ERR(vj)) {
|
|
+ err = PTR_ERR(vj);
|
|
break;
|
|
}
|
|
ppp_lock(ppp);
|
|
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
|
|
index 1252d9c726a7..b52eabc168a0 100644
|
|
--- a/drivers/net/slip/slhc.c
|
|
+++ b/drivers/net/slip/slhc.c
|
|
@@ -84,8 +84,9 @@ static long decode(unsigned char **cpp);
|
|
static unsigned char * put16(unsigned char *cp, unsigned short x);
|
|
static unsigned short pull16(unsigned char **cpp);
|
|
|
|
-/* Initialize compression data structure
|
|
+/* Allocate compression data structure
|
|
* slots must be in range 0 to 255 (zero meaning no compression)
|
|
+ * Returns pointer to structure or ERR_PTR() on error.
|
|
*/
|
|
struct slcompress *
|
|
slhc_init(int rslots, int tslots)
|
|
@@ -94,11 +95,14 @@ slhc_init(int rslots, int tslots)
|
|
register struct cstate *ts;
|
|
struct slcompress *comp;
|
|
|
|
+ if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL);
|
|
if (! comp)
|
|
goto out_fail;
|
|
|
|
- if ( rslots > 0 && rslots < 256 ) {
|
|
+ if (rslots > 0) {
|
|
size_t rsize = rslots * sizeof(struct cstate);
|
|
comp->rstate = kzalloc(rsize, GFP_KERNEL);
|
|
if (! comp->rstate)
|
|
@@ -106,7 +110,7 @@ slhc_init(int rslots, int tslots)
|
|
comp->rslot_limit = rslots - 1;
|
|
}
|
|
|
|
- if ( tslots > 0 && tslots < 256 ) {
|
|
+ if (tslots > 0) {
|
|
size_t tsize = tslots * sizeof(struct cstate);
|
|
comp->tstate = kzalloc(tsize, GFP_KERNEL);
|
|
if (! comp->tstate)
|
|
@@ -141,7 +145,7 @@ out_free2:
|
|
out_free:
|
|
kfree(comp);
|
|
out_fail:
|
|
- return NULL;
|
|
+ return ERR_PTR(-ENOMEM);
|
|
}
|
|
|
|
|
|
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
|
|
index a34d6bf5e43b..ca3e73753fb8 100644
|
|
--- a/drivers/net/slip/slip.c
|
|
+++ b/drivers/net/slip/slip.c
|
|
@@ -163,7 +163,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
|
|
if (cbuff == NULL)
|
|
goto err_exit;
|
|
slcomp = slhc_init(16, 16);
|
|
- if (slcomp == NULL)
|
|
+ if (IS_ERR(slcomp))
|
|
goto err_exit;
|
|
#endif
|
|
spin_lock_bh(&sl->lock);
|
|
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
|
|
index 14179a6593ef..5225d4321e7c 100644
|
|
--- a/drivers/net/team/team.c
|
|
+++ b/drivers/net/team/team.c
|
|
@@ -1636,10 +1636,10 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
|
|
struct team *team = netdev_priv(dev);
|
|
struct team_port *port;
|
|
|
|
- rcu_read_lock();
|
|
- list_for_each_entry_rcu(port, &team->port_list, list)
|
|
+ mutex_lock(&team->lock);
|
|
+ list_for_each_entry(port, &team->port_list, list)
|
|
vlan_vid_del(port->dev, proto, vid);
|
|
- rcu_read_unlock();
|
|
+ mutex_unlock(&team->lock);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
|
|
index 177f911f5946..cc6d3f987436 100644
|
|
--- a/drivers/net/veth.c
|
|
+++ b/drivers/net/veth.c
|
|
@@ -116,12 +116,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
kfree_skb(skb);
|
|
goto drop;
|
|
}
|
|
- /* don't change ip_summed == CHECKSUM_PARTIAL, as that
|
|
- * will cause bad checksum on forwarded packets
|
|
- */
|
|
- if (skb->ip_summed == CHECKSUM_NONE &&
|
|
- rcv->features & NETIF_F_RXCSUM)
|
|
- skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
|
if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {
|
|
struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);
|
|
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
|
|
index 8c33491b21fe..c6aa38883466 100644
|
|
--- a/drivers/parisc/iommu-helpers.h
|
|
+++ b/drivers/parisc/iommu-helpers.h
|
|
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
|
|
struct scatterlist *contig_sg; /* contig chunk head */
|
|
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
|
|
unsigned int n_mappings = 0;
|
|
- unsigned int max_seg_size = dma_get_max_seg_size(dev);
|
|
+ unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
|
|
+ (unsigned)DMA_CHUNK_SIZE);
|
|
+ unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
|
|
+ if (max_seg_boundary) /* check if the addition above didn't overflow */
|
|
+ max_seg_size = min(max_seg_size, max_seg_boundary);
|
|
|
|
while (nents > 0) {
|
|
|
|
@@ -139,14 +143,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
|
|
|
|
/*
|
|
** First make sure current dma stream won't
|
|
- ** exceed DMA_CHUNK_SIZE if we coalesce the
|
|
+ ** exceed max_seg_size if we coalesce the
|
|
** next entry.
|
|
*/
|
|
- if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
|
|
- IOVP_SIZE) > DMA_CHUNK_SIZE))
|
|
- break;
|
|
-
|
|
- if (startsg->length + dma_len > max_seg_size)
|
|
+ if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
|
|
+ max_seg_size))
|
|
break;
|
|
|
|
/*
|
|
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
|
index a3431e90345f..4dc18615cd0f 100644
|
|
--- a/drivers/usb/host/xhci.c
|
|
+++ b/drivers/usb/host/xhci.c
|
|
@@ -4615,8 +4615,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
|
|
ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
|
|
slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
|
|
slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
|
|
+ /*
|
|
+ * refer to section 6.2.2: MTT should be 0 for full speed hub,
|
|
+ * but it may be already set to 1 when setup an xHCI virtual
|
|
+ * device, so clear it anyway.
|
|
+ */
|
|
if (tt->multi)
|
|
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
|
|
+ else if (hdev->speed == USB_SPEED_FULL)
|
|
+ slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
|
|
+
|
|
if (xhci->hci_version > 0x95) {
|
|
xhci_dbg(xhci, "xHCI version %x needs hub "
|
|
"TT think time and number of ports\n",
|
|
@@ -4807,6 +4815,10 @@ static int __init xhci_hcd_init(void)
|
|
BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
|
|
/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
|
|
BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
|
|
+
|
|
+ if (usb_disabled())
|
|
+ return -ENODEV;
|
|
+
|
|
return 0;
|
|
unreg_pci:
|
|
xhci_unregister_pci();
|
|
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
|
|
index 25522e98602e..72c14d7d604f 100644
|
|
--- a/drivers/usb/serial/cp210x.c
|
|
+++ b/drivers/usb/serial/cp210x.c
|
|
@@ -160,6 +160,7 @@ static const struct usb_device_id id_table[] = {
|
|
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
|
|
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
|
|
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
|
|
+ { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
|
|
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
|
|
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
|
|
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
|
|
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
|
|
index 76c9a847da5d..e03900e8c667 100644
|
|
--- a/drivers/usb/serial/ipaq.c
|
|
+++ b/drivers/usb/serial/ipaq.c
|
|
@@ -532,7 +532,8 @@ static int ipaq_open(struct tty_struct *tty,
|
|
* through. Since this has a reasonably high failure rate, we retry
|
|
* several times.
|
|
*/
|
|
- while (retries--) {
|
|
+ while (retries) {
|
|
+ retries--;
|
|
result = usb_control_msg(serial->dev,
|
|
usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
|
|
0x1, 0, NULL, 0, 100);
|
|
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
|
|
index e68205cbc46e..3d8e6098cd40 100644
|
|
--- a/drivers/xen/gntdev.c
|
|
+++ b/drivers/xen/gntdev.c
|
|
@@ -770,7 +770,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
|
|
|
|
vma->vm_ops = &gntdev_vmops;
|
|
|
|
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
|
|
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
|
|
|
|
if (use_ptemod)
|
|
vma->vm_flags |= VM_DONTCOPY;
|
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
|
index 7cf305d036db..4781332f2e11 100644
|
|
--- a/include/linux/sched.h
|
|
+++ b/include/linux/sched.h
|
|
@@ -670,6 +670,7 @@ struct user_struct {
|
|
unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
|
|
#endif
|
|
unsigned long locked_shm; /* How many pages of mlocked shm ? */
|
|
+ unsigned long unix_inflight; /* How many files in flight in unix sockets */
|
|
|
|
#ifdef CONFIG_KEYS
|
|
struct key *uid_keyring; /* UID specific keyring */
|
|
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
|
|
index 84662ecc7b51..e1bc430133f4 100644
|
|
--- a/include/linux/syscalls.h
|
|
+++ b/include/linux/syscalls.h
|
|
@@ -498,7 +498,7 @@ asmlinkage long sys_chown(const char __user *filename,
|
|
asmlinkage long sys_lchown(const char __user *filename,
|
|
uid_t user, gid_t group);
|
|
asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
|
|
-#ifdef CONFIG_UID16
|
|
+#ifdef CONFIG_HAVE_UID16
|
|
asmlinkage long sys_chown16(const char __user *filename,
|
|
old_uid_t user, old_gid_t group);
|
|
asmlinkage long sys_lchown16(const char __user *filename,
|
|
diff --git a/include/linux/types.h b/include/linux/types.h
|
|
index 4d118ba11349..83db8e5974dc 100644
|
|
--- a/include/linux/types.h
|
|
+++ b/include/linux/types.h
|
|
@@ -35,7 +35,7 @@ typedef __kernel_gid16_t gid16_t;
|
|
|
|
typedef unsigned long uintptr_t;
|
|
|
|
-#ifdef CONFIG_UID16
|
|
+#ifdef CONFIG_HAVE_UID16
|
|
/* This is defined by include/asm-{arch}/posix_types.h */
|
|
typedef __kernel_old_uid_t old_uid_t;
|
|
typedef __kernel_old_gid_t old_gid_t;
|
|
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
|
|
index 886f6d6dc48a..3995a66c3e4e 100644
|
|
--- a/net/bridge/br_stp_if.c
|
|
+++ b/net/bridge/br_stp_if.c
|
|
@@ -128,7 +128,10 @@ static void br_stp_start(struct net_bridge *br)
|
|
char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL };
|
|
char *envp[] = { NULL };
|
|
|
|
- r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
|
|
+ if (net_eq(dev_net(br->dev), &init_net))
|
|
+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
|
|
+ else
|
|
+ r = -ENOENT;
|
|
|
|
spin_lock_bh(&br->lock);
|
|
|
|
diff --git a/net/core/dst.c b/net/core/dst.c
|
|
index 01f9980af86e..1bf6842b89b8 100644
|
|
--- a/net/core/dst.c
|
|
+++ b/net/core/dst.c
|
|
@@ -280,10 +280,11 @@ void dst_release(struct dst_entry *dst)
|
|
{
|
|
if (dst) {
|
|
int newrefcnt;
|
|
+ unsigned short nocache = dst->flags & DST_NOCACHE;
|
|
|
|
newrefcnt = atomic_dec_return(&dst->__refcnt);
|
|
WARN_ON(newrefcnt < 0);
|
|
- if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
|
|
+ if (!newrefcnt && unlikely(nocache))
|
|
call_rcu(&dst->rcu_head, dst_destroy_rcu);
|
|
}
|
|
}
|
|
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c
|
|
index 05c3b6f0e8e1..bf8321d6f2ef 100644
|
|
--- a/net/ipv4/tcp_yeah.c
|
|
+++ b/net/ipv4/tcp_yeah.c
|
|
@@ -222,7 +222,7 @@ static u32 tcp_yeah_ssthresh(struct sock *sk) {
|
|
yeah->fast_count = 0;
|
|
yeah->reno_count = max(yeah->reno_count>>1, 2U);
|
|
|
|
- return tp->snd_cwnd - reduction;
|
|
+ return max_t(int, tp->snd_cwnd - reduction, 2);
|
|
}
|
|
|
|
static struct tcp_congestion_ops tcp_yeah __read_mostly = {
|
|
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
|
|
index b30ad3741b46..d5c918975c8c 100644
|
|
--- a/net/ipv6/addrlabel.c
|
|
+++ b/net/ipv6/addrlabel.c
|
|
@@ -558,7 +558,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh)
|
|
|
|
rcu_read_lock();
|
|
p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
|
|
- if (p && ip6addrlbl_hold(p))
|
|
+ if (p && !ip6addrlbl_hold(p))
|
|
p = NULL;
|
|
lseq = ip6addrlbl_table.seq;
|
|
rcu_read_unlock();
|
|
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
|
|
index 5a940dbd74a3..f0229223bf91 100644
|
|
--- a/net/phonet/af_phonet.c
|
|
+++ b/net/phonet/af_phonet.c
|
|
@@ -377,6 +377,10 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
|
|
struct sockaddr_pn sa;
|
|
u16 len;
|
|
|
|
+ skb = skb_share_check(skb, GFP_ATOMIC);
|
|
+ if (!skb)
|
|
+ return NET_RX_DROP;
|
|
+
|
|
/* check we have at least a full Phonet header */
|
|
if (!pskb_pull(skb, sizeof(struct phonethdr)))
|
|
goto out;
|
|
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
|
|
index c52763a26297..d9cbecb62aca 100644
|
|
--- a/net/sctp/sm_statefuns.c
|
|
+++ b/net/sctp/sm_statefuns.c
|
|
@@ -4835,7 +4835,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
|
|
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
|
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
|
+ if (abort)
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
|
|
|
/* Even if we can't send the ABORT due to low memory delete the
|
|
* TCB. This is a departure from our typical NOMEM handling.
|
|
@@ -4972,7 +4973,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
|
|
|
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
|
+ if (abort)
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
|
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
|
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
|
|
index 80bd61ae5945..bdc3fb66717d 100644
|
|
--- a/net/sctp/socket.c
|
|
+++ b/net/sctp/socket.c
|
|
@@ -1533,8 +1533,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
|
|
struct sctp_chunk *chunk;
|
|
|
|
chunk = sctp_make_abort_user(asoc, NULL, 0);
|
|
- if (chunk)
|
|
- sctp_primitive_ABORT(net, asoc, chunk);
|
|
+ sctp_primitive_ABORT(net, asoc, chunk);
|
|
} else
|
|
sctp_primitive_SHUTDOWN(net, asoc, NULL);
|
|
}
|
|
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
|
index f934e7ba5eb8..a673c1f4f638 100644
|
|
--- a/net/unix/af_unix.c
|
|
+++ b/net/unix/af_unix.c
|
|
@@ -1483,6 +1483,21 @@ static void unix_destruct_scm(struct sk_buff *skb)
|
|
sock_wfree(skb);
|
|
}
|
|
|
|
+/*
|
|
+ * The "user->unix_inflight" variable is protected by the garbage
|
|
+ * collection lock, and we just read it locklessly here. If you go
|
|
+ * over the limit, there might be a tiny race in actually noticing
|
|
+ * it across threads. Tough.
|
|
+ */
|
|
+static inline bool too_many_unix_fds(struct task_struct *p)
|
|
+{
|
|
+ struct user_struct *user = current_user();
|
|
+
|
|
+ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
|
|
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
|
|
+ return false;
|
|
+}
|
|
+
|
|
#define MAX_RECURSION_LEVEL 4
|
|
|
|
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
|
@@ -1491,6 +1506,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
|
unsigned char max_level = 0;
|
|
int unix_sock_count = 0;
|
|
|
|
+ if (too_many_unix_fds(current))
|
|
+ return -ETOOMANYREFS;
|
|
+
|
|
for (i = scm->fp->count - 1; i >= 0; i--) {
|
|
struct sock *sk = unix_get_socket(scm->fp->fp[i]);
|
|
|
|
@@ -1512,10 +1530,8 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
|
if (!UNIXCB(skb).fp)
|
|
return -ENOMEM;
|
|
|
|
- if (unix_sock_count) {
|
|
- for (i = scm->fp->count - 1; i >= 0; i--)
|
|
- unix_inflight(scm->fp->fp[i]);
|
|
- }
|
|
+ for (i = scm->fp->count - 1; i >= 0; i--)
|
|
+ unix_inflight(scm->fp->fp[i]);
|
|
return max_level;
|
|
}
|
|
|
|
@@ -1934,7 +1950,14 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
if (flags&MSG_OOB)
|
|
goto out;
|
|
|
|
- mutex_lock(&u->readlock);
|
|
+ err = mutex_lock_interruptible(&u->readlock);
|
|
+ if (unlikely(err)) {
|
|
+ /* recvmsg() in non blocking mode is supposed to return -EAGAIN
|
|
+ * sk_rcvtimeo is not honored by mutex_lock_interruptible()
|
|
+ */
|
|
+ err = noblock ? -EAGAIN : -ERESTARTSYS;
|
|
+ goto out;
|
|
+ }
|
|
|
|
skip = sk_peek_offset(sk, flags);
|
|
|
|
@@ -2083,14 +2106,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
memset(&tmp_scm, 0, sizeof(tmp_scm));
|
|
}
|
|
|
|
- err = mutex_lock_interruptible(&u->readlock);
|
|
- if (unlikely(err)) {
|
|
- /* recvmsg() in non blocking mode is supposed to return -EAGAIN
|
|
- * sk_rcvtimeo is not honored by mutex_lock_interruptible()
|
|
- */
|
|
- err = noblock ? -EAGAIN : -ERESTARTSYS;
|
|
- goto out;
|
|
- }
|
|
+ mutex_lock(&u->readlock);
|
|
|
|
do {
|
|
int chunk;
|
|
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
|
|
index 9bc73f87f64a..06730fe6ad9d 100644
|
|
--- a/net/unix/garbage.c
|
|
+++ b/net/unix/garbage.c
|
|
@@ -125,9 +125,12 @@ struct sock *unix_get_socket(struct file *filp)
|
|
void unix_inflight(struct file *fp)
|
|
{
|
|
struct sock *s = unix_get_socket(fp);
|
|
+
|
|
+ spin_lock(&unix_gc_lock);
|
|
+
|
|
if (s) {
|
|
struct unix_sock *u = unix_sk(s);
|
|
- spin_lock(&unix_gc_lock);
|
|
+
|
|
if (atomic_long_inc_return(&u->inflight) == 1) {
|
|
BUG_ON(!list_empty(&u->link));
|
|
list_add_tail(&u->link, &gc_inflight_list);
|
|
@@ -135,22 +138,27 @@ void unix_inflight(struct file *fp)
|
|
BUG_ON(list_empty(&u->link));
|
|
}
|
|
unix_tot_inflight++;
|
|
- spin_unlock(&unix_gc_lock);
|
|
}
|
|
+ fp->f_cred->user->unix_inflight++;
|
|
+ spin_unlock(&unix_gc_lock);
|
|
}
|
|
|
|
void unix_notinflight(struct file *fp)
|
|
{
|
|
struct sock *s = unix_get_socket(fp);
|
|
+
|
|
+ spin_lock(&unix_gc_lock);
|
|
+
|
|
if (s) {
|
|
struct unix_sock *u = unix_sk(s);
|
|
- spin_lock(&unix_gc_lock);
|
|
+
|
|
BUG_ON(list_empty(&u->link));
|
|
if (atomic_long_dec_and_test(&u->inflight))
|
|
list_del_init(&u->link);
|
|
unix_tot_inflight--;
|
|
- spin_unlock(&unix_gc_lock);
|
|
}
|
|
+ fp->f_cred->user->unix_inflight--;
|
|
+ spin_unlock(&unix_gc_lock);
|
|
}
|
|
|
|
static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
|
|
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
|
|
index 679218b56ede..f94f6a2d6988 100755
|
|
--- a/scripts/recordmcount.pl
|
|
+++ b/scripts/recordmcount.pl
|
|
@@ -265,7 +265,8 @@ if ($arch eq "x86_64") {
|
|
|
|
} elsif ($arch eq "powerpc") {
|
|
$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
|
|
- $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
|
|
+ # See comment in the sparc64 section for why we use '\w'.
|
|
+ $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:";
|
|
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
|
|
|
|
if ($bits == 64) {
|
|
diff --git a/sound/core/control.c b/sound/core/control.c
|
|
index f2082a35b890..3fcead61f0ef 100644
|
|
--- a/sound/core/control.c
|
|
+++ b/sound/core/control.c
|
|
@@ -1325,6 +1325,8 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
|
|
return -EFAULT;
|
|
if (tlv.length < sizeof(unsigned int) * 2)
|
|
return -EINVAL;
|
|
+ if (!tlv.numid)
|
|
+ return -EINVAL;
|
|
down_read(&card->controls_rwsem);
|
|
kctl = snd_ctl_find_numid(card, tlv.numid);
|
|
if (kctl == NULL) {
|
|
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
|
|
index b8b31c433d64..14d483d6b3b0 100644
|
|
--- a/sound/core/hrtimer.c
|
|
+++ b/sound/core/hrtimer.c
|
|
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
|
|
struct snd_hrtimer *stime = t->private_data;
|
|
|
|
atomic_set(&stime->running, 0);
|
|
- hrtimer_cancel(&stime->hrt);
|
|
+ hrtimer_try_to_cancel(&stime->hrt);
|
|
hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
|
|
HRTIMER_MODE_REL);
|
|
atomic_set(&stime->running, 1);
|
|
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
|
|
{
|
|
struct snd_hrtimer *stime = t->private_data;
|
|
atomic_set(&stime->running, 0);
|
|
+ hrtimer_try_to_cancel(&stime->hrt);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
|
|
index c4ac3c1e19af..1bb1a43c7d03 100644
|
|
--- a/sound/core/pcm_compat.c
|
|
+++ b/sound/core/pcm_compat.c
|
|
@@ -236,10 +236,15 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
|
|
if (! (runtime = substream->runtime))
|
|
return -ENOTTY;
|
|
|
|
- /* only fifo_size is different, so just copy all */
|
|
- data = memdup_user(data32, sizeof(*data32));
|
|
- if (IS_ERR(data))
|
|
- return PTR_ERR(data);
|
|
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
|
|
+ if (!data)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ /* only fifo_size (RO from userspace) is different, so just copy all */
|
|
+ if (copy_from_user(data, data32, sizeof(*data32))) {
|
|
+ err = -EFAULT;
|
|
+ goto error;
|
|
+ }
|
|
|
|
if (refine)
|
|
err = snd_pcm_hw_refine(substream, data);
|
|
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
|
|
index 4dc6bae80e15..ecfbf5f39d38 100644
|
|
--- a/sound/core/seq/seq_clientmgr.c
|
|
+++ b/sound/core/seq/seq_clientmgr.c
|
|
@@ -1950,7 +1950,7 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
|
|
* No restrictions so for a user client we can clear
|
|
* the whole fifo
|
|
*/
|
|
- if (client->type == USER_CLIENT)
|
|
+ if (client->type == USER_CLIENT && client->data.user.fifo)
|
|
snd_seq_fifo_clear(client->data.user.fifo);
|
|
}
|
|
|
|
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
|
|
index 81f7c109dc46..65175902a68a 100644
|
|
--- a/sound/core/seq/seq_compat.c
|
|
+++ b/sound/core/seq/seq_compat.c
|
|
@@ -49,11 +49,12 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
|
|
struct snd_seq_port_info *data;
|
|
mm_segment_t fs;
|
|
|
|
- data = memdup_user(data32, sizeof(*data32));
|
|
- if (IS_ERR(data))
|
|
- return PTR_ERR(data);
|
|
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
|
|
+ if (!data)
|
|
+ return -ENOMEM;
|
|
|
|
- if (get_user(data->flags, &data32->flags) ||
|
|
+ if (copy_from_user(data, data32, sizeof(*data32)) ||
|
|
+ get_user(data->flags, &data32->flags) ||
|
|
get_user(data->time_queue, &data32->time_queue))
|
|
goto error;
|
|
data->kernel = NULL;
|
|
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
|
|
index f9077361c119..4c9aa462de9b 100644
|
|
--- a/sound/core/seq/seq_queue.c
|
|
+++ b/sound/core/seq/seq_queue.c
|
|
@@ -144,8 +144,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
|
|
static void queue_delete(struct snd_seq_queue *q)
|
|
{
|
|
/* stop and release the timer */
|
|
+ mutex_lock(&q->timer_mutex);
|
|
snd_seq_timer_stop(q->timer);
|
|
snd_seq_timer_close(q);
|
|
+ mutex_unlock(&q->timer_mutex);
|
|
/* wait until access free */
|
|
snd_use_lock_sync(&q->use_lock);
|
|
/* release resources... */
|
|
diff --git a/sound/core/timer.c b/sound/core/timer.c
|
|
index 6ddcf06f52f9..4e436fe53afa 100644
|
|
--- a/sound/core/timer.c
|
|
+++ b/sound/core/timer.c
|
|
@@ -73,7 +73,7 @@ struct snd_timer_user {
|
|
struct timespec tstamp; /* trigger tstamp */
|
|
wait_queue_head_t qchange_sleep;
|
|
struct fasync_struct *fasync;
|
|
- struct mutex tread_sem;
|
|
+ struct mutex ioctl_lock;
|
|
};
|
|
|
|
/* list of timers */
|
|
@@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
|
|
slave->slave_id == master->slave_id) {
|
|
list_move_tail(&slave->open_list, &master->slave_list_head);
|
|
spin_lock_irq(&slave_active_lock);
|
|
+ spin_lock(&master->timer->lock);
|
|
slave->master = master;
|
|
slave->timer = master->timer;
|
|
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
|
|
list_add_tail(&slave->active_list,
|
|
&master->slave_active_head);
|
|
+ spin_unlock(&master->timer->lock);
|
|
spin_unlock_irq(&slave_active_lock);
|
|
}
|
|
}
|
|
@@ -345,15 +347,18 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
|
timer->hw.close)
|
|
timer->hw.close(timer);
|
|
/* remove slave links */
|
|
+ spin_lock_irq(&slave_active_lock);
|
|
+ spin_lock(&timer->lock);
|
|
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
|
|
open_list) {
|
|
- spin_lock_irq(&slave_active_lock);
|
|
- _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
|
|
list_move_tail(&slave->open_list, &snd_timer_slave_list);
|
|
slave->master = NULL;
|
|
slave->timer = NULL;
|
|
- spin_unlock_irq(&slave_active_lock);
|
|
+ list_del_init(&slave->ack_list);
|
|
+ list_del_init(&slave->active_list);
|
|
}
|
|
+ spin_unlock(&timer->lock);
|
|
+ spin_unlock_irq(&slave_active_lock);
|
|
mutex_unlock(®ister_mutex);
|
|
}
|
|
out:
|
|
@@ -440,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
|
|
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
|
|
- if (timeri->master)
|
|
+ if (timeri->master && timeri->timer) {
|
|
+ spin_lock(&timeri->timer->lock);
|
|
list_add_tail(&timeri->active_list,
|
|
&timeri->master->slave_active_head);
|
|
+ spin_unlock(&timeri->timer->lock);
|
|
+ }
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
return 1; /* delayed start */
|
|
}
|
|
@@ -488,6 +496,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
|
|
if (!keep_flag) {
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
|
|
+ list_del_init(&timeri->ack_list);
|
|
+ list_del_init(&timeri->active_list);
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
}
|
|
goto __end;
|
|
@@ -693,7 +703,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
|
|
} else {
|
|
ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
|
|
if (--timer->running)
|
|
- list_del(&ti->active_list);
|
|
+ list_del_init(&ti->active_list);
|
|
}
|
|
if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
|
|
(ti->flags & SNDRV_TIMER_IFLG_FAST))
|
|
@@ -1256,7 +1266,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
|
|
return -ENOMEM;
|
|
spin_lock_init(&tu->qlock);
|
|
init_waitqueue_head(&tu->qchange_sleep);
|
|
- mutex_init(&tu->tread_sem);
|
|
+ mutex_init(&tu->ioctl_lock);
|
|
tu->ticks = 1;
|
|
tu->queue_size = 128;
|
|
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
|
|
@@ -1276,8 +1286,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
|
|
if (file->private_data) {
|
|
tu = file->private_data;
|
|
file->private_data = NULL;
|
|
+ mutex_lock(&tu->ioctl_lock);
|
|
if (tu->timeri)
|
|
snd_timer_close(tu->timeri);
|
|
+ mutex_unlock(&tu->ioctl_lock);
|
|
kfree(tu->queue);
|
|
kfree(tu->tqueue);
|
|
kfree(tu);
|
|
@@ -1515,7 +1527,6 @@ static int snd_timer_user_tselect(struct file *file,
|
|
int err = 0;
|
|
|
|
tu = file->private_data;
|
|
- mutex_lock(&tu->tread_sem);
|
|
if (tu->timeri) {
|
|
snd_timer_close(tu->timeri);
|
|
tu->timeri = NULL;
|
|
@@ -1559,7 +1570,6 @@ static int snd_timer_user_tselect(struct file *file,
|
|
}
|
|
|
|
__err:
|
|
- mutex_unlock(&tu->tread_sem);
|
|
return err;
|
|
}
|
|
|
|
@@ -1772,7 +1782,7 @@ enum {
|
|
SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
|
|
};
|
|
|
|
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|
+static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|
unsigned long arg)
|
|
{
|
|
struct snd_timer_user *tu;
|
|
@@ -1789,17 +1799,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|
{
|
|
int xarg;
|
|
|
|
- mutex_lock(&tu->tread_sem);
|
|
- if (tu->timeri) { /* too late */
|
|
- mutex_unlock(&tu->tread_sem);
|
|
+ if (tu->timeri) /* too late */
|
|
return -EBUSY;
|
|
- }
|
|
- if (get_user(xarg, p)) {
|
|
- mutex_unlock(&tu->tread_sem);
|
|
+ if (get_user(xarg, p))
|
|
return -EFAULT;
|
|
- }
|
|
tu->tread = xarg ? 1 : 0;
|
|
- mutex_unlock(&tu->tread_sem);
|
|
return 0;
|
|
}
|
|
case SNDRV_TIMER_IOCTL_GINFO:
|
|
@@ -1832,6 +1836,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|
return -ENOTTY;
|
|
}
|
|
|
|
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|
+ unsigned long arg)
|
|
+{
|
|
+ struct snd_timer_user *tu = file->private_data;
|
|
+ long ret;
|
|
+
|
|
+ mutex_lock(&tu->ioctl_lock);
|
|
+ ret = __snd_timer_user_ioctl(file, cmd, arg);
|
|
+ mutex_unlock(&tu->ioctl_lock);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int snd_timer_user_fasync(int fd, struct file * file, int on)
|
|
{
|
|
struct snd_timer_user *tu;
|
|
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
|
index 1800db643a16..57d01f101b04 100644
|
|
--- a/sound/pci/hda/hda_intel.c
|
|
+++ b/sound/pci/hda/hda_intel.c
|
|
@@ -1104,6 +1104,36 @@ static unsigned int azx_get_response(struct hda_bus *bus,
|
|
return azx_rirb_get_response(bus, addr);
|
|
}
|
|
|
|
+#ifdef CONFIG_PM_SLEEP
|
|
+/* put codec down to D3 at hibernation for Intel SKL+;
|
|
+ * otherwise BIOS may still access the codec and screw up the driver
|
|
+ */
|
|
+#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
|
|
+#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
|
|
+#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
|
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
|
|
+
|
|
+static int azx_freeze_noirq(struct device *dev)
|
|
+{
|
|
+ struct pci_dev *pci = to_pci_dev(dev);
|
|
+
|
|
+ if (IS_SKL_PLUS(pci))
|
|
+ pci_set_power_state(pci, PCI_D3hot);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int azx_thaw_noirq(struct device *dev)
|
|
+{
|
|
+ struct pci_dev *pci = to_pci_dev(dev);
|
|
+
|
|
+ if (IS_SKL_PLUS(pci))
|
|
+ pci_set_power_state(pci, PCI_D0);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif /* CONFIG_PM_SLEEP */
|
|
+
|
|
#ifdef CONFIG_PM
|
|
static void azx_power_notify(struct hda_bus *bus, bool power_up);
|
|
#endif
|
|
@@ -2974,6 +3004,10 @@ static int azx_runtime_idle(struct device *dev)
|
|
#ifdef CONFIG_PM
|
|
static const struct dev_pm_ops azx_pm = {
|
|
SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
|
|
+#ifdef CONFIG_PM_SLEEP
|
|
+ .freeze_noirq = azx_freeze_noirq,
|
|
+ .thaw_noirq = azx_thaw_noirq,
|
|
+#endif
|
|
SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
|
|
};
|
|
|
|
@@ -3864,6 +3898,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
{ PCI_DEVICE(0x8086, 0x8d21),
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
+ /* Lewisburg */
|
|
+ { PCI_DEVICE(0x8086, 0xa1f0),
|
|
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
+ { PCI_DEVICE(0x8086, 0xa270),
|
|
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
/* Lynx Point-LP */
|
|
{ PCI_DEVICE(0x8086, 0x9c20),
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index 183a96ab2533..69a2aafb0b0f 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -1768,6 +1768,7 @@ enum {
|
|
ALC889_FIXUP_MBA11_VREF,
|
|
ALC889_FIXUP_MBA21_VREF,
|
|
ALC889_FIXUP_MP11_VREF,
|
|
+ ALC889_FIXUP_MP41_VREF,
|
|
ALC882_FIXUP_INV_DMIC,
|
|
ALC882_FIXUP_NO_PRIMARY_HP,
|
|
ALC887_FIXUP_ASUS_BASS,
|
|
@@ -1854,7 +1855,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
|
|
const struct hda_fixup *fix, int action)
|
|
{
|
|
struct alc_spec *spec = codec->spec;
|
|
- static hda_nid_t nids[2] = { 0x14, 0x15 };
|
|
+ static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
|
|
int i;
|
|
|
|
if (action != HDA_FIXUP_ACT_INIT)
|
|
@@ -2128,6 +2129,12 @@ static const struct hda_fixup alc882_fixups[] = {
|
|
.chained = true,
|
|
.chain_id = ALC885_FIXUP_MACPRO_GPIO,
|
|
},
|
|
+ [ALC889_FIXUP_MP41_VREF] = {
|
|
+ .type = HDA_FIXUP_FUNC,
|
|
+ .v.func = alc889_fixup_mbp_vref,
|
|
+ .chained = true,
|
|
+ .chain_id = ALC885_FIXUP_MACPRO_GPIO,
|
|
+ },
|
|
[ALC882_FIXUP_INV_DMIC] = {
|
|
.type = HDA_FIXUP_FUNC,
|
|
.v.func = alc_fixup_inv_dmic_0x12,
|
|
@@ -2200,7 +2207,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
|
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
|
|
SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
|
|
SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
|
|
- SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
|
|
+ SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
|
|
SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
|
|
SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
|
|
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
|
|
@@ -4446,6 +4453,7 @@ static const struct hda_fixup alc662_fixups[] = {
|
|
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
|
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
|
|
SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
|
|
+ SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
|
|
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
|
|
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
|
|
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
|
|
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
|
|
index 44d3fb95ebba..5ffe7992aaed 100644
|
|
--- a/sound/pci/hda/patch_sigmatel.c
|
|
+++ b/sound/pci/hda/patch_sigmatel.c
|
|
@@ -703,6 +703,7 @@ static bool hp_bnb2011_with_dock(struct hda_codec *codec)
|
|
static bool hp_blike_system(u32 subsystem_id)
|
|
{
|
|
switch (subsystem_id) {
|
|
+ case 0x103c1473: /* HP ProBook 6550b */
|
|
case 0x103c1520:
|
|
case 0x103c1521:
|
|
case 0x103c1523:
|
|
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
|
|
index 5fb88ac82aa9..4fdb234d74b4 100644
|
|
--- a/sound/pci/rme96.c
|
|
+++ b/sound/pci/rme96.c
|
|
@@ -703,10 +703,11 @@ snd_rme96_playback_setrate(struct rme96 *rme96,
|
|
{
|
|
/* change to/from double-speed: reset the DAC (if available) */
|
|
snd_rme96_reset_dac(rme96);
|
|
+ return 1; /* need to restore volume */
|
|
} else {
|
|
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
|
|
+ return 0;
|
|
}
|
|
- return 0;
|
|
}
|
|
|
|
static int
|
|
@@ -944,6 +945,7 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
|
|
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
int err, rate, dummy;
|
|
+ bool apply_dac_volume = false;
|
|
|
|
runtime->dma_area = (void __force *)(rme96->iobase +
|
|
RME96_IO_PLAY_BUFFER);
|
|
@@ -957,24 +959,26 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
|
|
{
|
|
/* slave clock */
|
|
if ((int)params_rate(params) != rate) {
|
|
- spin_unlock_irq(&rme96->lock);
|
|
- return -EIO;
|
|
- }
|
|
- } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
|
|
- spin_unlock_irq(&rme96->lock);
|
|
- return err;
|
|
- }
|
|
- if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
|
|
- spin_unlock_irq(&rme96->lock);
|
|
- return err;
|
|
+ err = -EIO;
|
|
+ goto error;
|
|
+ }
|
|
+ } else {
|
|
+ err = snd_rme96_playback_setrate(rme96, params_rate(params));
|
|
+ if (err < 0)
|
|
+ goto error;
|
|
+ apply_dac_volume = err > 0; /* need to restore volume later? */
|
|
}
|
|
+
|
|
+ err = snd_rme96_playback_setformat(rme96, params_format(params));
|
|
+ if (err < 0)
|
|
+ goto error;
|
|
snd_rme96_setframelog(rme96, params_channels(params), 1);
|
|
if (rme96->capture_periodsize != 0) {
|
|
if (params_period_size(params) << rme96->playback_frlog !=
|
|
rme96->capture_periodsize)
|
|
{
|
|
- spin_unlock_irq(&rme96->lock);
|
|
- return -EBUSY;
|
|
+ err = -EBUSY;
|
|
+ goto error;
|
|
}
|
|
}
|
|
rme96->playback_periodsize =
|
|
@@ -985,9 +989,16 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
|
|
rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
|
|
writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
|
|
}
|
|
+
|
|
+ err = 0;
|
|
+ error:
|
|
spin_unlock_irq(&rme96->lock);
|
|
-
|
|
- return 0;
|
|
+ if (apply_dac_volume) {
|
|
+ usleep_range(3000, 10000);
|
|
+ snd_rme96_apply_dac_volume(rme96);
|
|
+ }
|
|
+
|
|
+ return err;
|
|
}
|
|
|
|
static int
|
|
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
|
|
index 663a2a748626..56815af4e00b 100644
|
|
--- a/sound/soc/codecs/arizona.c
|
|
+++ b/sound/soc/codecs/arizona.c
|
|
@@ -1057,7 +1057,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
|
|
int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
|
|
int bclk, lrclk, wl, frame, bclk_target;
|
|
|
|
- if (params_rate(params) % 8000)
|
|
+ if (params_rate(params) % 4000)
|
|
rates = &arizona_44k1_bclk_rates[0];
|
|
else
|
|
rates = &arizona_48k_bclk_rates[0];
|
|
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
|
|
index 1ae1f8bd9c36..305d28dec668 100644
|
|
--- a/sound/soc/codecs/wm8962.c
|
|
+++ b/sound/soc/codecs/wm8962.c
|
|
@@ -363,8 +363,8 @@ static struct reg_default wm8962_reg[] = {
|
|
{ 16924, 0x0059 }, /* R16924 - HDBASS_PG_1 */
|
|
{ 16925, 0x999A }, /* R16925 - HDBASS_PG_0 */
|
|
|
|
- { 17048, 0x0083 }, /* R17408 - HPF_C_1 */
|
|
- { 17049, 0x98AD }, /* R17409 - HPF_C_0 */
|
|
+ { 17408, 0x0083 }, /* R17408 - HPF_C_1 */
|
|
+ { 17409, 0x98AD }, /* R17409 - HPF_C_0 */
|
|
|
|
{ 17920, 0x007F }, /* R17920 - ADCL_RETUNE_C1_1 */
|
|
{ 17921, 0xFFFF }, /* R17921 - ADCL_RETUNE_C1_0 */
|
|
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
|
|
index 06a8000aa07b..2340554981d6 100644
|
|
--- a/sound/soc/soc-compress.c
|
|
+++ b/sound/soc/soc-compress.c
|
|
@@ -384,17 +384,34 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
|
|
struct snd_compr *compr;
|
|
char new_name[64];
|
|
int ret = 0, direction = 0;
|
|
+ int playback = 0, capture = 0;
|
|
|
|
/* check client and interface hw capabilities */
|
|
snprintf(new_name, sizeof(new_name), "%s %s-%d",
|
|
rtd->dai_link->stream_name, codec_dai->name, num);
|
|
|
|
if (codec_dai->driver->playback.channels_min)
|
|
+ playback = 1;
|
|
+ if (codec_dai->driver->capture.channels_min)
|
|
+ capture = 1;
|
|
+
|
|
+ capture = capture && cpu_dai->driver->capture.channels_min;
|
|
+ playback = playback && cpu_dai->driver->playback.channels_min;
|
|
+
|
|
+ /*
|
|
+ * Compress devices are unidirectional so only one of the directions
|
|
+ * should be set, check for that (xor)
|
|
+ */
|
|
+ if (playback + capture != 1) {
|
|
+ dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
|
|
+ playback, capture);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(playback)
|
|
direction = SND_COMPRESS_PLAYBACK;
|
|
- else if (codec_dai->driver->capture.channels_min)
|
|
- direction = SND_COMPRESS_CAPTURE;
|
|
else
|
|
- return -EINVAL;
|
|
+ direction = SND_COMPRESS_CAPTURE;
|
|
|
|
compr = kzalloc(sizeof(*compr), GFP_KERNEL);
|
|
if (compr == NULL) {
|