Skip to contentSkip to conversation

3.3.5-stable review

PATCH In review Greg KH 5 participants 88 messages May 4, 2012 – May 22, 2012 1 message not in the archive

Subsystems (43)
lore
Share & tools
lore

Greg KH

author maintainer
#0 lore raw

cover 3.3.5-stable review

This is the start of the stable review cycle for the 3.3.5 release. There are 75 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sun May 6 20:42:22 UTC 2012. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.3.5-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------

 Makefile                                    |    4 +-
 arch/arm/Kconfig                            |    9 +
 arch/arm/include/asm/tls.h                  |    4 +
 arch/arm/kernel/irq.c                       |    6 +-
 arch/arm/mm/abort-ev6.S                     |   17 +-
 arch/mips/ath79/dev-wmac.c                  |    2 +-
 arch/powerpc/platforms/85xx/common.c        |    6 +
 arch/powerpc/platforms/85xx/mpc85xx_mds.c   |   11 +-
 arch/powerpc/platforms/85xx/p1022_ds.c      |   13 +-
 arch/x86/boot/Makefile                      |    3 +-
 arch/x86/boot/compressed/Makefile           |    1 +
 arch/x86/boot/compressed/eboot.c            |    8 +-
 arch/x86/boot/compressed/head_32.S          |   14 +-
 arch/x86/boot/compressed/head_64.S          |   22 ++-
 arch/x86/boot/compressed/mkpiggy.c          |   11 +-
 arch/x86/boot/tools/build.c                 |   42 ++--
 arch/x86/include/asm/x86_init.h             |    1 -
 arch/x86/kernel/apic/apic.c                 |   34 ++--
 arch/x86/kernel/apic/apic_numachip.c        |    7 +-
 arch/x86/kernel/cpu/amd.c                   |    7 +-
 arch/x86/kernel/cpu/common.c                |    9 -
 arch/x86/kernel/i387.c                      |    1 +
 arch/x86/kernel/microcode_amd.c             |   12 +-
 arch/x86/kernel/microcode_core.c            |   10 +-
 arch/x86/kernel/x86_init.c                  |    1 -
 arch/x86/xen/smp.c                          |   15 ++
 arch/x86/xen/xen-asm.S                      |    2 +-
 drivers/ata/libata-eh.c                     |    3 +-
 drivers/crypto/talitos.c                    |   20 +-
 drivers/dma/at_hdmac.c                      |    4 -
 drivers/firmware/efivars.c                  |  196 +++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c  |    8 +-
 drivers/gpu/drm/i915/i915_reg.h             |    1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c     |    8 +
 drivers/gpu/drm/i915/intel_sdvo.c           |   34 ++--
 drivers/gpu/drm/nouveau/nouveau_acpi.c      |    2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c      |    4 +-
 drivers/hwmon/coretemp.c                    |    6 +-
 drivers/hwmon/fam15h_power.c                |   42 ++++
 drivers/i2c/busses/i2c-pnx.c                |    3 +-
 drivers/input/mouse/synaptics.c             |    3 +-
 drivers/md/raid5.c                          |    4 +-
 drivers/net/wireless/b43/main.c             |   10 +-
 drivers/net/wireless/ipw2x00/ipw2200.c      |   13 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c     |    8 +-
 drivers/net/wireless/iwlwifi/iwl-2000.c     |   16 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c     |   11 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c     |   10 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    3 -
 drivers/net/wireless/iwlwifi/iwl-fh.h       |   24 ++-
 drivers/net/wireless/iwlwifi/iwl-mac80211.c |   10 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h     |   27 ++-
 drivers/net/wireless/rtlwifi/pci.c          |    1 +
 drivers/net/wireless/wl1251/main.c          |    1 +
 drivers/net/wireless/wl1251/sdio.c          |    2 +-
 drivers/platform/x86/dell-laptop.c          |    1 +
 drivers/scsi/libsas/sas_expander.c          |   26 ++-
 drivers/usb/class/cdc-wdm.c                 |    7 +-
 drivers/usb/core/hcd-pci.c                  |    9 +
 drivers/usb/gadget/dummy_hcd.c              |    1 -
 drivers/usb/gadget/f_mass_storage.c         |    2 +-
 drivers/usb/gadget/file_storage.c           |    2 +-
 drivers/usb/gadget/uvc.h                    |    2 +-
 drivers/usb/gadget/uvc_v4l2.c               |    2 +-
 drivers/usb/host/ehci-pci.c                 |    8 +
 drivers/usb/host/ehci-tegra.c               |    1 -
 fs/autofs4/autofs_i.h                       |   12 +-
 fs/autofs4/dev-ioctl.c                      |    3 +-
 fs/autofs4/inode.c                          |    4 +-
 fs/autofs4/waitq.c                          |   20 +-
 fs/exec.c                                   |    3 +
 fs/nfs/nfs4proc.c                           |   23 ++-
 fs/nfs/read.c                               |    2 +-
 fs/nfs/super.c                              |    8 +-
 fs/nfs/write.c                              |    2 +-
 fs/pipe.c                                   |   31 ++-
 include/linux/efi.h                         |   13 +-
 include/linux/pipe_fs_i.h                   |    1 +
 include/linux/usb/hcd.h                     |    2 +
 kernel/exit.c                               |   19 --
 kernel/power/swap.c                         |   28 ++-
 kernel/sched/core.c                         |   75 ++++----
 kernel/signal.c                             |    9 +
 kernel/trace/trace_output.c                 |    5 +
 net/mac80211/tx.c                           |    3 +-
 net/wireless/nl80211.c                      |   29 +--
 sound/pci/hda/patch_realtek.c               |    1 +
 sound/soc/codecs/wm8994.c                   |  276 +++++++++++++++++++++------
 sound/soc/soc-dapm.c                        |    2 +
 89 files changed, 1022 insertions(+), 356 deletions(-)
author maintainer
#1 lore raw

PATCH 1/75 nfs: Enclose hostname in brackets when needed in nfs_do_root_mount

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <[email protected]>

commit 98a2139f4f4d7b5fcc3a54c7fddbe88612abed20 upstream.

When hostname contains colon (e.g. when it is an IPv6 address) it needs to be enclosed in brackets to make parsing of NFS device string possible. Fix nfs_do_root_mount() to enclose hostname properly when needed. NFS code actually does not need this as it does not parse the string passed by nfs_do_root_mount() but the device string is exposed to userspace in /proc/mounts.

---
 fs/nfs/super.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
fs/nfs/super.c +6 -2
@@ -2707,11 +2707,15 @@ static struct vfsmount *nfs_do_root_moun
 	char *root_devname;
 	size_t len;
 
-	len = strlen(hostname) + 3;
+	len = strlen(hostname) + 5;
 	root_devname = kmalloc(len, GFP_KERNEL);
 	if (root_devname == NULL)
 		return ERR_PTR(-ENOMEM);
-	snprintf(root_devname, len, "%s:/", hostname);
+	/* Does hostname needs to be enclosed in brackets? */
+	if (strchr(hostname, ':'))
+		snprintf(root_devname, len, "[%s]:/", hostname);
+	else
+		snprintf(root_devname, len, "%s:/", hostname);
 	root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
 	kfree(root_devname);
 	return root_mnt;
author maintainer
#2 lore raw

PATCH 2/75 NFSv4: Ensure that the LOCK code sets exception->inode

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

commit 05ffe24f5290dc095f98fbaf84afe51ef404ccc5 upstream.

All callers of nfs4_handle_exception() that need to handle NFS4ERR_OPENMODE correctly should set exception->inode

---
 fs/nfs/nfs4proc.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +7 -2
@@ -4460,7 +4460,9 @@ static int _nfs4_do_setlk(struct nfs4_st
 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
-	struct nfs4_exception exception = { };
+	struct nfs4_exception exception = {
+		.inode = state->inode,
+	};
 	int err;
 
 	do {
@@ -4478,7 +4480,9 @@ static int nfs4_lock_reclaim(struct nfs4
 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
-	struct nfs4_exception exception = { };
+	struct nfs4_exception exception = {
+		.inode = state->inode,
+	};
 	int err;
 
 	err = nfs4_set_lock_state(state, request);
@@ -4558,6 +4562,7 @@ static int nfs4_proc_setlk(struct nfs4_s
 {
 	struct nfs4_exception exception = {
 		.state = state,
+		.inode = state->inode,
 	};
 	int err;
 
author maintainer
#3 lore raw

PATCH 3/75 NFSv4: Ensure that we check lock exclusive/shared type against open modes

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

commit 55725513b5ef9d462aa3e18527658a0362aaae83 upstream.

Since we may be simulating flock() locks using NFS byte range locks, we can't rely on the VFS having checked the file open mode for us.

---
 fs/nfs/nfs4proc.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
fs/nfs/nfs4proc.c +14 -0
@@ -4608,6 +4608,20 @@ nfs4_proc_lock(struct file *filp, int cm
 
 	if (state == NULL)
 		return -ENOLCK;
+	/*
+	 * Don't rely on the VFS having checked the file open mode,
+	 * since it won't do this for flock() locks.
+	 */
+	switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) {
+	case F_RDLCK:
+		if (!(filp->f_mode & FMODE_READ))
+			return -EBADF;
+		break;
+	case F_WRLCK:
+		if (!(filp->f_mode & FMODE_WRITE))
+			return -EBADF;
+	}
+
 	do {
 		status = nfs4_proc_setlk(state, cmd, request);
 		if ((status != -EAGAIN) || IS_SETLK(cmd))
author maintainer
#4 lore raw

PATCH 4/75 NFS: put open context on error in nfs_pagein_multi

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Fred Isaman <[email protected]>

commit 73fb7bc7c57d971b11f2e00536ac2d3e316e0609 upstream.

---
 fs/nfs/read.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/read.c +1 -1
@@ -324,7 +324,7 @@ out_bad:
 	while (!list_empty(res)) {
 		data = list_entry(res->next, struct nfs_read_data, list);
 		list_del(&data->list);
-		nfs_readdata_free(data);
+		nfs_readdata_release(data);
 	}
 	nfs_readpage_release(req);
 	return -ENOMEM;
author maintainer
#5 lore raw

PATCH 5/75 NFS: put open context on error in nfs_flush_multi

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Fred Isaman <[email protected]>

commit 8ccd271f7a3a846ce6f85ead0760d9d12994a611 upstream.

---
 fs/nfs/write.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/write.c +1 -1
@@ -974,7 +974,7 @@ out_bad:
 	while (!list_empty(res)) {
 		data = list_entry(res->next, struct nfs_write_data, list);
 		list_del(&data->list);
-		nfs_writedata_free(data);
+		nfs_writedata_release(data);
 	}
 	nfs_redirty_request(req);
 	return -ENOMEM;
author maintainer
#6 lore raw

PATCH 6/75 x86, microcode: Fix sysfs warning during module unload on unsupported CPUs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Herrmann <[email protected]>

commit a956bd6f8583326b18348ab1452b4686778f785d upstream.

Loading the microcode driver on an unsupported CPU and subsequently unloading the driver causes

 WARNING: at fs/sysfs/group.c:138 mc_device_remove+0x5f/0x70 [microcode]()
 Hardware name: 01972NG
 sysfs group ffffffffa00013d0 not found for kobject 'cpu0'
 Modules linked in: snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel btusb snd_hda_codec bluetooth thinkpad_acpi rfkill microcode(-) [last unloaded: cfg80211]
 Pid: 4560, comm: modprobe Not tainted 3.4.0-rc2-00002-g258f742 #5
 Call Trace:
  [<ffffffff8103113b>] ? warn_slowpath_common+0x7b/0xc0
  [<ffffffff81031235>] ? warn_slowpath_fmt+0x45/0x50
  [<ffffffff81120e74>] ? sysfs_remove_group+0x34/0x120
  [<ffffffffa00000ef>] ? mc_device_remove+0x5f/0x70 [microcode]
  [<ffffffff81331eb9>] ? subsys_interface_unregister+0x69/0xa0
  [<ffffffff81563526>] ? mutex_lock+0x16/0x40
  [<ffffffffa0000c3e>] ? microcode_exit+0x50/0x92 [microcode]
  [<ffffffff8107051d>] ? sys_delete_module+0x16d/0x260
  [<ffffffff810a0065>] ? wait_iff_congested+0x45/0x110
  [<ffffffff815656af>] ? page_fault+0x1f/0x30
  [<ffffffff81565ba2>] ? system_call_fastpath+0x16/0x1b

on recent kernels.

This is due to commit 8a25a2fd126c ("cpu: convert 'cpu' and 'machinecheck' sysdev_class to a regular subsystem") which renders commit 6c53cbfced04 ("x86, microcode: Correct sysdev_add error path") useless.

See http://marc.info/?l=linux-kernel&m=133416246406478

Avoid above warning by restoring the old driver behaviour before 6c53cbfced04 ("x86, microcode: Correct sysdev_add error path").

---
 arch/x86/kernel/microcode_core.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/kernel/microcode_core.c +1 -3
@@ -418,10 +418,8 @@ static int mc_device_add(struct device *
 	if (err)
 		return err;
 
-	if (microcode_init_cpu(cpu) == UCODE_ERROR) {
-		sysfs_remove_group(&dev->kobj, &mc_attr_group);
+	if (microcode_init_cpu(cpu) == UCODE_ERROR)
 		return -EINVAL;
-	}
 
 	return err;
 }
author maintainer
#7 lore raw

PATCH 7/75 x86, microcode: Ensure that module is only loaded on supported AMD CPUs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Herrmann <[email protected]>

commit 283c1f2558ef4a4411fe908364b15b73b6ab44cf upstream.

Exit early when there's no support for a particular CPU family. Also, fixup the "no support for this CPU vendor" to be issued only when the driver is attempted to be loaded on an unsupported vendor.

---
 arch/x86/kernel/microcode_amd.c  |   12 +++++++-----
 arch/x86/kernel/microcode_core.c |    6 +++---
 2 files changed, 10 insertions(+), 8 deletions(-)
arch/x86/kernel/microcode_amd.c +7 -5
@@ -82,11 +82,6 @@ static int collect_cpu_info_amd(int cpu,
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
-		pr_warning("CPU%d: family %d not supported\n", cpu, c->x86);
-		return -1;
-	}
-
 	csig->rev = c->microcode;
 	pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
 
@@ -380,6 +375,13 @@ static struct microcode_ops microcode_am
 
 struct microcode_ops * __init init_amd_microcode(void)
 {
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
+		pr_warning("AMD CPU family 0x%x not supported\n", c->x86);
+		return NULL;
+	}
+
 	patch = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!patch)
 		return NULL;
arch/x86/kernel/microcode_core.c +3 -3
@@ -511,11 +511,11 @@ static int __init microcode_init(void)
 		microcode_ops = init_intel_microcode();
 	else if (c->x86_vendor == X86_VENDOR_AMD)
 		microcode_ops = init_amd_microcode();
-
-	if (!microcode_ops) {
+	else
 		pr_err("no support for this CPU vendor\n");
+
+	if (!microcode_ops)
 		return -ENODEV;
-	}
 
 	microcode_pdev = platform_device_register_simple("microcode", -1,
 							 NULL, 0);
author maintainer
#8 lore raw

PATCH 8/75 x86, apic: APIC code touches invalid MSR on P5 class machines

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryan O'Donoghue <[email protected]>

commit cbf2829b61c136edcba302a5e1b6b40e97d32c00 upstream.

Current APIC code assumes MSR_IA32_APICBASE is present for all systems. Pentium Classic P5 and friends didn't have this MSR. MSR_IA32_APICBASE was introduced as an architectural MSR by Intel @ P6.

Code paths that can touch this MSR invalidly are when vendor == Intel && cpu-family == 5 and APIC bit is set in CPUID - or when you simply pass lapic on the kernel command line, on a P5.

The below patch stops Linux incorrectly interfering with the MSR_IA32_APICBASE for P5 class machines. Other code paths exist that touch the MSR - however those paths are not currently reachable for a conformant P5.

---
 arch/x86/kernel/apic/apic.c |   34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)
arch/x86/kernel/apic/apic.c +20 -14
@@ -1632,9 +1632,11 @@ static int __init apic_verify(void)
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
 
 	/* The BIOS may have set up the APIC at some other address */
-	rdmsr(MSR_IA32_APICBASE, l, h);
-	if (l & MSR_IA32_APICBASE_ENABLE)
-		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
+	if (boot_cpu_data.x86 >= 6) {
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		if (l & MSR_IA32_APICBASE_ENABLE)
+			mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
+	}
 
 	pr_info("Found and enabled local APIC!\n");
 	return 0;
@@ -1652,13 +1654,15 @@ int __init apic_force_enable(unsigned lo
 	 * MSR. This can only be done in software for Intel P6 or later
 	 * and AMD K7 (Model > 1) or later.
 	 */
-	rdmsr(MSR_IA32_APICBASE, l, h);
-	if (!(l & MSR_IA32_APICBASE_ENABLE)) {
-		pr_info("Local APIC disabled by BIOS -- reenabling.\n");
-		l &= ~MSR_IA32_APICBASE_BASE;
-		l |= MSR_IA32_APICBASE_ENABLE | addr;
-		wrmsr(MSR_IA32_APICBASE, l, h);
-		enabled_via_apicbase = 1;
+	if (boot_cpu_data.x86 >= 6) {
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		if (!(l & MSR_IA32_APICBASE_ENABLE)) {
+			pr_info("Local APIC disabled by BIOS -- reenabling.\n");
+			l &= ~MSR_IA32_APICBASE_BASE;
+			l |= MSR_IA32_APICBASE_ENABLE | addr;
+			wrmsr(MSR_IA32_APICBASE, l, h);
+			enabled_via_apicbase = 1;
+		}
 	}
 	return apic_verify();
 }
@@ -2204,10 +2208,12 @@ static void lapic_resume(void)
 		 * FIXME! This will be wrong if we ever support suspend on
 		 * SMP! We'll need to do this as part of the CPU restore!
 		 */
-		rdmsr(MSR_IA32_APICBASE, l, h);
-		l &= ~MSR_IA32_APICBASE_BASE;
-		l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
-		wrmsr(MSR_IA32_APICBASE, l, h);
+		if (boot_cpu_data.x86 >= 6) {
+			rdmsr(MSR_IA32_APICBASE, l, h);
+			l &= ~MSR_IA32_APICBASE_BASE;
+			l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
+			wrmsr(MSR_IA32_APICBASE, l, h);
+		}
 	}
 
 	maxlvt = lapic_get_maxlvt();
author maintainer
#9 lore raw

PATCH 9/75 x86/platform: Remove incorrect error message in x86_default_fixup_cpu_id()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Herrmann <[email protected]>

commit 68894632afb2729a1d8785c877840953894c7283 upstream.

It's only called from amd.c:srat_detect_node(). The introduced condition for calling the fixup code is true for all AMD multi-node processors, e.g. Magny-Cours and Interlagos. There we have 2 NUMA nodes on one socket. Thus there are cores having different numa-node-id but with equal phys_proc_id.

There is no point to print error messages in such a situation.

The confusing/misleading error message was introduced with commit 64be4c1c2428e148de6081af235e2418e6a66dda ("x86: Add x86_init platform override to fix up NUMA core numbering").

Remove the default fixup function (especially the error message) and replace it by a NULL pointer check, move the Numascale-specific condition for calling the fixup into the fixup-function itself and slightly adapt the comment.

---
 arch/x86/include/asm/x86_init.h      |    1 -
 arch/x86/kernel/apic/apic_numachip.c |    7 +++++--
 arch/x86/kernel/cpu/amd.c            |    7 ++++---
 arch/x86/kernel/cpu/common.c         |    9 ---------
 arch/x86/kernel/x86_init.c           |    1 -
 5 files changed, 9 insertions(+), 16 deletions(-)
arch/x86/include/asm/x86_init.h +0 -1
@@ -189,6 +189,5 @@ extern struct x86_msi_ops x86_msi;
 
 extern void x86_init_noop(void);
 extern void x86_init_uint_noop(unsigned int unused);
-extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node);
 
 #endif
arch/x86/kernel/apic/apic_numachip.c +5 -2
@@ -201,8 +201,11 @@ static void __init map_csrs(void)
 
 static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
 {
-	c->phys_proc_id = node;
-	per_cpu(cpu_llc_id, smp_processor_id()) = node;
+
+	if (c->phys_proc_id != node) {
+		c->phys_proc_id = node;
+		per_cpu(cpu_llc_id, smp_processor_id()) = node;
+	}
 }
 
 static int __init numachip_system_init(void)
arch/x86/kernel/cpu/amd.c +4 -3
@@ -352,10 +352,11 @@ static void __cpuinit srat_detect_node(s
 		node = per_cpu(cpu_llc_id, cpu);
 
 	/*
-	 * If core numbers are inconsistent, it's likely a multi-fabric platform,
-	 * so invoke platform-specific handler
+	 * On multi-fabric platform (e.g. Numascale NumaChip) a
+	 * platform-specific handler needs to be called to fixup some
+	 * IDs of the CPU.
 	 */
-	if (c->phys_proc_id != node)
+	if (x86_cpuinit.fixup_cpu_id)
 		x86_cpuinit.fixup_cpu_id(c, node);
 
 	if (!node_online(node)) {
arch/x86/kernel/cpu/common.c +0 -9
@@ -1163,15 +1163,6 @@ static void dbg_restore_debug_regs(void)
 #endif /* ! CONFIG_KGDB */
 
 /*
- * Prints an error where the NUMA and configured core-number mismatch and the
- * platform didn't override this to fix it up
- */
-void __cpuinit x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node)
-{
-	pr_err("NUMA core number %d differs from configured core number %d\n", node, c->phys_proc_id);
-}
-
-/*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
  * and IDT. We reload them nevertheless, this function acts as a
arch/x86/kernel/x86_init.c +0 -1
@@ -92,7 +92,6 @@ struct x86_init_ops x86_init __initdata
 
 struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
 	.setup_percpu_clockev		= setup_secondary_APIC_clock,
-	.fixup_cpu_id			= x86_default_fixup_cpu_id,
 };
 
 static void default_nmi_init(void) { };
author maintainer
#10 lore raw

PATCH 10/75 Revert "autofs: work around unhappy compat problem on x86-64"

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit fcbf94b9dedd2ce08e798a99aafc94fec8668161 upstream.

This reverts commit a32744d4abae24572eff7269bc17895c41bd0085.

While that commit was technically the right thing to do, and made the x86-64 compat mode work identically to native 32-bit mode (and thus fixing the problem with a 32-bit systemd install on a 64-bit kernel), it turns out that the automount binaries had workarounds for this compat problem.

Now, the workarounds are disgusting: doing an "uname()" to find out the architecture of the kernel, and then comparing it for the 64-bit cases and fixing up the size of the read() in automount for those. And they were confused: it's not actually a generic 64-bit issue at all, it's very much tied to just x86-64, which has different alignment for an 'u64' in 64-bit mode than in 32-bit mode.

But the end result is that fixing the compat layer actually breaks the case of a 32-bit automount on a x86-64 kernel.

There are various approaches to fix this (including just doing a "strcmp()" on current->comm and comparing it to "automount"), but I think that I will do the one that teaches pipes about a special "packet mode", which will allow user space to not have to care too deeply about the padding at the end of the autofs packet.

That change will make the compat workaround unnecessary, so let's revert it first, and get automount working again in compat mode. The packetized pipes will then fix autofs for systemd.

---
 fs/autofs4/autofs_i.h  |    1 -
 fs/autofs4/dev-ioctl.c |    1 -
 fs/autofs4/inode.c     |    2 --
 fs/autofs4/waitq.c     |   22 +++-------------------
 4 files changed, 3 insertions(+), 23 deletions(-)
fs/autofs4/autofs_i.h +0 -1
@@ -110,7 +110,6 @@ struct autofs_sb_info {
 	int sub_version;
 	int min_proto;
 	int max_proto;
-	int compat_daemon;
 	unsigned long exp_timeout;
 	unsigned int type;
 	int reghost_enabled;
fs/autofs4/dev-ioctl.c +0 -1
@@ -385,7 +385,6 @@ static int autofs_dev_ioctl_setpipefd(st
 		sbi->pipefd = pipefd;
 		sbi->pipe = pipe;
 		sbi->catatonic = 0;
-		sbi->compat_daemon = is_compat_task();
 	}
 out:
 	mutex_unlock(&sbi->wq_mutex);
fs/autofs4/inode.c +0 -2
@@ -19,7 +19,6 @@
 #include <linux/parser.h>
 #include <linux/bitops.h>
 #include <linux/magic.h>
-#include <linux/compat.h>
 #include "autofs_i.h"
 #include <linux/module.h>
 
@@ -225,7 +224,6 @@ int autofs4_fill_super(struct super_bloc
 	set_autofs_type_indirect(&sbi->type);
 	sbi->min_proto = 0;
 	sbi->max_proto = 0;
-	sbi->compat_daemon = is_compat_task();
 	mutex_init(&sbi->wq_mutex);
 	mutex_init(&sbi->pipe_mutex);
 	spin_lock_init(&sbi->fs_lock);
fs/autofs4/waitq.c +3 -19
@@ -91,24 +91,7 @@ static int autofs4_write(struct autofs_s
 
 	return (bytes > 0);
 }
-
-/*
- * The autofs_v5 packet was misdesigned.
- *
- * The packets are identical on x86-32 and x86-64, but have different
- * alignment. Which means that 'sizeof()' will give different results.
- * Fix it up for the case of running 32-bit user mode on a 64-bit kernel.
- */
-static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi)
-{
-	size_t pktsz = sizeof(struct autofs_v5_packet);
-#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
-	if (sbi->compat_daemon > 0)
-		pktsz -= 4;
-#endif
-	return pktsz;
-}
-
+
 static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
 				 struct autofs_wait_queue *wq,
 				 int type)
@@ -172,7 +155,8 @@ static void autofs4_notify_daemon(struct
 	{
 		struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
 
-		pktsz = autofs_v5_packet_size(sbi);
+		pktsz = sizeof(*packet);
+
 		packet->wait_queue_token = wq->wait_queue_token;
 		packet->len = wq->name.len;
 		memcpy(packet->name, wq->name.name, wq->name.len);
author maintainer
#11 lore raw

PATCH 11/75 xen: correctly check for pending events when restoring irq flags

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Vrabel <[email protected]>

commit 7eb7ce4d2e8991aff4ecb71a81949a907ca755ac upstream.

In xen_restore_fl_direct(), xen_force_evtchn_callback() was being called even if no events were pending. This resulted in (depending on workload) about a 100 times as many xen_version hypercalls as necessary.

Fix this by correcting the sense of the conditional jump.

This seems to give a significant performance benefit for some workloads.

There is some subtle tricksy "..since the check here is trying to check both pending and masked in a single cmpw, but I think this is correct. It will call check_events now only when the combined mask+pending word is 0x0001 (aka unmasked, pending)." (Ian)

---
 arch/x86/xen/xen-asm.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/xen-asm.S +1 -1
@@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct)
 
 	/* check for unmasked and pending */
 	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
-	jz 1f
+	jnz 1f
 2:	call check_events
 1:
 ENDPATCH(xen_restore_fl_direct)
author maintainer
#12 lore raw

PATCH 12/75 xen/smp: Fix crash when booting with ACPI hotplug CPUs.

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Konrad Rzeszutek Wilk <[email protected]>

commit cf405ae612b0f7e2358db7ff594c0e94846137aa upstream.

When we boot on a machine that can hotplug CPUs and we are using 'dom0_max_vcpus=X' on the Xen hypervisor line to clip the amount of CPUs available to the initial domain, we get this:

(XEN) Command line: com1=115200,8n1 dom0_mem=8G noreboot dom0_max_vcpus=8 sync_console mce_verbosity=verbose console=com1,vga loglvl=all guest_loglvl=all .. snip..
DMI: Intel Corporation S2600CP/S2600CP, BIOS SE5C600.86B.99.99.x032.072520111118 07/25/2011
.. snip.
SMP: Allowing 64 CPUs, 32 hotplug CPUs
installing Xen timer for CPU 7
cpu 7 spinlock event irq 361
NMI watchdog: disabled (cpu7): hardware events not enabled
Brought up 8 CPUs
.. snip..
[acpi processor finds the CPUs are not initialized and starts calling
arch_register_cpu, which creates /sys/devices/system/cpu/cpu8/online]
CPU 8 got hotplugged
CPU 9 got hotplugged
CPU 10 got hotplugged
.. snip..
initcall 1_acpi_battery_init_async+0x0/0x1b returned 0 after 406 usecs
calling erst_init+0x0/0x2bb @ 1

[and the scheduler sticks newly started tasks on the new CPUs, but said CPUs cannot be initialized b/c the hypervisor has limited the amount of vCPUS to 8 - as per the dom0_max_vcpus=8 flag. The spinlock tries to kick the other CPU, but the structure for that is not initialized and we crash.]

BUG: unable to handle kernel paging request at fffffffffffffed8
IP: [<ffffffff81035289>] xen_spin_lock+0x29/0x60
PGD 180d067 PUD 180e067 PMD 0
Oops: 0002 [#1] SMP
CPU 7
Modules linked in:

Pid: 1, comm: swapper/0 Not tainted 3.4.0-rc2upstream-00001-gf5154e8 #1 Intel Corporation S2600CP/S2600CP

RIP: e030:[<ffffffff81035289>]  [<ffffffff81035289>] xen_spin_lock+0x29/0x60
RSP: e02b:ffff8801fb9b3a70  EFLAGS: 00010282

With this patch, we cap the amount of vCPUS that the initial domain can run, to exactly what dom0_max_vcpus=X has specified.

In the future, if there is a hypercall that will allow a running domain to expand past its initial set of vCPUS, this patch should be re-evaluated.

---
 arch/x86/xen/smp.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)
arch/x86/xen/smp.c +15 -0
@@ -172,6 +172,7 @@ static void __init xen_fill_possible_map
 static void __init xen_filter_cpu_maps(void)
 {
 	int i, rc;
+	unsigned int subtract = 0;
 
 	if (!xen_initial_domain())
 		return;
@@ -186,8 +187,22 @@ static void __init xen_filter_cpu_maps(v
 		} else {
 			set_cpu_possible(i, false);
 			set_cpu_present(i, false);
+			subtract++;
 		}
 	}
+#ifdef CONFIG_HOTPLUG_CPU
+	/* This is akin to using 'nr_cpus' on the Linux command line.
+	 * Which is OK as when we use 'dom0_max_vcpus=X' we can only
+	 * have up to X, while nr_cpu_ids is greater than X. This
+	 * normally is not a problem, except when CPU hotplugging
+	 * is involved and then there might be more than X CPUs
+	 * in the guest - which will not work as there is no
+	 * hypercall to expand the max number of VCPUs an already
+	 * running guest has. So cap it up to X. */
+	if (subtract)
+		nr_cpu_ids = nr_cpu_ids - subtract;
+#endif
+
 }
 
 static void __init xen_smp_prepare_boot_cpu(void)
author maintainer
#13 lore raw

PATCH 13/75 ASoC: dapm: Ensure power gets managed for line widgets

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Brown <[email protected]>

commit 7e1f7c8a6e517900cd84da1b8ae020f08f286c3b upstream.

Line widgets had not been included in either the power up or power down sequences so if a widget had an event associated with it that event would never be run. Fix this minimally by adding them to the sequences, we should probably be doing away with the specific widget types as they all have the same priority anyway.

---
 sound/soc/soc-dapm.c |    2 ++
 1 file changed, 2 insertions(+)
sound/soc/soc-dapm.c +2 -0
@@ -70,6 +70,7 @@ static int dapm_up_seq[] = {
 	[snd_soc_dapm_out_drv] = 10,
 	[snd_soc_dapm_hp] = 10,
 	[snd_soc_dapm_spk] = 10,
+	[snd_soc_dapm_line] = 10,
 	[snd_soc_dapm_post] = 11,
 };
 
@@ -78,6 +79,7 @@ static int dapm_down_seq[] = {
 	[snd_soc_dapm_adc] = 1,
 	[snd_soc_dapm_hp] = 2,
 	[snd_soc_dapm_spk] = 2,
+	[snd_soc_dapm_line] = 2,
 	[snd_soc_dapm_out_drv] = 2,
 	[snd_soc_dapm_pga] = 4,
 	[snd_soc_dapm_mixer_named_ctl] = 5,
author maintainer
#14 lore raw

PATCH 14/75 ASoC: wm8994: Improve sequencing of AIF channel enables

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Brown <[email protected]>

commit 1a38336b8611a04f0a624330c1f815421f4bf5f4 upstream.

This ensures a clean startup of the channels, without this change some use cases could result in issues in a small proportion of cases.

---
 sound/soc/codecs/wm8994.c |  276 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 222 insertions(+), 54 deletions(-)
sound/soc/codecs/wm8994.c +222 -54
@@ -929,61 +929,170 @@ static void wm8994_update_class_w(struct
 	}
 }
 
-static int late_enable_ev(struct snd_soc_dapm_widget *w,
-			  struct snd_kcontrol *kcontrol, int event)
+static int aif1clk_ev(struct snd_soc_dapm_widget *w,
+		      struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994 *control = codec->control_data;
+	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
+	int dac;
+	int adc;
+	int val;
+
+	switch (control->type) {
+	case WM8994:
+	case WM8958:
+		mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA;
+		break;
+	default:
+		break;
+	}
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		if (wm8994->aif1clk_enable) {
-			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
-					    WM8994_AIF1CLK_ENA_MASK,
-					    WM8994_AIF1CLK_ENA);
-			wm8994->aif1clk_enable = 0;
-		}
-		if (wm8994->aif2clk_enable) {
-			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
-					    WM8994_AIF2CLK_ENA_MASK,
-					    WM8994_AIF2CLK_ENA);
-			wm8994->aif2clk_enable = 0;
-		}
+		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
+		if ((val & WM8994_AIF1ADCL_SRC) &&
+		    (val & WM8994_AIF1ADCR_SRC))
+			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA;
+		else if (!(val & WM8994_AIF1ADCL_SRC) &&
+			 !(val & WM8994_AIF1ADCR_SRC))
+			adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
+		else
+			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA |
+				WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
+
+		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2);
+		if ((val & WM8994_AIF1DACL_SRC) &&
+		    (val & WM8994_AIF1DACR_SRC))
+			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA;
+		else if (!(val & WM8994_AIF1DACL_SRC) &&
+			 !(val & WM8994_AIF1DACR_SRC))
+			dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
+		else
+			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA |
+				WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
+
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+				    mask, adc);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    mask, dac);
+		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+				    WM8994_AIF1DSPCLK_ENA |
+				    WM8994_SYSDSPCLK_ENA,
+				    WM8994_AIF1DSPCLK_ENA |
+				    WM8994_SYSDSPCLK_ENA);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask,
+				    WM8994_AIF1ADC1R_ENA |
+				    WM8994_AIF1ADC1L_ENA |
+				    WM8994_AIF1ADC2R_ENA |
+				    WM8994_AIF1ADC2L_ENA);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask,
+				    WM8994_AIF1DAC1R_ENA |
+				    WM8994_AIF1DAC1L_ENA |
+				    WM8994_AIF1DAC2R_ENA |
+				    WM8994_AIF1DAC2L_ENA);
 		break;
-	}
 
-	/* We may also have postponed startup of DSP, handle that. */
-	wm8958_aif_ev(w, kcontrol, event);
+	case SND_SOC_DAPM_PRE_PMD:
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    mask, 0);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+				    mask, 0);
+
+		val = snd_soc_read(codec, WM8994_CLOCKING_1);
+		if (val & WM8994_AIF2DSPCLK_ENA)
+			val = WM8994_SYSDSPCLK_ENA;
+		else
+			val = 0;
+		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+				    WM8994_SYSDSPCLK_ENA |
+				    WM8994_AIF1DSPCLK_ENA, val);
+		break;
+	}
 
 	return 0;
 }
 
-static int late_disable_ev(struct snd_soc_dapm_widget *w,
-			   struct snd_kcontrol *kcontrol, int event)
+static int aif2clk_ev(struct snd_soc_dapm_widget *w,
+		      struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
-	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	int dac;
+	int adc;
+	int val;
 
 	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1);
+		if ((val & WM8994_AIF2ADCL_SRC) &&
+		    (val & WM8994_AIF2ADCR_SRC))
+			adc = WM8994_AIF2ADCR_ENA;
+		else if (!(val & WM8994_AIF2ADCL_SRC) &&
+			 !(val & WM8994_AIF2ADCR_SRC))
+			adc = WM8994_AIF2ADCL_ENA;
+		else
+			adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
+
+
+		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2);
+		if ((val & WM8994_AIF2DACL_SRC) &&
+		    (val & WM8994_AIF2DACR_SRC))
+			dac = WM8994_AIF2DACR_ENA;
+		else if (!(val & WM8994_AIF2DACL_SRC) &&
+			 !(val & WM8994_AIF2DACR_SRC))
+			dac = WM8994_AIF2DACL_ENA;
+		else
+			dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA;
+
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+				    WM8994_AIF2ADCL_ENA |
+				    WM8994_AIF2ADCR_ENA, adc);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    WM8994_AIF2DACL_ENA |
+				    WM8994_AIF2DACR_ENA, dac);
+		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+				    WM8994_AIF2DSPCLK_ENA |
+				    WM8994_SYSDSPCLK_ENA,
+				    WM8994_AIF2DSPCLK_ENA |
+				    WM8994_SYSDSPCLK_ENA);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+				    WM8994_AIF2ADCL_ENA |
+				    WM8994_AIF2ADCR_ENA,
+				    WM8994_AIF2ADCL_ENA |
+				    WM8994_AIF2ADCR_ENA);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    WM8994_AIF2DACL_ENA |
+				    WM8994_AIF2DACR_ENA,
+				    WM8994_AIF2DACL_ENA |
+				    WM8994_AIF2DACR_ENA);
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
 	case SND_SOC_DAPM_POST_PMD:
-		if (wm8994->aif1clk_disable) {
-			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
-					    WM8994_AIF1CLK_ENA_MASK, 0);
-			wm8994->aif1clk_disable = 0;
-		}
-		if (wm8994->aif2clk_disable) {
-			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
-					    WM8994_AIF2CLK_ENA_MASK, 0);
-			wm8994->aif2clk_disable = 0;
-		}
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    WM8994_AIF2DACL_ENA |
+				    WM8994_AIF2DACR_ENA, 0);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				    WM8994_AIF2ADCL_ENA |
+				    WM8994_AIF2ADCR_ENA, 0);
+
+		val = snd_soc_read(codec, WM8994_CLOCKING_1);
+		if (val & WM8994_AIF1DSPCLK_ENA)
+			val = WM8994_SYSDSPCLK_ENA;
+		else
+			val = 0;
+		snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+				    WM8994_SYSDSPCLK_ENA |
+				    WM8994_AIF2DSPCLK_ENA, val);
 		break;
 	}
 
 	return 0;
 }
 
-static int aif1clk_ev(struct snd_soc_dapm_widget *w,
-		      struct snd_kcontrol *kcontrol, int event)
+static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
+			   struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1000,8 +1109,8 @@ static int aif1clk_ev(struct snd_soc_dap
 	return 0;
 }
 
-static int aif2clk_ev(struct snd_soc_dapm_widget *w,
-		      struct snd_kcontrol *kcontrol, int event)
+static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
+			   struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1018,6 +1127,63 @@ static int aif2clk_ev(struct snd_soc_dap
 	return 0;
 }
 
+static int late_enable_ev(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (wm8994->aif1clk_enable) {
+			aif1clk_ev(w, kcontrol, event);
+			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
+					    WM8994_AIF1CLK_ENA_MASK,
+					    WM8994_AIF1CLK_ENA);
+			wm8994->aif1clk_enable = 0;
+		}
+		if (wm8994->aif2clk_enable) {
+			aif2clk_ev(w, kcontrol, event);
+			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
+					    WM8994_AIF2CLK_ENA_MASK,
+					    WM8994_AIF2CLK_ENA);
+			wm8994->aif2clk_enable = 0;
+		}
+		break;
+	}
+
+	/* We may also have postponed startup of DSP, handle that. */
+	wm8958_aif_ev(w, kcontrol, event);
+
+	return 0;
+}
+
+static int late_disable_ev(struct snd_soc_dapm_widget *w,
+			   struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMD:
+		if (wm8994->aif1clk_disable) {
+			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
+					    WM8994_AIF1CLK_ENA_MASK, 0);
+			aif1clk_ev(w, kcontrol, event);
+			wm8994->aif1clk_disable = 0;
+		}
+		if (wm8994->aif2clk_disable) {
+			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
+					    WM8994_AIF2CLK_ENA_MASK, 0);
+			aif2clk_ev(w, kcontrol, event);
+			wm8994->aif2clk_disable = 0;
+		}
+		break;
+	}
+
+	return 0;
+}
+
 static int adc_mux_ev(struct snd_soc_dapm_widget *w,
 		      struct snd_kcontrol *kcontrol, int event)
 {
@@ -1314,9 +1480,9 @@ static const struct snd_kcontrol_new aif
 	SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
 
 static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
-SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev,
+SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev,
 	SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev,
+SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev,
 	SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
@@ -1345,8 +1511,10 @@ SND_SOC_DAPM_POST("Late Disable PGA", la
 };
 
 static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
-SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
 		   left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
@@ -1399,30 +1567,30 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM
 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
 		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
-SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0),
 
 SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
-		     0, WM8994_POWER_MANAGEMENT_4, 9, 0),
+		     0, SND_SOC_NOPM, 9, 0),
 SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
-		     0, WM8994_POWER_MANAGEMENT_4, 8, 0),
+		     0, SND_SOC_NOPM, 8, 0),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 9, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 8, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
-		     0, WM8994_POWER_MANAGEMENT_4, 11, 0),
+		     0, SND_SOC_NOPM, 11, 0),
 SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
-		     0, WM8994_POWER_MANAGEMENT_4, 10, 0),
+		     0, SND_SOC_NOPM, 10, 0),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 11, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 10, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
@@ -1449,14 +1617,14 @@ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SO
 		   dac1r_mix, ARRAY_SIZE(dac1r_mix)),
 
 SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
-		     WM8994_POWER_MANAGEMENT_4, 13, 0),
+		     SND_SOC_NOPM, 13, 0),
 SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
-		     WM8994_POWER_MANAGEMENT_4, 12, 0),
+		     SND_SOC_NOPM, 12, 0),
 SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 13, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
-		      WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
+		      SND_SOC_NOPM, 12, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
author maintainer
#15 lore raw

PATCH 15/75 dmaengine: at_hdmac: remove clear-on-read in atc_dostart()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicolas Ferre <[email protected]>

commit ed8b0d67f33518a16c6b2450fe5ebebf180c2d04 upstream.

This loop on EBCISR register was designed to clear IRQ sources before enabling a DMA channel. This register is clear-on-read so a race condition can appear if another channel is already active and has just finished its transfer. Removing this read on EBCISR is fixing the issue as there is no case where an IRQ could be pending: we already make sure that this register is drained at probe() time and during resume.

---
 drivers/dma/at_hdmac.c |    4 ----
 1 file changed, 4 deletions(-)
drivers/dma/at_hdmac.c +0 -4
@@ -241,10 +241,6 @@ static void atc_dostart(struct at_dma_ch
 
 	vdbg_dump_regs(atchan);
 
-	/* clear any pending interrupt */
-	while (dma_readl(atdma, EBCISR))
-		cpu_relax();
-
 	channel_writel(atchan, SADDR, 0);
 	channel_writel(atchan, DADDR, 0);
 	channel_writel(atchan, CTRLA, 0);
author maintainer
#16 lore raw

PATCH 16/75 sched: Fix OOPS when build_sched_domains() percpu allocation fails

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: "he, bo" <[email protected]>

commit fb2cf2c660971bea0ad86a9a5c19ad39eab61344 upstream.

Under extreme memory used up situations, percpu allocation might fail. We hit it when system goes to suspend-to-ram, causing a kworker panic:

EIP: [<c124411a>] build_sched_domains+0x23a/0xad0

 Kernel panic - not syncing: Fatal exception
 Pid: 3026, comm: kworker/u:3
 3.0.8-137473-gf42fbef #1

 Call Trace:
  [<c18cc4f2>] panic+0x66/0x16c
  [...]
  [<c1244c37>] partition_sched_domains+0x287/0x4b0
  [<c12a77be>] cpuset_update_active_cpus+0x1fe/0x210
  [<c123712d>] cpuset_cpu_inactive+0x1d/0x30
  [...]

With this fix applied build_sched_domains() will return -ENOMEM and the suspend attempt fails.

[ So, we fail to deallocate a CPU because we cannot allocate RAM :-/
I don't like that kind of sad behavior but nevertheless it should not crash under high memory load. ]

---
 kernel/sched/core.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
kernel/sched/core.c +16 -6
@@ -6334,16 +6334,26 @@ static void __sdt_free(const struct cpum
 		struct sd_data *sdd = &tl->data;
 
 		for_each_cpu(j, cpu_map) {
-			struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j);
-			if (sd && (sd->flags & SD_OVERLAP))
-				free_sched_groups(sd->groups, 0);
-			kfree(*per_cpu_ptr(sdd->sd, j));
-			kfree(*per_cpu_ptr(sdd->sg, j));
-			kfree(*per_cpu_ptr(sdd->sgp, j));
+			struct sched_domain *sd;
+
+			if (sdd->sd) {
+				sd = *per_cpu_ptr(sdd->sd, j);
+				if (sd && (sd->flags & SD_OVERLAP))
+					free_sched_groups(sd->groups, 0);
+				kfree(*per_cpu_ptr(sdd->sd, j));
+			}
+
+			if (sdd->sg)
+				kfree(*per_cpu_ptr(sdd->sg, j));
+			if (sdd->sgp)
+				kfree(*per_cpu_ptr(sdd->sgp, j));
 		}
 		free_percpu(sdd->sd);
+		sdd->sd = NULL;
 		free_percpu(sdd->sg);
+		sdd->sg = NULL;
 		free_percpu(sdd->sgp);
+		sdd->sgp = NULL;
 	}
 }
 
author maintainer
#17 lore raw

PATCH 17/75 tracing: Fix stacktrace of latency tracers (irqsoff and friends)

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <[email protected]>

commit db4c75cbebd7e5910cd3bcb6790272fcc3042857 upstream.

While debugging a latency with someone on IRC (mirage335) on #linux-rt (OFTC), we discovered that the stacktrace output of the latency tracers (preemptirqsoff) was empty.

This bug was caused by the creation of the dynamic length stack trace again (like commit 12b5da3 "tracing: Fix ent_size in trace output" was).

This bug is caused by the latency tracers requiring the next event to determine the time between the current event and the next. But by grabbing the next event, the iter->ent_size is set to the next event instead of the current one. As the stacktrace event is the last event, this makes the ent_size zero and causes nothing to be printed for the stack trace. The dynamic stacktrace uses the ent_size to determine how much of the stack can be printed. The ent_size of zero means no stack.

The simple fix is to save the iter->ent_size before finding the next event.

Note, mirage335 asked to remain anonymous from LKML and git, so I will not add the Reported-by and Tested-by tags, even though he did report the issue and tested the fix.

---
 kernel/trace/trace_output.c |    5 +++++
 1 file changed, 5 insertions(+)
kernel/trace/trace_output.c +5 -0
@@ -650,6 +650,8 @@ int trace_print_lat_context(struct trace
 {
 	u64 next_ts;
 	int ret;
+	/* trace_find_next_entry will reset ent_size */
+	int ent_size = iter->ent_size;
 	struct trace_seq *s = &iter->seq;
 	struct trace_entry *entry = iter->ent,
 			   *next_entry = trace_find_next_entry(iter, NULL,
@@ -658,6 +660,9 @@ int trace_print_lat_context(struct trace
 	unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
 	unsigned long rel_usecs;
 
+	/* Restore the original ent_size */
+	iter->ent_size = ent_size;
+
 	if (!next_entry)
 		next_ts = iter->ts;
 	rel_usecs = ns2usecs(next_ts - iter->ts);
author maintainer
#18 lore raw

PATCH 18/75 hwmon: fam15h_power: fix bogus values with current BIOSes

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andre Przywara <[email protected]>

commit 00250ec90963b7ef6678438888f3244985ecde14 upstream.

Newer BKDG[1] versions recommend a different initialization value for the running average range register in the northbridge. This improves the power reading by avoiding counter saturations resulting in bogus values for anything below about 80% of TDP power consumption. Updated BIOSes will have this new value set up from the beginning, but meanwhile we correct this value ourselves.
This needs to be done on all northbridges, even on those where the driver itself does not register at.

This fixes the driver on all current machines to provide proper values for idle load.

[1]
http://support.amd.com/us/Processor_TechDocs/42301_15h_Mod_00h-0Fh_BKDG.pdf
Chapter 3.8: D18F5xE0 Processor TDP Running Average (p. 452)

---
 drivers/hwmon/fam15h_power.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/hwmon/fam15h_power.c +39 -0
@@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_in
 	return true;
 }
 
+/*
+ * Newer BKDG versions have an updated recommendation on how to properly
+ * initialize the running average range (was: 0xE, now: 0x9). This avoids
+ * counter saturations resulting in bogus power readings.
+ * We correct this value ourselves to cope with older BIOSes.
+ */
+static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+{
+	u32 val;
+	const struct pci_device_id affected_device = {
+		PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
+
+	/*
+	 * let this quirk apply only to the current version of the
+	 * northbridge, since future versions may change the behavior
+	 */
+	if (!pci_match_id(&affected_device, pdev))
+		return;
+
+	pci_bus_read_config_dword(pdev->bus,
+		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+		REG_TDP_RUNNING_AVERAGE, &val);
+	if ((val & 0xf) != 0xe)
+		return;
+
+	val &= ~0xf;
+	val |=  0x9;
+	pci_bus_write_config_dword(pdev->bus,
+		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+		REG_TDP_RUNNING_AVERAGE, val);
+}
+
 static void __devinit fam15h_power_init_data(struct pci_dev *f4,
 					     struct fam15h_power_data *data)
 {
@@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(
 	struct device *dev;
 	int err;
 
+	/*
+	 * though we ignore every other northbridge, we still have to
+	 * do the tweaking on _each_ node in MCM processors as the counters
+	 * are working hand-in-hand
+	 */
+	tweak_runavg_range(pdev);
+
 	if (!fam15h_power_is_internal_node0(pdev)) {
 		err = -ENODEV;
 		goto exit;
author maintainer
#19 lore raw

PATCH 19/75 hwmon: (fam15h_power) Fix pci_device_id array

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit c3e40a9972428d6e2d8e287ed0233a57a218c30f upstream.

pci_match_id() takes an *array* of IDs which must be properly zero- terminated.

---
 drivers/hwmon/fam15h_power.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/hwmon/fam15h_power.c +6 -3
@@ -128,17 +128,20 @@ static bool __devinit fam15h_power_is_in
  * counter saturations resulting in bogus power readings.
  * We correct this value ourselves to cope with older BIOSes.
  */
+static DEFINE_PCI_DEVICE_TABLE(affected_device) = {
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
+	{ 0 }
+};
+
 static void __devinit tweak_runavg_range(struct pci_dev *pdev)
 {
 	u32 val;
-	const struct pci_device_id affected_device = {
-		PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
 
 	/*
 	 * let this quirk apply only to the current version of the
 	 * northbridge, since future versions may change the behavior
 	 */
-	if (!pci_match_id(&affected_device, pdev))
+	if (!pci_match_id(affected_device, pdev))
 		return;
 
 	pci_bus_read_config_dword(pdev->bus,
author maintainer
#20 lore raw

PATCH 20/75 dell-laptop: Terminate quirks list properly

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Martin Nyhus <[email protected]>

commit d62d421b071b08249361044d8e56c8b5c3ed6aa7 upstream.

Add missing DMI_NONE entry to end of the quirks list so dmi_check_system() won't read past the end of the list.

---
 drivers/platform/x86/dell-laptop.c |    1 +
 1 file changed, 1 insertion(+)
drivers/platform/x86/dell-laptop.c +1 -0
@@ -211,6 +211,7 @@ static struct dmi_system_id __devinitdat
 		},
 		.driver_data = &quirk_dell_vostro_v130,
 	},
+	{ }
 };
 
 static struct calling_interface_buffer *buffer;
author maintainer
#21 lore raw

PATCH 21/75 drm/radeon/kms: need to set up ss on DP bridges as well

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Deucher <[email protected]>

commit 700698e7c303f5095107c62a81872c2c3dad1702 upstream.

Makes Nutmeg DP to VGA bridges work for me.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=42490

Noticed by Jerome Glisse (after weeks of debugging).

---
 drivers/gpu/drm/radeon/atombios_crtc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/atombios_crtc.c +2 -2
@@ -912,8 +912,8 @@ static void atombios_crtc_set_pll(struct
 		break;
 	}
 
-	if (radeon_encoder->active_device &
-	    (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
+	if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
+	    (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
 		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 		struct drm_connector *connector =
 			radeon_get_connector_for_encoder(encoder);
author maintainer
#22 lore raw

PATCH 22/75 drm/i915: handle input/output sdvo timings separately in mode_set

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Vetter <[email protected]>

commit 6651819b4b4fc3caa6964c5d825eb4bb996f3905 upstream.

We seem to have a decent confusion between the output timings and the input timings of the sdvo encoder. If I understand the code correctly, we use the original mode unchanged for the output timings, safe for the lvds case. And we should use the adjusted mode for input timings.

Clarify the situation by adding an explicit output_dtd to the sdvo mode_set function and streamline the code-flow by moving the input and output mode setting in the sdvo encode together.

Furthermore testing showed that the sdvo input timing needs the unadjusted dotclock, the sdvo chip will automatically compute the required pixel multiplier to get a dotclock above 100 MHz.

Fix this up when converting a drm mode to an sdvo dtd.

This regression was introduced in

commit c74696b9c890074c1e1ee3d7496fc71eb3680ced

Author: Pavel Roskin <[email protected]>
Date:   Thu Sep 2 14:46:34 2010 -0400

i915: revert some checks added by commit 32aad86f

particularly the following hunk:

# diff --git a/drivers/gpu/drm/i915/intel_sdvo.c
# b/drivers/gpu/drm/i915/intel_sdvo.c
# index 093e914..62d22ae 100644
# --- a/drivers/gpu/drm/i915/intel_sdvo.c
# +++ b/drivers/gpu/drm/i915/intel_sdvo.c
# @@ -1122,11 +1123,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
#
# /* We have tried to get input timing in mode_fixup, and filled into
# adjusted_mode */
# - if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
# - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
# + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
# + if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
# input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags;
# - } else
# - intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
#
# /* If it's a TV, we already set the output timing in mode_fixup.
# * Otherwise, the output timing is equal to the input timing.

Due to questions raised in review, below a more elaborate analysis of the bug at hand:

Sdvo seems to have two timings, one is the output timing which will be sent over whatever is connected on the other side of the sdvo chip (panel, hdmi screen, tv), the other is the input timing which will be generated by the gmch pipe. It looks like sdvo is expected to scale between the two.

To make things slightly more complicated, we have a bunch of special cases:
- For lvds panel we always use a fixed output timing, namely intel_sdvo->sdvo_lvds_fixed_mode, hence that special case.
- Sdvo has an interface to generate a preferred input timing for a given output timing. This is the confusing thing that I've tried to clear up with the follow-on patches.
- A special requirement is that the input pixel clock needs to be between 100MHz and 200MHz (likely to keep it within the electromechanical design range of PCIe), 270MHz on later gen4+. Lower pixel clocks are doubled/quadrupled.

The thing this patch tries to fix is that the pipe needs to be explicitly instructed to double/quadruple the pixels and needs the correspondingly higher pixel clock, whereas the sdvo adaptor seems to do that itself and needs the unadjusted pixel clock. For the sdvo encode side we already set the pixel mutliplier with a different command (0x21).

This patch tries to fix this mess by:
- Keeping the output mode timing in the unadjusted plain mode, safe for the lvds case.
- Storing the input timing in the adjusted_mode with the adjusted pixel clock. This way we don't need to frob around with the core crtc mode set code.
- Fixing up the pixelclock when constructing the sdvo dtd timing struct. This is why the first hunk of the patch is an integral part of the series.
- Dropping the is_tv special case because input_dtd is equivalent to adjusted_mode after these changes. Follow-up patches clear this up further (by simply ripping out intel_sdvo->input_dtd because it's not needed).

v2: Extend commit message with an in-depth bug analysis.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48157

---
 drivers/gpu/drm/i915/intel_sdvo.c |   34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)
drivers/gpu/drm/i915/intel_sdvo.c +18 -16
@@ -731,6 +731,7 @@ static void intel_sdvo_get_dtd_from_mode
 	uint16_t width, height;
 	uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
 	uint16_t h_sync_offset, v_sync_offset;
+	int mode_clock;
 
 	width = mode->crtc_hdisplay;
 	height = mode->crtc_vdisplay;
@@ -745,7 +746,11 @@ static void intel_sdvo_get_dtd_from_mode
 	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
 	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
 
-	dtd->part1.clock = mode->clock / 10;
+	mode_clock = mode->clock;
+	mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1;
+	mode_clock /= 10;
+	dtd->part1.clock = mode_clock;
+
 	dtd->part1.h_active = width & 0xff;
 	dtd->part1.h_blank = h_blank_len & 0xff;
 	dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
@@ -997,7 +1002,7 @@ static void intel_sdvo_mode_set(struct d
 	struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
-	struct intel_sdvo_dtd input_dtd;
+	struct intel_sdvo_dtd input_dtd, output_dtd;
 	int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
 	int rate;
 
@@ -1022,20 +1027,13 @@ static void intel_sdvo_mode_set(struct d
 					  intel_sdvo->attached_output))
 		return;
 
-	/* We have tried to get input timing in mode_fixup, and filled into
-	 * adjusted_mode.
-	 */
-	if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
-		input_dtd = intel_sdvo->input_dtd;
-	} else {
-		/* Set the output timing to the screen */
-		if (!intel_sdvo_set_target_output(intel_sdvo,
-						  intel_sdvo->attached_output))
-			return;
-
-		intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
-		(void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd);
-	}
+	/* lvds has a special fixed output timing. */
+	if (intel_sdvo->is_lvds)
+		intel_sdvo_get_dtd_from_mode(&output_dtd,
+					     intel_sdvo->sdvo_lvds_fixed_mode);
+	else
+		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+	(void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);
 
 	/* Set the input timing to the screen. Assume always input 0. */
 	if (!intel_sdvo_set_target_input(intel_sdvo))
@@ -1053,6 +1051,10 @@ static void intel_sdvo_mode_set(struct d
 	    !intel_sdvo_set_tv_format(intel_sdvo))
 		return;
 
+	/* We have tried to get input timing in mode_fixup, and filled into
+	 * adjusted_mode.
+	 */
+	intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
 	(void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);
 
 	switch (pixel_multiplier) {
author maintainer
#23 lore raw

PATCH 23/75 drm/i915: Set the Stencil Cache eviction policy to non-LRA mode.

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kenneth Graunke <[email protected]>

commit 3a69ddd6f872180b6f61fda87152b37202118fbc upstream.

Clearing bit 5 of CACHE_MODE_0 is necessary to prevent GPU hangs in OpenGL programs such as Google MapsGL, Google Earth, and gzdoom when using separate stencil buffers. Without it, the GPU tries to use the LRA eviction policy, which isn't supported. This was supposed to be off by default, but seems to be on for many machines.

This cannot be done in gen6_init_clock_gating with most of the other workaround bits; the render ring needs to exist. Otherwise, the register write gets dropped on the floor (one printk will show it changed, but a second printk immediately following shows the value reverts to the old one).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=47535

---
 drivers/gpu/drm/i915/i915_reg.h         |    1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c |    8 ++++++++
 2 files changed, 9 insertions(+)
drivers/gpu/drm/i915/i915_reg.h +1 -0
@@ -523,6 +523,7 @@
 #define   CM0_MASK_SHIFT          16
 #define   CM0_IZ_OPT_DISABLE      (1<<6)
 #define   CM0_ZR_OPT_DISABLE      (1<<5)
+#define	  CM0_STC_EVICT_DISABLE_LRA_SNB	(1<<5)
 #define   CM0_DEPTH_EVICT_DISABLE (1<<4)
 #define   CM0_COLOR_EVICT_DISABLE (1<<3)
 #define   CM0_DEPTH_WRITE_DISABLE (1<<1)
drivers/gpu/drm/i915/intel_ringbuffer.c +8 -0
@@ -417,6 +417,14 @@ static int init_render_ring(struct intel
 	if (INTEL_INFO(dev)->gen >= 6) {
 		I915_WRITE(INSTPM,
 			   INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
+
+		/* From the Sandybridge PRM, volume 1 part 3, page 24:
+		 * "If this bit is set, STCunit will have LRA as replacement
+		 *  policy. [...] This bit must be reset.  LRA replacement
+		 *  policy is not supported."
+		 */
+		I915_WRITE(CACHE_MODE_0,
+			   CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);
 	}
 
 	return ret;
author maintainer
#24 lore raw

PATCH 24/75 drm/i915: fix integer overflow in i915_gem_execbuffer2()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xi Wang <[email protected]>

commit ed8cd3b2cd61004cab85380c52b1817aca1ca49b upstream.

On 32-bit systems, a large args->buffer_count from userspace via ioctl may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 8408c282 ("drm/i915:
First try a normal large kmalloc for the temporary exec buffers").

---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_gem_execbuffer.c +2 -1
@@ -1353,7 +1353,8 @@ i915_gem_execbuffer2(struct drm_device *
 	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
 	int ret;
 
-	if (args->buffer_count < 1) {
+	if (args->buffer_count < 1 ||
+	    args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
 		DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count);
 		return -EINVAL;
 	}
author maintainer
#25 lore raw

PATCH 25/75 drm/i915: fix integer overflow in i915_gem_do_execbuffer()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xi Wang <[email protected]>

commit 44afb3a04391a74309d16180d1e4f8386fdfa745 upstream.

On 32-bit systems, a large args->num_cliprects from userspace via ioctl may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 432e58ed ("drm/i915: Avoid allocation for execbuffer object list").

---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/gpu/drm/i915/i915_gem_execbuffer.c +5 -0
@@ -1082,6 +1082,11 @@ i915_gem_do_execbuffer(struct drm_device
 			return -EINVAL;
 		}
 
+		if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
+			DRM_DEBUG("execbuf with %u cliprects\n",
+				  args->num_cliprects);
+			return -EINVAL;
+		}
 		cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
 				    GFP_KERNEL);
 		if (cliprects == NULL) {
author maintainer
#26 lore raw

PATCH 26/75 i387: ptrace breaks the lazy-fpu-restore logic

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit 089f9fba56faf33cc6dd2a6442b7ac92c58b8209 upstream.

Starting from 7e16838d "i387: support lazy restore of FPU state" we assume that fpu_owner_task doesn't need restore_fpu_checking() on the context switch, its FPU state should match what we already have in the FPU on this CPU.

However, debugger can change the tracee's FPU state, in this case we should reset fpu.last_cpu to ensure fpu_lazy_restore() can't return true.

Change init_fpu() to do this, it is called by user_regset->set() methods.

---
 arch/x86/kernel/i387.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kernel/i387.c +1 -0
@@ -154,6 +154,7 @@ int init_fpu(struct task_struct *tsk)
 	if (tsk_used_math(tsk)) {
 		if (HAVE_HWFP && tsk == current)
 			unlazy_fpu(tsk);
+		tsk->thread.fpu.last_cpu = ~0;
 		return 0;
 	}
 
author maintainer
#27 lore raw

PATCH 27/75 nl80211: ensure interface is up in various APIs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

commit 2b5f8b0b44e17e625cfba1e7b88db44f4dcc0441 upstream. [backported by Ben Greear]

The nl80211 handling code should ensure as much as it can that the interface is in a valid state, it can certainly ensure the interface is running.

Not doing so can cause calls through mac80211 into the driver that result in warnings and unspecified behaviour in the driver.

---
 net/wireless/nl80211.c |   29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)
net/wireless/nl80211.c +17 -12
@@ -1293,6 +1293,11 @@ static int nl80211_set_wiphy(struct sk_b
 			goto bad_res;
 		}
 
+		if (!netif_running(netdev)) {
+			result = -ENETDOWN;
+			goto bad_res;
+		}
+
 		nla_for_each_nested(nl_txq_params,
 				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
 				    rem_txq_params) {
@@ -6262,7 +6267,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_get_key,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6294,7 +6299,7 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 		.doit = nl80211_addset_beacon,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6302,7 +6307,7 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 		.doit = nl80211_addset_beacon,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6326,7 +6331,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_set_station,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6342,7 +6347,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_del_station,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6375,7 +6380,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_del_mpath,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6383,7 +6388,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_set_bss,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6409,7 +6414,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_get_mesh_config,
 		.policy = nl80211_policy,
 		/* can be retrieved by unprivileged users */
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6542,7 +6547,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_setdel_pmksa,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6550,7 +6555,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_setdel_pmksa,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6558,7 +6563,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_flush_pmksa,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
@@ -6718,7 +6723,7 @@ static struct genl_ops nl80211_ops[] = {
 		.doit = nl80211_probe_client,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
-		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
author maintainer
#28 lore raw

PATCH 28/75 ALSA: HDA: Add external mic quirk for Asus Zenbook UX31E

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Henningsson <[email protected]>

commit 5ac57550f279c3d991ef0b398681bcaca18169f7 upstream.

According to the reporter, external mic starts to work if the laptop-dmic model is used. According to BIOS pin config, all pins are consistent with the alc269vb_laptop_dmic fixup, except for the external mic, which is not present.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -5402,6 +5402,7 @@ static const struct alc_fixup alc269_fix
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
 	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
author maintainer
#29 lore raw

PATCH 29/75 USB: cdc-wdm: fix race leading leading to memory corruption

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 5c22837adca7c30b66121cf18ad3e160134268d4 upstream.

This patch fixes a race whereby a pointer to a buffer would be overwritten while the buffer was in use leading to a double free and a memory leak. This causes crashes. This bug was introduced in 2.6.34

---
 drivers/usb/class/cdc-wdm.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/class/cdc-wdm.c +5 -2
@@ -108,8 +108,9 @@ static void wdm_out_callback(struct urb
 	spin_lock(&desc->iuspin);
 	desc->werr = urb->status;
 	spin_unlock(&desc->iuspin);
-	clear_bit(WDM_IN_USE, &desc->flags);
 	kfree(desc->outbuf);
+	desc->outbuf = NULL;
+	clear_bit(WDM_IN_USE, &desc->flags);
 	wake_up(&desc->wait);
 }
 
@@ -312,7 +313,7 @@ static ssize_t wdm_write
 	if (we < 0)
 		return -EIO;
 
-	desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+	buf = kmalloc(count, GFP_KERNEL);
 	if (!buf) {
 		rv = -ENOMEM;
 		goto outnl;
@@ -376,10 +377,12 @@ static ssize_t wdm_write
 	req->wIndex = desc->inum;
 	req->wLength = cpu_to_le16(count);
 	set_bit(WDM_IN_USE, &desc->flags);
+	desc->outbuf = buf;
 
 	rv = usb_submit_urb(desc->command, GFP_KERNEL);
 	if (rv < 0) {
 		kfree(buf);
+		desc->outbuf = NULL;
 		clear_bit(WDM_IN_USE, &desc->flags);
 		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
 	} else {
author maintainer
#30 lore raw

PATCH 30/75 USB: EHCI: fix crash during suspend on ASUS computers

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit 151b61284776be2d6f02d48c23c3625678960b97 upstream.

This patch (as1545) fixes a problem affecting several ASUS computers:
The machine crashes or corrupts memory when going into suspend if the ehci-hcd driver is bound to any controllers. Users have been forced to unbind or unload ehci-hcd before putting their systems to sleep.

After extensive testing, it was determined that the machines don't like going into suspend when any EHCI controllers are in the PCI D3 power state. Presumably this is a firmware bug, but there's nothing we can do about it except to avoid putting the controllers in D3 during system sleep.

The patch adds a new flag to indicate whether the problem is present, and avoids changing the controller's power state if the flag is set. Runtime suspend is unaffected; this matters only for system suspend. However as a side effect, the controller will not respond to remote wakeup requests while the system is asleep. Hence USB wakeup is not functional -- but of course, this is already true in the current state of affairs.

This fixes Bugzilla #42728.

---
 drivers/usb/core/hcd-pci.c  |    9 +++++++++
 drivers/usb/host/ehci-pci.c |    8 ++++++++
 include/linux/usb/hcd.h     |    2 ++
 3 files changed, 19 insertions(+)
drivers/usb/core/hcd-pci.c +9 -0
@@ -491,6 +491,15 @@ static int hcd_pci_suspend_noirq(struct
 
 	pci_save_state(pci_dev);
 
+	/*
+	 * Some systems crash if an EHCI controller is in D3 during
+	 * a sleep transition.  We have to leave such controllers in D0.
+	 */
+	if (hcd->broken_pci_sleep) {
+		dev_dbg(dev, "Staying in PCI D0\n");
+		return retval;
+	}
+
 	/* If the root hub is dead rather than suspended, disallow remote
 	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as
 	 * dying, so we only need to check the primary roothub.
drivers/usb/host/ehci-pci.c +8 -0
@@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd
 			hcd->has_tt = 1;
 			tdi_reset(ehci);
 		}
+		if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) {
+			/* EHCI #1 or #2 on 6 Series/C200 Series chipset */
+			if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) {
+				ehci_info(ehci, "broken D3 during system sleep on ASUS\n");
+				hcd->broken_pci_sleep = 1;
+				device_set_wakeup_capable(&pdev->dev, false);
+			}
+		}
 		break;
 	case PCI_VENDOR_ID_TDI:
 		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
include/linux/usb/hcd.h +2 -0
@@ -126,6 +126,8 @@ struct usb_hcd {
 	unsigned		wireless:1;	/* Wireless USB HCD */
 	unsigned		authorized_default:1;
 	unsigned		has_tt:1;	/* Integrated TT in root hub */
+	unsigned		broken_pci_sleep:1;	/* Don't put the
+			controller in PCI-D3 for system sleep */
 
 	int			irq;		/* irq allocated */
 	void __iomem		*regs;		/* device memory/io */
author maintainer
#31 lore raw

PATCH 31/75 USB: gadget: storage gadgets send wrong error code for unknown commands

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit c85dcdac5852295cf6822f5c4331a6ddab72581f upstream.

This patch (as1539) fixes a minor bug in the mass-storage gadget drivers. When an unknown command is received, the error code sent back is "Invalid Field in CDB" rather than "Invalid Command". This is because the bitmask of CDB bytes allowed to be nonzero is incorrect.

When handling an unknown command, we don't care which command bytes are nonzero. All the bits in the mask should be set, not just eight of them.

---
 drivers/usb/gadget/f_mass_storage.c |    2 +-
 drivers/usb/gadget/file_storage.c   |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/usb/gadget/f_mass_storage.c +1 -1
@@ -2190,7 +2190,7 @@ unknown_cmnd:
 		common->data_size_from_cmnd = 0;
 		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);
 		reply = check_command(common, common->cmnd_size,
-				      DATA_DIR_UNKNOWN, 0xff, 0, unknown);
+				      DATA_DIR_UNKNOWN, ~0, 0, unknown);
 		if (reply == 0) {
 			common->curlun->sense_data = SS_INVALID_COMMAND;
 			reply = -EINVAL;
drivers/usb/gadget/file_storage.c +1 -1
@@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_de
 		fsg->data_size_from_cmnd = 0;
 		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
 		if ((reply = check_command(fsg, fsg->cmnd_size,
-				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) {
+				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {
 			fsg->curlun->sense_data = SS_INVALID_COMMAND;
 			reply = -EINVAL;
 		}
author maintainer
#32 lore raw

PATCH 32/75 usb: gadget: dummy: do not call pullup() on udc_stop()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felipe Balbi <[email protected]>

commit 15b120d67019d691e4389372967332d74a80522a upstream.

pullup() is already called properly by udc-core.c and there's no need to call it from udc_stop(), in fact that will cause issues.

---
 drivers/usb/gadget/dummy_hcd.c |    1 -
 1 file changed, 1 deletion(-)
drivers/usb/gadget/dummy_hcd.c +0 -1
@@ -924,7 +924,6 @@ static int dummy_udc_stop(struct usb_gad
 
 	dum->driver = NULL;
 
-	dummy_pullup(&dum->gadget, 0);
 	return 0;
 }
 
author maintainer
#33 lore raw

PATCH 33/75 usb gadget: uvc: uvc_request_data::length field must be signed

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Laurent Pinchart <[email protected]>

commit 6f6543f53f9ce136e01d7114bf6f0818ca54fb41 upstream.

The field is used to pass the UVC request data length, but can also be used to signal an error when setting it to a negative value. Switch from unsigned int to __s32.

---
 drivers/usb/gadget/uvc.h      |    2 +-
 drivers/usb/gadget/uvc_v4l2.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/usb/gadget/uvc.h +1 -1
@@ -28,7 +28,7 @@
 
 struct uvc_request_data
 {
-	unsigned int length;
+	__s32 length;
 	__u8 data[60];
 };
 
drivers/usb/gadget/uvc_v4l2.c +1 -1
@@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc
 	if (data->length < 0)
 		return usb_ep_set_halt(cdev->gadget->ep0);
 
-	req->length = min(uvc->event_length, data->length);
+	req->length = min_t(unsigned int, uvc->event_length, data->length);
 	req->zero = data->length < uvc->event_length;
 	req->dma = DMA_ADDR_INVALID;
 
author maintainer
#34 lore raw

PATCH 34/75 pipes: add a "packetized pipe" mode for writing

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 9883035ae7edef3ec62ad215611cb8e17d6a1a5d upstream.

The actual internal pipe implementation is already really about individual packets (called "pipe buffers"), and this simply exposes that as a special packetized mode.

When we are in the packetized mode (marked by O_DIRECT as suggested by Alan Cox), a write() on a pipe will not merge the new data with previous writes, so each write will get a pipe buffer of its own. The pipe buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn will tell the reader side to break the read at that boundary (and throw away any partial packet contents that do not fit in the read buffer).

End result: as long as you do writes less than PIPE_BUF in size (so that the pipe doesn't have to split them up), you can now treat the pipe as a packet interface, where each read() system call will read one packet at a time. You can just use a sufficiently big read buffer (PIPE_BUF is sufficient, since bigger than that doesn't guarantee atomicity anyway), and the return value of the read() will naturally give you the size of the packet.

NOTE! We do not support zero-sized packets, and zero-sized reads and writes to a pipe continue to be no-ops. Also note that big packets will currently be split at write time, but that the size at which that happens is not really specified (except that it's bigger than PIPE_BUF). Currently that limit is the system page size, but we might want to explicitly support bigger packets some day.

The main user for this is going to be the autofs packet interface, allowing us to stop having to care so deeply about exact packet sizes (which have had bugs with 32/64-bit compatibility modes). But user space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will fail with an EINVAL on kernels that do not support this interface.

---
 fs/pipe.c                 |   31 +++++++++++++++++++++++++++++--
 include/linux/pipe_fs_i.h |    1 +
 2 files changed, 30 insertions(+), 2 deletions(-)
fs/pipe.c +29 -2
@@ -345,6 +345,16 @@ static const struct pipe_buf_operations
 	.get = generic_pipe_buf_get,
 };
 
+static const struct pipe_buf_operations packet_pipe_buf_ops = {
+	.can_merge = 0,
+	.map = generic_pipe_buf_map,
+	.unmap = generic_pipe_buf_unmap,
+	.confirm = generic_pipe_buf_confirm,
+	.release = anon_pipe_buf_release,
+	.steal = generic_pipe_buf_steal,
+	.get = generic_pipe_buf_get,
+};
+
 static ssize_t
 pipe_read(struct kiocb *iocb, const struct iovec *_iov,
 	   unsigned long nr_segs, loff_t pos)
@@ -406,6 +416,13 @@ redo:
 			ret += chars;
 			buf->offset += chars;
 			buf->len -= chars;
+
+			/* Was it a packet buffer? Clean up and exit */
+			if (buf->flags & PIPE_BUF_FLAG_PACKET) {
+				total_len = chars;
+				buf->len = 0;
+			}
+
 			if (!buf->len) {
 				buf->ops = NULL;
 				ops->release(pipe, buf);
@@ -458,6 +475,11 @@ redo:
 	return ret;
 }
 
+static inline int is_packetized(struct file *file)
+{
+	return (file->f_flags & O_DIRECT) != 0;
+}
+
 static ssize_t
 pipe_write(struct kiocb *iocb, const struct iovec *_iov,
 	    unsigned long nr_segs, loff_t ppos)
@@ -592,6 +614,11 @@ redo2:
 			buf->ops = &anon_pipe_buf_ops;
 			buf->offset = 0;
 			buf->len = chars;
+			buf->flags = 0;
+			if (is_packetized(filp)) {
+				buf->ops = &packet_pipe_buf_ops;
+				buf->flags = PIPE_BUF_FLAG_PACKET;
+			}
 			pipe->nrbufs = ++bufs;
 			pipe->tmp_page = NULL;
 
@@ -1012,7 +1039,7 @@ struct file *create_write_pipe(int flags
 		goto err_dentry;
 	f->f_mapping = inode->i_mapping;
 
-	f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
+	f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
 	f->f_version = 0;
 
 	return f;
@@ -1056,7 +1083,7 @@ int do_pipe_flags(int *fd, int flags)
 	int error;
 	int fdw, fdr;
 
-	if (flags & ~(O_CLOEXEC | O_NONBLOCK))
+	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
 		return -EINVAL;
 
 	fw = create_write_pipe(flags);
include/linux/pipe_fs_i.h +1 -0
@@ -8,6 +8,7 @@
 #define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
 #define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
 #define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
+#define PIPE_BUF_FLAG_PACKET	0x08	/* read() as a packet */
 
 /**
  *	struct pipe_buffer - a linux kernel pipe buffer
author maintainer
#35 lore raw

PATCH 35/75 autofs: make the autofsv5 packet file descriptor use a packetized pipe

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 64f371bc3107e69efce563a3d0f0e6880de0d537 upstream.

The autofs packet size has had a very unfortunate size problem on x86:
because the alignment of 'u64' differs in 32-bit and 64-bit modes, and because the packet data was not 8-byte aligned, the size of the autofsv5 packet structure differed between 32-bit and 64-bit modes despite looking otherwise identical (300 vs 304 bytes respectively).

We first fixed that up by making the 64-bit compat mode know about this problem in commit a32744d4abae ("autofs: work around unhappy compat problem on x86-64"), and that made a 32-bit 'systemd' work happily on a 64-bit kernel because everything then worked the same way as on a 32-bit kernel.

But it turned out that 'automount' had actually known and worked around this problem in user space, so fixing the kernel to do the proper 32-bit compatibility handling actually *broke* 32-bit automount on a 64-bit kernel, because it knew that the packet sizes were wrong and expected those incorrect sizes.

As a result, we ended up reverting that compatibility mode fix, and thus breaking systemd again, in commit fcbf94b9dedd.

With both automount and systemd doing a single read() system call, and verifying that they get *exactly* the size they expect but using different sizes, it seemed that fixing one of them inevitably seemed to break the other. At one point, a patch I seriously considered applying from Michael Tokarev did a "strcmp()" to see if it was automount that was doing the operation. Ugly, ugly.

However, a prettier solution exists now thanks to the packetized pipe mode. By marking the communication pipe as being packetized (by simply setting the O_DIRECT flag), we can always just write the bigger packet size, and if user-space does a smaller read, it will just get that partial end result and the extra alignment padding will simply be thrown away.

This makes both automount and systemd happy, since they now get the size they asked for, and the kernel side of autofs simply no longer needs to care - it could pad out the packet arbitrarily.

Of course, if there is some *other* user of autofs (please, please, please tell me it ain't so - and we haven't heard of any) that tries to read the packets with multiple writes, that other user will now be broken - the whole point of the packetized mode is that one system call gets exactly one packet, and you cannot read a packet in pieces.

---
 fs/autofs4/autofs_i.h  |   11 +++++++++++
 fs/autofs4/dev-ioctl.c |    2 +-
 fs/autofs4/inode.c     |    2 +-
 3 files changed, 13 insertions(+), 2 deletions(-)
fs/autofs4/autofs_i.h +11 -0
@@ -269,6 +269,17 @@ int autofs4_fill_super(struct super_bloc
 struct autofs_info *autofs4_new_ino(struct autofs_sb_info *);
 void autofs4_clean_ino(struct autofs_info *);
 
+static inline int autofs_prepare_pipe(struct file *pipe)
+{
+	if (!pipe->f_op || !pipe->f_op->write)
+		return -EINVAL;
+	if (!S_ISFIFO(pipe->f_dentry->d_inode->i_mode))
+		return -EINVAL;
+	/* We want a packet pipe */
+	pipe->f_flags |= O_DIRECT;
+	return 0;
+}
+
 /* Queue management functions */
 
 int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
fs/autofs4/dev-ioctl.c +1 -1
@@ -376,7 +376,7 @@ static int autofs_dev_ioctl_setpipefd(st
 			err = -EBADF;
 			goto out;
 		}
-		if (!pipe->f_op || !pipe->f_op->write) {
+		if (autofs_prepare_pipe(pipe) < 0) {
 			err = -EPIPE;
 			fput(pipe);
 			goto out;
fs/autofs4/inode.c +1 -1
@@ -293,7 +293,7 @@ int autofs4_fill_super(struct super_bloc
 		printk("autofs: could not open pipe file descriptor\n");
 		goto fail_dput;
 	}
-	if (!pipe->f_op || !pipe->f_op->write)
+	if (autofs_prepare_pipe(pipe) < 0)
 		goto fail_fput;
 	sbi->pipe = pipe;
 	sbi->pipefd = pipefd;
author maintainer
#36 lore raw

PATCH 36/75 crypto: talitos - properly lock access to global talitos registers

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Horia Geanta <[email protected]>

commit 511d63cb19329235bc9298b64010ec494b5e1408 upstream.

Access to global talitos registers must be protected for the case when affinities are configured such that primary and secondary talitos irqs run on different cpus.

---
 drivers/crypto/talitos.c |   20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/crypto/talitos.c +17 -3
@@ -124,6 +124,9 @@ struct talitos_private {
 	void __iomem *reg;
 	int irq[2];
 
+	/* SEC global registers lock  */
+	spinlock_t reg_lock ____cacheline_aligned;
+
 	/* SEC version geometry (from device tree node) */
 	unsigned int num_channels;
 	unsigned int chfifo_len;
@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned
 {									\
 	struct device *dev = (struct device *)data;			\
 	struct talitos_private *priv = dev_get_drvdata(dev);		\
+	unsigned long flags;						\
 									\
 	if (ch_done_mask & 1)						\
 		flush_channel(dev, 0, 0, 0);				\
@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned
 out:									\
 	/* At this point, all completed channels have been processed */	\
 	/* Unmask done interrupts for channels completed later on. */	\
+	spin_lock_irqsave(&priv->reg_lock, flags);			\
 	setbits32(priv->reg + TALITOS_IMR, ch_done_mask);		\
 	setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);	\
+	spin_unlock_irqrestore(&priv->reg_lock, flags);			\
 }
 DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
 DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
@@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##n
 	struct device *dev = data;					       \
 	struct talitos_private *priv = dev_get_drvdata(dev);		       \
 	u32 isr, isr_lo;						       \
+	unsigned long flags;						       \
 									       \
+	spin_lock_irqsave(&priv->reg_lock, flags);			       \
 	isr = in_be32(priv->reg + TALITOS_ISR);				       \
 	isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);			       \
 	/* Acknowledge interrupt */					       \
 	out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
 	out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);			       \
 									       \
-	if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo))    \
-		talitos_error(dev, isr, isr_lo);			       \
-	else								       \
+	if (unlikely(isr & ch_err_mask || isr_lo)) {			       \
+		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \
+		talitos_error(dev, isr & ch_err_mask, isr_lo);		       \
+	}								       \
+	else {								       \
 		if (likely(isr & ch_done_mask)) {			       \
 			/* mask further done interrupts. */		       \
 			clrbits32(priv->reg + TALITOS_IMR, ch_done_mask);      \
 			/* done_task will unmask done interrupts at exit */    \
 			tasklet_schedule(&priv->done_task[tlet]);	       \
 		}							       \
+		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \
+	}								       \
 									       \
 	return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED :  \
 								IRQ_NONE;      \
@@ -2718,6 +2730,8 @@ static int talitos_probe(struct platform
 
 	priv->ofdev = ofdev;
 
+	spin_lock_init(&priv->reg_lock);
+
 	err = talitos_probe_irq(ofdev);
 	if (err)
 		goto err_out;
author maintainer
#37 lore raw

PATCH 37/75 Input: synaptics - fix regression with "image sensor" trackpads

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Herrenschmidt <[email protected]>

commit 899c612d74d4a242158a4db20367388d6299c028 upstream.

commit 7968a5dd492ccc38345013e534ad4c8d6eb60ed1
Input: synaptics - add support for Relative mode

Accidentally broke support for advanced gestures (multitouch) on some trackpads such as the one in my ThinkPad X220 by incorretly changing the condition for enabling them. This restores it.

---
 drivers/input/mouse/synaptics.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/input/mouse/synaptics.c +2 -1
@@ -274,7 +274,8 @@ static int synaptics_set_advanced_gestur
 	static unsigned char param = 0xc8;
 	struct synaptics_data *priv = psmouse->private;
 
-	if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
+	if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
+	      SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
 		return 0;
 
 	if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
author maintainer
#38 lore raw

PATCH 38/75 USB: ehci-tegra: remove redundant gpio_set_value

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stephen Warren <[email protected]>

commit 04c235c92ce8474e9f2b358bd97f013a500385f2 upstream.

The immediately preceding gpio_direction_output() already set the value, so there's no need to repeat it. This also prevents gpio_set_value() from WARNing when the GPIO is sleepable (e.g. is on an I2C expander); the set direction API is always sleepable, but plain set_value isn't.

---
 drivers/usb/host/ehci-tegra.c |    1 -
 1 file changed, 1 deletion(-)
drivers/usb/host/ehci-tegra.c +0 -1
@@ -601,7 +601,6 @@ static int setup_vbus_gpio(struct platfo
 		dev_err(&pdev->dev, "can't enable vbus\n");
 		return err;
 	}
-	gpio_set_value(gpio, 1);
 
 	return err;
 }
author maintainer
#39 lore raw

PATCH 39/75 ARM: 7396/1: errata: only handle ARM erratum #326103 on affected cores

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit f0c4b8d653f5ee091fb8d4d02ed7eaad397491bb upstream.

Erratum #326103 ("FSR write bit incorrect on a SWP to read-only memory") only affects the ARM 1136 core prior to r1p0. The workaround disassembles the faulting instruction to determine whether it was a read or write access on all v6 cores.

An issue has been reported on the ARM 11MPCore whereby loading the faulting instruction may happen in parallel with that page being unmapped, resulting in a deadlock due to the lack of TLB broadcasting in hardware:

http://lists.infradead.org/pipermail/linux-arm-kernel/2012-March/091561.html

This patch limits the workaround so that it is only used on affected cores, which are known to be UP only. Other v6 cores can rely on the FSR to indicate the access type correctly.

---
 arch/arm/Kconfig        |    9 +++++++++
 arch/arm/mm/abort-ev6.S |   17 +++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)
arch/arm/Kconfig +9 -0
@@ -1163,6 +1163,15 @@ if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
 
+config ARM_ERRATA_326103
+	bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
+	depends on CPU_V6
+	help
+	  Executing a SWP instruction to read-only memory does not set bit 11
+	  of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to
+	  treat the access as a read, preventing a COW from occurring and
+	  causing the faulting task to livelock.
+
 config ARM_ERRATA_411920
 	bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
 	depends on CPU_V6 || CPU_V6K
arch/arm/mm/abort-ev6.S +11 -6
@@ -26,18 +26,23 @@ ENTRY(v6_early_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 /*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
- * The test below covers all the write situations, including Java bytecodes
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
  */
-	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
+#ifdef CONFIG_ARM_ERRATA_326103
+	ldr	ip, =0x4107b36
+	mrc	p15, 0, r3, c0, c0, 0		@ get processor id
+	teq	ip, r3, lsr #4			@ r0 ARM1136?
+	bne	do_DataAbort
 	tst	r5, #PSR_J_BIT			@ Java?
+	tsteq	r5, #PSR_T_BIT			@ Thumb?
 	bne	do_DataAbort
-	do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
-	ldreq	r3, [r4]			@ read aborted ARM instruction
+	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
+	ldr	r3, [r4]			@ read aborted ARM instruction
 #ifdef CONFIG_CPU_ENDIAN_BE8
-	reveq	r3, r3
+	rev	r3, r3
 #endif
 	do_ldrd_abort tmp=ip, insn=r3
 	tst	r3, #1 << 20			@ L = 0 -> write
 	orreq	r1, r1, #1 << 11		@ yes.
+#endif
 	b	do_DataAbort
author maintainer
#40 lore raw

PATCH 40/75 ARM: 7403/1: tls: remove covert channel via TPIDRURW

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit 6a1c53124aa161eb624ce7b1e40ade728186d34c upstream.

TPIDRURW is a user read/write register forming part of the group of thread registers in more recent versions of the ARM architecture (~v6+).

Currently, the kernel does not touch this register, which allows tasks to communicate covertly by reading and writing to the register without context-switching affecting its contents.

This patch clears TPIDRURW when TPIDRURO is updated via the set_tls macro, which is called directly from __switch_to. Since the current behaviour makes the register useless to userspace as far as thread pointers are concerned, simply clearing the register (rather than saving and restoring it) will not cause any problems to userspace.

---
 arch/arm/include/asm/tls.h |    4 ++++
 1 file changed, 4 insertions(+)
arch/arm/include/asm/tls.h +4 -0
@@ -7,6 +7,8 @@
 
 	.macro set_tls_v6k, tp, tmp1, tmp2
 	mcr	p15, 0, \tp, c13, c0, 3		@ set TLS register
+	mov	\tmp1, #0
+	mcr	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	.endm
 
 	.macro set_tls_v6, tp, tmp1, tmp2
@@ -15,6 +17,8 @@
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
 	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	movne	\tmp1, #0
+	mcrne	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
 
author maintainer
#41 lore raw

PATCH 41/75 ARM: 7406/1: hotplug: copy the affinity mask when forcefully migrating IRQs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit 5e7371ded05adfcfcee44a8bc070bfc37979b8f2 upstream.

When a CPU is hotplugged off, we migrate any IRQs currently affine to it away and onto another online CPU by calling the irq_set_affinity function of the relevant interrupt controller chip. This function returns either IRQ_SET_MASK_OK or IRQ_SET_MASK_OK_NOCOPY, to indicate whether irq_data.affinity was updated.

If we are forcefully migrating an interrupt (because the affinity mask no longer identifies any online CPUs) then we should update the IRQ affinity mask to reflect the new CPU set. Failure to do so can potentially leave /proc/irq/n/smp_affinity identifying only offline CPUs, which may confuse userspace IRQ balancing daemons.

This patch updates migrate_one_irq to copy the affinity mask when the interrupt chip returns IRQ_SET_MASK_OK after forcefully changing the affinity of an interrupt.

---
 arch/arm/kernel/irq.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/kernel/irq.c +3 -3
@@ -156,10 +156,10 @@ static bool migrate_one_irq(struct irq_d
 	}
 
 	c = irq_data_get_irq_chip(d);
-	if (c->irq_set_affinity)
-		c->irq_set_affinity(d, affinity, true);
-	else
+	if (!c->irq_set_affinity)
 		pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+	else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
+		cpumask_copy(d->affinity, affinity);
 
 	return ret;
 }
author maintainer
#42 lore raw

PATCH 42/75 MIPS: ath79: fix AR933X WMAC reset code

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gabor Juhos <[email protected]>

commit de14ca6ae2c592d66db88f1e5596b26f7f011384 upstream.

The current code puts the built-in WMAC device of the AR933X SoCs into reset instead of starting it. This causes a hard lock on AR933X based boards when the wireless driver tries to access the device.

Patchwork: https://patchwork.linux-mips.org/patch/3484/

---
 arch/mips/ath79/dev-wmac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/ath79/dev-wmac.c +1 -1
@@ -58,8 +58,8 @@ static void __init ar913x_wmac_setup(voi
 
 static int ar933x_wmac_reset(void)
 {
-	ath79_device_reset_clear(AR933X_RESET_WMAC);
 	ath79_device_reset_set(AR933X_RESET_WMAC);
+	ath79_device_reset_clear(AR933X_RESET_WMAC);
 
 	return 0;
 }
author maintainer
#43 lore raw

PATCH 43/75 SCSI: libsas: fix sas_find_bcast_phy() in the presence of vacant phys

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Jackson <[email protected]>

commit 1699490db339e2c6b3037ea8e7dcd6b2755b688e upstream.

If an expander reports 'PHY VACANT' for a phy index prior to the one that generated a BCN libsas fails rediscovery. Since a vacant phy is defined as a valid phy index that will never have an attached device just continue the search.

---
 drivers/scsi/libsas/sas_expander.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/scsi/libsas/sas_expander.c +12 -5
@@ -1643,9 +1643,17 @@ static int sas_find_bcast_phy(struct dom
 		int phy_change_count = 0;
 
 		res = sas_get_phy_change_count(dev, i, &phy_change_count);
-		if (res)
-			goto out;
-		else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
+		switch (res) {
+		case SMP_RESP_PHY_VACANT:
+		case SMP_RESP_NO_PHY:
+			continue;
+		case SMP_RESP_FUNC_ACC:
+			break;
+		default:
+			return res;
+		}
+
+		if (phy_change_count != ex->ex_phy[i].phy_change_count) {
 			if (update)
 				ex->ex_phy[i].phy_change_count =
 					phy_change_count;
@@ -1653,8 +1661,7 @@ static int sas_find_bcast_phy(struct dom
 			return 0;
 		}
 	}
-out:
-	return res;
+	return 0;
 }
 
 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
author maintainer
#44 lore raw

PATCH 44/75 SCSI: libsas: fix false positive device attached conditions

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Williams <[email protected]>

commit 7d1d865181185bdf1316d236b1b4bd02c9020729 upstream.

Normalize phy->attached_sas_addr to return a zero-address in the case when device-type == NO_DEVICE or the linkrate is invalid to handle expanders that put non-zero sas addresses in the discovery response:

sas: ex 5001b4da000f903f phy02:U:0 attached: 0100000000000000 (no device)
sas: ex 5001b4da000f903f phy01:U:0 attached: 0100000000000000 (no device)
sas: ex 5001b4da000f903f phy03:U:0 attached: 0100000000000000 (no device)
sas: ex 5001b4da000f903f phy00:U:0 attached: 0100000000000000 (no device)

---
 drivers/scsi/libsas/sas_expander.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/scsi/libsas/sas_expander.c +8 -1
@@ -192,7 +192,14 @@ static void sas_set_ex_phy(struct domain
 	phy->attached_sata_ps   = dr->attached_sata_ps;
 	phy->attached_iproto = dr->iproto << 1;
 	phy->attached_tproto = dr->tproto << 1;
-	memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
+	/* help some expanders that fail to zero sas_address in the 'no
+	 * device' case
+	 */
+	if (phy->attached_dev_type == NO_DEVICE ||
+	    phy->linkrate < SAS_LINK_RATE_1_5_GBPS)
+		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
+	else
+		memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
 	phy->attached_phy_id = dr->attached_phy_id;
 	phy->phy_change_count = dr->change_count;
 	phy->routing_attr = dr->routing_attr;
author maintainer
#45 lore raw

PATCH 45/75 efi: Add new variable attributes

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matthew Garrett <[email protected]>

commit 41b3254c93acc56adc3c4477fef7c9512d47659e upstream.

More recent versions of the UEFI spec have added new attributes for variables. Add them.

---
 include/linux/efi.h |   11 +++++++++++
 1 file changed, 11 insertions(+)
include/linux/efi.h +11 -0
@@ -510,7 +510,18 @@ extern int __init efi_setup_pcdp_console
 #define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
 #define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020
+#define EFI_VARIABLE_APPEND_WRITE	0x0000000000000040
 
+#define EFI_VARIABLE_MASK 	(EFI_VARIABLE_NON_VOLATILE | \
+				EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+				EFI_VARIABLE_RUNTIME_ACCESS | \
+				EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
+				EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
+				EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
+				EFI_VARIABLE_APPEND_WRITE)
 /*
  * The type of search to perform when calling boottime->locate_handle
  */
author maintainer
#46 lore raw

PATCH 46/75 efi: Validate UEFI boot variables

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matthew Garrett <[email protected]>

commit fec6c20b570bcf541e581fc97f2e0cbdb9725b98 upstream.

A common flaw in UEFI systems is a refusal to POST triggered by a malformed boot variable. Once in this state, machines may only be restored by reflashing their firmware with an external hardware device. While this is obviously a firmware bug, the serious nature of the outcome suggests that operating systems should filter their variable writes in order to prevent a malicious user from rendering the machine unusable.

---
 drivers/firmware/efivars.c |  182 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 182 insertions(+)
drivers/firmware/efivars.c +182 -0
@@ -191,6 +191,176 @@ utf16_strncmp(const efi_char16_t *a, con
 	}
 }
 
+static bool
+validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len)
+{
+	struct efi_generic_dev_path *node;
+	int offset = 0;
+
+	node = (struct efi_generic_dev_path *)buffer;
+
+	while (offset < len) {
+		offset += node->length;
+
+		if (offset > len)
+			return false;
+
+		if ((node->type == EFI_DEV_END_PATH ||
+		     node->type == EFI_DEV_END_PATH2) &&
+		    node->sub_type == EFI_DEV_END_ENTIRE)
+			return true;
+
+		node = (struct efi_generic_dev_path *)(buffer + offset);
+	}
+
+	/*
+	 * If we're here then either node->length pointed past the end
+	 * of the buffer or we reached the end of the buffer without
+	 * finding a device path end node.
+	 */
+	return false;
+}
+
+static bool
+validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len)
+{
+	/* An array of 16-bit integers */
+	if ((len % 2) != 0)
+		return false;
+
+	return true;
+}
+
+static bool
+validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len)
+{
+	u16 filepathlength;
+	int i, desclength = 0;
+
+	/* Either "Boot" or "Driver" followed by four digits of hex */
+	for (i = match; i < match+4; i++) {
+		if (hex_to_bin(var->VariableName[i] & 0xff) < 0)
+			return true;
+	}
+
+	/* A valid entry must be at least 6 bytes */
+	if (len < 6)
+		return false;
+
+	filepathlength = buffer[4] | buffer[5] << 8;
+
+	/*
+	 * There's no stored length for the description, so it has to be
+	 * found by hand
+	 */
+	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2;
+
+	/* Each boot entry must have a descriptor */
+	if (!desclength)
+		return false;
+
+	/*
+	 * If the sum of the length of the description, the claimed filepath
+	 * length and the original header are greater than the length of the
+	 * variable, it's malformed
+	 */
+	if ((desclength + filepathlength + 6) > len)
+		return false;
+
+	/*
+	 * And, finally, check the filepath
+	 */
+	return validate_device_path(var, match, buffer + desclength + 6,
+				    filepathlength);
+}
+
+static bool
+validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len)
+{
+	/* A single 16-bit integer */
+	if (len != 2)
+		return false;
+
+	return true;
+}
+
+static bool
+validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		if (buffer[i] > 127)
+			return false;
+
+		if (buffer[i] == 0)
+			return true;
+	}
+
+	return false;
+}
+
+struct variable_validate {
+	char *name;
+	bool (*validate)(struct efi_variable *var, int match, u8 *data,
+			 int len);
+};
+
+static const struct variable_validate variable_validate[] = {
+	{ "BootNext", validate_uint16 },
+	{ "BootOrder", validate_boot_order },
+	{ "DriverOrder", validate_boot_order },
+	{ "Boot*", validate_load_option },
+	{ "Driver*", validate_load_option },
+	{ "ConIn", validate_device_path },
+	{ "ConInDev", validate_device_path },
+	{ "ConOut", validate_device_path },
+	{ "ConOutDev", validate_device_path },
+	{ "ErrOut", validate_device_path },
+	{ "ErrOutDev", validate_device_path },
+	{ "Timeout", validate_uint16 },
+	{ "Lang", validate_ascii_string },
+	{ "PlatformLang", validate_ascii_string },
+	{ "", NULL },
+};
+
+static bool
+validate_var(struct efi_variable *var, u8 *data, int len)
+{
+	int i;
+	u16 *unicode_name = var->VariableName;
+
+	for (i = 0; variable_validate[i].validate != NULL; i++) {
+		const char *name = variable_validate[i].name;
+		int match;
+
+		for (match = 0; ; match++) {
+			char c = name[match];
+			u16 u = unicode_name[match];
+
+			/* All special variables are plain ascii */
+			if (u > 127)
+				return true;
+
+			/* Wildcard in the matching name means we've matched */
+			if (c == '*')
+				return variable_validate[i].validate(var,
+							     match, data, len);
+
+			/* Case sensitive match */
+			if (c != u)
+				break;
+
+			/* Reached the end of the string while matching */
+			if (!c)
+				return variable_validate[i].validate(var,
+							     match, data, len);
+		}
+	}
+
+	return true;
+}
+
 static efi_status_t
 get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
 {
@@ -324,6 +494,12 @@ efivar_store_raw(struct efivar_entry *en
 		return -EINVAL;
 	}
 
+	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
+		printk(KERN_ERR "efivars: Malformed variable content\n");
+		return -EINVAL;
+	}
+
 	spin_lock(&efivars->lock);
 	status = efivars->ops->set_variable(new_var->VariableName,
 					    &new_var->VendorGuid,
@@ -626,6 +802,12 @@ static ssize_t efivar_create(struct file
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
+	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
+		printk(KERN_ERR "efivars: Malformed variable content\n");
+		return -EINVAL;
+	}
+
 	spin_lock(&efivars->lock);
 
 	/*
author maintainer
#47 lore raw

PATCH 47/75 x86, efi: Fix pointer math issue in handle_ramdisks()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit c7b738351ba92f48b943ac59aff6b5b0f17f37c9 upstream.

"filename" is a efi_char16_t string so this check for reaching the end of the array doesn't work. We need to cast the pointer to (u8 *) before doing the math.

This patch changes the "filename" to "filename_16" to avoid confusion in the future.

---
 arch/x86/boot/compressed/eboot.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/boot/compressed/eboot.c +4 -4
@@ -539,7 +539,7 @@ static efi_status_t handle_ramdisks(efi_
 		struct initrd *initrd;
 		efi_file_handle_t *h;
 		efi_file_info_t *info;
-		efi_char16_t filename[256];
+		efi_char16_t filename_16[256];
 		unsigned long info_sz;
 		efi_guid_t info_guid = EFI_FILE_INFO_ID;
 		efi_char16_t *p;
@@ -552,14 +552,14 @@ static efi_status_t handle_ramdisks(efi_
 		str += 7;
 
 		initrd = &initrds[i];
-		p = filename;
+		p = filename_16;
 
 		/* Skip any leading slashes */
 		while (*str == '/' || *str == '\\')
 			str++;
 
 		while (*str && *str != ' ' && *str != '\n') {
-			if (p >= filename + sizeof(filename))
+			if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
 				break;
 
 			*p++ = *str++;
@@ -583,7 +583,7 @@ static efi_status_t handle_ramdisks(efi_
 				goto free_initrds;
 		}
 
-		status = efi_call_phys5(fh->open, fh, &h, filename,
+		status = efi_call_phys5(fh->open, fh, &h, filename_16,
 					EFI_FILE_MODE_READ, (u64)0);
 		if (status != EFI_SUCCESS)
 			goto close_handles;
author maintainer
#48 lore raw

PATCH 48/75 tools/include: Add byteshift headers for endian access

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Fleming <[email protected]>

commit a07f7672d7cf0ff0d6e548a9feb6e0bd016d9c6c upstream.

There are various hostprogs in the kernel that are rolling their own implementations of {get,put}_unaligned_le*(). Copy the byteshift headers from include/linux/unaligned so that they can all use a single implementation.

This requires changing some of the data types to the userspace exported ones (u32 -> __u32, etc).

---
 tools/include/tools/be_byteshift.h |   70 +++++++++++++++++++++++++++++++++++++
 tools/include/tools/le_byteshift.h |   70 +++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
tools/include/tools/be_byteshift.h new file +70 -0
@@ -0,0 +1,70 @@
+#ifndef _TOOLS_BE_BYTESHIFT_H
+#define _TOOLS_BE_BYTESHIFT_H
+
+#include <linux/types.h>
+
+static inline __u16 __get_unaligned_be16(const __u8 *p)
+{
+	return p[0] << 8 | p[1];
+}
+
+static inline __u32 __get_unaligned_be32(const __u8 *p)
+{
+	return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+}
+
+static inline __u64 __get_unaligned_be64(const __u8 *p)
+{
+	return (__u64)__get_unaligned_be32(p) << 32 |
+	       __get_unaligned_be32(p + 4);
+}
+
+static inline void __put_unaligned_be16(__u16 val, __u8 *p)
+{
+	*p++ = val >> 8;
+	*p++ = val;
+}
+
+static inline void __put_unaligned_be32(__u32 val, __u8 *p)
+{
+	__put_unaligned_be16(val >> 16, p);
+	__put_unaligned_be16(val, p + 2);
+}
+
+static inline void __put_unaligned_be64(__u64 val, __u8 *p)
+{
+	__put_unaligned_be32(val >> 32, p);
+	__put_unaligned_be32(val, p + 4);
+}
+
+static inline __u16 get_unaligned_be16(const void *p)
+{
+	return __get_unaligned_be16((const __u8 *)p);
+}
+
+static inline __u32 get_unaligned_be32(const void *p)
+{
+	return __get_unaligned_be32((const __u8 *)p);
+}
+
+static inline __u64 get_unaligned_be64(const void *p)
+{
+	return __get_unaligned_be64((const __u8 *)p);
+}
+
+static inline void put_unaligned_be16(__u16 val, void *p)
+{
+	__put_unaligned_be16(val, p);
+}
+
+static inline void put_unaligned_be32(__u32 val, void *p)
+{
+	__put_unaligned_be32(val, p);
+}
+
+static inline void put_unaligned_be64(__u64 val, void *p)
+{
+	__put_unaligned_be64(val, p);
+}
+
+#endif /* _TOOLS_BE_BYTESHIFT_H */
tools/include/tools/le_byteshift.h new file +70 -0

70 lines not on this page · raw message

author maintainer
#49 lore raw

PATCH 49/75 x86, mkpiggy: Dont open code put_unaligned_le32()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Fleming <[email protected]>

commit 12871c568305a0b20f116315479a18cd46882e9b upstream.

Use the new headers in tools/include instead of rolling our own put_unaligned_le32() implementation.

---
 arch/x86/boot/compressed/Makefile  |    1 +
 arch/x86/boot/compressed/mkpiggy.c |   11 ++---------
 2 files changed, 3 insertions(+), 9 deletions(-)
arch/x86/boot/compressed/Makefile +1 -0
@@ -22,6 +22,7 @@ LDFLAGS := -m elf_$(UTS_MACHINE)
 LDFLAGS_vmlinux := -T
 
 hostprogs-y	:= mkpiggy
+HOST_EXTRACFLAGS += -I$(srctree)/tools/include
 
 VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \
 	$(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \
arch/x86/boot/compressed/mkpiggy.c +2 -9
@@ -29,14 +29,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
-
-static uint32_t getle32(const void *p)
-{
-	const uint8_t *cp = p;
-
-	return (uint32_t)cp[0] + ((uint32_t)cp[1] << 8) +
-		((uint32_t)cp[2] << 16) + ((uint32_t)cp[3] << 24);
-}
+#include <tools/le_byteshift.h>
 
 int main(int argc, char *argv[])
 {
@@ -69,7 +62,7 @@ int main(int argc, char *argv[])
 	}
 
 	ilen = ftell(f);
-	olen = getle32(&olen);
+	olen = get_unaligned_le32(&olen);
 	fclose(f);
 
 	/*
author maintainer
#50 lore raw

PATCH 50/75 x86, boot: Restrict CFLAGS for hostprogs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Fleming <[email protected]>

commit d40f833630a1299fd377408dc8d8fac370d621b0 upstream.

Currently tools/build has access to all the kernel headers in $(srctree). This is unnecessary and could potentially allow tools/build to erroneously include kernel headers when it should only be including userspace-exported headers.

Unfortunately, mkcpustr still needs access to some of the asm kernel headers, so explicitly special case that hostprog.

---
 arch/x86/boot/Makefile |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/boot/Makefile +3 -2
@@ -37,8 +37,9 @@ setup-y		+= video-bios.o
 targets		+= $(setup-y)
 hostprogs-y	:= mkcpustr tools/build
 
-HOST_EXTRACFLAGS += $(LINUXINCLUDE)
-
+HOSTCFLAGS_mkcpustr.o := -I$(srctree)/arch/$(SRCARCH)/include
+HOST_EXTRACFLAGS += -I$(objtree)/include -I$(srctree)/tools/include \
+                   -include $(srctree)/include/linux/kconfig.h
 $(obj)/cpu.o: $(obj)/cpustr.h
 
 quiet_cmd_cpustr = CPUSTR  $@
author maintainer
#51 lore raw

PATCH 51/75 x86, efi: Fix endian issues and unaligned accesses

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Fleming <[email protected]>

commit 92f42c50f227ad228f815a8f4eec872524dae3a5 upstream.

We may need to convert the endianness of the data we read from/write to 'buf', so let's use {get,put}_unaligned_le32() to do that. Failure to do so can result in accessing invalid memory, leading to a segfault. Stephen Rothwell noticed this bug while cross-building an x86_64 allmodconfig kernel on PowerPC.

We need to read from and write to 'buf' a byte at a time otherwise it's possible we'll perform an unaligned access, which can lead to bus errors when cross-building an x86 kernel on risc architectures.

---
 arch/x86/boot/tools/build.c |   31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)
arch/x86/boot/tools/build.c +15 -16
@@ -34,6 +34,7 @@
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <asm/boot.h>
+#include <tools/le_byteshift.h>
 
 typedef unsigned char  u8;
 typedef unsigned short u16;
@@ -41,6 +42,7 @@ typedef unsigned long  u32;
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
+#define DEFAULT_ROOT_DEV (DEFAULT_MAJOR_ROOT << 8 | DEFAULT_MINOR_ROOT)
 
 /* Minimal number of setup sectors */
 #define SETUP_SECT_MIN 5
@@ -159,7 +161,7 @@ int main(int argc, char ** argv)
 		die("read-error on `setup'");
 	if (c < 1024)
 		die("The setup must be at least 1024 bytes");
-	if (buf[510] != 0x55 || buf[511] != 0xaa)
+	if (get_unaligned_le16(&buf[510]) != 0xAA55)
 		die("Boot block hasn't got boot flag (0xAA55)");
 	fclose(file);
 
@@ -171,8 +173,7 @@ int main(int argc, char ** argv)
 	memset(buf+c, 0, i-c);
 
 	/* Set the default root device */
-	buf[508] = DEFAULT_MINOR_ROOT;
-	buf[509] = DEFAULT_MAJOR_ROOT;
+	put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
 
 	fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
 
@@ -192,44 +193,42 @@ int main(int argc, char ** argv)
 
 	/* Patch the setup code with the appropriate size parameters */
 	buf[0x1f1] = setup_sectors-1;
-	buf[0x1f4] = sys_size;
-	buf[0x1f5] = sys_size >> 8;
-	buf[0x1f6] = sys_size >> 16;
-	buf[0x1f7] = sys_size >> 24;
+	put_unaligned_le32(sys_size, &buf[0x1f4]);
 
 #ifdef CONFIG_EFI_STUB
 	file_sz = sz + i + ((sys_size * 16) - sz);
 
-	pe_header = *(unsigned int *)&buf[0x3c];
+	pe_header = get_unaligned_le32(&buf[0x3c]);
 
 	/* Size of code */
-	*(unsigned int *)&buf[pe_header + 0x1c] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0x1c]);
 
 	/* Size of image */
-	*(unsigned int *)&buf[pe_header + 0x50] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
 
 #ifdef CONFIG_X86_32
 	/* Address of entry point */
-	*(unsigned int *)&buf[pe_header + 0x28] = i;
+	put_unaligned_le32(i, &buf[pe_header + 0x28]);
 
 	/* .text size */
-	*(unsigned int *)&buf[pe_header + 0xb0] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]);
 
 	/* .text size of initialised data */
-	*(unsigned int *)&buf[pe_header + 0xb8] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0xb8]);
 #else
 	/*
 	 * Address of entry point. startup_32 is at the beginning and
 	 * the 64-bit entry point (startup_64) is always 512 bytes
 	 * after.
 	 */
-	*(unsigned int *)&buf[pe_header + 0x28] = i + 512;
+	put_unaligned_le32(i + 512, &buf[pe_header + 0x28]);
 
 	/* .text size */
-	*(unsigned int *)&buf[pe_header + 0xc0] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]);
 
 	/* .text size of initialised data */
-	*(unsigned int *)&buf[pe_header + 0xc8] = file_sz;
+	put_unaligned_le32(file_sz, &buf[pe_header + 0xc8]);
+
 #endif /* CONFIG_X86_32 */
 #endif /* CONFIG_EFI_STUB */
 
author maintainer
#52 lore raw

PATCH 52/75 x86, boot: Correct CFLAGS for hostprogs

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: "H. Peter Anvin" <[email protected]>

commit 446e1c86d51d0823e003a43a2b85c430efce2733 upstream.

This is a partial revert of commit:
d40f833 "Restrict CFLAGS for hostprogs"

The endian-manipulation macros in tools/include need <linux/types.h>, but the hostprogs in arch/x86/boot need several headers from the kernel build tree, which means we have to add the kernel headers to the include path. This picks up <linux/types.h> from the kernel tree, which gives a warning.

Since this use of <linux/types.h> is intentional, add -D__EXPORTED_HEADERS__ to the command line to silence the warning.

A better way to fix this would be to always install the exported kernel headers into $(objtree)/usr/include as a standard part of the kernel build, but that is a lot more involved.

---
 arch/x86/boot/Makefile |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/boot/Makefile +3 -3
@@ -37,9 +37,9 @@ setup-y		+= video-bios.o
 targets		+= $(setup-y)
 hostprogs-y	:= mkcpustr tools/build
 
-HOSTCFLAGS_mkcpustr.o := -I$(srctree)/arch/$(SRCARCH)/include
-HOST_EXTRACFLAGS += -I$(objtree)/include -I$(srctree)/tools/include \
-                   -include $(srctree)/include/linux/kconfig.h
+HOST_EXTRACFLAGS += -I$(srctree)/tools/include $(LINUXINCLUDE) \
+	            -D__EXPORTED_HEADERS__
+
 $(obj)/cpu.o: $(obj)/cpustr.h
 
 quiet_cmd_cpustr = CPUSTR  $@
author maintainer
#53 lore raw

PATCH 53/75 x86, efi: Add dedicated EFI stub entry point

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Fleming <[email protected]>

commit b1994304fc399f5d3a5368c81111d713490c4799 upstream.

The method used to work out whether we were booted by EFI firmware or via a boot loader is broken. Because efi_main() is always executed when booting from a boot loader we will dereference invalid pointers either on the stack (CONFIG_X86_32) or contained in %rdx (CONFIG_X86_64) when searching for an EFI System Table signature.

Instead of dereferencing these invalid system table pointers, add a new entry point that is only used when booting from EFI firmware, when we know the pointer arguments will be valid. With this change legacy boot loaders will no longer execute efi_main(), but will instead skip EFI stub initialisation completely.

[ hpa: Marking this for urgent/stable since it is a regression when
the option is enabled; without the option the patch has no effect ]

---
 arch/x86/boot/compressed/head_32.S |   14 +++++++++++---
 arch/x86/boot/compressed/head_64.S |   22 ++++++++++++++++------
 arch/x86/boot/tools/build.c        |   15 +++++++++++----
 3 files changed, 38 insertions(+), 13 deletions(-)
arch/x86/boot/compressed/head_32.S +11 -3
@@ -33,6 +33,9 @@
 	__HEAD
 ENTRY(startup_32)
 #ifdef CONFIG_EFI_STUB
+	jmp	preferred_addr
+
+	.balign	0x10
 	/*
 	 * We don't need the return address, so set up the stack so
 	 * efi_main() can find its arugments.
@@ -41,12 +44,17 @@ ENTRY(startup_32)
 
 	call	efi_main
 	cmpl	$0, %eax
-	je	preferred_addr
 	movl	%eax, %esi
-	call	1f
+	jne	2f
 1:
+	/* EFI init failed, so hang. */
+	hlt
+	jmp	1b
+2:
+	call	3f
+3:
 	popl	%eax
-	subl	$1b, %eax
+	subl	$3b, %eax
 	subl	BP_pref_address(%esi), %eax
 	add	BP_code32_start(%esi), %eax
 	leal	preferred_addr(%eax), %eax
arch/x86/boot/compressed/head_64.S +16 -6
@@ -200,18 +200,28 @@ ENTRY(startup_64)
 	 * entire text+data+bss and hopefully all of memory.
 	 */
 #ifdef CONFIG_EFI_STUB
-	pushq	%rsi
+	/*
+	 * The entry point for the PE/COFF executable is 0x210, so only
+	 * legacy boot loaders will execute this jmp.
+	 */
+	jmp	preferred_addr
+
+	.org 0x210
 	mov	%rcx, %rdi
 	mov	%rdx, %rsi
 	call	efi_main
-	popq	%rsi
-	cmpq	$0,%rax
-	je	preferred_addr
 	movq	%rax,%rsi
-	call	1f
+	cmpq	$0,%rax
+	jne	2f
 1:
+	/* EFI init failed, so hang. */
+	hlt
+	jmp	1b
+2:
+	call	3f
+3:
 	popq	%rax
-	subq	$1b, %rax
+	subq	$3b, %rax
 	subq	BP_pref_address(%rsi), %rax
 	add	BP_code32_start(%esi), %eax
 	leaq	preferred_addr(%rax), %rax
arch/x86/boot/tools/build.c +11 -4
@@ -207,8 +207,13 @@ int main(int argc, char ** argv)
 	put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
 
 #ifdef CONFIG_X86_32
-	/* Address of entry point */
-	put_unaligned_le32(i, &buf[pe_header + 0x28]);
+	/*
+	 * Address of entry point.
+	 *
+	 * The EFI stub entry point is +16 bytes from the start of
+	 * the .text section.
+	 */
+	put_unaligned_le32(i + 16, &buf[pe_header + 0x28]);
 
 	/* .text size */
 	put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]);
@@ -219,9 +224,11 @@ int main(int argc, char ** argv)
 	/*
 	 * Address of entry point. startup_32 is at the beginning and
 	 * the 64-bit entry point (startup_64) is always 512 bytes
-	 * after.
+	 * after. The EFI stub entry point is 16 bytes after that, as
+	 * the first instruction allows legacy loaders to jump over
+	 * the EFI stub initialisation
 	 */
-	put_unaligned_le32(i + 512, &buf[pe_header + 0x28]);
+	put_unaligned_le32(i + 528, &buf[pe_header + 0x28]);
 
 	/* .text size */
 	put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]);
author maintainer
#54 lore raw

PATCH 54/75 powerpc/85xx: dont call of_platform_bus_probe() twice

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Timur Tabi <[email protected]>

commit 8a95bc8dfe06982fc2b8a0a2adda7baa2346a17b upstream.

Commit 46d026ac ("powerpc/85xx: consolidate of_platform_bus_probe calls") replaced platform-specific of_device_id tables with a single function that probes the most of the busses in 85xx device trees. If a specific platform needed additional busses probed, then it could call of_platform_bus_probe() again. Typically, the additional platform-specific busses are children of existing busses that have already been probed. of_platform_bus_probe() does not handle those child busses automatically.

Unfortunately, this doesn't actually work. The second (platform-specific) call to of_platform_bus_probe() never finds any of the busses it's asked to find.

To remedy this, the platform-specific of_device_id tables are eliminated, and their entries are merged into mpc85xx_common_ids[], so that all busses are probed at once.

---
 arch/powerpc/platforms/85xx/common.c      |    6 ++++++
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |   11 +----------
 arch/powerpc/platforms/85xx/p1022_ds.c    |   13 +------------
 3 files changed, 8 insertions(+), 22 deletions(-)
arch/powerpc/platforms/85xx/common.c +6 -0
@@ -21,6 +21,12 @@ static struct of_device_id __initdata mp
 	{ .compatible = "fsl,qe", },
 	{ .compatible = "fsl,cpm2", },
 	{ .compatible = "fsl,srio", },
+	/* So that the DMA channel nodes can be probed individually: */
+	{ .compatible = "fsl,eloplus-dma", },
+	/* For the PMC driver */
+	{ .compatible = "fsl,mpc8548-guts", },
+	/* Probably unnecessary? */
+	{ .compatible = "gpio-leds", },
 	{},
 };
 
arch/powerpc/platforms/85xx/mpc85xx_mds.c +1 -10
@@ -405,12 +405,6 @@ static int __init board_fixups(void)
 machine_arch_initcall(mpc8568_mds, board_fixups);
 machine_arch_initcall(mpc8569_mds, board_fixups);
 
-static struct of_device_id mpc85xx_ids[] = {
-	{ .compatible = "fsl,mpc8548-guts", },
-	{ .compatible = "gpio-leds", },
-	{},
-};
-
 static int __init mpc85xx_publish_devices(void)
 {
 	if (machine_is(mpc8568_mds))
@@ -418,10 +412,7 @@ static int __init mpc85xx_publish_device
 	if (machine_is(mpc8569_mds))
 		simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
 
-	mpc85xx_common_publish_devices();
-	of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
-
-	return 0;
+	return mpc85xx_common_publish_devices();
 }
 
 machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
arch/powerpc/platforms/85xx/p1022_ds.c +1 -12
@@ -303,18 +303,7 @@ static void __init p1022_ds_setup_arch(v
 	pr_info("Freescale P1022 DS reference board\n");
 }
 
-static struct of_device_id __initdata p1022_ds_ids[] = {
-	/* So that the DMA channel nodes can be probed individually: */
-	{ .compatible = "fsl,eloplus-dma", },
-	{},
-};
-
-static int __init p1022_ds_publish_devices(void)
-{
-	mpc85xx_common_publish_devices();
-	return of_platform_bus_probe(NULL, p1022_ds_ids, NULL);
-}
-machine_device_initcall(p1022_ds, p1022_ds_publish_devices);
+machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices);
 
 machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier);
 
author maintainer
#55 lore raw

PATCH 55/75 PM / Hibernate: fix the number of pages used for hibernate/thaw buffering

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bojan Smojver <[email protected]>

commit f8262d476823a7ea1eb497ff9676d1eab2393c75 upstream.

Hibernation regression fix, since 3.2.

Calculate the number of required free pages based on non-high memory pages only, because that is where the buffers will come from.

Commit 081a9d043c983f161b78fdc4671324d1342b86bc introduced a new buffer page allocation logic during hibernation, in order to improve the performance. The amount of pages allocated was calculated based on total amount of pages available, although only non-high memory pages are usable for this purpose. This caused hibernation code to attempt to over allocate pages on platforms that have high memory, which led to hangs.

---
 kernel/power/swap.c |   28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)
kernel/power/swap.c +22 -6
@@ -51,6 +51,23 @@
 
 #define MAP_PAGE_ENTRIES	(PAGE_SIZE / sizeof(sector_t) - 1)
 
+/*
+ * Number of free pages that are not high.
+ */
+static inline unsigned long low_free_pages(void)
+{
+	return nr_free_pages() - nr_free_highpages();
+}
+
+/*
+ * Number of pages required to be kept free while writing the image. Always
+ * half of all available low pages before the writing starts.
+ */
+static inline unsigned long reqd_free_pages(void)
+{
+	return low_free_pages() / 2;
+}
+
 struct swap_map_page {
 	sector_t entries[MAP_PAGE_ENTRIES];
 	sector_t next_swap;
@@ -72,7 +89,7 @@ struct swap_map_handle {
 	sector_t cur_swap;
 	sector_t first_sector;
 	unsigned int k;
-	unsigned long nr_free_pages, written;
+	unsigned long reqd_free_pages;
 	u32 crc32;
 };
 
@@ -316,8 +333,7 @@ static int get_swap_writer(struct swap_m
 		goto err_rel;
 	}
 	handle->k = 0;
-	handle->nr_free_pages = nr_free_pages() >> 1;
-	handle->written = 0;
+	handle->reqd_free_pages = reqd_free_pages();
 	handle->first_sector = handle->cur_swap;
 	return 0;
 err_rel:
@@ -352,11 +368,11 @@ static int swap_write_page(struct swap_m
 		handle->cur_swap = offset;
 		handle->k = 0;
 	}
-	if (bio_chain && ++handle->written > handle->nr_free_pages) {
+	if (bio_chain && low_free_pages() <= handle->reqd_free_pages) {
 		error = hib_wait_on_bio_chain(bio_chain);
 		if (error)
 			goto out;
-		handle->written = 0;
+		handle->reqd_free_pages = reqd_free_pages();
 	}
  out:
 	return error;
@@ -618,7 +634,7 @@ static int save_image_lzo(struct swap_ma
 	 * Adjust number of free pages after all allocations have been done.
 	 * We don't want to run out of pages when writing.
 	 */
-	handle->nr_free_pages = nr_free_pages() >> 1;
+	handle->reqd_free_pages = reqd_free_pages();
 
 	/*
 	 * Start the CRC32 thread.
author maintainer
#56 lore raw

PATCH 56/75 sched: Fix nohz load accounting -- again!

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit c308b56b5398779cd3da0f62ab26b0453494c3d4 upstream.

Various people reported nohz load tracking still being wrecked, but Doug spotted the actual problem. We fold the nohz remainder in too soon, causing us to loose samples and under-account.

So instead of playing catch-up up-front, always do a single load-fold with whatever state we encounter and only then fold the nohz remainder and play catch-up.

---
 kernel/sched/core.c |   53 +++++++++++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 27 deletions(-)
kernel/sched/core.c +26 -27
@@ -2266,13 +2266,10 @@ calc_load_n(unsigned long load, unsigned
  * Once we've updated the global active value, we need to apply the exponential
  * weights adjusted to the number of cycles missed.
  */
-static void calc_global_nohz(unsigned long ticks)
+static void calc_global_nohz(void)
 {
 	long delta, active, n;
 
-	if (time_before(jiffies, calc_load_update))
-		return;
-
 	/*
 	 * If we crossed a calc_load_update boundary, make sure to fold
 	 * any pending idle changes, the respective CPUs might have
@@ -2284,31 +2281,25 @@ static void calc_global_nohz(unsigned lo
 		atomic_long_add(delta, &calc_load_tasks);
 
 	/*
-	 * If we were idle for multiple load cycles, apply them.
+	 * It could be the one fold was all it took, we done!
 	 */
-	if (ticks >= LOAD_FREQ) {
-		n = ticks / LOAD_FREQ;
+	if (time_before(jiffies, calc_load_update + 10))
+		return;
 
-		active = atomic_long_read(&calc_load_tasks);
-		active = active > 0 ? active * FIXED_1 : 0;
+	/*
+	 * Catch-up, fold however many we are behind still
+	 */
+	delta = jiffies - calc_load_update - 10;
+	n = 1 + (delta / LOAD_FREQ);
 
-		avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
-		avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
-		avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+	active = atomic_long_read(&calc_load_tasks);
+	active = active > 0 ? active * FIXED_1 : 0;
 
-		calc_load_update += n * LOAD_FREQ;
-	}
+	avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+	avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+	avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
 
-	/*
-	 * Its possible the remainder of the above division also crosses
-	 * a LOAD_FREQ period, the regular check in calc_global_load()
-	 * which comes after this will take care of that.
-	 *
-	 * Consider us being 11 ticks before a cycle completion, and us
-	 * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
-	 * age us 4 cycles, and the test in calc_global_load() will
-	 * pick up the final one.
-	 */
+	calc_load_update += n * LOAD_FREQ;
 }
 #else
 void calc_load_account_idle(struct rq *this_rq)
@@ -2320,7 +2311,7 @@ static inline long calc_load_fold_idle(v
 	return 0;
 }
 
-static void calc_global_nohz(unsigned long ticks)
+static void calc_global_nohz(void)
 {
 }
 #endif
@@ -2348,8 +2339,6 @@ void calc_global_load(unsigned long tick
 {
 	long active;
 
-	calc_global_nohz(ticks);
-
 	if (time_before(jiffies, calc_load_update + 10))
 		return;
 
@@ -2361,6 +2350,16 @@ void calc_global_load(unsigned long tick
 	avenrun[2] = calc_load(avenrun[2], EXP_15, active);
 
 	calc_load_update += LOAD_FREQ;
+
+	/*
+	 * Account one period with whatever state we found before
+	 * folding in the nohz state and ageing the entire idle period.
+	 *
+	 * This avoids loosing a sample when we go idle between
+	 * calc_load_account_active() (10 ticks ago) and now and thus
+	 * under-accounting.
+	 */
+	calc_global_nohz();
 }
 
 /*
#57 lore raw

RE: [ 56/75] sched: Fix nohz load accounting -- again!

Just earlier this morning, an issue was raised against this patch on the related thread on Ubuntu launchpad.
The complaint is that reported load averages are now to high under conditions of "high" frequency enter into / exit from cpu idle conditions where the cpu is very lightly loaded.
Most of the testing I did was with medium to heavy load on the cpu and relatively short idle periods. This is the opposite.
For a quick test, I hacked up my test program, and was able to reproduce the issue.
I am still attempting to understand better and also determine the lower bound to "high" frequency (I think it is 25 Hertz, and scales from there down, but no proof yet). I'll also go backwards and test this scenario without the patch. I'll let this list know the results, but it might be a few days. My quick test results are attached.

Doug Smythies

References (even though I have been told not to include links in e-mails to this list):

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/838811 <<< starting from post #52

version:

doug@s15:~/c$ uname -a
Linux s15 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
doug@s15:~/c$ cat /proc/version
Linux version 3.2.0-24-generic (buildd@yellow) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012

-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: May-04-2012 13:43
To: [email protected]; [email protected]
Cc: [email protected]; [email protected]; [email protected]; Doug Smythies; LesÅ�aw Kopeć; Aman Gupta; Peter Zijlstra; Ingo Molnar; Kerin Millar
Subject: [ 56/75] sched: Fix nohz load accounting -- again!

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit c308b56b5398779cd3da0f62ab26b0453494c3d4 upstream.

Various people reported nohz load tracking still being wrecked, but Doug spotted the actual problem. We fold the nohz remainder in too soon, causing us to loose samples and under-account.

So instead of playing catch-up up-front, always do a single load-fold with whatever state we encounter and only then fold the nohz remainder and play catch-up.

---
 kernel/sched/core.c |   53 +++++++++++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 27 deletions(-)
kernel/sched/core.c +1 -4
@@ -2266,13 +2266,10 @@ calc_load_n(unsigned long load, unsigned
  * Once we've updated the global active value, we need to apply the exponential
  * weights adjusted to the number of cycles missed.
  */
-static void calc_global_nohz(unsigned long ticks)
+static void calc_global_nohz(void)
 {
 	long delta, active, n;
 
-	if (time_before(jiffies, calc_load_update))
-		return;
-
 	/*
 	 * If we crossed a calc_load_update boundary, make sure to fold
 	 * any pending idle changes, the respective CPUs might have @@ -2284,31 +2281,25 @@ static void calc_global_nohz(unsigned lo

atomic_long_add(delta, &calc_load_tasks);

/*
- * If we were idle for multiple load cycles, apply them.
+ * It could be the one fold was all it took, we done!
*/
- if (ticks >= LOAD_FREQ) {
- n = ticks / LOAD_FREQ;
+ if (time_before(jiffies, calc_load_update + 10))
+ return;

- active = atomic_long_read(&calc_load_tasks);
- active = active > 0 ? active * FIXED_1 : 0;
+ /*
+ * Catch-up, fold however many we are behind still
+ */
+ delta = jiffies - calc_load_update - 10;
+ n = 1 + (delta / LOAD_FREQ);

- avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
- avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
- avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+ active = atomic_long_read(&calc_load_tasks);
+ active = active > 0 ? active * FIXED_1 : 0;

- calc_load_update += n * LOAD_FREQ;
- }
+ avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+ avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+ avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);

- /*
- * Its possible the remainder of the above division also crosses
- * a LOAD_FREQ period, the regular check in calc_global_load()
- * which comes after this will take care of that.
- *
- * Consider us being 11 ticks before a cycle completion, and us
- * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
- * age us 4 cycles, and the test in calc_global_load() will
- * pick up the final one.
- */
+ calc_load_update += n * LOAD_FREQ;
}
#else
void calc_load_account_idle(struct rq *this_rq) @@ -2320,7 +2311,7 @@ static inline long calc_load_fold_idle(v
return 0;
}

-static void calc_global_nohz(unsigned long ticks) +static void calc_global_nohz(void)
{
}
#endif
@@ -2348,8 +2339,6 @@ void calc_global_load(unsigned long tick {
long active;

- calc_global_nohz(ticks);
-
if (time_before(jiffies, calc_load_update + 10))
return;

@@ -2361,6 +2350,16 @@ void calc_global_load(unsigned long tick
avenrun[2] = calc_load(avenrun[2], EXP_15, active);

calc_load_update += LOAD_FREQ;
+
+ /*
+ * Account one period with whatever state we found before
+ * folding in the nohz state and ageing the entire idle period.
+ *
+ * This avoids loosing a sample when we go idle between
+ * calc_load_account_active() (10 ticks ago) and now and thus
+ * under-accounting.
+ */
+ calc_global_nohz();
}

/*

Doug Smythies 2012.05.04 CPU's enter and exit idle at high frequencies. but with very very low actual utilization. The majority of previous testing was very high utilization.

Excerpt from "Top"

top - 11:57:04 up 1 day, 15:28, 3 users, load average: 0.91, 0.87, 0.76

Tasks: 144 total,   2 running, 142 sleeping,   0 stopped,   0 zombie
Cpu0  :  0.9%us,  8.8%sy,  0.0%ni, 90.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu1  :  1.0%us,  4.8%sy,  0.0%ni, 94.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  :  0.3%us,  0.3%sy,  0.0%ni, 99.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.7%us,  0.0%sy,  0.0%ni, 99.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  0.3%us,  2.6%sy,  0.0%ni, 97.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu7  :  0.3%us,  0.3%sy,  0.0%ni, 99.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   7956400k total,  1591044k used,  6365356k free,   292288k buffers
Swap:  8294396k total,        0k used,  8294396k free,   882488k cached
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
15970 doug      20   0  4156   88    0 S    2  0.0   0:23.23 waiter
15972 doug      20   0  4156   88    0 S    2  0.0   0:23.24 waiter
15968 doug      20   0  4156   88    0 S    2  0.0   0:23.30 waiter
15971 doug      20   0  4156   88    0 S    2  0.0   0:23.36 waiter
15969 doug      20   0  4156   88    0 S    1  0.0   0:23.51 waiter
15986 doug      20   0 17332 1332  960 R    1  0.0   0:01.24 top
    1 root      20   0 24724 2616 1344 S    0  0.0   0:01.42 init

Similar excerpt from test program output. Note: TOP resource time = user cpu + sys cpu times.

Child 0 lp 706 of 9999: Elapsed:1411.97 s. Delta: 2.00 s. user cpu: 5.03 s. sys cpu: 18.46 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 1 lp 706 of 9999: Elapsed:1411.98 s. Delta: 2.00 s. user cpu: 5.38 s. sys cpu: 18.31 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.004 Hz.
Child 2 lp 706 of 9999: Elapsed:1411.97 s. Delta: 2.00 s. user cpu: 5.02 s. sys cpu: 18.39 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 3 lp 706 of 9999: Elapsed:1411.97 s. Delta: 2.00 s. user cpu: 5.23 s. sys cpu: 18.35 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 4 lp 706 of 9999: Elapsed:1411.97 s. Delta: 2.00 s. user cpu: 5.25 s. sys cpu: 18.22 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 0 lp 707 of 9999: Elapsed:1413.97 s. Delta: 2.00 s. user cpu: 5.04 s. sys cpu: 18.47 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 1 lp 707 of 9999: Elapsed:1413.98 s. Delta: 2.00 s. user cpu: 5.39 s. sys cpu: 18.34 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.004 Hz.
Child 2 lp 707 of 9999: Elapsed:1413.97 s. Delta: 2.00 s. user cpu: 5.02 s. sys cpu: 18.41 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 3 lp 707 of 9999: Elapsed:1413.97 s. Delta: 2.00 s. user cpu: 5.24 s. sys cpu: 18.38 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.
Child 4 lp 707 of 9999: Elapsed:1413.97 s. Delta: 2.00 s. user cpu: 5.26 s. sys cpu: 18.24 s. last sleep freq.: 250.000 Hz. average sleep freq.: 250.005 Hz.

Resource math: ~23.5 seconds / 1414 seconds * 5 occurances ~~= 0.08 real load average.

Similar output from vmstat (but it was running at a different time than above):
(While I have a relatively high context switch rate and interrupt rate in this example, the issue exists over a wide range)

doug@s15:~/c$ vmstat -n 10 10
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 6366016 292320 882488    0    0     1     1    7   12  0  0 100  0
 0  0      0 6366008 292320 882488    0    0     0     0 1319 2693  1  2 98  0
 0  0      0 6366008 292320 882488    0    0     0     0 1270 2541  0  0 100  0
 0  0      0 6366008 292324 882488    0    0     0     1 1268 2542  0  0 100  0
 0  0      0 6366008 292324 882488    0    0     0     0 1313 2678  1  1 98  0
 0  0      0 6366008 292324 882488    0    0     0     0 1306 2677  0  1 98  0
 0  0      0 6366008 292324 882488    0    0     0     0 1339 2773  0  3 97  0
 0  0      0 6366008 292324 882488    0    0     0     0 1347 2828  0  3 96  0
 0  0      0 6366008 292324 882488    0    0     0     0 1324 2721  0  2 98  0
 0  0      0 6366008 292328 882488    0    0     0     1 1341 2811  0  3 97  0

A message that is not in the archive (sent off-list or not yet received): 002101cd2e38$3adfbc80$b09f3580$@net

#59 lore raw

RE: [ 56/75] sched: Fix nohz load accounting -- again!

Further to my e-mail from a couple of weeks ago, attached is a revised version of the png file I attached. Hopefully it clarifies things a little, and I hope it helps. As before, it would be best to view with zoom set to 1:1 and to scroll down as you read and look at the graphs.

Doug Smythies

-----Original Message-----
From: Doug Smythies [mailto:[email protected]]
Sent: May-09-2012 16:05
To: 'Greg KH'; [email protected]; [email protected]
Cc: [email protected]; [email protected]; [email protected]; 'LesÅ�aw Kopeć'; 'Aman Gupta'; 'Peter Zijlstra'; 'Ingo Molnar'; 'Kerin Millar'; 'Doug Smythies'
Subject: RE: [ 56/75] sched: Fix nohz load accounting -- again!

Now I have some more test results for low load conditions.

Summary:

Reported load averages are very much improved for conditions of medium to high actual loads and higher idle enter/exit frequencies.

Reported load averages are in error, too high, by a factor of roughly between 3 and 7 times for conditions of low actual loads and any idle enter/exit frequency.

The complaints that are being raised (not by me, I like the fix, but now by many on Ubuntu Luanchpad. I think all complaints are from desktop users. I only use server versions myself, and never observer the issues) are related to the actual low load average case, and is compounded by the point of reference, the non-commit kernels, being in error on the low side.

Detail:

For my part of it, I made a mistake when I was testing my original patch proposal and the one from Peter Z. I did notice a huge change in load averages when the idle / not idle duty cycle went low enough. However, I attributed it all to the CPUs throttling back to a lower clock frequency. I continued testing with a preference to always having a high enough load to keep the CPUs at maximum frequency. My mistake was not realizing the contribution from incorrectly reported load averages at lower loads, in addition to the CPU clock frequency changes. New tests done for this e-mail were done with the frequency governors set to "powersave" mode for all CPUs (except where I forgot for one test).

Attached is an old e-mail with a bunch of test results for high load conditions, with control samples and such.
Summary: Everything looked good for the patch Peter Z. proposed.

Attached is a PNG file with my test results and comments for new low actual load tests. It would be best to view with zoom set to 1:1 and to scroll down as you read and look at the graphs.

Doug Smythies

References (even though I have been told not to include links in e-mails to this list):
My web notes (although it will be a few days before they are caught up): http://www.smythies.com/~doug/network/load_average/index.html
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/838811 <<< starting from post #52
https://bugs.launchpad.net/xubuntu-desktop/+bug/985661

-----Original Message-----
From: Doug Smythies [mailto:[email protected]]
Sent: May-04-2012 15:03
To: 'Greg KH'; [email protected]; [email protected]
Cc: [email protected]; [email protected]; [email protected]; 'LesÅ�aw Kopeć'; 'Aman Gupta'; 'Peter Zijlstra'; 'Ingo Molnar'; 'Kerin Millar'; Doug Smythies
Subject: RE: [ 56/75] sched: Fix nohz load accounting -- again!

Just earlier this morning, an issue was raised against this patch on the related thread on Ubuntu launchpad.
The complaint is that reported load averages are now to high under conditions of "high" frequency enter into / exit from cpu idle conditions where the cpu is very lightly loaded.
Most of the testing I did was with medium to heavy load on the cpu and relatively short idle periods. This is the opposite.
For a quick test, I hacked up my test program, and was able to reproduce the issue.
I am still attempting to understand better and also determine the lower bound to "high" frequency (I think it is 25 Hertz, and scales from there down, but no proof yet). I'll also go backwards and test this scenario without the patch. I'll let this list know the results, but it might be a few days. My quick test results are attached.

Doug Smythies

References (even though I have been told not to include links in e-mails to this list):

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/838811 <<< starting from post #52

version:

doug@s15:~/c$ uname -a
Linux s15 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux doug@s15:~/c$ cat /proc/version Linux version 3.2.0-24-generic (buildd@yellow) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012

-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: May-04-2012 13:43
To: [email protected]; [email protected]
Cc: [email protected]; [email protected]; [email protected]; Doug Smythies; LesÅ aw Kopeć; Aman Gupta; Peter Zijlstra; Ingo Molnar; Kerin Millar
Subject: [ 56/75] sched: Fix nohz load accounting -- again!

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit c308b56b5398779cd3da0f62ab26b0453494c3d4 upstream.

Various people reported nohz load tracking still being wrecked, but Doug spotted the actual problem. We fold the nohz remainder in too soon, causing us to loose samples and under-account.

So instead of playing catch-up up-front, always do a single load-fold with whatever state we encounter and only then fold the nohz remainder and play catch-up.

---
 kernel/sched/core.c |   53 +++++++++++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 27 deletions(-)
kernel/sched/core.c +1 -4
@@ -2266,13 +2266,10 @@ calc_load_n(unsigned long load, unsigned
  * Once we've updated the global active value, we need to apply the exponential
  * weights adjusted to the number of cycles missed.
  */
-static void calc_global_nohz(unsigned long ticks)
+static void calc_global_nohz(void)
 {
 	long delta, active, n;
 
-	if (time_before(jiffies, calc_load_update))
-		return;
-
 	/*
 	 * If we crossed a calc_load_update boundary, make sure to fold
 	 * any pending idle changes, the respective CPUs might have @@ -2284,31 +2281,25 @@ static void calc_global_nohz(unsigned lo

atomic_long_add(delta, &calc_load_tasks);

/*
- * If we were idle for multiple load cycles, apply them.
+ * It could be the one fold was all it took, we done!
*/
- if (ticks >= LOAD_FREQ) {
- n = ticks / LOAD_FREQ;
+ if (time_before(jiffies, calc_load_update + 10))
+ return;

- active = atomic_long_read(&calc_load_tasks);
- active = active > 0 ? active * FIXED_1 : 0;
+ /*
+ * Catch-up, fold however many we are behind still
+ */
+ delta = jiffies - calc_load_update - 10;
+ n = 1 + (delta / LOAD_FREQ);

- avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
- avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
- avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+ active = atomic_long_read(&calc_load_tasks);
+ active = active > 0 ? active * FIXED_1 : 0;

- calc_load_update += n * LOAD_FREQ;
- }
+ avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+ avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+ avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);

- /*
- * Its possible the remainder of the above division also crosses
- * a LOAD_FREQ period, the regular check in calc_global_load()
- * which comes after this will take care of that.
- *
- * Consider us being 11 ticks before a cycle completion, and us
- * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
- * age us 4 cycles, and the test in calc_global_load() will
- * pick up the final one.
- */
+ calc_load_update += n * LOAD_FREQ;
}
#else
void calc_load_account_idle(struct rq *this_rq) @@ -2320,7 +2311,7 @@ static inline long calc_load_fold_idle(v
return 0;
}

-static void calc_global_nohz(unsigned long ticks) +static void calc_global_nohz(void)
{
}
#endif
@@ -2348,8 +2339,6 @@ void calc_global_load(unsigned long tick {
long active;

- calc_global_nohz(ticks);
-
if (time_before(jiffies, calc_load_update + 10))
return;

@@ -2361,6 +2350,16 @@ void calc_global_load(unsigned long tick
avenrun[2] = calc_load(avenrun[2], EXP_15, active);

calc_load_update += LOAD_FREQ;
+
+ /*
+ * Account one period with whatever state we found before
+ * folding in the nohz state and ageing the entire idle period.
+ *
+ * This avoids loosing a sample when we go idle between
+ * calc_load_account_active() (10 ticks ago) and now and thus
+ * under-accounting.
+ */
+ calc_global_nohz();
}

/*

author maintainer
#60 lore raw

PATCH 57/75 exit_signal: simplify the "we have changed execution domain" logic

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit e636825346b36a07ccfc8e30946d52855e21f681 upstream.

exit_notify() checks "tsk->self_exec_id != tsk->parent_exec_id" to handle the "we have changed execution domain" case.

We can change do_thread() to always set ->exit_signal = SIGCHLD and remove this check to simplify the code.

We could change setup_new_exec() instead, this looks more logical because it increments ->self_exec_id. But note that de_thread() already resets ->exit_signal if it changes the leader, let's keep both changes close to each other.

Note that we change ->exit_signal lockless, this changes the rules. Thereafter ->exit_signal is not stable under tasklist but this is fine, the only possible change is OLDSIG -> SIGCHLD. This can race with eligible_child() but the race is harmless. We can race with reparent_leader() which changes our ->exit_signal in parallel, but it does the same change to SIGCHLD.

The noticeable user-visible change is that the execing task is not "visible" to do_wait()->eligible_child(__WCLONE) right after exec. To me this looks more logical, and this is consistent with mt case.

---
 fs/exec.c     |    3 +++
 kernel/exit.c |    7 +------
 2 files changed, 4 insertions(+), 6 deletions(-)
fs/exec.c +3 -0
@@ -975,6 +975,9 @@ static int de_thread(struct task_struct
 	sig->notify_count = 0;
 
 no_thread_group:
+	/* we have changed execution domain */
+	tsk->exit_signal = SIGCHLD;
+
 	if (current->mm)
 		setmax_mm_hiwater_rss(&sig->maxrss, current->mm);
 
kernel/exit.c +1 -6
@@ -827,14 +827,9 @@ static void exit_notify(struct task_stru
 	 * If the parent exec id doesn't match the exec id we saved
 	 * when we started then we know the parent has changed security
 	 * domain.
-	 *
-	 * If our self_exec id doesn't match our parent_exec_id then
-	 * we have changed execution domain as these two values started
-	 * the same after a fork.
 	 */
 	if (thread_group_leader(tsk) && tsk->exit_signal != SIGCHLD &&
-	    (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
-	     tsk->self_exec_id != tsk->parent_exec_id))
+	    tsk->parent_exec_id != tsk->real_parent->self_exec_id)
 		tsk->exit_signal = SIGCHLD;
 
 	if (unlikely(tsk->ptrace)) {
#61 lore raw

Re: [ 57/75] exit_signal: simplify the "we have changed execution domain" logic

Quoted 7 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit e636825346b36a07ccfc8e30946d52855e21f681 upstream.

[...]

This and the following commit b6e238dceed36891cc633167afe7151f1f3d83c5 ('exit_signal: fix the "parent has changed security domain" logic') appear to be applicable to 3.2.y as well. Should I queue them up?

Ben.

Signature · 3 lines
Ben Hutchings
Hoare's Law of Large Problems:
        Inside every large problem is a small problem struggling to get out.
author maintainer
#62 lore raw

Re: [ 57/75] exit_signal: simplify the "we have changed execution domain" logic

Quoted 5 lines · Ben Hutchings
Quoted 4 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

Quoted 8 lines
Quoted 3 lines

From: Oleg Nesterov <[email protected]>

commit e636825346b36a07ccfc8e30946d52855e21f681 upstream.

[...]

This and the following commit b6e238dceed36891cc633167afe7151f1f3d83c5 ('exit_signal: fix the "parent has changed security domain" logic') appear to be applicable to 3.2.y as well. Should I queue them up?

Yes, that would be good to do.

greg k-h

#63 lore raw

Re: [ 57/75] exit_signal: simplify the "we have changed execution domain" logic

Quoted 8 lines · Greg KH
Quoted 7 lines · Ben Hutchings
Quoted 6 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

commit e636825346b36a07ccfc8e30946d52855e21f681 upstream.

[...]

This and the following commit b6e238dceed36891cc633167afe7151f1f3d83c5 ('exit_signal: fix the "parent has changed security domain" logic') appear to be applicable to 3.2.y as well. Should I queue them up?

Yes, that would be good to do.

Done.

Ben.

Signature · 3 lines
Ben Hutchings
Life is what happens to you while you're busy making other plans.
                                                               - John Lennon
author maintainer
#64 lore raw

PATCH 58/75 exit_signal: fix the "parent has changed security domain" logic

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit b6e238dceed36891cc633167afe7151f1f3d83c5 upstream.

exit_notify() changes ->exit_signal if the parent already did exec. This doesn't really work, we are not going to send the signal now if there is another live thread or the exiting task is traced. The parent can exec before the last dies or the tracer detaches.

Move this check into do_notify_parent() which actually sends the signal.

The user-visible change is that we do not change ->exit_signal, and thus the exiting task is still "clone children" for do_wait()->eligible_child(__WCLONE). Hopefully this is fine, the current logic is racy anyway.

---
 kernel/exit.c   |   14 --------------
 kernel/signal.c |    9 +++++++++
 2 files changed, 9 insertions(+), 14 deletions(-)
kernel/exit.c +0 -14
@@ -818,20 +818,6 @@ static void exit_notify(struct task_stru
 	if (group_dead)
 		kill_orphaned_pgrp(tsk->group_leader, NULL);
 
-	/* Let father know we died
-	 *
-	 * Thread signals are configurable, but you aren't going to use
-	 * that to send signals to arbitrary processes.
-	 * That stops right now.
-	 *
-	 * If the parent exec id doesn't match the exec id we saved
-	 * when we started then we know the parent has changed security
-	 * domain.
-	 */
-	if (thread_group_leader(tsk) && tsk->exit_signal != SIGCHLD &&
-	    tsk->parent_exec_id != tsk->real_parent->self_exec_id)
-		tsk->exit_signal = SIGCHLD;
-
 	if (unlikely(tsk->ptrace)) {
 		int sig = thread_group_leader(tsk) &&
 				thread_group_empty(tsk) &&
kernel/signal.c +9 -0
@@ -1642,6 +1642,15 @@ bool do_notify_parent(struct task_struct
 	BUG_ON(!tsk->ptrace &&
 	       (tsk->group_leader != tsk || !thread_group_empty(tsk)));
 
+	if (sig != SIGCHLD) {
+		/*
+		 * This is only possible if parent == real_parent.
+		 * Check if it has changed security domain.
+		 */
+		if (tsk->parent_exec_id != tsk->parent->self_exec_id)
+			sig = SIGCHLD;
+	}
+
 	info.si_signo = sig;
 	info.si_errno = 0;
 	/*
author maintainer
#65 lore raw

PATCH 59/75 md/raid5: Fix a bug about judging if the operation is syncing or replacing

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: majianpeng <[email protected]>

commit c6d2e084c7411f61f2b446d94989e5aaf9879b0f upstream.

When create a raid5 using assume-clean and echo check or repair to sync_action.Then component disks did not operated IO but the raid check/resync faster than normal.
Because the judgement in function analyse_stripe():

		if (do_recovery ||
		    sh->sector >= conf->mddev->recovery_cp)
			s->syncing = 1;
		else
			s->replacing = 1;

When check or repair,the recovery_cp == MaxSectore,so syncing equal zero not one.

This bug was introduced by commit 9a3e1101b827
md/raid5: detect and handle replacements during recovery.
so this patch is suitable for 3.3-stable.

---
 drivers/md/raid5.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/raid5.c +3 -1
@@ -3277,12 +3277,14 @@ static void analyse_stripe(struct stripe
 		/* If there is a failed device being replaced,
 		 *     we must be recovering.
 		 * else if we are after recovery_cp, we must be syncing
+		 * else if MD_RECOVERY_REQUESTED is set, we also are syncing.
 		 * else we can only be replacing
 		 * sync and recovery both need to read all devices, and so
 		 * use the same flag.
 		 */
 		if (do_recovery ||
-		    sh->sector >= conf->mddev->recovery_cp)
+		    sh->sector >= conf->mddev->recovery_cp ||
+		    test_bit(MD_RECOVERY_REQUESTED, &(conf->mddev->recovery)))
 			s->syncing = 1;
 		else
 			s->replacing = 1;
author maintainer
#66 lore raw

PATCH 60/75 efivars: Improve variable validation

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matthew Garrett <[email protected]>

commit 54b3a4d311c98ad94b737802a8b5f2c8c6bfd627 upstream.

Ben Hutchings pointed out that the validation in efivars was inadequate - most obviously, an entry with size 0 would server as a DoS against the kernel. Improve this based on his suggestions.

---
 drivers/firmware/efivars.c |   46 +++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)
drivers/firmware/efivars.c +30 -16
@@ -192,18 +192,21 @@ utf16_strncmp(const efi_char16_t *a, con
 }
 
 static bool
-validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len)
+validate_device_path(struct efi_variable *var, int match, u8 *buffer,
+		     unsigned long len)
 {
 	struct efi_generic_dev_path *node;
 	int offset = 0;
 
 	node = (struct efi_generic_dev_path *)buffer;
 
-	while (offset < len) {
-		offset += node->length;
+	if (len < sizeof(*node))
+		return false;
 
-		if (offset > len)
-			return false;
+	while (offset <= len - sizeof(*node) &&
+	       node->length >= sizeof(*node) &&
+		node->length <= len - offset) {
+		offset += node->length;
 
 		if ((node->type == EFI_DEV_END_PATH ||
 		     node->type == EFI_DEV_END_PATH2) &&
@@ -222,7 +225,8 @@ validate_device_path(struct efi_variable
 }
 
 static bool
-validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len)
+validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
+		    unsigned long len)
 {
 	/* An array of 16-bit integers */
 	if ((len % 2) != 0)
@@ -232,19 +236,27 @@ validate_boot_order(struct efi_variable
 }
 
 static bool
-validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len)
+validate_load_option(struct efi_variable *var, int match, u8 *buffer,
+		     unsigned long len)
 {
 	u16 filepathlength;
-	int i, desclength = 0;
+	int i, desclength = 0, namelen;
+
+	namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
 
 	/* Either "Boot" or "Driver" followed by four digits of hex */
 	for (i = match; i < match+4; i++) {
-		if (hex_to_bin(var->VariableName[i] & 0xff) < 0)
+		if (var->VariableName[i] > 127 ||
+		    hex_to_bin(var->VariableName[i] & 0xff) < 0)
 			return true;
 	}
 
-	/* A valid entry must be at least 6 bytes */
-	if (len < 6)
+	/* Reject it if there's 4 digits of hex and then further content */
+	if (namelen > match + 4)
+		return false;
+
+	/* A valid entry must be at least 8 bytes */
+	if (len < 8)
 		return false;
 
 	filepathlength = buffer[4] | buffer[5] << 8;
@@ -253,7 +265,7 @@ validate_load_option(struct efi_variable
 	 * There's no stored length for the description, so it has to be
 	 * found by hand
 	 */
-	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2;
+	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
 
 	/* Each boot entry must have a descriptor */
 	if (!desclength)
@@ -275,7 +287,8 @@ validate_load_option(struct efi_variable
 }
 
 static bool
-validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len)
+validate_uint16(struct efi_variable *var, int match, u8 *buffer,
+		unsigned long len)
 {
 	/* A single 16-bit integer */
 	if (len != 2)
@@ -285,7 +298,8 @@ validate_uint16(struct efi_variable *var
 }
 
 static bool
-validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len)
+validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
+		      unsigned long len)
 {
 	int i;
 
@@ -303,7 +317,7 @@ validate_ascii_string(struct efi_variabl
 struct variable_validate {
 	char *name;
 	bool (*validate)(struct efi_variable *var, int match, u8 *data,
-			 int len);
+			 unsigned long len);
 };
 
 static const struct variable_validate variable_validate[] = {
@@ -325,7 +339,7 @@ static const struct variable_validate va
 };
 
 static bool
-validate_var(struct efi_variable *var, u8 *data, int len)
+validate_var(struct efi_variable *var, u8 *data, unsigned long len)
 {
 	int i;
 	u16 *unicode_name = var->VariableName;
author maintainer
#67 lore raw

PATCH 61/75 hwmon: (coretemp) Increase CPU core limit

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit bdc71c9a87b898e4c380c23b2e3e18071312ecde upstream.

CPU core ID is used to index the core_data[] array. The core ID is, however, not sequential; 10-core CPUS can have a core ID as high as 25. Increase the limit to 32 to be able to deal with current CPUs.

---
 drivers/hwmon/coretemp.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/coretemp.c +1 -1
@@ -51,7 +51,7 @@ module_param_named(tjmax, force_tjmax, i
 MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
 
 #define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */
-#define NUM_REAL_CORES		16	/* Number of Real cores per cpu */
+#define NUM_REAL_CORES		32	/* Number of Real cores per cpu */
 #define CORETEMP_NAME_LENGTH	17	/* String Length of attrs */
 #define MAX_CORE_ATTRS		4	/* Maximum no of basic attrs */
 #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
author maintainer
#68 lore raw

PATCH 62/75 nouveau: initialise has_optimus variable.

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dave Airlie <[email protected]>

commit addde4ec31456c5f1e9b61aae3edcfeb0f338f87 upstream.

We should initialise this to 0 really to avoid getting false positives.

---
 drivers/gpu/drm/nouveau/nouveau_acpi.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nouveau_acpi.c +1 -1
@@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void)
 	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
 	struct pci_dev *pdev = NULL;
 	int has_dsm = 0;
-	int has_optimus;
+	int has_optimus = 0;
 	int vga_count = 0;
 	bool guid_valid;
 	int retval;
author maintainer
#69 lore raw

PATCH 63/75 hwmon: (coretemp) fix oops on cpu unplug

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Kirill A. Shutemov" <[email protected]>

commit b704871124b477807966f06789c2b32f2de58bf7 upstream.

coretemp tries to access core_data array beyond bounds on cpu unplug if core id of the cpu if more than NUM_REAL_CORES-1.

BUG: unable to handle kernel NULL pointer dereference at 000000000000013c
IP: [<ffffffffa00159af>] coretemp_cpu_callback+0x93/0x1ba [coretemp]
PGD 673e5a067 PUD 66e9b3067 PMD 0
Oops: 0000 [#1] SMP
CPU 79
Modules linked in: sunrpc cpufreq_ondemand acpi_cpufreq freq_table mperf bnep bluetooth rfkill ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter nf_conntrack_ipv4 nf_defrag_ipv4 ip6_tables xt_state nf_conntrack coretemp crc32c_intel asix tpm_tis pcspkr usbnet iTCO_wdt i2c_i801 microcode mii joydev tpm i2c_core iTCO_vendor_support tpm_bios i7core_edac igb ioatdma edac_core dca megaraid_sas [last unloaded: oprofile]

Pid: 3315, comm: set-cpus Tainted: G W 3.4.0-rc5+ #2 QCI QSSC-S4R/QSSC-S4R

RIP: 0010:[<ffffffffa00159af>]  [<ffffffffa00159af>] coretemp_cpu_callback+0x93/0x1ba [coretemp]
RSP: 0018:ffff880472fb3d48  EFLAGS: 00010246
RAX: 0000000000000124 RBX: 0000000000000034 RCX: 00000000ffffffff
RDX: 0000000000000000 RSI: 0000000000000046 RDI: 0000000000000246
RBP: ffff880472fb3d88 R08: ffff88077fcd36c0 R09: 0000000000000001
R10: ffffffff8184bc48 R11: 0000000000000000 R12: ffff880273095800
R13: 0000000000000013 R14: ffff8802730a1810 R15: 0000000000000000
FS:  00007f694a20f720(0000) GS:ffff88077fcc0000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 000000000000013c CR3: 000000067209b000 CR4: 00000000000007e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process set-cpus (pid: 3315, threadinfo ffff880472fb2000, task ffff880471fa0000)
Stack:
 ffff880277b4c308 0000000000000003 ffff880472fb3d88 0000000000000005
 0000000000000034 00000000ffffffd1 ffffffff81cadc70 ffff880472fb3e14
 ffff880472fb3dc8 ffffffff8161f48d ffff880471fa0000 0000000000000034
Call Trace:
 [<ffffffff8161f48d>] notifier_call_chain+0x4d/0x70
 [<ffffffff8107f1be>] __raw_notifier_call_chain+0xe/0x10
 [<ffffffff81059d30>] __cpu_notify+0x20/0x40
 [<ffffffff815fa251>] _cpu_down+0x81/0x270
 [<ffffffff815fa477>] cpu_down+0x37/0x50
 [<ffffffff815fd6a3>] store_online+0x63/0xc0
 [<ffffffff813c7078>] dev_attr_store+0x18/0x30
 [<ffffffff811f02cf>] sysfs_write_file+0xef/0x170
 [<ffffffff81180443>] vfs_write+0xb3/0x180
 [<ffffffff8118076a>] sys_write+0x4a/0x90
 [<ffffffff816236a9>] system_call_fastpath+0x16/0x1b
Code: 48 c7 c7 94 60 01 a0 44 0f b7 ac 10 ac 00 00 00 31 c0 e8 41 b7 5f e1 41 83 c5 02 49 63 c5 49 8b 44 c4 10 48 85 c0 74 56 45 31 ff <39> 58 18 75 4e eb 1f 49 63 d7 4c 89 f7 48 89 45 c8 48 6b d2 28
RIP  [<ffffffffa00159af>] coretemp_cpu_callback+0x93/0x1ba [coretemp]
 RSP <ffff880472fb3d48>

CR2: 000000000000013c

---
 drivers/hwmon/coretemp.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/hwmon/coretemp.c +4 -0
@@ -708,6 +708,10 @@ static void __cpuinit put_core_offline(u
 
 	indx = TO_ATTR_NO(cpu);
 
+	/* The core id is too big, just return */
+	if (indx > MAX_CORE_DATA - 1)
+		return;
+
 	if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu)
 		coretemp_remove_core(pdata, &pdev->dev, indx);
 
author maintainer
#70 lore raw

PATCH 64/75 libata: skip old error history when counting probe trials

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lin Ming <[email protected]>

commit 6868225e3e92399068be9a5f1635752d91012ad5 upstream.

Commit d902747("[libata] Add ATA transport class") introduced ATA_EFLAG_OLD_ER to mark entries in the error ring as cleared.

But ata_count_probe_trials_cb() didn't check this flag and it still counts the old error history. So wrong probe trials count is returned and it causes problem, for example, SATA link speed is slowed down from 3.0Gbps to 1.5Gbps.

Fix it by checking ATA_EFLAG_OLD_ER in ata_count_probe_trials_cb().

---
 drivers/ata/libata-eh.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/ata/libata-eh.c +2 -1
@@ -3500,7 +3500,8 @@ static int ata_count_probe_trials_cb(str
 	u64 now = get_jiffies_64();
 	int *trials = void_arg;
 
-	if (ent->timestamp < now - min(now, interval))
+	if ((ent->eflags & ATA_EFLAG_OLD_ER) ||
+	    (ent->timestamp < now - min(now, interval)))
 		return -1;
 
 	(*trials)++;
author maintainer
#71 lore raw

PATCH 65/75 b43: only reload config after successful initialization

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Seth Forshee <[email protected]>

commit dbdedbdf4fbff3d4962a0786f37aa86dfdc48a7e upstream.

Commit 2a19032 (b43: reload phy and bss settings after core restarts) introduced an unconditional call to b43_op_config() at the end of b43_op_start(). When firmware fails to load this can wedge the system. There's no need to reload the configuration after a failed initialization anyway, so only make the call if initialization was successful.

---
 drivers/net/wireless/b43/main.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/net/wireless/b43/main.c +8 -2
@@ -4841,8 +4841,14 @@ static int b43_op_start(struct ieee80211
  out_mutex_unlock:
 	mutex_unlock(&wl->mutex);
 
-	/* reload configuration */
-	b43_op_config(hw, ~0);
+	/*
+	 * Configuration may have been overwritten during initialization.
+	 * Reload the configuration, but only if initialization was
+	 * successful. Reloading the configuration after a failed init
+	 * may hang the system.
+	 */
+	if (!err)
+		b43_op_config(hw, ~0);
 
 	return err;
 }
author maintainer
#72 lore raw

PATCH 66/75 i2c: pnx: Disable clk in suspend

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Roland Stigge <[email protected]>

commit 6c557cfee08751d22aed34840f389b846f0f4508 upstream.

In the driver's suspend function, clk_enable() was used instead of clk_disable(). This is corrected with this patch.

---
 drivers/i2c/busses/i2c-pnx.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/i2c/busses/i2c-pnx.c +1 -2
@@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(st
 {
 	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
 
-	/* FIXME: shouldn't this be clk_disable? */
-	clk_enable(alg_data->clk);
+	clk_disable(alg_data->clk);
 
 	return 0;
 }
author maintainer
#73 lore raw

PATCH 67/75 ipw2200: Fix race condition in the command completion acknowledge

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stanislav Yakovlev <[email protected]>

commit dd447319895d0c0af423e483d9b63f84f3f8869a upstream.

Driver incorrectly validates command completion: instead of waiting for a command to be acknowledged it continues execution. Most of the time driver gets acknowledge of the command completion in a tasklet before it executes the next one. But sometimes it sends the next command before it gets acknowledge for the previous one. In such a case one of the following error messages appear in the log:

Failed to send SYSTEM_CONFIG: Already sending a command. Failed to send ASSOCIATE: Already sending a command. Failed to send TX_POWER: Already sending a command.

After that you need to reload the driver to get it working again.

This bug occurs during roaming (reported by Sam Varshavchik)
https://bugzilla.redhat.com/show_bug.cgi?id=738508
and machine booting (reported by Tom Gundersen and Mads Kiilerich)
https://bugs.archlinux.org/task/28097
https://bugzilla.redhat.com/show_bug.cgi?id=802106

This patch doesn't fix the delay issue during firmware load. But at least device now works as usual after boot.

---
 drivers/net/wireless/ipw2x00/ipw2200.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/net/wireless/ipw2x00/ipw2200.c +12 -1
@@ -2191,6 +2191,7 @@ static int __ipw_send_cmd(struct ipw_pri
 {
 	int rc = 0;
 	unsigned long flags;
+	unsigned long now, end;
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->status & STATUS_HCMD_ACTIVE) {
@@ -2232,10 +2233,20 @@ static int __ipw_send_cmd(struct ipw_pri
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	now = jiffies;
+	end = now + HOST_COMPLETE_TIMEOUT;
+again:
 	rc = wait_event_interruptible_timeout(priv->wait_command_queue,
 					      !(priv->
 						status & STATUS_HCMD_ACTIVE),
-					      HOST_COMPLETE_TIMEOUT);
+					      end - now);
+	if (rc < 0) {
+		now = jiffies;
+		if (time_before(now, end))
+			goto again;
+		rc = 0;
+	}
+
 	if (rc == 0) {
 		spin_lock_irqsave(&priv->lock, flags);
 		if (priv->status & STATUS_HCMD_ACTIVE) {
#74 lore raw

Re: [ 67/75] ipw2200: Fix race condition in the command completion acknowledge

Quoted 14 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stanislav Yakovlev <[email protected]>

commit dd447319895d0c0af423e483d9b63f84f3f8869a upstream.

Driver incorrectly validates command completion: instead of waiting for a command to be acknowledged it continues execution. Most of the time driver gets acknowledge of the command completion in a tasklet before it executes the next one. But sometimes it sends the next command before it gets acknowledge for the previous one. In such a case one of the following error messages appear in the log:

[...]

Quoted 4 lines
drivers/net/wireless/ipw2x00/ipw2200.c +3 -0
+	now = jiffies;
+	end = now + HOST_COMPLETE_TIMEOUT;
+again:
 	rc = wait_event_interruptible_timeout(priv->wait_command_queue,

drivers/net/wireless/ipw2x00/ipw2200.c static int __ipw_send_cmd(struct ipw_pri · line 2248

Quoted 10 lines
drivers/net/wireless/ipw2x00/ipw2200.c +7 -1
 					      !(priv->
 						status & STATUS_HCMD_ACTIVE),
-					      HOST_COMPLETE_TIMEOUT);
+					      end - now);
+	if (rc < 0) {
+		now = jiffies;
+		if (time_before(now, end))
+			goto again;
+		rc = 0;
+	}

[...]

If you don't want the wait to be interrupted, use wait_event_timeout() instead of this ridiculous loop!

Ben.

Signature · 3 lines
Ben Hutchings
Hoare's Law of Large Problems:
        Inside every large problem is a small problem struggling to get out.
#75 lore raw

Re: [ 67/75] ipw2200: Fix race condition in the command completion acknowledge

Quoted 30 lines · Ben Hutchings
Quoted 14 lines · Greg KH

3.3-stable review patch. �If anyone has any objections, please let me know.

------------------

From: Stanislav Yakovlev <[email protected]>

commit dd447319895d0c0af423e483d9b63f84f3f8869a upstream.

Driver incorrectly validates command completion: instead of waiting for a command to be acknowledged it continues execution. �Most of the time driver gets acknowledge of the command completion in a tasklet before it executes the next one. But sometimes it sends the next command before it gets acknowledge for the previous one. In such a case one of the following error messages appear in the log:

[...]

Quoted 6 lines

+ � � now = jiffies;
+ � � end = now + HOST_COMPLETE_TIMEOUT;
+again:
� � � rc = wait_event_interruptible_timeout(priv->wait_command_queue,
� � � � � � � � � � � � � � � � � � � � � � !(priv->
� � � � � � � � � � � � � � � � � � � � � � � status & STATUS_HCMD_ACTIVE),

Quoted 8 lines

- � � � � � � � � � � � � � � � � � � � � � HOST_COMPLETE_TIMEOUT);
+ � � � � � � � � � � � � � � � � � � � � � end - now);
+ � � if (rc < 0) {
+ � � � � � � now = jiffies;
+ � � � � � � if (time_before(now, end))
+ � � � � � � � � � � goto again;
+ � � � � � � rc = 0;
+ � � }

Quoted 4 lines

[...]

If you don't want the wait to be interrupted, use wait_event_timeout() instead of this ridiculous loop!

Usually "modprobe ipw2200" takes less than a second, and after switching to wait_event_timeout it will take more than 10 seconds. We can not decrease the waiting timeout because we want to keep it big enough for the worst case(when the firmware did not reply).

There is a relevant discussion on lklm:
https://lkml.org/lkml/2008/9/25/2
https://lkml.org/lkml/2008/9/26/194

Stanislav.

Quoted 6 lines

Ben.

--
Ben Hutchings
Hoare's Law of Large Problems:
� � � �Inside every large problem is a small problem struggling to get out.

#76 lore raw

Re: [ 67/75] ipw2200: Fix race condition in the command completion acknowledge

Quoted 36 lines · Stanislav Yakovlev
Quoted 30 lines · Ben Hutchings
Quoted 14 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stanislav Yakovlev <[email protected]>

commit dd447319895d0c0af423e483d9b63f84f3f8869a upstream.

Driver incorrectly validates command completion: instead of waiting for a command to be acknowledged it continues execution. Most of the time driver gets acknowledge of the command completion in a tasklet before it executes the next one. But sometimes it sends the next command before it gets acknowledge for the previous one. In such a case one of the following error messages appear in the log:

[...]

Quoted 4 lines
drivers/net/wireless/ipw2x00/ipw2200.c +3 -0
+     now = jiffies;
+     end = now + HOST_COMPLETE_TIMEOUT;
+again:
      rc = wait_event_interruptible_timeout(priv->wait_command_queue,

drivers/net/wireless/ipw2x00/ipw2200.c static int __ipw_send_cmd(struct ipw_pri · line 2248

Quoted 10 lines
drivers/net/wireless/ipw2x00/ipw2200.c +7 -1
                                            !(priv->
                                              status & STATUS_HCMD_ACTIVE),
-                                           HOST_COMPLETE_TIMEOUT);
+                                           end - now);
+     if (rc < 0) {
+             now = jiffies;
+             if (time_before(now, end))
+                     goto again;
+             rc = 0;
+     }
Quoted 4 lines

[...]

If you don't want the wait to be interrupted, use wait_event_timeout() instead of this ridiculous loop!

Quoted 8 lines

Usually "modprobe ipw2200" takes less than a second, and after switching to wait_event_timeout it will take more than 10 seconds. We can not decrease the waiting timeout because we want to keep it big enough for the worst case(when the firmware did not reply).

There is a relevant discussion on lklm:
https://lkml.org/lkml/2008/9/25/2
https://lkml.org/lkml/2008/9/26/194

That's irrelevant: you aren't letting userland handle the signal here, so you should use wait_event_timeout() and no loop.

Ben.

Signature · 3 lines
Ben Hutchings
Life is what happens to you while you're busy making other plans.
                                                               - John Lennon
author maintainer
#77 lore raw

PATCH 68/75 mac80211: fix AP mode EAP tx for VLAN stations

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <[email protected]>

commit 66f2c99af3d6f2d0aa1120884cf1c60613ef61c0 upstream.

EAP frames for stations in an AP VLAN are sent on the main AP interface to avoid race conditions wrt. moving stations.
For that to work properly, sta_info_get_bss must be used instead of sta_info_get when sending EAP packets.
Previously this was only done for cooked monitor injected packets, so this patch adds a check for tx->skb->protocol to the same place.

---
 net/mac80211/tx.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/mac80211/tx.c +2 -1
@@ -1144,7 +1144,8 @@ ieee80211_tx_prepare(struct ieee80211_su
 		tx->sta = rcu_dereference(sdata->u.vlan.sta);
 		if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
 			return TX_DROP;
-	} else if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+	} else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
+		   tx->sdata->control_port_protocol == tx->skb->protocol) {
 		tx->sta = sta_info_get_bss(sdata, hdr->addr1);
 	}
 	if (!tx->sta)
author maintainer
#78 lore raw

PATCH 69/75 rtlwifi: Fix oops on unload

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Larry Finger <[email protected]>

commit 44eb65cfd8da4b9c231238998729e858e963a980 upstream.

Under some circumstances, a PCI-based driver reports the following OOPs:

Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Oops: 0000 [#1] SMP
--snip--
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Pid: 19627, comm: rmmod
Not tainted 3.2.9-2.fc16.x86_64 #1 LENOVO 05962RU/05962RU
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] RIP:
0010:[<ffffffffa0418d39>]  [<ffffffffa0418d39>]
rtl92ce_get_desc+0x19/0xd0 [rtl8192ce]
--snip--
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Process rmmod (pid:
19627, threadinfo ffff880050262000, task ffff8801156d5cc0)
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Stack:
Mar 19 08:14:35 kvothe kernel: [ 6584.626011]  0000000000000002
ffff8801176c2540 ffff880050263ca8 ffffffffa03348e7
Mar 19 08:14:35 kvothe kernel: [ 6584.626011]  0000000000000282
0000000180150014 ffff880050263fd8 ffff8801176c2810
Mar 19 08:14:35 kvothe kernel: [ 6584.626011]  ffff880050263bc8
ffffffff810550e2 00000000000002c0 ffff8801176c0d40
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Call Trace:
Mar 19 08:14:35 kvothe kernel: [ 6584.626011]  [<ffffffffa03348e7>]
_rtl_pci_rx_interrupt+0x187/0x650 [rtlwifi]
--snip--
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] Code: ff 09 d0 89 07 48
83 c4 08 5b 5d c3 66 0f 1f 44 00 00 55 48 89 e5 53 48 83 ec 08 66 66
66 66 90 40 84 f6 89 d3 74 13 84 d2 75 57 <8b> 07 48 83 c4 08 5b 5d c1
e8 1f c3 0f 1f 00 84 d2 74 ed 80 fa
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] RIP
[<ffffffffa0418d39>] rtl92ce_get_desc+0x19/0xd0 [rtl8192ce]
Mar 19 08:14:35 kvothe kernel: [ 6584.626011]  RSP <ffff880050263b58>
Mar 19 08:14:35 kvothe kernel: [ 6584.626011] CR2: 00000000000006e0
Mar 19 08:14:35 kvothe kernel: [ 6584.646491] ---[ end trace

8636c766dcfbe0e6 ]---

This oops is due to interrupts not being disabled in this particular path.

---
 drivers/net/wireless/rtlwifi/pci.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/rtlwifi/pci.c +1 -0
@@ -1955,6 +1955,7 @@ void rtl_pci_disconnect(struct pci_dev *
 		rtl_deinit_deferred_work(hw);
 		rtlpriv->intf_ops->adapter_stop(hw);
 	}
+	rtlpriv->cfg->ops->disable_interrupt(hw);
 
 	/*deinit rfkill */
 	rtl_deinit_rfkill(hw);
author maintainer
#79 lore raw

PATCH 70/75 wl1251: fix crash on remove due to premature kfree

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Grazvydas Ignotas <[email protected]>

commit 328c32f0f85467af5a6c4c3289e168d9ad2555af upstream.

Currently SDIO glue frees it's own structure before calling wl1251_free_hw(), which in turn calls ieee80211_unregister_hw(). The later call may result in a need to communicate with the chip to stop it (as it happens now if the interface is still up before rmmod), which means calls are made back to the glue, resulting in freed memory access.

Fix this by freeing glue data last.

---
 drivers/net/wireless/wl1251/sdio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/wl1251/sdio.c +1 -1
@@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove
 
 	if (wl->irq)
 		free_irq(wl->irq, wl);
-	kfree(wl_sdio);
 	wl1251_free_hw(wl);
+	kfree(wl_sdio);
 
 	sdio_claim_host(func);
 	sdio_release_irq(func);
author maintainer
#80 lore raw

PATCH 71/75 wl1251: fix crash on remove due to leftover work item

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Grazvydas Ignotas <[email protected]>

commit 4c1bcdb5a3354b250b82a67549f57ac27a3bb85f upstream.

This driver currently leaves elp_work behind when stopping, which occasionally results in data corruption because work function ends up accessing freed memory, typical symptoms of this are various worker_thread crashes. Fix it by cancelling elp_work.

---
 drivers/net/wireless/wl1251/main.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/wl1251/main.c +1 -0
@@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80
 	cancel_work_sync(&wl->irq_work);
 	cancel_work_sync(&wl->tx_work);
 	cancel_work_sync(&wl->filter_work);
+	cancel_delayed_work_sync(&wl->elp_work);
 
 	mutex_lock(&wl->mutex);
 
author maintainer
#81 lore raw

PATCH 72/75 iwlwifi: do not nulify ctx->vif on reset

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stanislaw Gruszka <[email protected]>

commit 8db4c7e25d153fb049e81715d72fa3be3a0c3b69 upstream.

ctx->vif is dereferenced in different part of iwlwifi code, so do not nullify it.

This should address at least one of the possible reasons of WARNING at iwlagn_mac_remove_interface, and perhaps some random crashes when firmware reset is performed.

---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    3 ---
 drivers/net/wireless/iwlwifi/iwl-mac80211.c |   10 +++++++++-
 2 files changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl-agn.c +0 -3
@@ -1403,7 +1403,6 @@ static void iwl_bg_run_time_calib_work(s
 
 void iwlagn_prepare_restart(struct iwl_priv *priv)
 {
-	struct iwl_rxon_context *ctx;
 	bool bt_full_concurrent;
 	u8 bt_ci_compliance;
 	u8 bt_load;
@@ -1412,8 +1411,6 @@ void iwlagn_prepare_restart(struct iwl_p
 
 	lockdep_assert_held(&priv->shrd->mutex);
 
-	for_each_context(priv, ctx)
-		ctx->vif = NULL;
 	priv->is_open = 0;
 
 	/*
drivers/net/wireless/iwlwifi/iwl-mac80211.c +9 -1
@@ -1226,6 +1226,7 @@ static int iwlagn_mac_add_interface(stru
 	struct iwl_rxon_context *tmp, *ctx = NULL;
 	int err;
 	enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif);
+	bool reset = false;
 
 	IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
 			   viftype, vif->addr);
@@ -1247,6 +1248,13 @@ static int iwlagn_mac_add_interface(stru
 			tmp->interface_modes | tmp->exclusive_interface_modes;
 
 		if (tmp->vif) {
+			/* On reset we need to add the same interface again */
+			if (tmp->vif == vif) {
+				reset = true;
+				ctx = tmp;
+				break;
+			}
+
 			/* check if this busy context is exclusive */
 			if (tmp->exclusive_interface_modes &
 						BIT(tmp->vif->type)) {
@@ -1273,7 +1281,7 @@ static int iwlagn_mac_add_interface(stru
 	ctx->vif = vif;
 
 	err = iwl_setup_interface(priv, ctx);
-	if (!err)
+	if (!err || reset)
 		goto out;
 
 	ctx->vif = NULL;
author maintainer
#82 lore raw

PATCH 73/75 iwlwifi: use correct released ucode version

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Meenakshi Venkataraman <[email protected]>

commit 78cbcf2b9dbe0565820dc7721316f9c401000a68 upstream.

Report correctly the latest released version
of the iwlwifi firmware for all
iwlwifi-supported devices.

---
 drivers/net/wireless/iwlwifi/iwl-1000.c |    8 ++++----
 drivers/net/wireless/iwlwifi/iwl-2000.c |   16 ++++++++--------
 drivers/net/wireless/iwlwifi/iwl-5000.c |   11 +++++++++--
 drivers/net/wireless/iwlwifi/iwl-6000.c |   10 ++++++----
 4 files changed, 27 insertions(+), 18 deletions(-)
drivers/net/wireless/iwlwifi/iwl-1000.c +4 -4
@@ -45,8 +45,8 @@
 #include "iwl-cfg.h"
 
 /* Highest firmware API version supported */
-#define IWL1000_UCODE_API_MAX 6
-#define IWL100_UCODE_API_MAX 6
+#define IWL1000_UCODE_API_MAX 5
+#define IWL100_UCODE_API_MAX 5
 
 /* Oldest version we won't warn about */
 #define IWL1000_UCODE_API_OK 5
@@ -235,5 +235,5 @@ struct iwl_cfg iwl100_bg_cfg = {
 	IWL_DEVICE_100,
 };
 
-MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK));
drivers/net/wireless/iwlwifi/iwl-2000.c +8 -8
@@ -51,10 +51,10 @@
 #define IWL135_UCODE_API_MAX 6
 
 /* Oldest version we won't warn about */
-#define IWL2030_UCODE_API_OK 5
-#define IWL2000_UCODE_API_OK 5
-#define IWL105_UCODE_API_OK 5
-#define IWL135_UCODE_API_OK 5
+#define IWL2030_UCODE_API_OK 6
+#define IWL2000_UCODE_API_OK 6
+#define IWL105_UCODE_API_OK 6
+#define IWL135_UCODE_API_OK 6
 
 /* Lowest firmware API version supported */
 #define IWL2030_UCODE_API_MIN 5
@@ -338,7 +338,7 @@ struct iwl_cfg iwl135_bgn_cfg = {
 	.ht_params = &iwl2000_ht_params,
 };
 
-MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK));
+MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK));
+MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK));
drivers/net/wireless/iwlwifi/iwl-5000.c +9 -2
@@ -50,6 +50,10 @@
 #define IWL5000_UCODE_API_MAX 5
 #define IWL5150_UCODE_API_MAX 2
 
+/* Oldest version we won't warn about */
+#define IWL5000_UCODE_API_OK 5
+#define IWL5150_UCODE_API_OK 2
+
 /* Lowest firmware API version supported */
 #define IWL5000_UCODE_API_MIN 1
 #define IWL5150_UCODE_API_MIN 1
@@ -359,6 +363,7 @@ static struct iwl_ht_params iwl5000_ht_p
 #define IWL_DEVICE_5000						\
 	.fw_name_pre = IWL5000_FW_PRE,				\
 	.ucode_api_max = IWL5000_UCODE_API_MAX,			\
+	.ucode_api_ok = IWL5000_UCODE_API_OK,			\
 	.ucode_api_min = IWL5000_UCODE_API_MIN,			\
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,	\
@@ -402,6 +407,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
 	.fw_name_pre = IWL5000_FW_PRE,
 	.ucode_api_max = IWL5000_UCODE_API_MAX,
+	.ucode_api_ok = IWL5000_UCODE_API_OK,
 	.ucode_api_min = IWL5000_UCODE_API_MIN,
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
@@ -415,6 +421,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
 #define IWL_DEVICE_5150						\
 	.fw_name_pre = IWL5150_FW_PRE,				\
 	.ucode_api_max = IWL5150_UCODE_API_MAX,			\
+	.ucode_api_ok = IWL5150_UCODE_API_OK,			\
 	.ucode_api_min = IWL5150_UCODE_API_MIN,			\
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,	\
@@ -436,5 +443,5 @@ struct iwl_cfg iwl5150_abg_cfg = {
 	IWL_DEVICE_5150,
 };
 
-MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK));
drivers/net/wireless/iwlwifi/iwl-6000.c +6 -4
@@ -53,6 +53,8 @@
 /* Oldest version we won't warn about */
 #define IWL6000_UCODE_API_OK 4
 #define IWL6000G2_UCODE_API_OK 5
+#define IWL6050_UCODE_API_OK 5
+#define IWL6000G2B_UCODE_API_OK 6
 
 /* Lowest firmware API version supported */
 #define IWL6000_UCODE_API_MIN 4
@@ -349,7 +351,7 @@ static struct iwl_bt_params iwl6000_bt_p
 #define IWL_DEVICE_6005						\
 	.fw_name_pre = IWL6005_FW_PRE,				\
 	.ucode_api_max = IWL6000G2_UCODE_API_MAX,		\
-	.ucode_api_ok = IWL6000G2_UCODE_API_OK,			\
+	.ucode_api_ok = IWL6000G2B_UCODE_API_OK,		\
 	.ucode_api_min = IWL6000G2_UCODE_API_MIN,		\
 	.eeprom_ver = EEPROM_6005_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,	\
@@ -548,6 +550,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK));
-MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK));
+MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK));
+MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK));
#83 lore raw

Re: [ 73/75] iwlwifi: use correct released ucode version

Quoted 11 lines · Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Meenakshi Venkataraman <[email protected]>

commit 78cbcf2b9dbe0565820dc7721316f9c401000a68 upstream.

Report correctly the latest released version
of the iwlwifi firmware for all
iwlwifi-supported devices.

[...]

Isn't this also applicable to 3.2.y?

Ben.

Signature · 3 lines
Ben Hutchings
Hoare's Law of Large Problems:
        Inside every large problem is a small problem struggling to get out.
#84 lore raw

RE: [ 73/75] iwlwifi: use correct released ucode version

Hi Ben,

Quoted 7 lines · Greg KH
Quoted 6 lines

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Meenakshi Venkataraman <[email protected]>

Quoted 7 lines
Quoted 4 lines

commit 78cbcf2b9dbe0565820dc7721316f9c401000a68 upstream.

Report correctly the latest released version of the iwlwifi firmware for all iwlwifi-supported devices.

[...]

Isn't this also applicable to 3.2.y?

[MV] Just checked -- it is indeed applicable to 3.2 stable kernels as well. Do I need to modify the patch to get it into 3.2 as well?

Thanks,
Meenakshi

#85 lore raw

RE: [ 73/75] iwlwifi: use correct released ucode version

Quoted 11 lines · Meenakshi

Hi Ben,

Quoted 9 lines · Greg KH
Quoted 8 lines

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Meenakshi Venkataraman <[email protected]>

commit 78cbcf2b9dbe0565820dc7721316f9c401000a68 upstream.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Report correctly the latest released version of the iwlwifi firmware for all iwlwifi-supported devices.

[...]

Isn't this also applicable to 3.2.y?

[MV] Just checked -- it is indeed applicable to 3.2 stable kernels as well. Do I need to modify the patch to get it into 3.2 as well?

No, it was easy enough to fix up the context. I have now queued up:

b914811524fbe9e91fe50845f5d7bd4316b8a6ee iwlagn: allow up to uCode API 6 for 6000 devices 78cbcf2b9dbe0565820dc7721316f9c401000a68 iwlwifi: use correct released ucode version 1ed2ec37b44e86eaa8e0a03b908a39c80f65ee45 iwlwifi: use 6000G2B for 6030 device series

Ben.

Signature · 3 lines
Ben Hutchings
Life is what happens to you while you're busy making other plans.
                                                               - John Lennon
author maintainer
#86 lore raw

PATCH 74/75 iwlwifi: fix hardware queue programming

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

commit 5ef4acd58ab2abd0dd0c8e3cacd61a0dc5d73646 upstream.

Newer devices have 20 (5000 series) or 30 (6000 series) hardware queues, rather than the 16 that 4965 had. This was added to the driver a long time ago, but improperly:
the queue registers for the higher queues aren't just continuations of the registers for the first 16 queues, they are in other places. Therefore, the hardware would lock up when trying to activate queue 16 or above and the device would have to be restarted.

Thanks goes to Emmanuel who identified this and told me how the queue programming should be done.

Note that we don't use queues 20 and higher today and doing so needs more work than this.

---
 drivers/net/wireless/iwlwifi/iwl-fh.h   |   22 ++++++++++++++++++----
 drivers/net/wireless/iwlwifi/iwl-prph.h |   27 ++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 7 deletions(-)
drivers/net/wireless/iwlwifi/iwl-fh.h +18 -4
@@ -104,15 +104,29 @@
  * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04
  * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte
  * aligned (address bits 0-7 must be 0).
+ * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers
+ * for them are in different places.
  *
  * Bit fields in each pointer register:
  *  27-0: TFD CB physical base address [35:8], must be 256-byte aligned
  */
-#define FH_MEM_CBBC_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0x9D0)
-#define FH_MEM_CBBC_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xA10)
+#define FH_MEM_CBBC_0_15_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0x9D0)
+#define FH_MEM_CBBC_0_15_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xA10)
+#define FH_MEM_CBBC_16_19_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xBF0)
+#define FH_MEM_CBBC_16_19_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xC00)
+#define FH_MEM_CBBC_20_31_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xB20)
+#define FH_MEM_CBBC_20_31_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xB80)
 
-/* Find TFD CB base pointer for given queue (range 0-15). */
-#define FH_MEM_CBBC_QUEUE(x)  (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
+/* Find TFD CB base pointer for given queue */
+static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
+{
+	if (chnl < 16)
+		return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl;
+	if (chnl < 20)
+		return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16);
+	WARN_ON_ONCE(chnl >= 32);
+	return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20);
+}
 
 
 /**
drivers/net/wireless/iwlwifi/iwl-prph.h +24 -3
@@ -227,12 +227,33 @@
 #define SCD_AIT			(SCD_BASE + 0x0c)
 #define SCD_TXFACT		(SCD_BASE + 0x10)
 #define SCD_ACTIVE		(SCD_BASE + 0x14)
-#define SCD_QUEUE_WRPTR(x)	(SCD_BASE + 0x18 + (x) * 4)
-#define SCD_QUEUE_RDPTR(x)	(SCD_BASE + 0x68 + (x) * 4)
 #define SCD_QUEUECHAIN_SEL	(SCD_BASE + 0xe8)
 #define SCD_AGGR_SEL		(SCD_BASE + 0x248)
 #define SCD_INTERRUPT_MASK	(SCD_BASE + 0x108)
-#define SCD_QUEUE_STATUS_BITS(x)	(SCD_BASE + 0x10c + (x) * 4)
+
+static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
+{
+	if (chnl < 20)
+		return SCD_BASE + 0x18 + chnl * 4;
+	WARN_ON_ONCE(chnl >= 32);
+	return SCD_BASE + 0x284 + (chnl - 20) * 4;
+}
+
+static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
+{
+	if (chnl < 20)
+		return SCD_BASE + 0x68 + chnl * 4;
+	WARN_ON_ONCE(chnl >= 32);
+	return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
+}
+
+static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
+{
+	if (chnl < 20)
+		return SCD_BASE + 0x10c + chnl * 4;
+	WARN_ON_ONCE(chnl >= 32);
+	return SCD_BASE + 0x384 + (chnl - 20) * 4;
+}
 
 /*********************** END TX SCHEDULER *************************************/
 
author maintainer
#87 lore raw

PATCH 75/75 iwlwifi: use 6000G2B for 6030 device series

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wey-Yi Guy <[email protected]>

commit 1ed2ec37b44e86eaa8e0a03b908a39c80f65ee45 upstream.

"iwlwifi: use correct released ucode version" change the ucode api ok from 6000G2 to 6000G2B, but it shall belong to 6030 device series, not the 6005 device series. Fix it

---
 drivers/net/wireless/iwlwifi/iwl-6000.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl-6000.c +2 -2
@@ -351,7 +351,7 @@ static struct iwl_bt_params iwl6000_bt_p
 #define IWL_DEVICE_6005						\
 	.fw_name_pre = IWL6005_FW_PRE,				\
 	.ucode_api_max = IWL6000G2_UCODE_API_MAX,		\
-	.ucode_api_ok = IWL6000G2B_UCODE_API_OK,		\
+	.ucode_api_ok = IWL6000G2_UCODE_API_OK,			\
 	.ucode_api_min = IWL6000G2_UCODE_API_MIN,		\
 	.eeprom_ver = EEPROM_6005_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,	\
@@ -391,7 +391,7 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
 #define IWL_DEVICE_6030						\
 	.fw_name_pre = IWL6030_FW_PRE,				\
 	.ucode_api_max = IWL6000G2_UCODE_API_MAX,		\
-	.ucode_api_ok = IWL6000G2_UCODE_API_OK,			\
+	.ucode_api_ok = IWL6000G2B_UCODE_API_OK,		\
 	.ucode_api_min = IWL6000G2_UCODE_API_MIN,		\
 	.eeprom_ver = EEPROM_6030_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,	\
author maintainer
#88 lore raw
In reply to Greg KH

Paul Kimoto pointed out that I messed up generating the 3.3.5-rc1 patch, so here is the 3.3.5-rc2 patch, with the proper header files added.
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.3.5-rc2.gz
The diffstat can be found below.

thanks,

greg k-h

 Makefile                                    |    4 +-
 arch/arm/Kconfig                            |    9 +
 arch/arm/include/asm/tls.h                  |    4 +
 arch/arm/kernel/irq.c                       |    6 +-
 arch/arm/mm/abort-ev6.S                     |   17 +-
 arch/mips/ath79/dev-wmac.c                  |    2 +-
 arch/powerpc/platforms/85xx/common.c        |    6 +
 arch/powerpc/platforms/85xx/mpc85xx_mds.c   |   11 +-
 arch/powerpc/platforms/85xx/p1022_ds.c      |   13 +-
 arch/x86/boot/Makefile                      |    3 +-
 arch/x86/boot/compressed/Makefile           |    1 +
 arch/x86/boot/compressed/eboot.c            |    8 +-
 arch/x86/boot/compressed/head_32.S          |   14 +-
 arch/x86/boot/compressed/head_64.S          |   22 ++-
 arch/x86/boot/compressed/mkpiggy.c          |   11 +-
 arch/x86/boot/tools/build.c                 |   42 ++--
 arch/x86/include/asm/x86_init.h             |    1 -
 arch/x86/kernel/apic/apic.c                 |   34 ++--
 arch/x86/kernel/apic/apic_numachip.c        |    7 +-
 arch/x86/kernel/cpu/amd.c                   |    7 +-
 arch/x86/kernel/cpu/common.c                |    9 -
 arch/x86/kernel/i387.c                      |    1 +
 arch/x86/kernel/microcode_amd.c             |   12 +-
 arch/x86/kernel/microcode_core.c            |   10 +-
 arch/x86/kernel/x86_init.c                  |    1 -
 arch/x86/xen/smp.c                          |   15 ++
 arch/x86/xen/xen-asm.S                      |    2 +-
 drivers/ata/libata-eh.c                     |    3 +-
 drivers/crypto/talitos.c                    |   20 +-
 drivers/dma/at_hdmac.c                      |    4 -
 drivers/firmware/efivars.c                  |  196 +++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c  |    8 +-
 drivers/gpu/drm/i915/i915_reg.h             |    1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c     |    8 +
 drivers/gpu/drm/i915/intel_sdvo.c           |   34 ++--
 drivers/gpu/drm/nouveau/nouveau_acpi.c      |    2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c      |    4 +-
 drivers/hwmon/coretemp.c                    |    6 +-
 drivers/hwmon/fam15h_power.c                |   42 ++++
 drivers/i2c/busses/i2c-pnx.c                |    3 +-
 drivers/input/mouse/synaptics.c             |    3 +-
 drivers/md/raid5.c                          |    4 +-
 drivers/net/wireless/b43/main.c             |   10 +-
 drivers/net/wireless/ipw2x00/ipw2200.c      |   13 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c     |    8 +-
 drivers/net/wireless/iwlwifi/iwl-2000.c     |   16 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c     |   11 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c     |   10 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    3 -
 drivers/net/wireless/iwlwifi/iwl-fh.h       |   24 ++-
 drivers/net/wireless/iwlwifi/iwl-mac80211.c |   10 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h     |   27 ++-
 drivers/net/wireless/rtlwifi/pci.c          |    1 +
 drivers/net/wireless/wl1251/main.c          |    1 +
 drivers/net/wireless/wl1251/sdio.c          |    2 +-
 drivers/platform/x86/dell-laptop.c          |    1 +
 drivers/scsi/libsas/sas_expander.c          |   26 ++-
 drivers/usb/class/cdc-wdm.c                 |    7 +-
 drivers/usb/core/hcd-pci.c                  |    9 +
 drivers/usb/gadget/dummy_hcd.c              |    1 -
 drivers/usb/gadget/f_mass_storage.c         |    2 +-
 drivers/usb/gadget/file_storage.c           |    2 +-
 drivers/usb/gadget/uvc.h                    |    2 +-
 drivers/usb/gadget/uvc_v4l2.c               |    2 +-
 drivers/usb/host/ehci-pci.c                 |    8 +
 drivers/usb/host/ehci-tegra.c               |    1 -
 fs/autofs4/autofs_i.h                       |   12 +-
 fs/autofs4/dev-ioctl.c                      |    3 +-
 fs/autofs4/inode.c                          |    4 +-
 fs/autofs4/waitq.c                          |   20 +-
 fs/exec.c                                   |    3 +
 fs/hfsplus/catalog.c                        |    4 +
 fs/hfsplus/dir.c                            |   11 ++
 fs/nfs/nfs4proc.c                           |   23 ++-
 fs/nfs/read.c                               |    2 +-
 fs/nfs/super.c                              |    8 +-
 fs/nfs/write.c                              |    2 +-
 fs/pipe.c                                   |   31 ++-
 include/linux/efi.h                         |   13 +-
 include/linux/pipe_fs_i.h                   |    1 +
 include/linux/usb/hcd.h                     |    2 +
 kernel/exit.c                               |   19 --
 kernel/power/swap.c                         |   28 ++-
 kernel/sched/core.c                         |   75 ++++----
 kernel/signal.c                             |    9 +
 kernel/trace/trace_output.c                 |    5 +
 net/mac80211/tx.c                           |    3 +-
 net/wireless/nl80211.c                      |   29 +--
 sound/pci/hda/patch_realtek.c               |    1 +
 sound/soc/codecs/wm8994.c                   |  276 +++++++++++++++++++++------
 sound/soc/soc-dapm.c                        |    2 +
 tools/include/tools/be_byteshift.h          |   70 +++++++
 tools/include/tools/le_byteshift.h          |   70 +++++++
 93 files changed, 1177 insertions(+), 356 deletions(-)