Skip to contentSkip to conversation

3.9.8-stable review

PATCH In review Greg Kroah-Hartman 2 participants 98 messages Jun 25, 2013 – Jun 26, 2013

Subsystems (55)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 3.9.8-stable review

This is the start of the stable review cycle for the 3.9.8 release. There are 95 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 Thu Jun 27 18:18:29 UTC 2013. 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.9.8-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 3.9.8-rc1

Mika Westerberg <[email protected]>
spi/pxa2xx: fix memory corruption due to wrong size used in devm_kzalloc()

Mika Westerberg <[email protected]>
spi/pxa2xx: use GFP_ATOMIC in sg table allocation

Damian Hobson-Garcia <[email protected]>
drivers: uio: Fix UIO device registration failure

Peter Zijlstra <[email protected]>
perf: Fix mmap() accounting hole

Peter Zijlstra <[email protected]>
perf: Fix perf mmap bugs

Josh Durgin <[email protected]>
rbd: use the correct length for format 2 object names

Joern Engel <[email protected]>
target/iscsi: don't corrupt bh_count in iscsit_stop_time2retain_timer()

Peter Hurley <[email protected]>
tty: Fix transient pty write() EIO

Roland Dreier <[email protected]>
tcm_qla2xxx: Fix residual for underrun commands that fail

Ming Lei <[email protected]>
firmware loader: fix use-after-free by double abort

Anders Hammarquist <[email protected]>
USB: serial: ti_usb_3410_5052: new device id for Abbot strip port cable

Shawn Joseph <[email protected]>
Input: xpad - fix for "Mad Catz Street Fighter IV FightPad" controllers

Ben Hutchings <[email protected]>
Input: add missing dependencies on CONFIG_HAS_IOMEM

Ferruh Yigit <[email protected]>
Input: cyttsp - fix memcpy size param

Jason Wang <[email protected]>
net_sched: better precise estimation on packet length for untrusted packets

Jason Wang <[email protected]>
netback: set transport header before passing it to kernel

Jason Wang <[email protected]>
packet: set transport header before doing xmit

Jason Wang <[email protected]>
tuntap: set transport header before passing it to kernel

Jason Wang <[email protected]>
macvtap: set transport header before passing skb to lower device

Jason Wang <[email protected]>
tuntap: correct the return value in tun_set_iff()

Yoshihiro Shimoda <[email protected]>
net: sh_eth: fix incorrect RX length error if R8A7740

Neil Horman <[email protected]>
sctp: fully initialize sctp_outq in sctp_outq_init

Guillaume Nault <[email protected]>
l2tp: Fix sendmsg() return value

Guillaume Nault <[email protected]>
l2tp: Fix PPP header erasure and memory leak

Daniel Borkmann <[email protected]>
packet: packet_getname_spkt: make sure string is always 0-terminated

Jiri Pirko <[email protected]>
team: move add to port list before port enablement

Jiri Pirko <[email protected]>
team: check return value of team_get_port_by_index_rcu() for NULL

Jason Wang <[email protected]>
tuntap: set SOCK_ZEROCOPY flag during open

Daniel Borkmann <[email protected]>
net: sctp: fix NULL pointer dereference in socket destruction

Jason Wang <[email protected]>
vhost_net: clear msg.control for non-zerocopy case during tx

Eric Dumazet <[email protected]>
net_sched: htb: do not mix 1ns and 64ns time units

Gao feng <[email protected]>
ipv6: assign rt6_info to inet6_ifaddr in init_loopback

Eric Dumazet <[email protected]>
net_sched: restore "overhead xxx" handling

Eric Dumazet <[email protected]>
net: force a reload of first item in hlist_nulls_for_each_entry_rcu

Pravin B Shelar <[email protected]>
udp6: Fix udp fragmentation for tunnel traffic.

Jason Wang <[email protected]>
tuntap: forbid changing mq flag for persistent device

Federico Vaga <[email protected]>
net/core/sock.c: add missing VSOCK string in af_family_*_key_strings

Andy Lutomirski <[email protected]>
net: Block MSG_CMSG_COMPAT in send(m)msg and recv(m)msg

Michal Kubecek <[email protected]>
ipv4: fix redirect handling for TCP packets

Giuseppe CAVALLARO <[email protected]>
net: phy: fix a bug when verify the EEE support

Eric Dumazet <[email protected]>
ip_tunnel: fix kernel panic with icmp_dest_unreach

Eric Dumazet <[email protected]>
tcp: xps: fix reordering issues

Timo Teräs <[email protected]>
xfrm: properly handle invalid states as an error

Nandita Dukkipati <[email protected]>
tcp: bug fix in proportional rate reduction.

stephen hemminger <[email protected]>
8139cp: reset BQL when ring tx ring cleared

Francois Romieu <[email protected]>
r8169: fix offloaded tx checksum for small packets.

Paul Moore <[email protected]>
netlabel: improve domain mapping validation

Eric Dumazet <[email protected]>
ipv6: fix possible crashes in ip6_cork_release()

Sridhar Samudrala <[email protected]>
vxlan: Update vxlan fdb 'used' field after each usage

Wei Yongjun <[email protected]>
gianfar: add missing iounmap() on error in gianfar_ptp_probe()

Eric Dumazet <[email protected]>
net/802/mrp: fix lockdep splat

Eric Dumazet <[email protected]>
tcp: fix tcp_md5_hash_skb_data()

Frank Li <[email protected]>
net: fec: fix kernel oops when plug/unplug cable many times

Paul Gortmaker <[email protected]>
x86: Fix section mismatch on load_ucode_ap

Randy Dunlap <[email protected]>
x86: fix build error and kconfig for ia32_emulation and binfmt

Yinghai Lu <[email protected]>
x86, mtrr: Fix original mtrr range get for mtrr_cleanup

Yinghai Lu <[email protected]>
range: Do not add new blank slot with add_range_with_merge

Jerome Glisse <[email protected]>
drm/radeon: update lockup tracking when scheduling in empty ring

Jerome Glisse <[email protected]>
drm/radeon: do not try to uselessly update virtual memory pagetable

Laurent Pinchart <[email protected]>
drm/prime: Honor requested file flags when exporting a buffer

Rafael J. Wysocki <[email protected]>
ACPI / PM: Fix error code path for power resources initialization

Rafael J. Wysocki <[email protected]>
ACPI / dock: Take ACPI scan lock in write_undock()

Mika Westerberg <[email protected]>
ACPI / resources: call acpi_get_override_irq() only for legacy IRQ resources

Zhanghaoyu (A) <[email protected]>
KVM: x86: remove vcpu's CPL check in host-invoked XCR set

Igor Mammedov <[email protected]>
x86: kvmclock: zero initialize pvclock shared memory area

Ben Hutchings <[email protected]>
x86/efi: Fix dummy variable buffer allocation

Christian Lamparter <[email protected]>
carl9170: fix frame drop and WARN due to minstrel_ht change

Thomas Bogendoerfer <[email protected]>
parisc: provide pci_mmap_page_range() for parisc

Thomas Bogendoerfer <[email protected]>
parisc: fix serial ports on C8000 workstation

Helge Deller <[email protected]>
parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50 (part 2)

Helge Deller <[email protected]>
parisc: parport0: fix this legacy no-device port driver!

Chen Gang <[email protected]>
parisc: kernel: using strlcpy() instead of strcpy()

Paul Bolle <[email protected]>

    parisc: rename "CONFIG_PA7100" to "CONFIG_PA7000"

Helge Deller <[email protected]>
parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50

Chen Gang <[email protected]>
parisc: memory overflow, 'name' length is too short for using

Helge Deller <[email protected]>
parisc: fix irq stack on UP and SMP

John David Anglin <[email protected]>
parisc: make interrupt and interruption stack allocation reentrant

Helge Deller <[email protected]>
parisc: show number of FPE and unaligned access handler calls in /proc/interrupts

Helge Deller <[email protected]>
parisc: add rp5470 entry to machine database

Helge Deller <[email protected]>
parisc: implement irq stacks - part 2 (v2)

Zhao Hongjiang <[email protected]>
parisc: remove the second argument of kmap_atomic()

Helge Deller <[email protected]>
parisc: tlb flush counting fix for SMP and UP

Helge Deller <[email protected]>
parisc: more irq statistics in /proc/interrupts

Helge Deller <[email protected]>
parisc: implement irq stacks

Helge Deller <[email protected]>
parisc: add kernel stack overflow check

Hante Meuleman <[email protected]>
brcmfmac: Turn off ARP offloading when configured for AP.

Larry Finger <[email protected]>
rtlwifi: rtl8192cu: Fix problem in connecting to WEP or WPA(1) networks

Chris Metcalf <[email protected]>
tilepro: work around module link error with gcc 4.7

Lai Jiangshan <[email protected]>
clk: remove notifier from list before freeing it

Clemens Ladisch <[email protected]>
ALSA: usb-audio: work around Android accessory firmware bug

Takashi Iwai <[email protected]>
ALSA: hda - Fix pin configurations for MacBook Air 4,2

Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix invalid volume resolution for Logitech HD Webcam c310

Jed Davis <[email protected]>
perf: arm64: Record the user-mode PC in the call chain.

Gregory CLEMENT <[email protected]>
ARM: 7754/1: Fix the CPU ID and the mask associated to the PJ4B

Jon Medhurst <[email protected]>
ARM: 7752/1: errata: LoUIS bit field in CLIDR register is incorrect

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

Diffstat:

 Makefile                                           |   4 +-
 arch/arm/Kconfig                                   |  10 +
 arch/arm/mm/cache-v7.S                             |   8 +
 arch/arm/mm/proc-v7.S                              |   4 +-
 arch/arm64/kernel/perf_event.c                     |   1 +
 arch/parisc/Kconfig                                |   8 +
 arch/parisc/Kconfig.debug                          |  11 +
 arch/parisc/Makefile                               |   2 +-
 arch/parisc/include/asm/assembly.h                 |   1 -
 arch/parisc/include/asm/hardirq.h                  |  38 +++-
 arch/parisc/include/asm/mmzone.h                   |   7 +-
 arch/parisc/include/asm/pci.h                      |   5 +
 arch/parisc/include/asm/processor.h                |   4 -
 arch/parisc/include/asm/thread_info.h              |   2 +-
 arch/parisc/include/asm/tlbflush.h                 |   2 +
 arch/parisc/kernel/cache.c                         |   6 +-
 arch/parisc/kernel/drivers.c                       |   2 +-
 arch/parisc/kernel/entry.S                         |  60 +++++-
 arch/parisc/kernel/hardware.c                      |   2 +
 arch/parisc/kernel/irq.c                           | 198 ++++++++++++++++-
 arch/parisc/kernel/pci.c                           |  27 +++
 arch/parisc/kernel/setup.c                         |   3 +-
 arch/parisc/kernel/smp.c                           |  14 +-
 arch/parisc/kernel/traps.c                         |   1 +
 arch/parisc/kernel/unaligned.c                     |   3 +
 arch/parisc/kernel/vmlinux.lds.S                   |   2 +-
 arch/parisc/mm/init.c                              |   4 +-
 arch/tile/lib/exports.c                            |   2 +
 arch/x86/Kconfig                                   |   1 +
 arch/x86/include/asm/microcode.h                   |   4 +-
 arch/x86/kernel/cpu/mtrr/cleanup.c                 |   8 +-
 arch/x86/kernel/kvmclock.c                         |   1 +
 arch/x86/kvm/x86.c                                 |   5 +-
 arch/x86/platform/efi/efi.c                        |   7 +-
 drivers/acpi/dock.c                                |   2 +
 drivers/acpi/power.c                               |   1 +
 drivers/acpi/resource.c                            |  16 +-
 drivers/base/firmware_class.c                      |  27 ++-
 drivers/block/rbd.c                                |   6 +-
 drivers/clk/clk.c                                  |   1 +
 drivers/gpu/drm/drm_prime.c                        |   3 +-
 drivers/gpu/drm/radeon/radeon_gart.c               |   6 +-
 drivers/gpu/drm/radeon/radeon_ring.c               |   7 +
 drivers/input/joystick/xpad.c                      |   2 +-
 drivers/input/keyboard/Kconfig                     |   1 +
 drivers/input/serio/Kconfig                        |   1 +
 drivers/input/touchscreen/cyttsp_core.c            |   2 +-
 drivers/net/ethernet/freescale/fec.c               |  44 +++-
 drivers/net/ethernet/freescale/fec.h               |  10 +-
 drivers/net/ethernet/freescale/gianfar_ptp.c       |   1 +
 drivers/net/ethernet/realtek/8139cp.c              |   1 +
 drivers/net/ethernet/realtek/r8169.c               |  41 ++--
 drivers/net/ethernet/renesas/sh_eth.c              |  15 +-
 drivers/net/macvtap.c                              |   9 +
 drivers/net/phy/phy.c                              |   2 +-
 drivers/net/team/team.c                            |   2 +-
 drivers/net/team/team_mode_roundrobin.c            |   2 +
 drivers/net/tun.c                                  |  24 ++-
 drivers/net/vxlan.c                                |  17 +-
 drivers/net/wireless/ath/carl9170/tx.c             |  69 +++---
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |  18 --
 .../net/wireless/brcm80211/brcmfmac/fwil_types.h   |   6 +
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |  40 +++-
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c        | 134 +++++++++---
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.h        |   4 -
 drivers/net/wireless/rtlwifi/rtl8192cu/mac.c       |  18 +-
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c        |   4 +-
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.h        |   3 +
 drivers/net/wireless/rtlwifi/usb.c                 |  13 ++
 drivers/net/wireless/rtlwifi/wifi.h                |   4 +
 drivers/net/xen-netback/netback.c                  |  12 ++
 drivers/parisc/iosapic.c                           |  66 ++++++
 drivers/parport/parport_gsc.c                      |   6 +-
 drivers/parport/parport_gsc.h                      |   2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c                 |   6 +-
 drivers/spi/spi-pxa2xx-dma.c                       |   2 +-
 drivers/spi/spi-pxa2xx.c                           |   2 +-
 drivers/target/iscsi/iscsi_target_erl0.c           |   4 +-
 drivers/tty/pty.c                                  |  13 +-
 drivers/tty/serial/8250/8250_gsc.c                 |  10 +-
 drivers/uio/uio.c                                  |   1 +
 drivers/usb/serial/ti_usb_3410_5052.c              |   3 +-
 drivers/usb/serial/ti_usb_3410_5052.h              |   4 +-
 drivers/vhost/net.c                                |   3 +-
 include/linux/perf_event.h                         |   3 +-
 include/linux/rculist_nulls.h                      |   7 +-
 include/linux/skbuff.h                             |  15 ++
 include/linux/socket.h                             |   3 +
 include/net/sch_generic.h                          |  18 +-
 kernel/events/core.c                               | 233 ++++++++++++++-------
 kernel/events/internal.h                           |   4 +
 kernel/range.c                                     |  21 +-
 net/802/mrp.c                                      |   4 +-
 net/compat.c                                       |  13 +-
 net/core/dev.c                                     |   8 +-
 net/core/sock.c                                    |   6 +-
 net/ipv4/ip_gre.c                                  |   2 +-
 net/ipv4/ipip.c                                    |   2 +-
 net/ipv4/route.c                                   |   7 +-
 net/ipv4/tcp.c                                     |   7 +-
 net/ipv4/tcp_input.c                               |  23 +-
 net/ipv4/tcp_output.c                              |  10 +-
 net/ipv6/addrconf.c                                |   4 +-
 net/ipv6/ip6_output.c                              |   2 +-
 net/ipv6/udp_offload.c                             |  20 +-
 net/l2tp/l2tp_ppp.c                                |   6 +-
 net/netlabel/netlabel_domainhash.c                 |  69 ++++++
 net/packet/af_packet.c                             |  26 ++-
 net/sched/act_police.c                             |   8 +-
 net/sched/sch_generic.c                            |   8 +-
 net/sched/sch_htb.c                                |  42 ++--
 net/sched/sch_tbf.c                                |   8 +-
 net/sctp/outqueue.c                                |   8 +-
 net/sctp/socket.c                                  |   6 +
 net/socket.c                                       |  61 ++++--
 net/xfrm/xfrm_output.c                             |   1 +
 sound/pci/hda/patch_cirrus.c                       |  23 ++
 sound/usb/card.c                                   |  22 +-
 sound/usb/mixer.c                                  |   1 +
 119 files changed, 1413 insertions(+), 435 deletions(-)
author maintainer
#1 lore raw

PATCH 1/95 ARM: 7752/1: errata: LoUIS bit field in CLIDR register is incorrect

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

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

From: Jon Medhurst <[email protected]>

commit 691557941af4c12bd307ad81a4d9fa9c7743ac28 upstream.

On Cortex-A9 before version r1p0, the LoUIS bit field of the CLIDR register returns zero when it should return one. This leads to cache maintenance operations which rely on this value to not function as intended, causing data corruption.

The workaround for this errata is to detect affected CPUs and correct the LoUIS value read.

---
 arch/arm/Kconfig       |   10 ++++++++++
 arch/arm/mm/cache-v7.S |    8 ++++++++
 2 files changed, 18 insertions(+)
arch/arm/Kconfig +10 -0
@@ -1306,6 +1306,16 @@ config PL310_ERRATA_588369
 	   is not correctly implemented in PL310 as clean lines are not
 	   invalidated as a result of these operations.
 
+config ARM_ERRATA_643719
+	bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
+	depends on CPU_V7 && SMP
+	help
+	  This option enables the workaround for the 643719 Cortex-A9 (prior to
+	  r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR
+	  register returns zero when it should return one. The workaround
+	  corrects this value, ensuring cache maintenance operations which use
+	  it behave as intended and avoiding data corruption.
+
 config ARM_ERRATA_720789
 	bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
 	depends on CPU_V7
arch/arm/mm/cache-v7.S +8 -0
@@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis)
 	mrc	p15, 1, r0, c0, c0, 1		@ read clidr, r0 = clidr
 	ALT_SMP(ands	r3, r0, #(7 << 21))	@ extract LoUIS from clidr
 	ALT_UP(ands	r3, r0, #(7 << 27))	@ extract LoUU from clidr
+#ifdef CONFIG_ARM_ERRATA_643719
+	ALT_SMP(mrceq	p15, 0, r2, c0, c0, 0)	@ read main ID register
+	ALT_UP(moveq	pc, lr)			@ LoUU is zero, so nothing to do
+	ldreq	r1, =0x410fc090                 @ ID of ARM Cortex A9 r0p?
+	biceq	r2, r2, #0x0000000f             @ clear minor revision number
+	teqeq	r2, r1                          @ test for errata affected core and if so...
+	orreqs	r3, #(1 << 21)			@   fix LoUIS value (and set flags state to 'ne')
+#endif
 	ALT_SMP(mov	r3, r3, lsr #20)	@ r3 = LoUIS * 2
 	ALT_UP(mov	r3, r3, lsr #26)	@ r3 = LoUU * 2
 	moveq	pc, lr				@ return if level == 0
author maintainer
#2 lore raw

PATCH 2/95 ARM: 7754/1: Fix the CPU ID and the mask associated to the PJ4B

In reply to Greg Kroah-Hartman

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

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

From: Gregory CLEMENT <[email protected]>

commit 049be07053ebbf0ee8543caea23ae7bdf0765bb2 upstream.

This commit fixes the ID and mask for the PJ4B which was too restrictive and didn't match the CPU of the Armada 370 SoC.

---
 arch/arm/mm/proc-v7.S |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mm/proc-v7.S +2 -2
@@ -407,8 +407,8 @@ __v7_ca9mp_proc_info:
 	 */
 	.type   __v7_pj4b_proc_info, #object
 __v7_pj4b_proc_info:
-	.long	0x562f5840
-	.long	0xfffffff0
+	.long	0x560f5800
+	.long	0xff0fff00
 	__v7_proc __v7_pj4b_setup
 	.size	__v7_pj4b_proc_info, . - __v7_pj4b_proc_info
 #endif	/* CONFIG_ARM_LPAE */
author maintainer
#3 lore raw

PATCH 3/95 perf: arm64: Record the user-mode PC in the call chain.

In reply to Greg Kroah-Hartman

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

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

From: Jed Davis <[email protected]>

commit abc41254181e901ef5eda2c884ca6cd88a186b6d upstream.

With this change, we no longer lose the innermost entry in the user-mode part of the call chain. See also the x86 port, which includes the ip, and the corresponding change in arch/arm.

---
 arch/arm64/kernel/perf_event.c |    1 +
 1 file changed, 1 insertion(+)
arch/arm64/kernel/perf_event.c +1 -0
@@ -1336,6 +1336,7 @@ void perf_callchain_user(struct perf_cal
 		return;
 	}
 
+	perf_callchain_store(entry, regs->pc);
 	tail = (struct frame_tail __user *)regs->regs[29];
 
 	while (entry->nr < PERF_MAX_STACK_DEPTH &&
author maintainer
#4 lore raw

PATCH 4/95 ALSA: usb-audio: Fix invalid volume resolution for Logitech HD Webcam c310

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit 36691e1be6ec551eef4a5225f126a281f8c051c2 upstream.

Just like the previous fix for LogitechHD Webcam c270 in commit 11e7064f35bb87da8f427d1aa4bbd8b7473a3993, c310 model also requires the same workaround for avoiding the kernel warning.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=59741

---
 sound/usb/mixer.c |    1 +
 1 file changed, 1 insertion(+)
sound/usb/mixer.c +1 -0
@@ -885,6 +885,7 @@ static void volume_control_quirks(struct
 
 	case USB_ID(0x046d, 0x0808):
 	case USB_ID(0x046d, 0x0809):
+	case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
 	case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
 	case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
 	case USB_ID(0x046d, 0x0991):
author maintainer
#5 lore raw

PATCH 5/95 ALSA: hda - Fix pin configurations for MacBook Air 4,2

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit 6ab982e8cf8e5760da407ccdc4abc815bea23179 upstream.

MacBook Air 4,2 requires the whole default pin configuration table to be overridden by the driver, as usual, as Apple's machines don't set up properly after boot. Otherwise mic won't work, and other ill effect may happen.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=59381

---
 sound/pci/hda/patch_cirrus.c |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
sound/pci/hda/patch_cirrus.c +23 -0
@@ -58,6 +58,7 @@ enum {
 	CS420X_GPIO_23,
 	CS420X_MBP101,
 	CS420X_MBP81,
+	CS420X_MBA42,
 	CS420X_AUTO,
 	/* aliases */
 	CS420X_IMAC27_122 = CS420X_GPIO_23,
@@ -345,6 +346,7 @@ static const struct hda_model_fixup cs42
 	{ .id = CS420X_APPLE, .name = "apple" },
 	{ .id = CS420X_MBP101, .name = "mbp101" },
 	{ .id = CS420X_MBP81, .name = "mbp81" },
+	{ .id = CS420X_MBA42, .name = "mba42" },
 	{}
 };
 
@@ -360,6 +362,7 @@ static const struct snd_pci_quirk cs420x
 	SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
 	SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
 	SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
+	SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42),
 	SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
 	{} /* terminator */
 };
@@ -413,6 +416,20 @@ static const struct hda_pintbl mbp101_pi
 	{} /* terminator */
 };
 
+static const struct hda_pintbl mba42_pincfgs[] = {
+	{ 0x09, 0x012b4030 }, /* HP */
+	{ 0x0a, 0x400000f0 },
+	{ 0x0b, 0x90100120 }, /* speaker */
+	{ 0x0c, 0x400000f0 },
+	{ 0x0d, 0x90a00110 }, /* mic */
+	{ 0x0e, 0x400000f0 },
+	{ 0x0f, 0x400000f0 },
+	{ 0x10, 0x400000f0 },
+	{ 0x12, 0x400000f0 },
+	{ 0x15, 0x400000f0 },
+	{} /* terminator */
+};
+
 static void cs420x_fixup_gpio_13(struct hda_codec *codec,
 				 const struct hda_fixup *fix, int action)
 {
@@ -481,6 +498,12 @@ static const struct hda_fixup cs420x_fix
 		.chained = true,
 		.chain_id = CS420X_GPIO_13,
 	},
+	[CS420X_MBA42] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = mba42_pincfgs,
+		.chained = true,
+		.chain_id = CS420X_GPIO_13,
+	},
 };
 
 static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid)
author maintainer
#6 lore raw

PATCH 6/95 ALSA: usb-audio: work around Android accessory firmware bug

In reply to Greg Kroah-Hartman

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

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

From: Clemens Ladisch <[email protected]>

commit 342cda29343a6272c630f94ed56810a76740251b upstream.

When the Android firmware enables the audio interfaces in accessory mode, it always declares in the control interface's baInterfaceNr array that interfaces 0 and 1 belong to the audio function. However, the accessory interface itself, if also enabled, already is at index 0 and shifts the actual audio interface numbers to 1 and 2, which prevents the PCM streaming interface from being seen by the host driver.

To get the PCM interface interface to work, detect when the descriptors point to the (for this driver useless) accessory interface, and redirect to the correct one.

---
 sound/usb/card.c |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
sound/usb/card.c +20 -2
@@ -144,14 +144,32 @@ static int snd_usb_create_stream(struct
 		return -EINVAL;
 	}
 
+	alts = &iface->altsetting[0];
+	altsd = get_iface_desc(alts);
+
+	/*
+	 * Android with both accessory and audio interfaces enabled gets the
+	 * interface numbers wrong.
+	 */
+	if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) ||
+	     chip->usb_id == USB_ID(0x18d1, 0x2d05)) &&
+	    interface == 0 &&
+	    altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
+	    altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) {
+		interface = 2;
+		iface = usb_ifnum_to_if(dev, interface);
+		if (!iface)
+			return -EINVAL;
+		alts = &iface->altsetting[0];
+		altsd = get_iface_desc(alts);
+	}
+
 	if (usb_interface_claimed(iface)) {
 		snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
 						dev->devnum, ctrlif, interface);
 		return -EINVAL;
 	}
 
-	alts = &iface->altsetting[0];
-	altsd = get_iface_desc(alts);
 	if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
 	     altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
 	    altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
author maintainer
#7 lore raw

PATCH 7/95 clk: remove notifier from list before freeing it

In reply to Greg Kroah-Hartman

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

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

From: Lai Jiangshan <[email protected]>

commit 72b5322f11ff0abf6a52b3007486656578d2c982 upstream.

The @cn is stay in @clk_notifier_list after it is freed, it cause memory corruption.

Example, if @clk is registered(first), unregistered(first), registered(second), unregistered(second).

The freed @cn will be used when @clk is registered(second), and the bug will be happened when @clk is unregistered(second):

[  517.040000] clk_notif_dbg clk_notif_dbg.1: clk_notifier_unregister()
[  517.040000] Unable to handle kernel paging request at virtual address 00df3008
[  517.050000] pgd = ed858000
[  517.050000] [00df3008] *pgd=00000000
[  517.060000] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[  517.060000] Modules linked in: clk_notif_dbg(O-) [last unloaded: clk_notif_dbg]
[  517.060000] CPU: 1 PID: 499 Comm: modprobe Tainted: G           O 3.10.0-rc3-00119-ga93cb29-dirty #85
[  517.060000] task: ee1e0180 ti: ee3e6000 task.ti: ee3e6000
[  517.060000] PC is at srcu_readers_seq_idx+0x48/0x84
[  517.060000] LR is at srcu_readers_seq_idx+0x60/0x84
[  517.060000] pc : [<c0052720>]    lr : [<c0052738>]    psr: 80070013
[  517.060000] sp : ee3e7d48  ip : 00000000  fp : ee3e7d6c
[  517.060000] r10: 00000000  r9 : ee3e6000  r8 : 00000000
[  517.060000] r7 : ed84fe4c  r6 : c068ec90  r5 : c068e430  r4 : 00000000
[  517.060000] r3 : 00df3000  r2 : 00000000  r1 : 00000002  r0 : 00000000
[  517.060000] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[  517.060000] Control: 18c5387d  Table: 2d85804a  DAC: 00000015
[  517.060000] Process modprobe (pid: 499, stack limit = 0xee3e6238)
[  517.060000] Stack: (0xee3e7d48 to 0xee3e8000)
....
[  517.060000] [<c0052720>] (srcu_readers_seq_idx+0x48/0x84) from [<c0052790>] (try_check_zero+0x34/0xfc)
[  517.060000] [<c0052790>] (try_check_zero+0x34/0xfc) from [<c00528b0>] (srcu_advance_batches+0x58/0x114)
[  517.060000] [<c00528b0>] (srcu_advance_batches+0x58/0x114) from [<c0052c30>] (__synchronize_srcu+0x114/0x1ac)
[  517.060000] [<c0052c30>] (__synchronize_srcu+0x114/0x1ac) from [<c0052d14>] (synchronize_srcu+0x2c/0x34)
[  517.060000] [<c0052d14>] (synchronize_srcu+0x2c/0x34) from [<c0053a08>] (srcu_notifier_chain_unregister+0x68/0x74)
[  517.060000] [<c0053a08>] (srcu_notifier_chain_unregister+0x68/0x74) from [<c0375a78>] (clk_notifier_unregister+0x7c/0xc0)
[  517.060000] [<c0375a78>] (clk_notifier_unregister+0x7c/0xc0) from [<bf008034>] (clk_notif_dbg_remove+0x34/0x9c [clk_notif_dbg])
[  517.060000] [<bf008034>] (clk_notif_dbg_remove+0x34/0x9c [clk_notif_dbg]) from [<c02bb974>] (platform_drv_remove+0x24/0x28)
[  517.060000] [<c02bb974>] (platform_drv_remove+0x24/0x28) from [<c02b9bf8>] (__device_release_driver+0x8c/0xd4)
[  517.060000] [<c02b9bf8>] (__device_release_driver+0x8c/0xd4) from [<c02ba680>] (driver_detach+0x9c/0xc4)
[  517.060000] [<c02ba680>] (driver_detach+0x9c/0xc4) from [<c02b99c4>] (bus_remove_driver+0xcc/0xfc)
[  517.060000] [<c02b99c4>] (bus_remove_driver+0xcc/0xfc) from [<c02bace4>] (driver_unregister+0x54/0x78)
[  517.060000] [<c02bace4>] (driver_unregister+0x54/0x78) from [<c02bbb44>] (platform_driver_unregister+0x1c/0x20)
[  517.060000] [<c02bbb44>] (platform_driver_unregister+0x1c/0x20) from [<bf0081f8>] (clk_notif_dbg_driver_exit+0x14/0x1c [clk_notif_dbg])
[  517.060000] [<bf0081f8>] (clk_notif_dbg_driver_exit+0x14/0x1c [clk_notif_dbg]) from [<c00835e4>] (SyS_delete_module+0x200/0x28c)
[  517.060000] [<c00835e4>] (SyS_delete_module+0x200/0x28c) from [<c000edc0>] (ret_fast_syscall+0x0/0x48)
[  517.060000] Code: e5973004 e7911102 e0833001 e2881002 (e7933101)
---
 drivers/clk/clk.c |    1 +
 1 file changed, 1 insertion(+)
drivers/clk/clk.c +1 -0
@@ -1759,6 +1759,7 @@ int clk_notifier_unregister(struct clk *
 		/* XXX the notifier code should handle this better */
 		if (!cn->notifier_head.head) {
 			srcu_cleanup_notifier_head(&cn->notifier_head);
+			list_del(&cn->node);
 			kfree(cn);
 		}
 
author maintainer
#8 lore raw

PATCH 8/95 tilepro: work around module link error with gcc 4.7

In reply to Greg Kroah-Hartman

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

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

From: Chris Metcalf <[email protected]>

commit 3cb3f839d306443f3d1e79b0bde1a2ad2c12b555 upstream.

gcc 4.7.x is emitting calls to __ffsdi2 where previously it used to inline the appropriate ctz instructions. While this needs to be fixed in gcc, it's also easy to avoid having it cause build failures when building with those compilers by exporting __ffsdi2 to modules.

---
 arch/tile/lib/exports.c |    2 ++
 1 file changed, 2 insertions(+)
arch/tile/lib/exports.c +2 -0
@@ -84,4 +84,6 @@ uint64_t __ashrdi3(uint64_t, unsigned in
 EXPORT_SYMBOL(__ashrdi3);
 uint64_t __ashldi3(uint64_t, unsigned int);
 EXPORT_SYMBOL(__ashldi3);
+int __ffsdi2(uint64_t);
+EXPORT_SYMBOL(__ffsdi2);
 #endif
author maintainer
#9 lore raw

PATCH 9/95 rtlwifi: rtl8192cu: Fix problem in connecting to WEP or WPA(1) networks

In reply to Greg Kroah-Hartman

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

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

From: Larry Finger <[email protected]>

commit 5b8df24e22e0b00b599cb9ae63dbb96e1959be30 upstream.

Driver rtl8192cu can connect to WPA2 networks, but fails for any other encryption method. The cause is a failure to set the rate control data blocks. These changes fix https://bugzilla.redhat.com/show_bug.cgi?id=952793
and https://bugzilla.redhat.com/show_bug.cgi?id=761525.

---
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c  |  132 ++++++++++++++++++++-------
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.h  |    4 
 drivers/net/wireless/rtlwifi/rtl8192cu/mac.c |   18 +++
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c  |    4 
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.h  |    3 
 drivers/net/wireless/rtlwifi/usb.c           |   13 ++
 drivers/net/wireless/rtlwifi/wifi.h          |    4 
 7 files changed, 138 insertions(+), 40 deletions(-)
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +99 -33
@@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211
 	}
 }
 
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
-				   struct ieee80211_sta *sta,
-				   u8 rssi_level)
+static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+					  struct ieee80211_sta *sta)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	u32 ratr_value = (u32) mac->basic_rates;
-	u8 *mcsrate = mac->mcs;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	u32 ratr_value;
 	u8 ratr_index = 0;
 	u8 nmode = mac->ht_enable;
-	u8 mimo_ps = 1;
-	u16 shortgi_rate = 0;
-	u32 tmp_ratr_value = 0;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
+	u16 shortgi_rate;
+	u32 tmp_ratr_value;
 	u8 curtxbw_40mhz = mac->bw_40;
-	u8 curshortgi_40mhz = mac->sgi_40;
-	u8 curshortgi_20mhz = mac->sgi_20;
+	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+			       1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+			       1 : 0;
 	enum wireless_mode wirelessmode = mac->mode;
 
-	ratr_value |= ((*(u16 *) (mcsrate))) << 12;
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_value = sta->supp_rates[1] << 4;
+	else
+		ratr_value = sta->supp_rates[0];
+	if (mac->opmode == NL80211_IFTYPE_ADHOC)
+		ratr_value = 0xfff;
+
+	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
 	case WIRELESS_MODE_B:
 		if (ratr_value & 0x0000000c)
@@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struc
 	case WIRELESS_MODE_N_24G:
 	case WIRELESS_MODE_N_5G:
 		nmode = 1;
-		if (mimo_ps == 0) {
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
 			ratr_value &= 0x0007F005;
 		} else {
 			u32 ratr_mask;
@@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struc
 				ratr_mask = 0x000ff005;
 			else
 				ratr_mask = 0x0f0ff005;
-			if (curtxbw_40mhz)
-				ratr_mask |= 0x00000010;
+
 			ratr_value &= ratr_mask;
 		}
 		break;
@@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struc
 			ratr_value &= 0x000ff0ff;
 		else
 			ratr_value &= 0x0f0ff0ff;
+
 		break;
 	}
+
 	ratr_value &= 0x0FFFFFFF;
-	if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
-	    (!curtxbw_40mhz && curshortgi_20mhz))) {
+
+	if (nmode && ((curtxbw_40mhz &&
+			 curshortgi_40mhz) || (!curtxbw_40mhz &&
+					       curshortgi_20mhz))) {
+
 		ratr_value |= 0x10000000;
 		tmp_ratr_value = (ratr_value >> 12);
+
 		for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
 			if ((1 << shortgi_rate) & tmp_ratr_value)
 				break;
 		}
+
 		shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
-			       (shortgi_rate << 4) | (shortgi_rate);
+		    (shortgi_rate << 4) | (shortgi_rate);
 	}
+
 	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+		 rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
+					 struct ieee80211_sta *sta,
+					 u8 rssi_level)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	u32 ratr_bitmap = (u32) mac->basic_rates;
-	u8 *p_mcsrate = mac->mcs;
-	u8 ratr_index = 0;
-	u8 curtxbw_40mhz = mac->bw_40;
-	u8 curshortgi_40mhz = mac->sgi_40;
-	u8 curshortgi_20mhz = mac->sgi_20;
-	enum wireless_mode wirelessmode = mac->mode;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
+	u32 ratr_bitmap;
+	u8 ratr_index;
+	u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
+	u8 curshortgi_40mhz = curtxbw_40mhz &&
+			      (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+				1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+				1 : 0;
+	enum wireless_mode wirelessmode = 0;
 	bool shortgi = false;
 	u8 rate_mask[5];
 	u8 macid = 0;
-	u8 mimops = 1;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
 
-	ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+	sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+	wirelessmode = sta_entry->wireless_mode;
+	if (mac->opmode == NL80211_IFTYPE_STATION ||
+	    mac->opmode == NL80211_IFTYPE_MESH_POINT)
+		curtxbw_40mhz = mac->bw_40;
+	else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC)
+		macid = sta->aid + 1;
+
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_bitmap = sta->supp_rates[1] << 4;
+	else
+		ratr_bitmap = sta->supp_rates[0];
+	if (mac->opmode == NL80211_IFTYPE_ADHOC)
+		ratr_bitmap = 0xfff;
+	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
 	case WIRELESS_MODE_B:
 		ratr_index = RATR_INX_WIRELESS_B;
@@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct
 		break;
 	case WIRELESS_MODE_G:
 		ratr_index = RATR_INX_WIRELESS_GB;
+
 		if (rssi_level == 1)
 			ratr_bitmap &= 0x00000f00;
 		else if (rssi_level == 2)
@@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct
 	case WIRELESS_MODE_N_24G:
 	case WIRELESS_MODE_N_5G:
 		ratr_index = RATR_INX_WIRELESS_NGB;
-		if (mimops == 0) {
+
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
 			if (rssi_level == 1)
 				ratr_bitmap &= 0x00070000;
 			else if (rssi_level == 2)
@@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct
 				}
 			}
 		}
+
 		if ((curtxbw_40mhz && curshortgi_40mhz) ||
 		    (!curtxbw_40mhz && curshortgi_20mhz)) {
+
 			if (macid == 0)
 				shortgi = true;
 			else if (macid == 1)
@@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct
 		break;
 	default:
 		ratr_index = RATR_INX_WIRELESS_NGB;
+
 		if (rtlphy->rf_type == RF_1T2R)
 			ratr_bitmap &= 0x000ff0ff;
 		else
 			ratr_bitmap &= 0x0f0ff0ff;
 		break;
 	}
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
-		 ratr_bitmap);
-	*(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
-				      ratr_index << 28);
+	sta_entry->ratr_index = ratr_index;
+
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+		 "ratr_bitmap :%x\n", ratr_bitmap);
+	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
+				     (ratr_index << 28);
 	rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
 	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
 		 "Rate_index:%x, ratr_val:%x, %5phC\n",
 		 ratr_index, ratr_bitmap, rate_mask);
-	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+	memcpy(rtlpriv->rate_mask, rate_mask, 5);
+	/* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
+	 * "scheduled while atomic" if called directly */
+	schedule_work(&rtlpriv->works.fill_h2c_cmd);
+
+	if (macid != 0)
+		sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+				 struct ieee80211_sta *sta,
+				 u8 rssi_level)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->dm.useramask)
+		rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
+	else
+		rtl92cu_update_hal_rate_table(hw, sta);
 }
 
 void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +0 -4
@@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struc
 				   u32 add_msr, u32 rm_msr);
 void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
 void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
-				   struct ieee80211_sta *sta,
-				   u8 rssi_level);
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
 
 void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
 bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +17 -1
@@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw
 				macaddr = cam_const_broad;
 				entry_id = key_index;
 			} else {
+				if (mac->opmode == NL80211_IFTYPE_AP ||
+				    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+					entry_id = rtl_cam_get_free_entry(hw,
+								 p_macaddr);
+					if (entry_id >=  TOTAL_CAM_ENTRY) {
+						RT_TRACE(rtlpriv, COMP_SEC,
+							 DBG_EMERG,
+							 "Can not find free hw security cam entry\n");
+						return;
+					}
+				} else {
+					entry_id = CAM_PAIRWISE_KEY_POSITION;
+				}
+
 				key_index = PAIRWISE_KEYIDX;
-				entry_id = CAM_PAIRWISE_KEY_POSITION;
 				is_pairwise = true;
 			}
 		}
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 				 "delete one entry\n");
+			if (mac->opmode == NL80211_IFTYPE_AP ||
+			    mac->opmode == NL80211_IFTYPE_MESH_POINT)
+				rtl_cam_del_entry(hw, p_macaddr);
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +2 -2
@@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_
 	.update_interrupt_mask = rtl92cu_update_interrupt_mask,
 	.get_hw_reg = rtl92cu_get_hw_reg,
 	.set_hw_reg = rtl92cu_set_hw_reg,
-	.update_rate_tbl = rtl92cu_update_hal_rate_table,
-	.update_rate_mask = rtl92cu_update_hal_rate_mask,
+	.update_rate_tbl = rtl92cu_update_hal_rate_tbl,
 	.fill_tx_desc = rtl92cu_tx_fill_desc,
 	.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
 	.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
@@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_
 	.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
 	.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
 	.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
+	.fill_h2c_cmd = rtl92c_fill_h2c_cmd,
 };
 
 static struct rtl_mod_params rtl92cu_mod_params = {
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +3 -0
@@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(stru
 u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
 			    enum radio_path rfpath, u32 regaddr, u32 bitmask);
 void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+				 struct ieee80211_sta *sta,
+				 u8 rssi_level);
 
 #endif
drivers/net/wireless/rtlwifi/usb.c +13 -0
@@ -740,6 +740,7 @@ static void rtl_usb_stop(struct ieee8021
 
 	/* should after adapter start and interrupt enable. */
 	set_hal_stop(rtlhal);
+	cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
 	/* Enable software */
 	SET_USB_STOP(rtlusb);
 	rtl_usb_deinit(hw);
@@ -942,6 +943,16 @@ static bool rtl_usb_tx_chk_waitq_insert(
 	return false;
 }
 
+static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work)
+{
+	struct rtl_works *rtlworks =
+	    container_of(work, struct rtl_works, fill_h2c_cmd);
+	struct ieee80211_hw *hw = rtlworks->hw;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask);
+}
+
 static struct rtl_intf_ops rtl_usb_ops = {
 	.adapter_start = rtl_usb_start,
 	.adapter_stop = rtl_usb_stop,
@@ -973,6 +984,8 @@ int rtl_usb_probe(struct usb_interface *
 
 	/* this spin lock must be initialized early */
 	spin_lock_init(&rtlpriv->locks.usb_lock);
+	INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
+		  rtl_fill_h2c_cmd_work_callback);
 
 	rtlpriv->usb_data_index = 0;
 	init_completion(&rtlpriv->firmware_loading_complete);
drivers/net/wireless/rtlwifi/wifi.h +4 -0
@@ -1572,6 +1572,8 @@ struct rtl_hal_ops {
 	void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
 					     bool mstate);
 	void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
+	void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
+			      u32 cmd_len, u8 *p_cmdbuffer);
 };
 
 struct rtl_intf_ops {
@@ -1698,6 +1700,7 @@ struct rtl_works {
 	struct delayed_work ps_rfon_wq;
 
 	struct work_struct lps_leave_work;
+	struct work_struct fill_h2c_cmd;
 };
 
 struct rtl_debug {
@@ -1866,6 +1869,7 @@ struct rtl_priv {
 			bool bt_operation_on;
 		};
 	};
+	u8 rate_mask[5];
 
 	/*This must be the last item so
 	   that it points to the data allocated
author maintainer
#10 lore raw

PATCH 10/95 brcmfmac: Turn off ARP offloading when configured for AP.

In reply to Greg Kroah-Hartman

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

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

From: Hante Meuleman <[email protected]>

commit b3657453f16a7b84eab9b93bb9a9a2901ffc70af upstream.

ARP offloading should only be used in STA or P2P client mode. It is currently configured once at init. When being configured for AP ARP offloading should be turned off and when AP mode is left it can be turned back on.

---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c  |   18 --------
 drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h  |    6 ++
 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c |   40 +++++++++++++++++-
 3 files changed, 45 insertions(+), 19 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +0 -18
@@ -26,7 +26,6 @@
 #include "fwil.h"
 
 #define PKTFILTER_BUF_SIZE		128
-#define BRCMF_ARPOL_MODE		0xb	/* agent|snoop|peer_autoreply */
 #define BRCMF_DEFAULT_BCN_TIMEOUT	3
 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME	40
 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME	40
@@ -337,23 +336,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
 		goto done;
 	}
 
-	/* Try to set and enable ARP offload feature, this may fail */
-	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
-	if (err) {
-		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
-			  BRCMF_ARPOL_MODE, err);
-		err = 0;
-	} else {
-		err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
-		if (err) {
-			brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
-				  err);
-			err = 0;
-		} else
-			brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
-				  BRCMF_ARPOL_MODE);
-	}
-
 	/* Setup packet filter */
 	brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
 	brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +6 -0
@@ -23,6 +23,12 @@
 
 #define BRCMF_FIL_ACTION_FRAME_SIZE	1800
 
+/* ARP Offload feature flags for arp_ol iovar */
+#define BRCMF_ARP_OL_AGENT		0x00000001
+#define BRCMF_ARP_OL_SNOOP		0x00000002
+#define BRCMF_ARP_OL_HOST_AUTO_REPLY	0x00000004
+#define BRCMF_ARP_OL_PEER_AUTO_REPLY	0x00000008
+
 
 enum brcmf_fil_p2p_if_types {
 	BRCMF_FIL_P2P_IF_CLIENT,
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +39 -1
@@ -505,6 +505,38 @@ send_key_to_dongle(struct net_device *nd
 	return err;
 }
 
+static s32
+brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
+{
+	s32 err;
+	u32 mode;
+
+	if (enable)
+		mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
+	else
+		mode = 0;
+
+	/* Try to set and enable ARP offload feature, this may fail, then it  */
+	/* is simply not supported and err 0 will be returned                 */
+	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
+	if (err) {
+		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+			  mode, err);
+		err = 0;
+	} else {
+		err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
+		if (err) {
+			brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
+				  enable, err);
+			err = 0;
+		} else
+			brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
+				  enable, mode);
+	}
+
+	return err;
+}
+
 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
 						     const char *name,
 						     enum nl80211_iftype type,
@@ -3709,6 +3741,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
 	}
 
 	brcmf_set_mpc(ndev, 0);
+	brcmf_configure_arp_offload(ifp, false);
 
 	/* find the RSN_IE */
 	rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3815,8 +3848,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
 	set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
 exit:
-	if (err)
+	if (err) {
 		brcmf_set_mpc(ndev, 1);
+		brcmf_configure_arp_offload(ifp, true);
+	}
 	return err;
 }
 
@@ -3857,6 +3892,7 @@ static int brcmf_cfg80211_stop_ap(struct
 			brcmf_err("bss_enable config failed %d\n", err);
 	}
 	brcmf_set_mpc(ndev, 1);
+	brcmf_configure_arp_offload(ifp, true);
 	set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
 	clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
@@ -4995,6 +5031,8 @@ static s32 brcmf_config_dongle(struct br
 	if (err)
 		goto default_conf_out;
 
+	brcmf_configure_arp_offload(ifp, true);
+
 	cfg->dongle_up = true;
 default_conf_out:
 
author maintainer
#11 lore raw

PATCH 11/95 parisc: add kernel stack overflow check

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 9372450cc22d185f708e5cc3557cf991be4b7dc5 upstream.

Add the CONFIG_DEBUG_STACKOVERFLOW config option to enable checks to detect kernel stack overflows.

Stack overflows can not be detected reliable since we do not want to introduce too much overhead.

Instead, during irq processing in do_cpu_irq_mask() we check kernel stack usage of the interrupted kernel process. Kernel threads can be easily detected by checking the value of space register 7 (sr7) which is zero when running inside the kernel.

Since THREAD_SIZE is 16k and PAGE_SIZE is 4k, reduce the alignment of the init thread to the lower value (PAGE_SIZE) in the kernel vmlinux.ld.S linker script.

---
 arch/parisc/Kconfig.debug             |   11 +++++++++++
 arch/parisc/include/asm/thread_info.h |    2 +-
 arch/parisc/kernel/irq.c              |   31 +++++++++++++++++++++++++++++--
 arch/parisc/kernel/vmlinux.lds.S      |    2 +-
 4 files changed, 42 insertions(+), 4 deletions(-)
arch/parisc/Kconfig.debug +11 -0
@@ -27,3 +27,14 @@ config DEBUG_STRICT_USER_COPY_CHECKS
 	  If unsure, or if you run an older (pre 4.4) gcc, say N.
 
 endmenu
+
+config DEBUG_STACKOVERFLOW
+	bool "Check for stack overflows"
+	default y
+	depends on DEBUG_KERNEL
+	---help---
+	  Say Y here if you want to check the overflows of kernel, IRQ
+	  and exception stacks. This option will cause messages of the
+	  stacks in detail when free stack space drops below a certain
+	  limit.
+	  If in doubt, say "N".
arch/parisc/include/asm/thread_info.h +1 -1
@@ -40,7 +40,7 @@ struct thread_info {
 
 /* thread information allocation */
 
-#define THREAD_SIZE_ORDER            2
+#define THREAD_SIZE_ORDER	2 /* PA-RISC requires at least 16k stack */
 /* Be sure to hunt all references to this down when you change the size of
  * the kernel stack */
 #define THREAD_SIZE             (PAGE_SIZE << THREAD_SIZE_ORDER)
arch/parisc/kernel/irq.c +29 -2
@@ -330,6 +330,34 @@ static inline int eirr_to_irq(unsigned l
 	return (BITS_PER_LONG - bit) + TIMER_IRQ;
 }
 
+int sysctl_panic_on_stackoverflow = 1;
+
+static inline void stack_overflow_check(struct pt_regs *regs)
+{
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	#define STACK_MARGIN	(256*6)
+
+	/* Our stack starts directly behind the thread_info struct. */
+	unsigned long stack_start = (unsigned long) current_thread_info();
+	unsigned long sp = regs->gr[30];
+
+	/* if sr7 != 0, we interrupted a userspace process which we do not want
+	 * to check for stack overflow. We will only check the kernel stack. */
+	if (regs->sr[7])
+		return;
+
+	if (likely((sp - stack_start) < (THREAD_SIZE - STACK_MARGIN)))
+		return;
+
+	pr_emerg("stackcheck: %s will most likely overflow kernel stack "
+		 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
+		current->comm, sp, stack_start, stack_start + THREAD_SIZE);
+
+	if (sysctl_panic_on_stackoverflow)
+		panic("low stack detected by irq handler - check messages\n");
+#endif
+}
+
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
@@ -364,6 +392,7 @@ void do_cpu_irq_mask(struct pt_regs *reg
 		goto set_out;
 	}
 #endif
+	stack_overflow_check(regs);
 	generic_handle_irq(irq);
 
  out:
@@ -420,6 +449,4 @@ void __init init_IRQ(void)
 	cpu_eiem = EIEM_MASK(TIMER_IRQ);
 #endif
         set_eiem(cpu_eiem);	/* EIEM : enable all external intr */
-
 }
-
arch/parisc/kernel/vmlinux.lds.S +1 -1
@@ -95,7 +95,7 @@ SECTIONS
 	NOTES
 
 	/* Data */
-	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, PAGE_SIZE)
 
 	/* PA-RISC locks requires 16-byte alignment */
 	. = ALIGN(16);
author maintainer
#12 lore raw

PATCH 12/95 parisc: implement irq stacks

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 200c880420a2c02a0899120ce52d801fad705b90 upstream.

Default kernel stack size on parisc is 16k. During tests we found that the kernel stack can easily grow beyond 13k, which leaves 3k left for irq processing.

This patch adds the possibility to activate an additional stack of 16k per CPU which is being used during irq processing. This implementation does not yet uses this irq stack for the irq bh handler.

The assembler code for call_on_stack was heavily cleaned up by John David Anglin.

---
 arch/parisc/Kconfig                 |    8 +++++++
 arch/parisc/include/asm/processor.h |   19 ++++++++++++++--
 arch/parisc/kernel/entry.S          |   41 ++++++++++++++++++++++++++++++++++++
 arch/parisc/kernel/irq.c            |   28 ++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 2 deletions(-)
arch/parisc/Kconfig +8 -0
@@ -241,6 +241,14 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
+config IRQSTACKS
+	bool "Use separate kernel stacks when processing interrupts"
+	default n
+	help
+	  If you say Y here the kernel will use separate kernel stacks
+	  for handling hard and soft interrupts.  This can help avoid
+	  overflowing the process kernel stacks.
+
 config HOTPLUG_CPU
 	bool
 	default y if SMP
arch/parisc/include/asm/processor.h +17 -2
@@ -20,8 +20,6 @@
 
 #endif /* __ASSEMBLY__ */
 
-#define KERNEL_STACK_SIZE 	(4*PAGE_SIZE)
-
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
@@ -61,6 +59,23 @@
 #ifndef __ASSEMBLY__
 
 /*
+ * IRQ STACK - used for irq handler
+ */
+#ifdef __KERNEL__
+
+#define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
+
+union irq_stack_union {
+	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+};
+
+DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
+
+void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
+
+#endif /* __KERNEL__ */
+
+/*
  * Data detected about CPUs at boot time which is the same for all CPU's.
  * HP boxes are SMP - ie identical processors.
  *
arch/parisc/kernel/entry.S +41 -0

47 lines not on this page · raw message

arch/parisc/kernel/irq.c +28 -0
@@ -358,6 +358,29 @@ static inline void stack_overflow_check(
 #endif
 }
 
+#ifdef CONFIG_IRQSTACKS
+DEFINE_PER_CPU(union irq_stack_union, irq_stack_union);
+
+static void execute_on_irq_stack(void *func, unsigned long param1)
+{
+	unsigned long *irq_stack_start;
+	unsigned long irq_stack;
+	int cpu = smp_processor_id();
+
+	irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0];
+	irq_stack = (unsigned long) irq_stack_start;
+	irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */
+
+	BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */
+	*irq_stack_start = 1;
+
+	/* This is where we switch to the IRQ stack. */
+	call_on_stack(param1, func, irq_stack);
+
+	*irq_stack_start = 0;
+}
+#endif /* CONFIG_IRQSTACKS */
+
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
@@ -393,7 +416,12 @@ void do_cpu_irq_mask(struct pt_regs *reg
 	}
 #endif
 	stack_overflow_check(regs);
+
+#ifdef CONFIG_IRQSTACKS
+	execute_on_irq_stack(&generic_handle_irq, irq);
+#else
 	generic_handle_irq(irq);
+#endif /* CONFIG_IRQSTACKS */
 
  out:
 	irq_exit();
author maintainer
#13 lore raw

PATCH 13/95 parisc: more irq statistics in /proc/interrupts

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit cd85d5514d5c4d7e78abac923fc032457d0c5091 upstream.

Add framework and initial values for more fine grained statistics in /proc/interrupts.

---
 arch/parisc/include/asm/hardirq.h   |   36 ++++++++++++++++++++++++++-
 arch/parisc/include/asm/processor.h |    1 
 arch/parisc/kernel/irq.c            |   48 +++++++++++++++++++++++++++++++++++-
 arch/parisc/kernel/smp.c            |    3 +-
 arch/parisc/mm/init.c               |    2 +
 5 files changed, 86 insertions(+), 4 deletions(-)
arch/parisc/include/asm/hardirq.h +35 -1
@@ -1,11 +1,45 @@
 /* hardirq.h: PA-RISC hard IRQ support.
  *
  * Copyright (C) 2001 Matthew Wilcox <[email protected]>
+ * Copyright (C) 2013 Helge Deller <[email protected]>
  */
 
 #ifndef _PARISC_HARDIRQ_H
 #define _PARISC_HARDIRQ_H
 
-#include <asm-generic/hardirq.h>
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	unsigned int kernel_stack_usage;
+#endif
+#ifdef CONFIG_SMP
+	unsigned int irq_resched_count;
+	unsigned int irq_call_count;
+	/*
+	 * irq_tlb_count is double-counted in irq_call_count, so it must be
+	 * subtracted from irq_call_count when displaying irq_call_count
+	 */
+	unsigned int irq_tlb_count;
+#endif
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+
+#define __ARCH_IRQ_STAT
+#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
+#define inc_irq_stat(member)	this_cpu_inc(irq_stat.member)
+#define local_softirq_pending()	this_cpu_read(irq_stat.__softirq_pending)
+
+#define __ARCH_SET_SOFTIRQ_PENDING
+
+#define set_softirq_pending(x)	\
+		this_cpu_write(irq_stat.__softirq_pending, (x))
+#define or_softirq_pending(x)	this_cpu_or(irq_stat.__softirq_pending, (x))
+
+#define ack_bad_irq(irq) WARN(1, "unexpected IRQ trap at vector %02x\n", irq)
 
 #endif /* _PARISC_HARDIRQ_H */
arch/parisc/include/asm/processor.h +0 -1
@@ -112,7 +112,6 @@ struct cpuinfo_parisc {
 	unsigned long txn_addr;     /* MMIO addr of EIR or id_eid */
 #ifdef CONFIG_SMP
 	unsigned long pending_ipi;  /* bitmap of type ipi_message_type */
-	unsigned long ipi_count;    /* number ipi Interrupts */
 #endif
 	unsigned long bh_count;     /* number of times bh was invoked */
 	unsigned long prof_counter; /* per CPU profiling support */
arch/parisc/kernel/irq.c +47 -1

72 lines not on this page · raw message

arch/parisc/kernel/smp.c +2 -1
@@ -127,7 +127,7 @@ ipi_interrupt(int irq, void *dev_id)
 	unsigned long flags;
 
 	/* Count this now; we may make a call that never returns. */
-	p->ipi_count++;
+	inc_irq_stat(irq_call_count);
 
 	mb();	/* Order interrupt and bit testing. */
 
@@ -155,6 +155,7 @@ ipi_interrupt(int irq, void *dev_id)
 				
 			case IPI_RESCHEDULE:
 				smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
+				inc_irq_stat(irq_resched_count);
 				scheduler_ipi();
 				break;
 
arch/parisc/mm/init.c +2 -0
@@ -1077,6 +1077,7 @@ void flush_tlb_all(void)
 {
 	int do_recycle;
 
+	inc_irq_stat(irq_tlb_count);
 	do_recycle = 0;
 	spin_lock(&sid_lock);
 	if (dirty_space_ids > RECYCLE_THRESHOLD) {
@@ -1097,6 +1098,7 @@ void flush_tlb_all(void)
 #else
 void flush_tlb_all(void)
 {
+	inc_irq_stat(irq_tlb_count);
 	spin_lock(&sid_lock);
 	flush_tlb_all_local(NULL);
 	recycle_sids();
author maintainer
#14 lore raw

PATCH 14/95 parisc: tlb flush counting fix for SMP and UP

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 0fc537d1d655cdae69b489dbba46ad617cfc1373 upstream.

Fix up build error on UP and show correctly number of function call (ipi) irqs.

---
 arch/parisc/include/asm/hardirq.h  |    6 +-----
 arch/parisc/include/asm/tlbflush.h |    2 ++
 arch/parisc/kernel/irq.c           |    5 ++---
 arch/parisc/kernel/smp.c           |   11 -----------
 4 files changed, 5 insertions(+), 19 deletions(-)
arch/parisc/include/asm/hardirq.h +1 -5
@@ -19,12 +19,8 @@ typedef struct {
 #ifdef CONFIG_SMP
 	unsigned int irq_resched_count;
 	unsigned int irq_call_count;
-	/*
-	 * irq_tlb_count is double-counted in irq_call_count, so it must be
-	 * subtracted from irq_call_count when displaying irq_call_count
-	 */
-	unsigned int irq_tlb_count;
 #endif
+	unsigned int irq_tlb_count;
 } ____cacheline_aligned irq_cpustat_t;
 
 DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
arch/parisc/include/asm/tlbflush.h +2 -0
@@ -22,6 +22,8 @@ extern spinlock_t pa_tlb_lock;
 extern void flush_tlb_all(void);
 extern void flush_tlb_all_local(void *);
 
+#define smp_flush_tlb_all()	flush_tlb_all()
+
 /*
  * flush_tlb_mm()
  *
arch/parisc/kernel/irq.c +2 -3
@@ -175,14 +175,13 @@ int arch_show_interrupts(struct seq_file
 	seq_printf(p, "  Rescheduling interrupts\n");
 	seq_printf(p, "%*s: ", prec, "CAL");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
-					irq_stats(j)->irq_tlb_count);
+		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
 	seq_printf(p, "  Function call interrupts\n");
+#endif
 	seq_printf(p, "%*s: ", prec, "TLB");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
 	seq_printf(p, "  TLB shootdowns\n");
-#endif
 	return 0;
 }
 
arch/parisc/kernel/smp.c +0 -11
@@ -264,17 +264,6 @@ void arch_send_call_function_single_ipi(
 }
 
 /*
- * Flush all other CPU's tlb and then mine.  Do this with on_each_cpu()
- * as we want to ensure all TLB's flushed before proceeding.
- */
-
-void
-smp_flush_tlb_all(void)
-{
-	on_each_cpu(flush_tlb_all_local, NULL, 1);
-}
-
-/*
  * Called by secondaries to update state and initialize CPU registers.
  */
 static void __init
author maintainer
#15 lore raw

PATCH 15/95 parisc: remove the second argument of kmap_atomic()

In reply to Greg Kroah-Hartman

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

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

From: Zhao Hongjiang <[email protected]>

commit 1ab4ce762370b82870834899e49c08129d7ae271 upstream.

kmap_atomic() requires only one argument now.

---
 arch/parisc/kernel/cache.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/parisc/kernel/cache.c +3 -3
@@ -606,7 +606,7 @@ void clear_user_highpage(struct page *pa
 	/* Clear using TMPALIAS region.  The page doesn't need to
 	   be flushed but the kernel mapping needs to be purged.  */
 
-	vto = kmap_atomic(page, KM_USER0);
+	vto = kmap_atomic(page);
 
 	/* The PA-RISC 2.0 Architecture book states on page F-6:
 	   "Before a write-capable translation is enabled, *all*
@@ -641,8 +641,8 @@ void copy_user_highpage(struct page *to,
 	   the `to' page must be flushed in copy_user_page_asm since
 	   it can be used to bring in executable code.  */
 
-	vfrom = kmap_atomic(from, KM_USER0);
-	vto = kmap_atomic(to, KM_USER1);
+	vfrom = kmap_atomic(from);
+	vto = kmap_atomic(to);
 
 	purge_kernel_dcache_page_asm((unsigned long)vto);
 	purge_tlb_start(flags);
author maintainer
#16 lore raw

PATCH 16/95 parisc: implement irq stacks - part 2 (v2)

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 416821d3d68164909b2cbcf398e4ba0797f5f8a2 upstream.

This patch fixes few build issues which were introduced with the last irq stack patch, e.g. the combination of stack overflow check and irq stack.

Furthermore we now do proper locking and change the irq bh handler to use the irq stack as well.

In /proc/interrupts one now can monitor how huge the irq stack has grown and how often it was preferred over the kernel stack.

IRQ stacks are now enabled by default just to make sure that we not overflow the kernel stack by accident.

---
 arch/parisc/Kconfig                 |    2 
 arch/parisc/include/asm/hardirq.h   |    9 +++
 arch/parisc/include/asm/processor.h |    3 +
 arch/parisc/kernel/irq.c            |  103 ++++++++++++++++++++++++++++++------
 arch/parisc/mm/init.c               |    4 -
 5 files changed, 103 insertions(+), 18 deletions(-)
arch/parisc/Kconfig +1 -1
@@ -243,7 +243,7 @@ config SMP
 
 config IRQSTACKS
 	bool "Use separate kernel stacks when processing interrupts"
-	default n
+	default y
 	help
 	  If you say Y here the kernel will use separate kernel stacks
 	  for handling hard and soft interrupts.  This can help avoid
arch/parisc/include/asm/hardirq.h +9 -0
@@ -11,10 +11,18 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+#ifdef CONFIG_IRQSTACKS
+#define __ARCH_HAS_DO_SOFTIRQ
+#endif
+
 typedef struct {
 	unsigned int __softirq_pending;
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	unsigned int kernel_stack_usage;
+#ifdef CONFIG_IRQSTACKS
+	unsigned int irq_stack_usage;
+	unsigned int irq_stack_counter;
+#endif
 #endif
 #ifdef CONFIG_SMP
 	unsigned int irq_resched_count;
@@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpust
 #define __ARCH_IRQ_STAT
 #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
 #define inc_irq_stat(member)	this_cpu_inc(irq_stat.member)
+#define __inc_irq_stat(member)	__this_cpu_inc(irq_stat.member)
 #define local_softirq_pending()	this_cpu_read(irq_stat.__softirq_pending)
 
 #define __ARCH_SET_SOFTIRQ_PENDING
arch/parisc/include/asm/processor.h +3 -0
@@ -63,10 +63,13 @@
  */
 #ifdef __KERNEL__
 
+#include <linux/spinlock_types.h>
+
 #define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
 
 union irq_stack_union {
 	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+	raw_spinlock_t lock;
 };
 
 DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
arch/parisc/kernel/irq.c +88 -15

154 lines not on this page · raw message

arch/parisc/mm/init.c +2 -2
@@ -1077,7 +1077,7 @@ void flush_tlb_all(void)
 {
 	int do_recycle;
 
-	inc_irq_stat(irq_tlb_count);
+	__inc_irq_stat(irq_tlb_count);
 	do_recycle = 0;
 	spin_lock(&sid_lock);
 	if (dirty_space_ids > RECYCLE_THRESHOLD) {
@@ -1098,7 +1098,7 @@ void flush_tlb_all(void)
 #else
 void flush_tlb_all(void)
 {
-	inc_irq_stat(irq_tlb_count);
+	__inc_irq_stat(irq_tlb_count);
 	spin_lock(&sid_lock);
 	flush_tlb_all_local(NULL);
 	recycle_sids();
author maintainer
#17 lore raw

PATCH 17/95 parisc: add rp5470 entry to machine database

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 949451b9b19da5e998778eb78929aafc73b5c227 upstream.

---
 arch/parisc/kernel/hardware.c |    1 +
 1 file changed, 1 insertion(+)
arch/parisc/kernel/hardware.c +1 -0
@@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_li
 	{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
 	{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
 	{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
+	{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
 	{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
 	{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
 	{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
author maintainer
#18 lore raw

PATCH 18/95 parisc: show number of FPE and unaligned access handler calls in /proc/interrupts

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit d0c3be806a3fe7f4abdb0f7e7287addb55e73f35 upstream.

Show number of floating point assistant and unaligned access fixup handler in /proc/interrupts file.

---
 arch/parisc/include/asm/hardirq.h |    2 ++
 arch/parisc/kernel/irq.c          |    8 ++++++++
 arch/parisc/kernel/traps.c        |    1 +
 arch/parisc/kernel/unaligned.c    |    3 +++
 4 files changed, 14 insertions(+)
arch/parisc/include/asm/hardirq.h +2 -0
@@ -28,6 +28,8 @@ typedef struct {
 	unsigned int irq_resched_count;
 	unsigned int irq_call_count;
 #endif
+	unsigned int irq_unaligned_count;
+	unsigned int irq_fpassist_count;
 	unsigned int irq_tlb_count;
 } ____cacheline_aligned irq_cpustat_t;
 
arch/parisc/kernel/irq.c +8 -0
@@ -188,6 +188,14 @@ int arch_show_interrupts(struct seq_file
 		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
 	seq_puts(p, "  Function call interrupts\n");
 #endif
+	seq_printf(p, "%*s: ", prec, "UAH");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
+	seq_puts(p, "  Unaligned access handler traps\n");
+	seq_printf(p, "%*s: ", prec, "FPA");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
+	seq_puts(p, "  Floating point assist traps\n");
 	seq_printf(p, "%*s: ", prec, "TLB");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
arch/parisc/kernel/traps.c +1 -0
@@ -652,6 +652,7 @@ void notrace handle_interruption(int cod
 	case 14:
 		/* Assist Exception Trap, i.e. floating point exception. */
 		die_if_kernel("Floating point exception", regs, 0); /* quiet */
+		__inc_irq_stat(irq_fpassist_count);
 		handle_fpe(regs);
 		return;
 		
arch/parisc/kernel/unaligned.c +3 -0
@@ -27,6 +27,7 @@
 #include <linux/signal.h>
 #include <linux/ratelimit.h>
 #include <asm/uaccess.h>
+#include <asm/hardirq.h>
 
 /* #define DEBUG_UNALIGNED 1 */
 
@@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *re
 	struct siginfo si;
 	register int flop=0;	/* true if this is a flop */
 
+	__inc_irq_stat(irq_unaligned_count);
+
 	/* log a message with pacing */
 	if (user_mode(regs)) {
 		if (current->thread.flags & PARISC_UAC_SIGBUS) {
author maintainer
#19 lore raw

PATCH 19/95 parisc: make interrupt and interruption stack allocation reentrant

In reply to Greg Kroah-Hartman

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

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

From: John David Anglin <[email protected]>

commit b63a2bbc0b9b106a93e11952ab057e2408f2eb02 upstream.

The get_stack_use_cr30 and get_stack_use_r30 macros allocate a stack frame for external interrupts and interruptions requiring a stack frame. They are currently not reentrant in that they save register context before the stack is set or adjusted.

I have observed a number of system crashes where there was clear evidence of stack corruption during interrupt processing, and as a result register corruption. Some interruptions can still occur during interruption processing, however external interrupts are disabled and data TLB misses don't occur for absolute accesses. So, it's not entirely clear what triggers this issue. Also, if an interruption occurs when Q=0, it is generally not possible to recover as the shadowed registers are not copied.

The attached patch reworks the get_stack_use_cr30 and get_stack_use_r30 macros to allocate stack before doing register saves. The new code is a couple of instructions shorter than the old implementation. Thus, it's an improvement even if it doesn't fully resolve the stack corruption issue. Based on limited testing, it improves SMP system stability.

---
 arch/parisc/include/asm/assembly.h |    1 -
 arch/parisc/kernel/entry.S         |   19 ++++++++++---------
 2 files changed, 10 insertions(+), 10 deletions(-)
arch/parisc/include/asm/assembly.h +0 -1
@@ -438,7 +438,6 @@
 	SAVE_SP  (%sr4, PT_SR4 (\regs))
 	SAVE_SP  (%sr5, PT_SR5 (\regs))
 	SAVE_SP  (%sr6, PT_SR6 (\regs))
-	SAVE_SP  (%sr7, PT_SR7 (\regs))
 
 	SAVE_CR  (%cr17, PT_IASQ0(\regs))
 	mtctl	 %r0,	%cr17
arch/parisc/kernel/entry.S +10 -9
@@ -65,15 +65,11 @@
 	rsm	PSW_SM_I, %r0	/* barrier for "Relied upon Translation */
 	mtsp	%r0, %sr4
 	mtsp	%r0, %sr5
-	mfsp	%sr7, %r1
-	or,=    %r0,%r1,%r0	/* Only save sr7 in sr3 if sr7 != 0 */
-	mtsp	%r1, %sr3
+	mtsp	%r0, %sr6
 	tovirt_r1 %r29
 	load32	KERNEL_PSW, %r1
 
 	rsm     PSW_SM_QUIET,%r0	/* second "heavy weight" ctl op */
-	mtsp	%r0, %sr6
-	mtsp	%r0, %sr7
 	mtctl	%r0, %cr17	/* Clear IIASQ tail */
 	mtctl	%r0, %cr17	/* Clear IIASQ head */
 	mtctl	%r1, %ipsw
@@ -119,17 +115,20 @@
 
 	/* we save the registers in the task struct */
 
+	copy	%r30, %r17
 	mfctl   %cr30, %r1
+	ldo	THREAD_SZ_ALGN(%r1), %r30
+	mtsp	%r0,%sr7
+	mtsp	%r16,%sr3
 	tophys  %r1,%r9
 	LDREG	TI_TASK(%r9), %r1	/* thread_info -> task_struct */
 	tophys  %r1,%r9
 	ldo     TASK_REGS(%r9),%r9
-	STREG   %r30, PT_GR30(%r9)
+	STREG   %r17,PT_GR30(%r9)
 	STREG   %r29,PT_GR29(%r9)
 	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
 	copy    %r9,%r29
-	mfctl   %cr30, %r1
-	ldo	THREAD_SZ_ALGN(%r1), %r30
 	.endm
 
 	.macro  get_stack_use_r30
@@ -137,10 +136,12 @@
 	/* we put a struct pt_regs on the stack and save the registers there */
 
 	tophys  %r30,%r9
-	STREG   %r30,PT_GR30(%r9)
+	copy	%r30,%r1
 	ldo	PT_SZ_ALGN(%r30),%r30
+	STREG   %r1,PT_GR30(%r9)
 	STREG   %r29,PT_GR29(%r9)
 	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
 	copy    %r9,%r29
 	.endm
 
author maintainer
#20 lore raw

PATCH 20/95 parisc: fix irq stack on UP and SMP

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit d96b51ec14650b490ab98e738bcc02309396e5bc upstream.

The logic to detect if the irq stack was already in use with raw_spin_trylock() is wrong, because it will generate a "trylock failure on UP" error message with CONFIG_SMP=n and CONFIG_DEBUG_SPINLOCK=y.

arch_spin_trylock() can't be used either since in the CONFIG_SMP=n case no atomic protection is given and we are reentrant here. A mutex didn't worked either and brings more overhead by turning off interrupts.

So, let's use the fastest path for parisc which is the ldcw instruction.

Counting how often the irq stack was used is pretty useless, so just drop this piece of code.

---
 arch/parisc/include/asm/hardirq.h   |    5 ----
 arch/parisc/include/asm/processor.h |   21 ------------------
 arch/parisc/kernel/irq.c            |   41 ++++++++++++++++++++++--------------
 3 files changed, 26 insertions(+), 41 deletions(-)
arch/parisc/include/asm/hardirq.h +0 -5
@@ -17,13 +17,8 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
 	unsigned int kernel_stack_usage;
-#ifdef CONFIG_IRQSTACKS
 	unsigned int irq_stack_usage;
-	unsigned int irq_stack_counter;
-#endif
-#endif
 #ifdef CONFIG_SMP
 	unsigned int irq_resched_count;
 	unsigned int irq_call_count;
arch/parisc/include/asm/processor.h +0 -21
@@ -17,7 +17,6 @@
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/percpu.h>
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -59,26 +58,6 @@
 #ifndef __ASSEMBLY__
 
 /*
- * IRQ STACK - used for irq handler
- */
-#ifdef __KERNEL__
-
-#include <linux/spinlock_types.h>
-
-#define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
-
-union irq_stack_union {
-	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
-	raw_spinlock_t lock;
-};
-
-DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
-
-void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
-
-#endif /* __KERNEL__ */
-
-/*
  * Data detected about CPUs at boot time which is the same for all CPU's.
  * HP boxes are SMP - ie identical processors.
  *
arch/parisc/kernel/irq.c +26 -15

90 lines not on this page · raw message

author maintainer
#21 lore raw

PATCH 21/95 parisc: memory overflow, name length is too short for using

In reply to Greg Kroah-Hartman

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

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

From: Chen Gang <[email protected]>

commit 3f108de96ba449a8df3d7e3c053bf890fee2cb95 upstream.

'path.bc[i]' can be asigned by PCI_SLOT() which can '> 10', so sizeof(6
* "%u:" + "%u" + '\0') may be 21.

Since 'name' length is 20, it may be memory overflow.

And 'path.bc[i]' is 'unsigned char' for printing, we can be sure the max length of 'name' must be less than 28.

So simplify thinking, we can use 28 instead of 20 directly, and do not think of whether 'patchc.bc[i]' can '> 100'.

---
 arch/parisc/kernel/drivers.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/kernel/drivers.c +1 -1
@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath);
 static void setup_bus_id(struct parisc_device *padev)
 {
 	struct hardware_path path;
-	char name[20];
+	char name[28];
 	char *output = name;
 	int i;
 
author maintainer
#22 lore raw

PATCH 22/95 parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit ae249b5fa27f9fba25aa59664d4338efc2dd2394 upstream.

With CONFIG_DISCONTIGMEM=y and multiple physical memory areas, cat /proc/kpageflags triggers this kernel bug:

kernel BUG at arch/parisc/include/asm/mmzone.h:50!

CPU: 2 PID: 7848 Comm: cat Tainted: G      D W 3.10.0-rc3-64bit #44
 IAOQ[0]: kpageflags_read0x128/0x238
 IAOQ[1]: kpageflags_read0x12c/0x238
 RP(r2): proc_reg_read0xbc/0x130
Backtrace:
 [<00000000402ca2d4>] proc_reg_read0xbc/0x130
 [<0000000040235bcc>] vfs_read0xc4/0x1d0
 [<0000000040235f0c>] SyS_read0x94/0xf0
 [<0000000040105fc0>] syscall_exit0x0/0x14

kpageflags_read() walks through the whole memory, even if some memory areas are physically not available. So, we should better not BUG on an unavailable pfn in pfn_to_nid() but just return the expected value -1 or 0.

---
 arch/parisc/include/asm/mmzone.h |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
arch/parisc/include/asm/mmzone.h +1 -4
@@ -39,17 +39,14 @@ extern unsigned char pfnnid_map[PFNNID_M
 static inline int pfn_to_nid(unsigned long pfn)
 {
 	unsigned int i;
-	unsigned char r;
 
 	if (unlikely(pfn_is_io(pfn)))
 		return 0;
 
 	i = pfn >> PFNNID_SHIFT;
 	BUG_ON(i >= ARRAY_SIZE(pfnnid_map));
-	r = pfnnid_map[i];
-	BUG_ON(r == 0xff);
 
-	return (int)r;
+	return (int)pfnnid_map[i];
 }
 
 static inline int pfn_valid(int pfn)
author maintainer
#23 lore raw

PATCH 23/95 parisc: rename "CONFIG_PA7100" to "CONFIG_PA7000"

In reply to Greg Kroah-Hartman

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

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

From: Paul Bolle <[email protected]>

commit 766039022a480ede847659daaa78772bdcc598ae upstream.

There's a Makefile line setting cflags for CONFIG_PA7100. But that Kconfig macro doesn't exist. There is a Kconfig symbol PA7000, which covers both PA7000 and PA7100 processors. So let's use the corresponding Kconfig macro.

---
 arch/parisc/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/Makefile +1 -1
@@ -66,7 +66,7 @@ KBUILD_CFLAGS_KERNEL += -mlong-calls
 endif
 
 # select which processor to optimise for
-cflags-$(CONFIG_PA7100)		+= -march=1.1 -mschedule=7100
+cflags-$(CONFIG_PA7000)		+= -march=1.1 -mschedule=7100
 cflags-$(CONFIG_PA7200)		+= -march=1.1 -mschedule=7200
 cflags-$(CONFIG_PA7100LC)	+= -march=1.1 -mschedule=7100LC
 cflags-$(CONFIG_PA7300LC)	+= -march=1.1 -mschedule=7300
author maintainer
#24 lore raw

PATCH 24/95 parisc: kernel: using strlcpy() instead of strcpy()

In reply to Greg Kroah-Hartman

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

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

From: Chen Gang <[email protected]>

commit ea99b1adf22abd62bdcf14b1c9a0a4d3664eefd8 upstream.

'boot_args' is an input args, and 'boot_command_line' has a fix length. So use strlcpy() instead of strcpy() to avoid memory overflow.

---
 arch/parisc/kernel/setup.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/parisc/kernel/setup.c +2 -1
@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline
 		/* called from hpux boot loader */
 		boot_command_line[0] = '\0';
 	} else {
-		strcpy(boot_command_line, (char *)__va(boot_args[1]));
+		strlcpy(boot_command_line, (char *)__va(boot_args[1]),
+			COMMAND_LINE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 		if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
author maintainer
#25 lore raw

PATCH 25/95 parisc: parport0: fix this legacy no-device port driver!

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 4edb38695d9a3cd62739f8595e21f36f0aabf4c2 upstream.

Fix the above kernel error from parport_announce_port() on 32bit GSC machines (e.g. B160L). The parport driver requires now a pointer to the device struct.

---
 drivers/parport/parport_gsc.c |    6 +++---
 drivers/parport/parport_gsc.h |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/parport/parport_gsc.c +3 -3
@@ -234,7 +234,7 @@ static int parport_PS2_supported(struct
 
 struct parport *parport_gsc_probe_port(unsigned long base,
 				       unsigned long base_hi, int irq,
-				       int dma, struct pci_dev *dev)
+				       int dma, struct parisc_device *padev)
 {
 	struct parport_gsc_private *priv;
 	struct parport_operations *ops;
@@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(u
 	priv->ctr_writable = 0xff;
 	priv->dma_buf = 0;
 	priv->dma_handle = 0;
-	priv->dev = dev;
 	p->base = base;
 	p->base_hi = base_hi;
 	p->irq = irq;
@@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(u
 		return NULL;
 	}
 
+	p->dev = &padev->dev;
 	p->base_hi = base_hi;
 	p->modes = tmp.modes;
 	p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
@@ -373,7 +373,7 @@ static int parport_init_chip(struct pari
 	}
 	
 	p = parport_gsc_probe_port(port, 0, dev->irq,
-			/* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL);
+			/* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev);
 	if (p)
 		parport_count++;
 	dev_set_drvdata(&dev->dev, p);
drivers/parport/parport_gsc.h +1 -1
@@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(vo
 extern struct parport *parport_gsc_probe_port(unsigned long base,
 						unsigned long base_hi,
 						int irq, int dma,
-						struct pci_dev *dev);
+						struct parisc_device *padev);
 
 #endif	/* __DRIVERS_PARPORT_PARPORT_GSC_H */
author maintainer
#26 lore raw

PATCH 26/95 parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50 (part 2)

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 91ea8207168793b365322be3c90a4ee9e8b03ed4 upstream.

Make sure that we really return -1 (instead of 0x00ff) as node id for page frame numbers which are not physically available.

This finally fixes the kernel panic when running
cat /proc/kpageflags /proc/kpagecount.

Theoretically this patch now limits the number of physical memory ranges to 127 instead of 254, but currently we have MAX_PHYSMEM_RANGES hardcoded to 8 which is sufficient for all existing parisc machines.

---
 arch/parisc/include/asm/mmzone.h |    4 ++--
 arch/parisc/mm/init.c            |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
arch/parisc/include/asm/mmzone.h +2 -2
@@ -27,7 +27,7 @@ extern struct node_map_data node_data[];
 
 #define PFNNID_SHIFT (30 - PAGE_SHIFT)
 #define PFNNID_MAP_MAX  512     /* support 512GB */
-extern unsigned char pfnnid_map[PFNNID_MAP_MAX];
+extern signed char pfnnid_map[PFNNID_MAP_MAX];
 
 #ifndef CONFIG_64BIT
 #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT))
@@ -46,7 +46,7 @@ static inline int pfn_to_nid(unsigned lo
 	i = pfn >> PFNNID_SHIFT;
 	BUG_ON(i >= ARRAY_SIZE(pfnnid_map));
 
-	return (int)pfnnid_map[i];
+	return pfnnid_map[i];
 }
 
 static inline int pfn_valid(int pfn)
arch/parisc/mm/init.c +1 -1
@@ -47,7 +47,7 @@ pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __a
 
 #ifdef CONFIG_DISCONTIGMEM
 struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
-unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
+signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
 #endif
 
 static struct resource data_resource = {
author maintainer
#27 lore raw

PATCH 27/95 parisc: fix serial ports on C8000 workstation

In reply to Greg Kroah-Hartman

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

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

From: Thomas Bogendoerfer <[email protected]>

commit 9a66d1869d90f13fbaf83dcce5b1aeec86fbc699 upstream.

The C8000 workstation (64 bit kernel only) has a somewhat different serial port configuration than other models.
Thomas Bogendoerfer sent a patch to fix this in September 2010, which was now minimally modified by me.

---
 arch/parisc/kernel/hardware.c      |    1 
 drivers/parisc/iosapic.c           |   66 +++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/8250_gsc.c |   10 +++++
 3 files changed, 76 insertions(+), 1 deletion(-)
arch/parisc/kernel/hardware.c +1 -0
@@ -1205,6 +1205,7 @@ static struct hp_hardware hp_hardware_li
 	{HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, 
 	{HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, 
 	{HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, 
+	{HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"},
 	{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, 
 	{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, 
 	{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, 
drivers/parisc/iosapic.c +66 -0

78 lines not on this page · raw message

drivers/tty/serial/8250/8250_gsc.c +9 -1
@@ -30,6 +30,12 @@ static int __init serial_init_chip(struc
 	unsigned long address;
 	int err;
 
+#ifdef CONFIG_64BIT
+	extern int iosapic_serial_irq(int cellnum);
+	if (!dev->irq && (dev->id.sversion == 0xad))
+		dev->irq = iosapic_serial_irq(dev->mod_index-1);
+#endif
+
 	if (!dev->irq) {
 		/* We find some unattached serial ports by walking native
 		 * busses.  These should be silently ignored.  Otherwise,
@@ -51,7 +57,8 @@ static int __init serial_init_chip(struc
 	memset(&uart, 0, sizeof(uart));
 	uart.port.iotype	= UPIO_MEM;
 	/* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
-	uart.port.uartclk	= 7272727;
+	uart.port.uartclk	= (dev->id.sversion != 0xad) ?
+					7272727 : 1843200;
 	uart.port.mapbase	= address;
 	uart.port.membase	= ioremap_nocache(address, 16);
 	uart.port.irq	= dev->irq;
@@ -73,6 +80,7 @@ static struct parisc_device_id serial_tb
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad },
 	{ 0 }
 };
 
author maintainer
#28 lore raw

PATCH 28/95 parisc: provide pci_mmap_page_range() for parisc

In reply to Greg Kroah-Hartman

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

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

From: Thomas Bogendoerfer <[email protected]>

commit 2cc7138f4347df939ce03f313e3d87794bab36f8 upstream.

pci_mmap_page_range() is needed for X11-server support on C8000 with ATI FireGL card.

Signed-off-by Thomas Bogendoerfer <[email protected]>

---
 arch/parisc/include/asm/pci.h |    5 +++++
 arch/parisc/kernel/pci.c      |   27 +++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)
arch/parisc/include/asm/pci.h +5 -0
@@ -225,4 +225,9 @@ static inline int pci_get_legacy_ide_irq
 	return channel ? 15 : 14;
 }
 
+#define HAVE_PCI_MMAP
+
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+	enum pci_mmap_state mmap_state, int write_combine);
+
 #endif /* __ASM_PARISC_PCI_H */
arch/parisc/kernel/pci.c +27 -0
@@ -220,6 +220,33 @@ resource_size_t pcibios_align_resource(v
 }
 
 
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	unsigned long prot;
+
+	/*
+	 * I/O space can be accessed via normal processor loads and stores on
+	 * this platform but for now we elect not to do this and portable
+	 * drivers should not do this anyway.
+	 */
+	if (mmap_state == pci_mmap_io)
+		return -EINVAL;
+
+	if (write_combine)
+		return -EINVAL;
+
+	/*
+	 * Ignore write-combine; for now only return uncached mappings.
+	 */
+	prot = pgprot_val(vma->vm_page_prot);
+	prot |= _PAGE_NO_CACHE;
+	vma->vm_page_prot = __pgprot(prot);
+
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+		vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
 /*
  * A driver is enabling the device.  We make sure that all the appropriate
  * bits are set to allow the device to operate as the driver is expecting.
author maintainer
#29 lore raw

PATCH 29/95 carl9170: fix frame drop and WARN due to minstrel_ht change

In reply to Greg Kroah-Hartman

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

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

From: Christian Lamparter <[email protected]>

commit 5f34608fa2acbfef5a06d0072a978c9943c28a2d upstream.

With "mac80211/minstrel_ht: add support for using CCK rates" minstrel_ht selects legacy CCK rates as viable rates for outgoing frames which might be sent as part of an A-MPDU [IEEE80211_TX_CTL_AMPDU is set].

This behavior triggered the following WARN_ON in the driver:

Quoted 1 line
WARNING: at carl9170/tx.c:995 carl9170_op_tx+0x1dd/0x6fd

The driver assumed that the rate control algorithm made a mistake and dropped the frame.

This patch removes the noisy warning altogether and allows said A-MPDU frames with CCK sample and/or fallback rates to be transmitted seamlessly.

---
 drivers/net/wireless/ath/carl9170/tx.c |   69 +++++++++++++--------------------
 1 file changed, 28 insertions(+), 41 deletions(-)
drivers/net/wireless/ath/carl9170/tx.c +28 -41
@@ -387,8 +387,7 @@ static void carl9170_tx_status_process_a
 	u8 tid;
 
 	if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
-	    txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
-	   (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
+	    txinfo->flags & IEEE80211_TX_CTL_INJECTED)
 		return;
 
 	rcu_read_lock();
@@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar
 
 		SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR,
 			txc->s.ampdu_settings, factor);
-
-		for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
-			txrate = &info->control.rates[i];
-			if (txrate->idx >= 0) {
-				txc->s.ri[i] =
-					CARL9170_TX_SUPER_RI_AMPDU;
-
-				if (WARN_ON(!(txrate->flags &
-					      IEEE80211_TX_RC_MCS))) {
-					/*
-					 * Not sure if it's even possible
-					 * to aggregate non-ht rates with
-					 * this HW.
-					 */
-					goto err_out;
-				}
-				continue;
-			}
-
-			txrate->idx = 0;
-			txrate->count = ar->hw->max_rate_tries;
-		}
-
-		mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
 	}
 
 	/*
@@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar
 	 * taken from mac_control. For all fallback rate, the firmware
 	 * updates the mac_control flags from the rate info field.
 	 */
-	for (i = 1; i < CARL9170_TX_MAX_RATES; i++) {
+	for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
+		__le32 phy_set;
 		txrate = &info->control.rates[i];
 		if (txrate->idx < 0)
 			break;
 
+		phy_set = carl9170_tx_physet(ar, info, txrate);
+		if (i == 0) {
+			/* first rate - part of the hw's frame header */
+			txc->f.phy_control = phy_set;
+
+			if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS)
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+			if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+			else if (carl9170_tx_cts_check(ar, txrate))
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+
+		} else {
+			/* fallback rates are stored in the firmware's
+			 * retry rate set array.
+			 */
+			txc->s.rr[i - 1] = phy_set;
+		}
+
 		SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
 			txrate->count);
 
@@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar
 			txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
 				CARL9170_TX_SUPER_RI_ERP_PROT_S);
 
-		txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate);
+		if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS))
+			txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
 	}
 
-	txrate = &info->control.rates[0];
-	SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count);
-
-	if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
-		mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-	else if (carl9170_tx_cts_check(ar, txrate))
-		mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
-
 	txc->s.len = cpu_to_le16(skb->len);
 	txc->f.length = cpu_to_le16(len + FCS_LEN);
 	txc->f.mac_control = mac_tmp;
-	txc->f.phy_control = carl9170_tx_physet(ar, info, txrate);
 
 	arinfo = (void *)info->rate_driver_data;
 	arinfo->timeout = jiffies;
@@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *a
 }
 
 static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
-	struct ieee80211_sta *sta, struct sk_buff *skb)
+	struct ieee80211_sta *sta, struct sk_buff *skb,
+	struct ieee80211_tx_info *txinfo)
 {
-	struct _carl9170_tx_superframe *super = (void *) skb->data;
 	struct carl9170_sta_info *sta_info;
 	struct carl9170_sta_tid *agg;
 	struct sk_buff *iter;
@@ -1450,7 +1437,7 @@ err_unlock:
 
 err_unlock_rcu:
 	rcu_read_unlock();
-	super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
+	txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU;
 	carl9170_tx_status(ar, skb, false);
 	ar->tx_dropped++;
 	return false;
@@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw
 		 * sta == NULL checks are redundant in this
 		 * special case.
 		 */
-		run = carl9170_tx_ampdu_queue(ar, sta, skb);
+		run = carl9170_tx_ampdu_queue(ar, sta, skb, info);
 		if (run)
 			carl9170_tx_ampdu(ar);
 
author maintainer
#30 lore raw

PATCH 30/95 x86/efi: Fix dummy variable buffer allocation

In reply to Greg Kroah-Hartman

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

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

From: Ben Hutchings <[email protected]>

commit b8cb62f82103083a6e8fa5470bfe634a2c06514d upstream.

1. Check for allocation failure
2. Clear the buffer contents, as they may actually be written to flash
3. Don't leak the buffer

Compile-tested only.

[ Tested successfully on my buggy ASUS machine - Matt ]

---
 arch/x86/platform/efi/efi.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/platform/efi/efi.c +6 -1
@@ -1059,7 +1059,10 @@ efi_status_t efi_query_variable_store(u3
 		 * that by attempting to use more space than is available.
 		 */
 		unsigned long dummy_size = remaining_size + 1024;
-		void *dummy = kmalloc(dummy_size, GFP_ATOMIC);
+		void *dummy = kzalloc(dummy_size, GFP_ATOMIC);
+
+		if (!dummy)
+			return EFI_OUT_OF_RESOURCES;
 
 		status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
 					  EFI_VARIABLE_NON_VOLATILE |
@@ -1079,6 +1082,8 @@ efi_status_t efi_query_variable_store(u3
 					 0, dummy);
 		}
 
+		kfree(dummy);
+
 		/*
 		 * The runtime code may now have triggered a garbage collection
 		 * run, so check the variable info again
author maintainer
#31 lore raw

PATCH 31/95 x86: kvmclock: zero initialize pvclock shared memory area

In reply to Greg Kroah-Hartman

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

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

From: Igor Mammedov <[email protected]>

commit 07868fc6aaf57847b0f3a3d53086b7556eb83f4a upstream.

kernel might hung in pvclock_clocksource_read() due to uninitialized memory might contain odd version value in following cycle:

        do {
                version = __pvclock_read_cycles(src, &ret, &flags);
        } while ((src->version & 1) || version != src->version);

if secondary kvmclock is accessed before it's registered with kvm.

Clear garbage in pvclock shared memory area right after it's allocated to avoid this issue.

Ref: https://bugzilla.kernel.org/show_bug.cgi?id=59521

[See BZ for analysis. We may want a different fix for 3.11, but
this is the safest for now - Paolo]

---
 arch/x86/kernel/kvmclock.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kernel/kvmclock.c +1 -0
@@ -238,6 +238,7 @@ void __init kvmclock_init(void)
 	if (!mem)
 		return;
 	hv_clock = __va(mem);
+	memset(hv_clock, 0, size);
 
 	if (kvm_register_clock("boot clock")) {
 		hv_clock = NULL;
author maintainer
#32 lore raw

PATCH 32/95 KVM: x86: remove vcpus CPL check in host-invoked XCR set

In reply to Greg Kroah-Hartman

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

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

From: "Zhanghaoyu (A)" <[email protected]>

commit 764bcbc5a6d7a2f3e75c9f0e4caa984e2926e346 upstream.

__kvm_set_xcr function does the CPL check when set xcr. __kvm_set_xcr is called in two flows, one is invoked by guest, call stack shown as below,

handle_xsetbv(or xsetbv_interception)

    kvm_set_xcr
      __kvm_set_xcr

the other one is invoked by host, for example during system reset:

kvm_arch_vcpu_ioctl

    kvm_vcpu_ioctl_x86_set_xcrs
      __kvm_set_xcr

The former does need the CPL check, but the latter does not.

[Tweaks to commit message. - Paolo]
---
 arch/x86/kvm/x86.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
arch/x86/kvm/x86.c +2 -3
@@ -558,8 +558,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu,
 	if (index != XCR_XFEATURE_ENABLED_MASK)
 		return 1;
 	xcr0 = xcr;
-	if (kvm_x86_ops->get_cpl(vcpu) != 0)
-		return 1;
 	if (!(xcr0 & XSTATE_FP))
 		return 1;
 	if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
@@ -573,7 +571,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu,
 
 int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
-	if (__kvm_set_xcr(vcpu, index, xcr)) {
+	if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
+	    __kvm_set_xcr(vcpu, index, xcr)) {
 		kvm_inject_gp(vcpu, 0);
 		return 1;
 	}
author maintainer
#33 lore raw

PATCH 33/95 ACPI / resources: call acpi_get_override_irq() only for legacy IRQ resources

In reply to Greg Kroah-Hartman

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

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

From: Mika Westerberg <[email protected]>

commit 204ebc0aa30a7115f300cac39fbb7eeb66524881 upstream.

acpi_get_override_irq() was added because there was a problem with buggy BIOSes passing wrong IRQ() resource for the RTC IRQ. The commit that added the workaround was 61fd47e0c8476 (ACPI: fix two IRQ8 issues in IOAPIC mode).

With ACPI 5 enumerated devices there are typically one or more extended IRQ resources per device (and these IRQs can be shared). However, the acpi_get_override_irq() workaround forces all IRQs in range 0 - 15 (the legacy ISA IRQs) to be edge triggered, active high as can be seen from the dmesg below:

ACPI: IRQ 6 override to edge, high
ACPI: IRQ 7 override to edge, high
ACPI: IRQ 7 override to edge, high
ACPI: IRQ 13 override to edge, high

Also /proc/interrupts for the I2C controllers (INT33C2 and INT33C3) shows the same thing:

7: 4 0 0 0 IO-APIC-edge INT33C2:00, INT33C3:00

The _CSR method for INT33C2 (and INT33C3) device returns following resource:

	Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,, )
	{
		0x00000007,
	}

which states that this is supposed to be level triggered, active low, shared IRQ instead.

Fix this by making sure that acpi_get_override_irq() gets only called when we are dealing with legacy IRQ() or IRQNoFlags() descriptors.

While we are there, correct pr_warning() to print the right triggering value.

This change turns out to be necessary to make DMA work correctly on systems based on the Intel Lynxpoint PCH (Platform Controller Hub).

---
 drivers/acpi/resource.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/acpi/resource.c +11 -5
@@ -304,7 +304,8 @@ static void acpi_dev_irqresource_disable
 }
 
 static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
-				     u8 triggering, u8 polarity, u8 shareable)
+				     u8 triggering, u8 polarity, u8 shareable,
+				     bool legacy)
 {
 	int irq, p, t;
 
@@ -317,14 +318,19 @@ static void acpi_dev_get_irqresource(str
 	 * In IO-APIC mode, use overrided attribute. Two reasons:
 	 * 1. BIOS bug in DSDT
 	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
+	 *
+	 * We do this only if we are dealing with IRQ() or IRQNoFlags()
+	 * resource (the legacy ISA resources). With modern ACPI 5 devices
+	 * using extended IRQ descriptors we take the IRQ configuration
+	 * from _CRS directly.
 	 */
-	if (!acpi_get_override_irq(gsi, &t, &p)) {
+	if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
 		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
 		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
 
 		if (triggering != trig || polarity != pol) {
 			pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
-				   t ? "edge" : "level", p ? "low" : "high");
+				   t ? "level" : "edge", p ? "low" : "high");
 			triggering = trig;
 			polarity = pol;
 		}
@@ -373,7 +379,7 @@ bool acpi_dev_resource_interrupt(struct
 		}
 		acpi_dev_get_irqresource(res, irq->interrupts[index],
 					 irq->triggering, irq->polarity,
-					 irq->sharable);
+					 irq->sharable, true);
 		break;
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		ext_irq = &ares->data.extended_irq;
@@ -383,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct
 		}
 		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
 					 ext_irq->triggering, ext_irq->polarity,
-					 ext_irq->sharable);
+					 ext_irq->sharable, false);
 		break;
 	default:
 		return false;
author maintainer
#34 lore raw

PATCH 34/95 ACPI / dock: Take ACPI scan lock in write_undock()

In reply to Greg Kroah-Hartman

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

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

From: "Rafael J. Wysocki" <[email protected]>

commit 8112006f41fd76ddf4988f8ddd904563db85613c upstream.

Since commit 3757b94 (ACPI / hotplug: Fix concurrency issues and memory leaks) acpi_bus_scan() and acpi_bus_trim() must always be called under acpi_scan_lock, but currently the following scenario violating that requirement is possible:

write_undock()
handle_eject_request()
hotplug_dock_devices()

    dock_remove_acpi_device()
     acpi_bus_trim()

Fix that by making write_undock() acquire acpi_scan_lock before calling handle_eject_request() as appropriate (begin_undock() is under the lock too in analogy with acpi_dock_deferred_cb()).

---
 drivers/acpi/dock.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/acpi/dock.c +2 -0
@@ -868,8 +868,10 @@ static ssize_t write_undock(struct devic
 	if (!count)
 		return -EINVAL;
 
+	acpi_scan_lock_acquire();
 	begin_undock(dock_station);
 	ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
+	acpi_scan_lock_release();
 	return ret ? ret: count;
 }
 static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
author maintainer
#35 lore raw

PATCH 35/95 ACPI / PM: Fix error code path for power resources initialization

In reply to Greg Kroah-Hartman

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

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

From: "Rafael J. Wysocki" <[email protected]>

commit 6ee22e9d59151550a55d370b14109bdae8b58bda upstream.

Commit 781d737 (ACPI: Drop power resources driver) introduced a bug in the power resources initialization error code path causing a NULL pointer to be referenced in acpi_release_power_resource() if there's an error triggering a jump to the 'err' label in acpi_add_power_resource(). This happens because the list_node field of struct acpi_power_resource has not been initialized yet at this point and doing a list_del() on it is a bad idea.

To prevent this problem from occuring, initialize the list_node field of struct acpi_power_resource upfront.

---
 drivers/acpi/power.c |    1 +
 1 file changed, 1 insertion(+)
drivers/acpi/power.c +1 -0
@@ -865,6 +865,7 @@ int acpi_add_power_resource(acpi_handle
 				ACPI_STA_DEFAULT);
 	mutex_init(&resource->resource_lock);
 	INIT_LIST_HEAD(&resource->dependent);
+	INIT_LIST_HEAD(&resource->list_node);
 	resource->name = device->pnp.bus_id;
 	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
author maintainer
#36 lore raw

PATCH 36/95 drm/prime: Honor requested file flags when exporting a buffer

In reply to Greg Kroah-Hartman

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

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

From: Laurent Pinchart <[email protected]>

commit ebc0bad4a05ad63979e8bc115cea3b8abdf814c7 upstream.

The DRM PRIME API passes file flags to the driver for the exported buffer. Honor them instead of hardcoding 0600.

---
 drivers/gpu/drm/drm_prime.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/drm_prime.c +1 -2
@@ -190,8 +190,7 @@ struct dma_buf *drm_gem_prime_export(str
 		if (ret)
 			return ERR_PTR(ret);
 	}
-	return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size,
-			      0600);
+	return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags);
 }
 EXPORT_SYMBOL(drm_gem_prime_export);
 
author maintainer
#37 lore raw

PATCH 37/95 drm/radeon: do not try to uselessly update virtual memory pagetable

In reply to Greg Kroah-Hartman

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

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

From: Jerome Glisse <[email protected]>

commit 3813f5ca9ab7a00e80a17aab34f155453c66c78a upstream.

If a buffer is never bound to a virtual memory pagetable than don't try to unbind it. Only drawback is that we don't update the pagetable when unbinding the ib pool buffer which is fine because it only happens at suspend or module unload/shutdown.

Fixes spurious messages about buffers without VM mappings. E.g.:
radeon 0000:01:00.0: bo ffff88020afac400 don't has a mapping in vm ffff88021ca2b900

---
 drivers/gpu/drm/radeon/radeon_gart.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_gart.c +4 -2
@@ -1197,11 +1197,13 @@ int radeon_vm_bo_update_pte(struct radeo
 int radeon_vm_bo_rmv(struct radeon_device *rdev,
 		     struct radeon_bo_va *bo_va)
 {
-	int r;
+	int r = 0;
 
 	mutex_lock(&rdev->vm_manager.lock);
 	mutex_lock(&bo_va->vm->mutex);
-	r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL);
+	if (bo_va->soffset) {
+		r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL);
+	}
 	mutex_unlock(&rdev->vm_manager.lock);
 	list_del(&bo_va->vm_list);
 	mutex_unlock(&bo_va->vm->mutex);
author maintainer
#38 lore raw

PATCH 38/95 drm/radeon: update lockup tracking when scheduling in empty ring

In reply to Greg Kroah-Hartman

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

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

From: Jerome Glisse <[email protected]>

commit 8444d5c69549aa0f0b574cc608742d4669e1cc01 upstream.

There might be issue with lockup detection when scheduling on an empty ring that have been sitting idle for a while. Thus update the lockup tracking data when scheduling new work in an empty ring.

---
 drivers/gpu/drm/radeon/radeon_ring.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/gpu/drm/radeon/radeon_ring.c +7 -0
@@ -402,6 +402,13 @@ int radeon_ring_alloc(struct radeon_devi
 		return -ENOMEM;
 	/* Align requested size with padding so unlock_commit can
 	 * pad safely */
+	radeon_ring_free_size(rdev, ring);
+	if (ring->ring_free_dw == (ring->ring_size / 4)) {
+		/* This is an empty ring update lockup info to avoid
+		 * false positive.
+		 */
+		radeon_ring_lockup_update(ring);
+	}
 	ndw = (ndw + ring->align_mask) & ~ring->align_mask;
 	while (ndw > (ring->ring_free_dw - 1)) {
 		radeon_ring_free_size(rdev, ring);
author maintainer
#39 lore raw

PATCH 39/95 range: Do not add new blank slot with add_range_with_merge

In reply to Greg Kroah-Hartman

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

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

From: Yinghai Lu <[email protected]>

commit 0541881502a1276149889fe468662ff6a8fc8f6d upstream.

Joshua reported: Commit cd7b304dfaf1 (x86, range: fix missing merge during add range) broke mtrr cleanup on his setup in 3.9.5. corresponding commit in upstream is fbe06b7bae7c.

The reason is add_range_with_merge could generate blank spot.

We could avoid that by searching new expanded start/end, that new range should include all connected ranges in range array. At last add the new expanded start/end to the range array. Also move up left array so do not add new blank slot in the range array.

-v2: move left array to avoid enhance add_range() -v3: include fix from Joshua about memmove declaring when
DYN_DEBUG is used.

---
 kernel/range.c |   23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)
kernel/range.c +12 -11
@@ -4,7 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sort.h>
-
+#include <linux/string.h>
 #include <linux/range.h>
 
 int add_range(struct range *range, int az, int nr_range, u64 start, u64 end)
@@ -32,9 +32,8 @@ int add_range_with_merge(struct range *r
 	if (start >= end)
 		return nr_range;
 
-	/* Try to merge it with old one: */
+	/* get new start/end: */
 	for (i = 0; i < nr_range; i++) {
-		u64 final_start, final_end;
 		u64 common_start, common_end;
 
 		if (!range[i].end)
@@ -45,14 +44,16 @@ int add_range_with_merge(struct range *r
 		if (common_start > common_end)
 			continue;
 
-		final_start = min(range[i].start, start);
-		final_end = max(range[i].end, end);
-
-		/* clear it and add it back for further merge */
-		range[i].start = 0;
-		range[i].end =  0;
-		return add_range_with_merge(range, az, nr_range,
-			final_start, final_end);
+		/* new start/end, will add it back at last */
+		start = min(range[i].start, start);
+		end = max(range[i].end, end);
+
+		memmove(&range[i], &range[i + 1],
+			(nr_range - (i + 1)) * sizeof(range[i]));
+		range[nr_range - 1].start = 0;
+		range[nr_range - 1].end   = 0;
+		nr_range--;
+		i--;
 	}
 
 	/* Need to add it: */
author maintainer
#40 lore raw

PATCH 40/95 x86, mtrr: Fix original mtrr range get for mtrr_cleanup

In reply to Greg Kroah-Hartman

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

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

From: Yinghai Lu <[email protected]>

commit d8d386c10630d8f7837700f4c466443d49e12cc0 upstream.

Joshua reported: Commit cd7b304dfaf1 (x86, range: fix missing merge during add range) broke mtrr cleanup on his setup in 3.9.5. corresponding commit in upstream is fbe06b7bae7c.

*BAD*gran_size: 64K chunk_size: 16M num_reg: 6 lose cover RAM: -0G

https://bugzilla.kernel.org/show_bug.cgi?id=59491

So it rejects new var mtrr layout.

It turns out we have some problem with initial mtrr range retrieval. The current sequence is:

	x86_get_mtrr_mem_range
		==> bunchs of add_range_with_merge
		==> bunchs of subract_range
		==> clean_sort_range
	add_range_with_merge for [0,1M)
	sort_range()

add_range_with_merge could have blank slots, so we can not just sort only, that will have final result have extra blank slot in head.

So move that calling add_range_with_merge for [0,1M), with that we could avoid extra clean_sort_range calling.

---
 arch/x86/kernel/cpu/mtrr/cleanup.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/cpu/mtrr/cleanup.c +4 -4
@@ -714,15 +714,15 @@ int __init mtrr_cleanup(unsigned address
 	if (mtrr_tom2)
 		x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base;
 
-	nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size);
 	/*
 	 * [0, 1M) should always be covered by var mtrr with WB
 	 * and fixed mtrrs should take effect before var mtrr for it:
 	 */
-	nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0,
+	nr_range = add_range_with_merge(range, RANGE_NUM, 0, 0,
 					1ULL<<(20 - PAGE_SHIFT));
-	/* Sort the ranges: */
-	sort_range(range, nr_range);
+	/* add from var mtrr at last */
+	nr_range = x86_get_mtrr_mem_range(range, nr_range,
+					  x_remove_base, x_remove_size);
 
 	range_sums = sum_ranges(range, nr_range);
 	printk(KERN_INFO "total RAM covered: %ldM\n",
author maintainer
#41 lore raw

PATCH 41/95 x86: fix build error and kconfig for ia32_emulation and binfmt

In reply to Greg Kroah-Hartman

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

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

From: Randy Dunlap <[email protected]>

commit d1603990ea626668c78527376d9ec084d634202d upstream.

Fix kconfig warning and build errors on x86_64 by selecting BINFMT_ELF when COMPAT_BINFMT_ELF is being selected.

warning: (IA32_EMULATION) selects COMPAT_BINFMT_ELF which has unmet direct dependencies (COMPAT && BINFMT_ELF)

fs/built-in.o: In function `elf_core_dump':
compat_binfmt_elf.c:(.text+0x3e093): undefined reference to elf_core_extra_phdrs' compat_binfmt_elf.c:(.text+0x3ebcd): undefined reference to elf_core_extra_data_size' compat_binfmt_elf.c:(.text+0x3eddd): undefined reference to elf_core_write_extra_phdrs' compat_binfmt_elf.c:(.text+0x3f004): undefined reference to elf_core_write_extra_data'

[ hpa: This was sent to me for -next but it is a low risk build fix ]

---
 arch/x86/Kconfig |    1 +
 1 file changed, 1 insertion(+)
arch/x86/Kconfig +1 -0
@@ -2268,6 +2268,7 @@ source "fs/Kconfig.binfmt"
 config IA32_EMULATION
 	bool "IA32 Emulation"
 	depends on X86_64
+	select BINFMT_ELF
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	---help---
author maintainer
#42 lore raw

PATCH 42/95 x86: Fix section mismatch on load_ucode_ap

In reply to Greg Kroah-Hartman

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

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

From: Paul Gortmaker <[email protected]>

commit 949785996ec2250fa958fc3a924e5186e9a8fa2c upstream.

We are in the process of removing all the __cpuinit annotations. While working on making that change, an existing problem was made evident:

WARNING: arch/x86/kernel/built-in.o(.text+0x198f2): Section mismatch in reference from the function cpu_init() to the function
.init.text:load_ucode_ap() The function cpu_init() references
the function __init load_ucode_ap(). This is often because cpu_init lacks a __init annotation or the annotation of load_ucode_ap is wrong.

This now appears because in my working tree, cpu_init() is no longer tagged as __cpuinit, and so the audit picks up the mismatch. The 2nd hypothesis from the audit is the correct one, as there was an incorrect __init tag on the prototype in the header (but __cpuinit was used on the function itself.)

The audit is telling us that the prototype's __init annotation took effect and the function did land in the .init.text section. Checking with objdump on a mainline tree that still has __cpuinit shows that the __cpuinit on the function takes precedence over the __init on the prototype, but that won't be true once we make __cpuinit a no-op.

Even though we are removing __cpuinit, we temporarily align both the function and the prototype on __cpuinit so that the changeset can be applied to stable trees if desired.

[ hpa: build fix only, no object code change ]

---
 arch/x86/include/asm/microcode.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/microcode.h +2 -2
@@ -60,11 +60,11 @@ static inline void __exit exit_amd_micro
 #ifdef CONFIG_MICROCODE_EARLY
 #define MAX_UCODE_COUNT 128
 extern void __init load_ucode_bsp(void);
-extern __init void load_ucode_ap(void);
+extern void __cpuinit load_ucode_ap(void);
 extern int __init save_microcode_in_initrd(void);
 #else
 static inline void __init load_ucode_bsp(void) {}
-static inline __init void load_ucode_ap(void) {}
+static inline void __cpuinit load_ucode_ap(void) {}
 static inline int __init save_microcode_in_initrd(void)
 {
 	return 0;
author maintainer
#43 lore raw

PATCH 43/95 net: fec: fix kernel oops when plug/unplug cable many times

In reply to Greg Kroah-Hartman

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

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

From: Frank Li <[email protected]>

[ Upstream commits 54309fa60b5f57b90c1842176f6045e665d21142 and
3169134478a9638baf0dbb4fdca5a0718cbe8e27 ]

reproduce steps
1. flood ping from other machine
ping -f -s 41000 IP
2. run below script

    while [ 1 ]; do ethtool -s eth0 autoneg off;
    sleep 3;ethtool -s eth0 autoneg on; sleep 4; done;

You can see oops in one hour.

The reason is fec_restart clear BD but NAPI may use it. The solution is disable NAPI and stop xmit when reset BD. disable NAPI may sleep, so fec_restart can't be call in atomic context.

---
 drivers/net/ethernet/freescale/fec.c |   44 ++++++++++++++++++++++++++---------
 drivers/net/ethernet/freescale/fec.h |   10 ++++---
 2 files changed, 39 insertions(+), 15 deletions(-)
drivers/net/ethernet/freescale/fec.c +33 -11
@@ -407,6 +407,13 @@ fec_restart(struct net_device *ndev, int
 	u32 rcntl = OPT_FRAME_SIZE | 0x04;
 	u32 ecntl = 0x2; /* ETHEREN */
 
+	if (netif_running(ndev)) {
+		netif_device_detach(ndev);
+		napi_disable(&fep->napi);
+		netif_stop_queue(ndev);
+		netif_tx_lock_bh(ndev);
+	}
+
 	/* Whack a reset.  We should wait for this. */
 	writel(1, fep->hwp + FEC_ECNTRL);
 	udelay(10);
@@ -559,6 +566,13 @@ fec_restart(struct net_device *ndev, int
 
 	/* Enable interrupts we wish to service */
 	writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+
+	if (netif_running(ndev)) {
+		netif_device_attach(ndev);
+		napi_enable(&fep->napi);
+		netif_wake_queue(ndev);
+		netif_tx_unlock_bh(ndev);
+	}
 }
 
 static void
@@ -598,8 +612,22 @@ fec_timeout(struct net_device *ndev)
 
 	ndev->stats.tx_errors++;
 
-	fec_restart(ndev, fep->full_duplex);
-	netif_wake_queue(ndev);
+	fep->delay_work.timeout = true;
+	schedule_delayed_work(&(fep->delay_work.delay_work), 0);
+}
+
+static void fec_enet_work(struct work_struct *work)
+{
+	struct fec_enet_private *fep =
+		container_of(work,
+			     struct fec_enet_private,
+			     delay_work.delay_work.work);
+
+	if (fep->delay_work.timeout) {
+		fep->delay_work.timeout = false;
+		fec_restart(fep->netdev, fep->full_duplex);
+		netif_wake_queue(fep->netdev);
+	}
 }
 
 static void
@@ -970,16 +998,12 @@ static void fec_enet_adjust_link(struct
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	struct phy_device *phy_dev = fep->phy_dev;
-	unsigned long flags;
-
 	int status_change = 0;
 
-	spin_lock_irqsave(&fep->hw_lock, flags);
-
 	/* Prevent a state halted on mii error */
 	if (fep->mii_timeout && phy_dev->state == PHY_HALTED) {
 		phy_dev->state = PHY_RESUMING;
-		goto spin_unlock;
+		return;
 	}
 
 	if (phy_dev->link) {
@@ -1007,9 +1031,6 @@ static void fec_enet_adjust_link(struct
 		}
 	}
 
-spin_unlock:
-	spin_unlock_irqrestore(&fep->hw_lock, flags);
-
 	if (status_change)
 		phy_print_status(phy_dev);
 }
@@ -1656,7 +1677,6 @@ static int fec_enet_init(struct net_devi
 	}
 
 	memset(cbd_base, 0, PAGE_SIZE);
-	spin_lock_init(&fep->hw_lock);
 
 	fep->netdev = ndev;
 
@@ -1882,6 +1902,7 @@ fec_probe(struct platform_device *pdev)
 	if (ret)
 		goto failed_register;
 
+	INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
 	return 0;
 
 failed_register:
@@ -1918,6 +1939,7 @@ fec_drv_remove(struct platform_device *p
 	struct resource *r;
 	int i;
 
+	cancel_delayed_work_sync(&(fep->delay_work.delay_work));
 	unregister_netdev(ndev);
 	fec_enet_mii_remove(fep);
 	del_timer_sync(&fep->time_keep);
drivers/net/ethernet/freescale/fec.h +6 -4
@@ -191,6 +191,11 @@ struct bufdesc_ex {
 #define BD_ENET_RX_INT          0x00800000
 #define BD_ENET_RX_PTP          ((ushort)0x0400)
 
+struct fec_enet_delayed_work {
+	struct delayed_work delay_work;
+	bool timeout;
+};
+
 /* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
  * tx_bd_base always point to the base of the buffer descriptors.  The
  * cur_rx and cur_tx point to the currently available buffer.
@@ -224,9 +229,6 @@ struct fec_enet_private {
 	/* The ring entries to be free()ed */
 	struct bufdesc	*dirty_tx;
 
-	/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
-	spinlock_t hw_lock;
-
 	struct	platform_device *pdev;
 
 	int	opened;
@@ -260,7 +262,7 @@ struct fec_enet_private {
 	int hwts_rx_en;
 	int hwts_tx_en;
 	struct timer_list time_keep;
-
+	struct fec_enet_delayed_work delay_work;
 };
 
 void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev);
author maintainer
#44 lore raw

PATCH 44/95 tcp: fix tcp_md5_hash_skb_data()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 54d27fcb338bd9c42d1dfc5a39e18f6f9d373c2e ]

TCP md5 communications fail [1] for some devices, because sg/crypto code assume page offsets are below PAGE_SIZE.

This was discovered using mlx4 driver [2], but I suspect loopback might trigger the same bug now we use order-3 pages in tcp_sendmsg()

[1] Failure is giving following messages.

huh, entered softirq 3 NET_RX ffffffff806ad230 preempt_count 00000100, exited with 00000101?

[2] mlx4 driver uses order-2 pages to allocate RX frags

---
 net/ipv4/tcp.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
net/ipv4/tcp.c +5 -2
@@ -3383,8 +3383,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5
 
 	for (i = 0; i < shi->nr_frags; ++i) {
 		const struct skb_frag_struct *f = &shi->frags[i];
-		struct page *page = skb_frag_page(f);
-		sg_set_page(&sg, page, skb_frag_size(f), f->page_offset);
+		unsigned int offset = f->page_offset;
+		struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
+
+		sg_set_page(&sg, page, skb_frag_size(f),
+			    offset_in_page(offset));
 		if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
 			return 1;
 	}
author maintainer
#45 lore raw

PATCH 45/95 net/802/mrp: fix lockdep splat

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit faff57a92ba1d7247c5e86ecea2886d2c9d54507 ]

commit fb745e9a037895 ("net/802/mrp: fix possible race condition when calling mrp_pdu_queue()") introduced a lockdep splat.

[   19.735147] =================================
[   19.735235] [ INFO: inconsistent lock state ]
[   19.735324] 3.9.2-build-0063 #4 Not tainted
[   19.735412] ---------------------------------
[   19.735500] inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
[   19.735592] rmmod/1840 [HC0[0]:SC0[0]:HE1:SE1] takes:
[   19.735682]  (&(&app->lock)->rlock#2){+.?...}, at: [<f862bb5b>]

mrp_uninit_applicant+0x69/0xba [mrp]

app->lock is normally taken under softirq context, so disable BH to avoid the splat.

---
 net/802/mrp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/802/mrp.c +2 -2
@@ -871,10 +871,10 @@ void mrp_uninit_applicant(struct net_dev
 	 */
 	del_timer_sync(&app->join_timer);
 
-	spin_lock(&app->lock);
+	spin_lock_bh(&app->lock);
 	mrp_mad_event(app, MRP_EVENT_TX);
 	mrp_pdu_queue(app);
-	spin_unlock(&app->lock);
+	spin_unlock_bh(&app->lock);
 
 	mrp_queue_xmit(app);
 
author maintainer
#46 lore raw

PATCH 46/95 gianfar: add missing iounmap() on error in gianfar_ptp_probe()

In reply to Greg Kroah-Hartman

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

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

From: Wei Yongjun <[email protected]>

[ Upstream commit e5f5e380e0f3bb11f04ca5bc66a551e58e0ad26e ]

Add the missing iounmap() before return from gianfar_ptp_probe() in the error handling case.

---
 drivers/net/ethernet/freescale/gianfar_ptp.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/freescale/gianfar_ptp.c +1 -0
@@ -521,6 +521,7 @@ static int gianfar_ptp_probe(struct plat
 	return 0;
 
 no_clock:
+	iounmap(etsects->regs);
 no_ioremap:
 	release_resource(etsects->rsrc);
 no_resource:
author maintainer
#47 lore raw

PATCH 47/95 vxlan: Update vxlan fdb used field after each usage

In reply to Greg Kroah-Hartman

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

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

From: Sridhar Samudrala <[email protected]>

[ Upstream commit 014be2c8eac3381e202f684c1f35ae184a8b152b ]

Fix some instances where vxlan fdb 'used' field is not updated after the entry is used.

v2: rename vxlan_find_mac() as __vxlan_find_mac() and create a new vxlan_find_mac() that also updates ->used field.

---
 drivers/net/vxlan.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/net/vxlan.c +14 -3
@@ -285,7 +285,7 @@ static inline struct hlist_head *vxlan_f
 }
 
 /* Look up Ethernet address in forwarding table */
-static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
+static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
 					const u8 *mac)
 
 {
@@ -300,6 +300,18 @@ static struct vxlan_fdb *vxlan_find_mac(
 	return NULL;
 }
 
+static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
+					const u8 *mac)
+{
+	struct vxlan_fdb *f;
+
+	f = __vxlan_find_mac(vxlan, mac);
+	if (f)
+		f->used = jiffies;
+
+	return f;
+}
+
 /* Add new entry to forwarding table -- assumes lock held */
 static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			    const u8 *mac, __be32 ip,
@@ -308,7 +320,7 @@ static int vxlan_fdb_create(struct vxlan
 	struct vxlan_fdb *f;
 	int notify = 0;
 
-	f = vxlan_find_mac(vxlan, mac);
+	f = __vxlan_find_mac(vxlan, mac);
 	if (f) {
 		if (flags & NLM_F_EXCL) {
 			netdev_dbg(vxlan->dev,
@@ -453,7 +465,6 @@ static void vxlan_snoop(struct net_devic
 
 	f = vxlan_find_mac(vxlan, src_mac);
 	if (likely(f)) {
-		f->used = jiffies;
 		if (likely(f->remote_ip == src_ip))
 			return;
 
author maintainer
#48 lore raw

PATCH 48/95 ipv6: fix possible crashes in ip6_cork_release()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 284041ef21fdf2e0d216ab6b787bc9072b4eb58a ]

commit 0178b695fd6b4 ("ipv6: Copy cork options in ip6_append_data") added some code duplication and bad error recovery, leading to potential crash in ip6_cork_release() as kfree() could be called with garbage.

use kzalloc() to make sure this wont happen.

---
 net/ipv6/ip6_output.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/ip6_output.c +1 -1
@@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int
 			if (WARN_ON(np->cork.opt))
 				return -EINVAL;
 
-			np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
+			np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
 			if (unlikely(np->cork.opt == NULL))
 				return -ENOBUFS;
 
author maintainer
#49 lore raw

PATCH 49/95 netlabel: improve domain mapping validation

In reply to Greg Kroah-Hartman

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

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

From: Paul Moore <[email protected]>

[ Upstream commit 6b21e1b77d1a3d58ebfd513264c885695e8a0ba5 ]

The net/netlabel/netlabel_domainhash.c:netlbl_domhsh_add() function does not properly validate new domain hash entries resulting in potential problems when an administrator attempts to add an invalid entry. One such problem, as reported by Vlad Halilov, is a kernel BUG (found in netlabel_domainhash.c:netlbl_domhsh_audit_add()) when adding an IPv6 outbound mapping with a CIPSO configuration.

This patch corrects this problem by adding the necessary validation code to netlbl_domhsh_add() via the newly created netlbl_domhsh_validate() function.

Ideally this patch should also be pushed to the currently active -stable trees.

---
 net/netlabel/netlabel_domainhash.c |   69 +++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
net/netlabel/netlabel_domainhash.c +69 -0
@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(stru
 	}
 }
 
+/**
+ * netlbl_domhsh_validate - Validate a new domain mapping entry
+ * @entry: the entry to validate
+ *
+ * This function validates the new domain mapping entry to ensure that it is
+ * a valid entry.  Returns zero on success, negative values on failure.
+ *
+ */
+static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
+{
+	struct netlbl_af4list *iter4;
+	struct netlbl_domaddr4_map *map4;
+#if IS_ENABLED(CONFIG_IPV6)
+	struct netlbl_af6list *iter6;
+	struct netlbl_domaddr6_map *map6;
+#endif /* IPv6 */
+
+	if (entry == NULL)
+		return -EINVAL;
+
+	switch (entry->type) {
+	case NETLBL_NLTYPE_UNLABELED:
+		if (entry->type_def.cipsov4 != NULL ||
+		    entry->type_def.addrsel != NULL)
+			return -EINVAL;
+		break;
+	case NETLBL_NLTYPE_CIPSOV4:
+		if (entry->type_def.cipsov4 == NULL)
+			return -EINVAL;
+		break;
+	case NETLBL_NLTYPE_ADDRSELECT:
+		netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) {
+			map4 = netlbl_domhsh_addr4_entry(iter4);
+			switch (map4->type) {
+			case NETLBL_NLTYPE_UNLABELED:
+				if (map4->type_def.cipsov4 != NULL)
+					return -EINVAL;
+				break;
+			case NETLBL_NLTYPE_CIPSOV4:
+				if (map4->type_def.cipsov4 == NULL)
+					return -EINVAL;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+#if IS_ENABLED(CONFIG_IPV6)
+		netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) {
+			map6 = netlbl_domhsh_addr6_entry(iter6);
+			switch (map6->type) {
+			case NETLBL_NLTYPE_UNLABELED:
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+#endif /* IPv6 */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * Domain Hash Table Functions
  */
@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_
 	struct netlbl_af6list *tmp6;
 #endif /* IPv6 */
 
+	ret_val = netlbl_domhsh_validate(entry);
+	if (ret_val != 0)
+		return ret_val;
+
 	/* XXX - we can remove this RCU read lock as the spinlock protects the
 	 *       entire function, but before we do we need to fixup the
 	 *       netlbl_af[4,6]list RCU functions to do "the right thing" with
author maintainer
#50 lore raw

PATCH 50/95 r8169: fix offloaded tx checksum for small packets.

In reply to Greg Kroah-Hartman

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

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

From: Francois Romieu <[email protected]>

[ Upstream commit b423e9ae49d78ea3f53b131c8d5a6087aed16fd6 ]

8168evl offloaded checksums are wrong since commit e5195c1f31f399289347e043d6abf3ffa80f0005 ("r8169: fix 8168evl frame padding.") pads small packets to 60 bytes (without ethernet checksum). Typical symptoms appear as UDP checksums which are wrong by the count of added bytes.

It isn't worth compensating. Let the driver checksum.

Due to the skb length changes, TSO code is moved before the Tx descriptor gets written.

---
 drivers/net/ethernet/realtek/r8169.c |   41 +++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 14 deletions(-)
drivers/net/ethernet/realtek/r8169.c +27 -14
@@ -5747,7 +5747,20 @@ err_out:
 	return -EIO;
 }
 
-static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
+static bool rtl_skb_pad(struct sk_buff *skb)
+{
+	if (skb_padto(skb, ETH_ZLEN))
+		return false;
+	skb_put(skb, ETH_ZLEN - skb->len);
+	return true;
+}
+
+static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
+{
+	return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
+}
+
+static inline bool rtl8169_tso_csum(struct rtl8169_private *tp,
 				    struct sk_buff *skb, u32 *opts)
 {
 	const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
@@ -5760,13 +5773,20 @@ static inline void rtl8169_tso_csum(stru
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const struct iphdr *ip = ip_hdr(skb);
 
+		if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
+			return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb);
+
 		if (ip->protocol == IPPROTO_TCP)
 			opts[offset] |= info->checksum.tcp;
 		else if (ip->protocol == IPPROTO_UDP)
 			opts[offset] |= info->checksum.udp;
 		else
 			WARN_ON_ONCE(1);
+	} else {
+		if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
+			return rtl_skb_pad(skb);
 	}
+	return true;
 }
 
 static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -5787,17 +5807,15 @@ static netdev_tx_t rtl8169_start_xmit(st
 		goto err_stop_0;
 	}
 
-	/* 8168evl does not automatically pad to minimum length. */
-	if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 &&
-		     skb->len < ETH_ZLEN)) {
-		if (skb_padto(skb, ETH_ZLEN))
-			goto err_update_stats;
-		skb_put(skb, ETH_ZLEN - skb->len);
-	}
-
 	if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
 		goto err_stop_0;
 
+	opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
+	opts[0] = DescOwn;
+
+	if (!rtl8169_tso_csum(tp, skb, opts))
+		goto err_update_stats;
+
 	len = skb_headlen(skb);
 	mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(d, mapping))) {
@@ -5809,11 +5827,6 @@ static netdev_tx_t rtl8169_start_xmit(st
 	tp->tx_skb[entry].len = len;
 	txd->addr = cpu_to_le64(mapping);
 
-	opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
-	opts[0] = DescOwn;
-
-	rtl8169_tso_csum(tp, skb, opts);
-
 	frags = rtl8169_xmit_frags(tp, skb, opts);
 	if (frags < 0)
 		goto err_dma_1;
author maintainer
#51 lore raw

PATCH 51/95 8139cp: reset BQL when ring tx ring cleared

In reply to Greg Kroah-Hartman

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

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

From: stephen hemminger <[email protected]>

[ Upstream commit 98962baad72fd6d393bf39dbb7c2076532c363c6 ]

This patch cures transmit timeout's with DHCP observed while running under KVM. When the transmit ring is cleaned out, the Byte Queue Limit values need to be reset.

---
 drivers/net/ethernet/realtek/8139cp.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/realtek/8139cp.c +1 -0
@@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_pr
 			cp->dev->stats.tx_dropped++;
 		}
 	}
+	netdev_reset_queue(cp->dev);
 
 	memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
 	memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
author maintainer
#52 lore raw

PATCH 52/95 tcp: bug fix in proportional rate reduction.

In reply to Greg Kroah-Hartman

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

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

From: Nandita Dukkipati <[email protected]>

[ Upstream commit 35f079ebbc860dcd1cca70890c9c8d59c1145525 ]

This patch is a fix for a bug triggering newly_acked_sacked < 0 in tcp_ack(.).

The bug is triggered by sacked_out decreasing relative to prior_sacked, but packets_out remaining the same as pior_packets. This is because the snapshot of prior_packets is taken after tcp_sacktag_write_queue() while prior_sacked is captured before tcp_sacktag_write_queue(). The problem
is: tcp_sacktag_write_queue (tcp_match_skb_to_sack() -> tcp_fragment) adjusts the pcount for packets_out and sacked_out (MSS change or other reason). As a result, this delta in pcount is reflected in (prior_sacked - sacked_out) but not in (prior_packets - packets_out).

This patch does the following:
1) initializes prior_packets at the start of tcp_ack() so as to capture the delta in packets_out created by tcp_fragment.
2) introduces a new "previous_packets_out" variable that snapshots packets_out right before tcp_clean_rtx_queue, so pkts_acked can be correctly computed as before.
3) Computes pkts_acked using previous_packets_out, and computes newly_acked_sacked using prior_packets.

---
 net/ipv4/tcp_input.c |   23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)
net/ipv4/tcp_input.c +13 -10
@@ -2885,8 +2885,8 @@ static void tcp_enter_recovery(struct so
  * tcp_xmit_retransmit_queue().
  */
 static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
-				  int prior_sacked, bool is_dupack,
-				  int flag)
+				  int prior_sacked, int prior_packets,
+				  bool is_dupack, int flag)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -2952,7 +2952,8 @@ static void tcp_fastretrans_alert(struct
 				tcp_add_reno_sack(sk);
 		} else
 			do_lost = tcp_try_undo_partial(sk, pkts_acked);
-		newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
+		newly_acked_sacked = prior_packets - tp->packets_out +
+				     tp->sacked_out - prior_sacked;
 		break;
 	case TCP_CA_Loss:
 		if (flag & FLAG_DATA_ACKED)
@@ -2974,7 +2975,8 @@ static void tcp_fastretrans_alert(struct
 			if (is_dupack)
 				tcp_add_reno_sack(sk);
 		}
-		newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
+		newly_acked_sacked = prior_packets - tp->packets_out +
+				     tp->sacked_out - prior_sacked;
 
 		if (icsk->icsk_ca_state <= TCP_CA_Disorder)
 			tcp_try_undo_dsack(sk);
@@ -3597,9 +3599,10 @@ static int tcp_ack(struct sock *sk, cons
 	bool is_dupack = false;
 	u32 prior_in_flight;
 	u32 prior_fackets;
-	int prior_packets;
+	int prior_packets = tp->packets_out;
 	int prior_sacked = tp->sacked_out;
 	int pkts_acked = 0;
+	int previous_packets_out = 0;
 	bool frto_cwnd = false;
 
 	/* If the ack is older than previous acks
@@ -3670,14 +3673,14 @@ static int tcp_ack(struct sock *sk, cons
 	sk->sk_err_soft = 0;
 	icsk->icsk_probes_out = 0;
 	tp->rcv_tstamp = tcp_time_stamp;
-	prior_packets = tp->packets_out;
 	if (!prior_packets)
 		goto no_queue;
 
 	/* See if we can take anything off of the retransmit queue. */
+	previous_packets_out = tp->packets_out;
 	flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
 
-	pkts_acked = prior_packets - tp->packets_out;
+	pkts_acked = previous_packets_out - tp->packets_out;
 
 	if (tp->frto_counter)
 		frto_cwnd = tcp_process_frto(sk, flag);
@@ -3692,7 +3695,7 @@ static int tcp_ack(struct sock *sk, cons
 			tcp_cong_avoid(sk, ack, prior_in_flight);
 		is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
 		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-				      is_dupack, flag);
+				      prior_packets, is_dupack, flag);
 	} else {
 		if ((flag & FLAG_DATA_ACKED) && !frto_cwnd)
 			tcp_cong_avoid(sk, ack, prior_in_flight);
@@ -3709,7 +3712,7 @@ no_queue:
 	/* If data was DSACKed, see if we can undo a cwnd reduction. */
 	if (flag & FLAG_DSACKING_ACK)
 		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-				      is_dupack, flag);
+				      prior_packets, is_dupack, flag);
 	/* If this ack opens up a zero window, clear backoff.  It was
 	 * being used to time the probes, and is probably far higher than
 	 * it needs to be for normal retransmission.
@@ -3729,7 +3732,7 @@ old_ack:
 	if (TCP_SKB_CB(skb)->sacked) {
 		flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
 		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-				      is_dupack, flag);
+				      prior_packets, is_dupack, flag);
 	}
 
 	SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);
author maintainer
#53 lore raw

PATCH 53/95 xfrm: properly handle invalid states as an error

In reply to Greg Kroah-Hartman

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

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

From: Timo Teräs <[email protected]>

[ Upstream commit 497574c72c9922cf20c12aed15313c389f722fa0 ]

The error exit path needs err explicitly set. Otherwise it returns success and the only caller, xfrm_output_resume(), would oops in skb_dst(skb)->ops derefence as skb_dst(skb) is NULL.

Bug introduced in commit bb65a9cb (xfrm: removes a superfluous check and add a statistic).

---
 net/xfrm/xfrm_output.c |    1 +
 1 file changed, 1 insertion(+)
net/xfrm/xfrm_output.c +1 -0
@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buf
 
 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
+			err = -EINVAL;
 			goto error;
 		}
 
author maintainer
#54 lore raw

PATCH 54/95 tcp: xps: fix reordering issues

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 547669d483e5783d722772af1483fa474da7caf9 ]

commit 3853b5841c01a ("xps: Improvements in TX queue selection") introduced ooo_okay flag, but the condition to set it is slightly wrong.

In our traces, we have seen ACK packets being received out of order, and RST packets sent in response.

We should test if we have any packets still in host queue.

---
 net/ipv4/tcp_output.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
net/ipv4/tcp_output.c +6 -4
@@ -1032,11 +1032,13 @@ static int tcp_transmit_skb(struct sock
 							   &md5);
 	tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
 
-	if (tcp_packets_in_flight(tp) == 0) {
+	if (tcp_packets_in_flight(tp) == 0)
 		tcp_ca_event(sk, CA_EVENT_TX_START);
-		skb->ooo_okay = 1;
-	} else
-		skb->ooo_okay = 0;
+
+	/* if no packet is in qdisc/device queue, then allow XPS to select
+	 * another queue.
+	 */
+	skb->ooo_okay = sk_wmem_alloc_get(sk) == 0;
 
 	skb_push(skb, tcp_header_size);
 	skb_reset_transport_header(skb);
author maintainer
#55 lore raw

PATCH 55/95 ip_tunnel: fix kernel panic with icmp_dest_unreach

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit a622260254ee481747cceaaa8609985b29a31565 ]

Daniel Petre reported crashes in icmp_dst_unreach() with following call graph:

Daniel found a similar problem mentioned in
http://lkml.indiana.edu/hypermail/linux/kernel/1007.0/00961.html

And indeed this is the root cause : skb->cb[] contains data fooling IP stack.

We must clear IPCB in ip_tunnel_xmit() sooner in case dst_link_failure() is called. Or else skb->cb[] might contain garbage from GSO segmentation layer.

A similar fix was tested on linux-3.9, but gre code was refactored in linux-3.10. I'll send patches for stable kernels as well.

Many thanks to Daniel for providing reports, patches and testing !

---
 net/ipv4/ip_gre.c |    2 +-
 net/ipv4/ipip.c   |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
net/ipv4/ip_gre.c +1 -1
@@ -804,6 +804,7 @@ static netdev_tx_t ipgre_tunnel_xmit(str
 		tiph = &tunnel->parms.iph;
 	}
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	if ((dst = tiph->daddr) == 0) {
 		/* NBMA tunnel */
 
@@ -952,7 +953,6 @@ static netdev_tx_t ipgre_tunnel_xmit(str
 	skb_push(skb, gre_hlen);
 	skb_reset_network_header(skb);
 	skb_set_transport_header(skb, sizeof(*iph));
-	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
 			      IPSKB_REROUTED);
 	skb_dst_drop(skb);
net/ipv4/ipip.c +1 -1
@@ -491,6 +491,7 @@ static netdev_tx_t ipip_tunnel_xmit(stru
 	if (tos & 1)
 		tos = old_iph->tos;
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	if (!dst) {
 		/* NBMA tunnel */
 		if ((rt = skb_rtable(skb)) == NULL) {
@@ -573,7 +574,6 @@ static netdev_tx_t ipip_tunnel_xmit(stru
 	skb->transport_header = skb->network_header;
 	skb_push(skb, sizeof(struct iphdr));
 	skb_reset_network_header(skb);
-	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
 			      IPSKB_REROUTED);
 	skb_dst_drop(skb);
author maintainer
#56 lore raw

PATCH 56/95 net: phy: fix a bug when verify the EEE support

In reply to Greg Kroah-Hartman

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

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

From: Giuseppe CAVALLARO <[email protected]>

[ Upstream commit 9a9c56cb34e65000d1f0a4b7553399bfcf7c5a52 ]

The phy_init_eee has to exit with an error when the local device and its link partner both do not support EEE. So this patch fixes a problem when verify this.

---
 drivers/net/phy/phy.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/phy.c +1 -1
@@ -1092,7 +1092,7 @@ int phy_init_eee(struct phy_device *phyd
 		adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
 		lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
 		idx = phy_find_setting(phydev->speed, phydev->duplex);
-		if ((lp & adv & settings[idx].setting))
+		if (!(lp & adv & settings[idx].setting))
 			goto eee_exit;
 
 		if (clk_stop_enable) {
author maintainer
#57 lore raw

PATCH 57/95 ipv4: fix redirect handling for TCP packets

In reply to Greg Kroah-Hartman

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

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

From: Michal Kubecek <[email protected]>

[ Upstream commit f96ef988cc603487c03a6de07807b06cbe641829 ]

Unlike ipv4_redirect() and ipv4_sk_redirect(), ip_do_redirect() doesn't call __build_flow_key() directly but via ip_rt_build_flow_key() wrapper. This leads to __build_flow_key() getting pointer to IPv4 header of the ICMP redirect packet rather than pointer to the embedded IPv4 header of the packet initiating the redirect.

As a result, handling of ICMP redirects initiated by TCP packets is broken. Issue was introduced by

	4895c771c ("ipv4: Add FIB nexthop exceptions.")
---
 net/ipv4/route.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/ipv4/route.c +6 -1
@@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_en
 {
 	struct rtable *rt;
 	struct flowi4 fl4;
+	const struct iphdr *iph = (const struct iphdr *) skb->data;
+	int oif = skb->dev->ifindex;
+	u8 tos = RT_TOS(iph->tos);
+	u8 prot = iph->protocol;
+	u32 mark = skb->mark;
 
 	rt = (struct rtable *) dst;
 
-	ip_rt_build_flow_key(&fl4, sk, skb);
+	__build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
 	__ip_do_redirect(rt, skb, &fl4, true);
 }
 
author maintainer
#58 lore raw

PATCH 58/95 net: Block MSG_CMSG_COMPAT in send(m)msg and recv(m)msg

In reply to Greg Kroah-Hartman

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

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

From: Andy Lutomirski <[email protected]>

[ Upstream commits 1be374a0518a288147c6a7398792583200a67261 and
a7526eb5d06b0084ef12d7b168d008fcf516caab ]

MSG_CMSG_COMPAT is (AFAIK) not intended to be part of the API -- it's a hack that steals a bit to indicate to other networking code that a compat entry was used. So don't allow it from a non-compat syscall.

This prevents an oops when running this code:

int main()

{
	int s;
	struct sockaddr_in addr;
	struct msghdr *hdr;

	char *highpage = mmap((void*)(TASK_SIZE_MAX - 4096), 4096,
	                      PROT_READ | PROT_WRITE,
	                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
	if (highpage == MAP_FAILED)
		err(1, "mmap");

	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1)
		err(1, "socket");

        addr.sin_family = AF_INET;
        addr.sin_port = htons(1);
        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) != 0)
		err(1, "connect");

	void *evil = highpage + 4096 - COMPAT_MSGHDR_SIZE;
	printf("Evil address is %p\n", evil);

	if (syscall(__NR_sendmmsg, s, evil, 1, MSG_CMSG_COMPAT) < 0)
		err(1, "sendmmsg");

	return 0;
}
---
 include/linux/socket.h |    3 ++
 net/compat.c           |   13 ++++++++--
 net/socket.c           |   61 +++++++++++++++++++++++++++++++++----------------
 3 files changed, 56 insertions(+), 21 deletions(-)
include/linux/socket.h +3 -0
@@ -321,6 +321,9 @@ extern int put_cmsg(struct msghdr*, int
 
 struct timespec;
 
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
+extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
+extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
 extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 			  unsigned int flags, struct timespec *timeout);
 extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
net/compat.c +11 -2
@@ -734,19 +734,25 @@ static unsigned char nas[21] = {
 
 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-	return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+	if (flags & MSG_CMSG_COMPAT)
+		return -EINVAL;
+	return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
 				    unsigned int vlen, unsigned int flags)
 {
+	if (flags & MSG_CMSG_COMPAT)
+		return -EINVAL;
 	return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
 			      flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-	return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+	if (flags & MSG_CMSG_COMPAT)
+		return -EINVAL;
+	return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags)
@@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int
 	int datagrams;
 	struct timespec ktspec;
 
+	if (flags & MSG_CMSG_COMPAT)
+		return -EINVAL;
+
 	if (COMPAT_USE_64BIT_TIME)
 		return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
 				      flags | MSG_CMSG_COMPAT,
net/socket.c +42 -19

142 lines not on this page · raw message

author maintainer
#59 lore raw

PATCH 59/95 net/core/sock.c: add missing VSOCK string in af_family_*_key_strings

In reply to Greg Kroah-Hartman

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

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

From: Federico Vaga <[email protected]>

[ Upstream commit 456db6a4d495f40777da6f1f32f62f13026f52db ]

The three arrays of strings: af_family_key_strings, af_family_slock_key_strings and af_family_clock_key_strings have not VSOCK's string

---
 net/core/sock.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/core/sock.c +3 -3
@@ -210,7 +210,7 @@ static const char *const af_family_key_s
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
   "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
-  "sk_lock-AF_NFC"   , "sk_lock-AF_MAX"
+  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_MAX"
 };
 static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -226,7 +226,7 @@ static const char *const af_family_slock
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
   "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
-  "slock-AF_NFC"   , "slock-AF_MAX"
+  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_MAX"
 };
 static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -242,7 +242,7 @@ static const char *const af_family_clock
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
   "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
-  "clock-AF_NFC"   , "clock-AF_MAX"
+  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_MAX"
 };
 
 /*
author maintainer
#60 lore raw

PATCH 60/95 tuntap: forbid changing mq flag for persistent device

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 8e6d91ae0917bf934ed86411148f79d904728d51 ]

We currently allow changing the mq flag (IFF_MULTI_QUEUE) for a persistent device. This will result a mismatch between the number the queues in netdev and tuntap. This is because we only allocate a 1q netdevice when IFF_MULTI_QUEUE was not specified, so when we set the IFF_MULTI_QUEUE and try to attach more queues later, netif_set_real_num_tx_queues() may fail which result a single queue netdevice with multiple sockets attached.

Solve this by disallowing changing the mq flag for persistent device.

Bug was introduced by commit edfb6a148ce62e5e19354a1dcd9a34e00815c2a1 (tuntap: reduce memory using of queues).

---
 drivers/net/tun.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/net/tun.c +4 -0
@@ -1585,6 +1585,10 @@ static int tun_set_iff(struct net *net,
 		else
 			return -EINVAL;
 
+		if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) !=
+		    !!(tun->flags & TUN_TAP_MQ))
+			return -EINVAL;
+
 		if (tun_not_capable(tun))
 			return -EPERM;
 		err = security_tun_dev_open(tun->security);
author maintainer
#61 lore raw

PATCH 61/95 udp6: Fix udp fragmentation for tunnel traffic.

In reply to Greg Kroah-Hartman

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

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

From: Pravin B Shelar <[email protected]>

[ Upstream commit 1e2bd517c108816220f262d7954b697af03b5f9c ]

udp6 over GRE tunnel does not work after to GRE tso changes. GRE tso handler passes inner packet but keeps track of outer header start in SKB_GSO_CB(skb)->mac_offset. udp6 fragment need to take care of outer header, which start at the mac_offset, while adding fragment header.
This bug is introduced by commit 68c3316311 (GRE: Add TCP segmentation offload for GRE).

---
 include/linux/skbuff.h |   15 +++++++++++++++
 net/ipv6/udp_offload.c |   20 ++++++++++++--------
 2 files changed, 27 insertions(+), 8 deletions(-)
include/linux/skbuff.h +15 -0
@@ -2761,6 +2761,21 @@ static inline int skb_tnl_header_len(con
 		SKB_GSO_CB(inner_skb)->mac_offset;
 }
 
+static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra)
+{
+	int new_headroom, headroom;
+	int ret;
+
+	headroom = skb_headroom(skb);
+	ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC);
+	if (ret)
+		return ret;
+
+	new_headroom = skb_headroom(skb);
+	SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom);
+	return 0;
+}
+
 static inline bool skb_is_gso(const struct sk_buff *skb)
 {
 	return skb_shinfo(skb)->gso_size;
net/ipv6/udp_offload.c +12 -8
@@ -42,11 +42,12 @@ static struct sk_buff *udp6_ufo_fragment
 	unsigned int mss;
 	unsigned int unfrag_ip6hlen, unfrag_len;
 	struct frag_hdr *fptr;
-	u8 *mac_start, *prevhdr;
+	u8 *packet_start, *prevhdr;
 	u8 nexthdr;
 	u8 frag_hdr_sz = sizeof(struct frag_hdr);
 	int offset;
 	__wsum csum;
+	int tnl_hlen;
 
 	mss = skb_shinfo(skb)->gso_size;
 	if (unlikely(skb->len <= mss))
@@ -77,9 +78,11 @@ static struct sk_buff *udp6_ufo_fragment
 	skb->ip_summed = CHECKSUM_NONE;
 
 	/* Check if there is enough headroom to insert fragment header. */
-	if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) &&
-	    pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
-		goto out;
+	tnl_hlen = skb_tnl_header_len(skb);
+	if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
+		if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
+			goto out;
+	}
 
 	/* Find the unfragmentable header and shift it left by frag_hdr_sz
 	 * bytes to insert fragment header.
@@ -87,11 +90,12 @@ static struct sk_buff *udp6_ufo_fragment
 	unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
 	nexthdr = *prevhdr;
 	*prevhdr = NEXTHDR_FRAGMENT;
-	unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +
-		     unfrag_ip6hlen;
-	mac_start = skb_mac_header(skb);
-	memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len);
+	unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) +
+		     unfrag_ip6hlen + tnl_hlen;
+	packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset;
+	memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len);
 
+	SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz;
 	skb->mac_header -= frag_hdr_sz;
 	skb->network_header -= frag_hdr_sz;
 
author maintainer
#62 lore raw

PATCH 62/95 net: force a reload of first item in hlist_nulls_for_each_entry_rcu

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit c87a124a5d5e8cf8e21c4363c3372bcaf53ea190 ]

Roman Gushchin discovered that udp4_lib_lookup2() was not reloading first item in the rcu protected list, in case the loop was restarted.

This produced soft lockups as in https://lkml.org/lkml/2013/4/16/37

rcu_dereference(X)/ACCESS_ONCE(X) seem to not work as intended if X is ptr->field :

In some cases, gcc caches the value or ptr->field in a register.

Use a barrier() to disallow such caching, as documented in Documentation/atomic_ops.txt line 114

Thanks a lot to Roman for providing analysis and numerous patches.

---
 include/linux/rculist_nulls.h |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
include/linux/rculist_nulls.h +6 -1
@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_
  * @head:	the head for your list.
  * @member:	the name of the hlist_nulls_node within the struct.
  *
+ * The barrier() is needed to make sure compiler doesn't cache first element [1],
+ * as this loop can be restarted [2]
+ * [1] Documentation/atomic_ops.txt around line 114
+ * [2] Documentation/RCU/rculist_nulls.txt around line 146
  */
 #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member)			\
-	for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));		\
+	for (({barrier();}),							\
+	     pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));		\
 		(!is_a_nulls(pos)) &&						\
 		({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
 		pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
author maintainer
#63 lore raw

PATCH 63/95 net_sched: restore "overhead xxx" handling

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 01cb71d2d47b78354358e4bb938bb06323e17498 ]

commit 56b765b79 ("htb: improved accuracy at high rates") broke the "overhead xxx" handling, as well as the "linklayer atm" attribute.

tc class add ... htb rate X ceil Y linklayer atm overhead 10

This patch restores the "overhead xxx" handling, for htb, tbf and act_police

The "linklayer atm" thing needs a separate fix.

---
 include/net/sch_generic.h |   18 +++++++++++-------
 net/sched/act_police.c    |    8 ++++----
 net/sched/sch_generic.c   |    8 +++++---
 net/sched/sch_htb.c       |    8 ++++----
 net/sched/sch_tbf.c       |    8 ++++----
 5 files changed, 28 insertions(+), 22 deletions(-)
include/net/sch_generic.h +11 -7
@@ -679,22 +679,26 @@ static inline struct sk_buff *skb_act_cl
 #endif
 
 struct psched_ratecfg {
-	u64 rate_bps;
-	u32 mult;
-	u32 shift;
+	u64	rate_bps;
+	u32	mult;
+	u16	overhead;
+	u8	shift;
 };
 
 static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
 				unsigned int len)
 {
-	return ((u64)len * r->mult) >> r->shift;
+	return ((u64)(len + r->overhead) * r->mult) >> r->shift;
 }
 
-extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate);
+extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf);
 
-static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r)
+static inline void psched_ratecfg_getrate(struct tc_ratespec *res,
+					  const struct psched_ratecfg *r)
 {
-	return r->rate_bps >> 3;
+	memset(res, 0, sizeof(*res));
+	res->rate = r->rate_bps >> 3;
+	res->overhead = r->overhead;
 }
 
 #endif
net/sched/act_police.c +4 -4
@@ -231,14 +231,14 @@ override:
 	}
 	if (R_tab) {
 		police->rate_present = true;
-		psched_ratecfg_precompute(&police->rate, R_tab->rate.rate);
+		psched_ratecfg_precompute(&police->rate, &R_tab->rate);
 		qdisc_put_rtab(R_tab);
 	} else {
 		police->rate_present = false;
 	}
 	if (P_tab) {
 		police->peak_present = true;
-		psched_ratecfg_precompute(&police->peak, P_tab->rate.rate);
+		psched_ratecfg_precompute(&police->peak, &P_tab->rate);
 		qdisc_put_rtab(P_tab);
 	} else {
 		police->peak_present = false;
@@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb,
 	};
 
 	if (police->rate_present)
-		opt.rate.rate = psched_ratecfg_getrate(&police->rate);
+		psched_ratecfg_getrate(&opt.rate, &police->rate);
 	if (police->peak_present)
-		opt.peakrate.rate = psched_ratecfg_getrate(&police->peak);
+		psched_ratecfg_getrate(&opt.peakrate, &police->peak);
 	if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
 		goto nla_put_failure;
 	if (police->tcfp_result &&
net/sched/sch_generic.c +5 -3
@@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev
 	WARN_ON(timer_pending(&dev->watchdog_timer));
 }
 
-void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate)
+void psched_ratecfg_precompute(struct psched_ratecfg *r,
+			       const struct tc_ratespec *conf)
 {
 	u64 factor;
 	u64 mult;
 	int shift;
 
-	r->rate_bps = (u64)rate << 3;
-	r->shift = 0;
+	memset(r, 0, sizeof(*r));
+	r->overhead = conf->overhead;
+	r->rate_bps = (u64)conf->rate << 3;
 	r->mult = 1;
 	/*
 	 * Calibrate mult, shift so that token counting is accurate
net/sched/sch_htb.c +4 -4
@@ -1089,9 +1089,9 @@ static int htb_dump_class(struct Qdisc *
 
 	memset(&opt, 0, sizeof(opt));
 
-	opt.rate.rate = psched_ratecfg_getrate(&cl->rate);
+	psched_ratecfg_getrate(&opt.rate, &cl->rate);
 	opt.buffer = PSCHED_NS2TICKS(cl->buffer);
-	opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil);
+	psched_ratecfg_getrate(&opt.ceil, &cl->ceil);
 	opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer);
 	opt.quantum = cl->quantum;
 	opt.prio = cl->prio;
@@ -1458,8 +1458,8 @@ static int htb_change_class(struct Qdisc
 			cl->prio = TC_HTB_NUMPRIO - 1;
 	}
 
-	psched_ratecfg_precompute(&cl->rate, hopt->rate.rate);
-	psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate);
+	psched_ratecfg_precompute(&cl->rate, &hopt->rate);
+	psched_ratecfg_precompute(&cl->ceil, &hopt->ceil);
 
 	cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
 	cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer);
net/sched/sch_tbf.c +4 -4
@@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch,
 	q->tokens = q->buffer;
 	q->ptokens = q->mtu;
 
-	psched_ratecfg_precompute(&q->rate, rtab->rate.rate);
+	psched_ratecfg_precompute(&q->rate, &rtab->rate);
 	if (ptab) {
-		psched_ratecfg_precompute(&q->peak, ptab->rate.rate);
+		psched_ratecfg_precompute(&q->peak, &ptab->rate);
 		q->peak_present = true;
 	} else {
 		q->peak_present = false;
@@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, s
 		goto nla_put_failure;
 
 	opt.limit = q->limit;
-	opt.rate.rate = psched_ratecfg_getrate(&q->rate);
+	psched_ratecfg_getrate(&opt.rate, &q->rate);
 	if (q->peak_present)
-		opt.peakrate.rate = psched_ratecfg_getrate(&q->peak);
+		psched_ratecfg_getrate(&opt.peakrate, &q->peak);
 	else
 		memset(&opt.peakrate, 0, sizeof(opt.peakrate));
 	opt.mtu = PSCHED_NS2TICKS(q->mtu);
author maintainer
#64 lore raw

PATCH 64/95 ipv6: assign rt6_info to inet6_ifaddr in init_loopback

In reply to Greg Kroah-Hartman

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

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

From: Gao feng <[email protected]>

[ Upstream commit 534c877928a16ae5f9776436a497109639bf67dc ]

Commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f
"net IPv6 : Fix broken IPv6 routing table after loopback down-up" forgot to assign rt6_info to the inet6_ifaddr.
When disable the net device, the rt6_info which allocated in init_loopback will not be destroied in __ipv6_ifa_notify.

This will trigger the waring message below

[23527.916091] unregister_netdevice: waiting for tap0 to become free. Usage count = 1
---
 net/ipv6/addrconf.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv6/addrconf.c +3 -1
@@ -2560,8 +2560,10 @@ static void init_loopback(struct net_dev
 			sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
 
 			/* Failure cases are ignored */
-			if (!IS_ERR(sp_rt))
+			if (!IS_ERR(sp_rt)) {
+				sp_ifa->rt = sp_rt;
 				ip6_ins_rt(sp_rt);
+			}
 		}
 		read_unlock_bh(&idev->lock);
 	}
author maintainer
#65 lore raw

PATCH 65/95 net_sched: htb: do not mix 1ns and 64ns time units

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 5343a7f8be11951cb3095b91e8e4eb506cfacc0f ]

commit 56b765b79 ("htb: improved accuracy at high rates") added another regression for low rates, because it mixes 1ns and 64ns time units.

So the maximum delay (mbuffer) was not 60 second, but 937 ms.

Lets convert all time fields to 1ns as 64bit arches are becoming the norm.

---
 net/sched/sch_htb.c |   34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)
net/sched/sch_htb.c +17 -17
@@ -109,7 +109,7 @@ struct htb_class {
 	} un;
 	struct rb_node node[TC_HTB_NUMPRIO];	/* node for self or feed tree */
 	struct rb_node pq_node;	/* node for event queue */
-	psched_time_t pq_key;
+	s64	pq_key;
 
 	int prio_activity;	/* for which prios are we active */
 	enum htb_cmode cmode;	/* current mode of the class */
@@ -121,10 +121,10 @@ struct htb_class {
 	/* token bucket parameters */
 	struct psched_ratecfg rate;
 	struct psched_ratecfg ceil;
-	s64 buffer, cbuffer;	/* token bucket depth/rate */
-	psched_tdiff_t mbuffer;	/* max wait time */
-	s64 tokens, ctokens;	/* current number of tokens */
-	psched_time_t t_c;	/* checkpoint time */
+	s64	buffer, cbuffer;	/* token bucket depth/rate */
+	s64	mbuffer;		/* max wait time */
+	s64	tokens, ctokens;	/* current number of tokens */
+	s64	t_c;			/* checkpoint time */
 };
 
 struct htb_sched {
@@ -141,15 +141,15 @@ struct htb_sched {
 	struct rb_root wait_pq[TC_HTB_MAXDEPTH];
 
 	/* time of nearest event per level (row) */
-	psched_time_t near_ev_cache[TC_HTB_MAXDEPTH];
+	s64	near_ev_cache[TC_HTB_MAXDEPTH];
 
 	int defcls;		/* class where unclassified flows go to */
 
 	/* filters for qdisc itself */
 	struct tcf_proto *filter_list;
 
-	int rate2quantum;	/* quant = rate / rate2quantum */
-	psched_time_t now;	/* cached dequeue time */
+	int	rate2quantum;	/* quant = rate / rate2quantum */
+	s64	now;	/* cached dequeue time */
 	struct qdisc_watchdog watchdog;
 
 	/* non shaped skbs; let them go directly thru */
@@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_
  * next pending event (0 for no event in pq, q->now for too many events).
  * Note: Applied are events whose have cl->pq_key <= q->now.
  */
-static psched_time_t htb_do_events(struct htb_sched *q, int level,
-				   unsigned long start)
+static s64 htb_do_events(struct htb_sched *q, int level,
+			 unsigned long start)
 {
 	/* don't run for longer than 2 jiffies; 2 is used instead of
 	 * 1 to simplify things when jiffy is going to be incremented
@@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struc
 	struct sk_buff *skb;
 	struct htb_sched *q = qdisc_priv(sch);
 	int level;
-	psched_time_t next_event;
+	s64 next_event;
 	unsigned long start_at;
 
 	/* try to dequeue direct packets as high prio (!) to minimize cpu work */
@@ -880,7 +880,7 @@ ok:
 	for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
 		/* common case optimization - skip event handler quickly */
 		int m;
-		psched_time_t event;
+		s64 event;
 
 		if (q->now >= q->near_ev_cache[level]) {
 			event = htb_do_events(q, level, start_at);
@@ -1116,8 +1116,8 @@ htb_dump_class_stats(struct Qdisc *sch,
 
 	if (!cl->level && cl->un.leaf.q)
 		cl->qstats.qlen = cl->un.leaf.q->q.qlen;
-	cl->xstats.tokens = cl->tokens;
-	cl->xstats.ctokens = cl->ctokens;
+	cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens);
+	cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens);
 
 	if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
 	    gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 ||
@@ -1199,7 +1199,7 @@ static void htb_parent_to_leaf(struct ht
 	parent->un.leaf.q = new_q ? new_q : &noop_qdisc;
 	parent->tokens = parent->buffer;
 	parent->ctokens = parent->cbuffer;
-	parent->t_c = psched_get_time();
+	parent->t_c = ktime_to_ns(ktime_get());
 	parent->cmode = HTB_CAN_SEND;
 }
 
@@ -1416,8 +1416,8 @@ static int htb_change_class(struct Qdisc
 		/* set class to be in HTB_CAN_SEND state */
 		cl->tokens = PSCHED_TICKS2NS(hopt->buffer);
 		cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer);
-		cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC;	/* 1min */
-		cl->t_c = psched_get_time();
+		cl->mbuffer = 60ULL * NSEC_PER_SEC;	/* 1min */
+		cl->t_c = ktime_to_ns(ktime_get());
 		cl->cmode = HTB_CAN_SEND;
 
 		/* attach to the hash list and parent's family */
author maintainer
#66 lore raw

PATCH 66/95 vhost_net: clear msg.control for non-zerocopy case during tx

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 4364d5f96eed7994a2c625bd9216656e55fba0cb ]

When we decide not use zero-copy, msg.control should be set to NULL otherwise macvtap/tap may set zerocopy callbacks which may decrease the kref of ubufs wrongly.

Bug were introduced by commit cedb9bdce099206290a2bdd02ce47a7b253b6a84 (vhost-net: skip head management if no outstanding).

This solves the following warnings:

WARNING: at include/linux/kref.h:47 handle_tx+0x477/0x4b0 [vhost_net]()
Modules linked in: vhost_net macvtap macvlan tun nfsd exportfs bridge stp llc openvswitch kvm_amd kvm bnx2 megaraid_sas [last unloaded: tun]
CPU: 5 PID: 8670 Comm: vhost-8668 Not tainted 3.10.0-rc2+ #1566
Hardware name: Dell Inc. PowerEdge R715/00XHKG, BIOS 1.5.2 04/19/2011
ffffffffa0198323 ffff88007c9ebd08 ffffffff81796b73 ffff88007c9ebd48
ffffffff8103d66b 000000007b773e20 ffff8800779f0000 ffff8800779f43f0
ffff8800779f8418 000000000000015c 0000000000000062 ffff88007c9ebd58
Call Trace:
[<ffffffff81796b73>] dump_stack+0x19/0x1e
[<ffffffff8103d66b>] warn_slowpath_common+0x6b/0xa0
[<ffffffff8103d6b5>] warn_slowpath_null+0x15/0x20
[<ffffffffa0197627>] handle_tx+0x477/0x4b0 [vhost_net]
[<ffffffffa0197690>] handle_tx_kick+0x10/0x20 [vhost_net]
[<ffffffffa019541e>] vhost_worker+0xfe/0x1a0 [vhost_net]
[<ffffffffa0195320>] ? vhost_attach_cgroups_work+0x30/0x30 [vhost_net]
[<ffffffffa0195320>] ? vhost_attach_cgroups_work+0x30/0x30 [vhost_net]
[<ffffffff81061f46>] kthread+0xc6/0xd0
[<ffffffff81061e80>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff817a1aec>] ret_from_fork+0x7c/0xb0
[<ffffffff81061e80>] ? kthread_freezable_should_stop+0x70/0x70
---
 drivers/vhost/net.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vhost/net.c +2 -1
@@ -353,7 +353,8 @@ static void handle_tx(struct vhost_net *
 				kref_get(&ubufs->kref);
 			}
 			vq->upend_idx = (vq->upend_idx + 1) % UIO_MAXIOV;
-		}
+		} else
+			msg.msg_control = NULL;
 		/* TODO: Check specific error and bomb out unless ENOBUFS? */
 		err = sock->ops->sendmsg(NULL, sock, &msg, len);
 		if (unlikely(err < 0)) {
author maintainer
#67 lore raw

PATCH 67/95 net: sctp: fix NULL pointer dereference in socket destruction

In reply to Greg Kroah-Hartman

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

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

From: Daniel Borkmann <[email protected]>

[ Upstream commit 1abd165ed757db1afdefaac0a4bc8a70f97d258c ]

While stress testing sctp sockets, I hit the following panic:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
IP: [<ffffffffa0490c4e>] sctp_endpoint_free+0xe/0x40 [sctp]
PGD 7cead067 PUD 7ce76067 PMD 0
Oops: 0000 [#1] SMP
Modules linked in: sctp(F) libcrc32c(F) [...]
CPU: 7 PID: 2950 Comm: acc Tainted: GF            3.10.0-rc2+ #1
Hardware name: Dell Inc. PowerEdge T410/0H19HD, BIOS 1.6.3 02/01/2011
task: ffff88007ce0e0c0 ti: ffff88007b568000 task.ti: ffff88007b568000
RIP: 0010:[<ffffffffa0490c4e>]  [<ffffffffa0490c4e>] sctp_endpoint_free+0xe/0x40 [sctp]
RSP: 0018:ffff88007b569e08  EFLAGS: 00010292
RAX: 0000000000000000 RBX: ffff88007db78a00 RCX: dead000000200200
RDX: ffffffffa049fdb0 RSI: ffff8800379baf38 RDI: 0000000000000000
RBP: ffff88007b569e18 R08: ffff88007c230da0 R09: 0000000000000001
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: ffff880077990d00 R14: 0000000000000084 R15: ffff88007db78a00
FS:  00007fc18ab61700(0000) GS:ffff88007fc60000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000020 CR3: 000000007cf9d000 CR4: 00000000000007e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
 ffff88007b569e38 ffff88007db78a00 ffff88007b569e38 ffffffffa049fded
 ffffffff81abf0c0 ffff88007db78a00 ffff88007b569e58 ffffffff8145b60e
 0000000000000000 0000000000000000 ffff88007b569eb8 ffffffff814df36e
Call Trace:
 [<ffffffffa049fded>] sctp_destroy_sock+0x3d/0x80 [sctp]
 [<ffffffff8145b60e>] sk_common_release+0x1e/0xf0
 [<ffffffff814df36e>] inet_create+0x2ae/0x350
 [<ffffffff81455a6f>] __sock_create+0x11f/0x240
 [<ffffffff81455bf0>] sock_create+0x30/0x40
 [<ffffffff8145696c>] SyS_socket+0x4c/0xc0
 [<ffffffff815403be>] ? do_page_fault+0xe/0x10
 [<ffffffff8153cb32>] ? page_fault+0x22/0x30
 [<ffffffff81544e02>] system_call_fastpath+0x16/0x1b
Code: 0c c9 c3 66 2e 0f 1f 84 00 00 00 00 00 e8 fb fe ff ff c9 c3 66 0f
      1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 <48>
      8b 47 20 48 89 fb c6 47 1c 01 c6 40 12 07 e8 9e 68 01 00 48
RIP  [<ffffffffa0490c4e>] sctp_endpoint_free+0xe/0x40 [sctp]
 RSP <ffff88007b569e08>
CR2: 0000000000000020
---[ end trace e0d71ec1108c1dd9 ]---

I did not hit this with the lksctp-tools functional tests, but with a small, multi-threaded test program, that heavily allocates, binds, listens and waits in accept on sctp sockets, and then randomly kills some of them (no need for an actual client in this case to hit this). Then, again, allocating, binding, etc, and then killing child processes.

This panic then only occurs when ``echo 1 > /proc/sys/net/sctp/auth_enable'' is set. The cause for that is actually very simple: in sctp_endpoint_init() we enter the path of sctp_auth_init_hmacs(). There, we try to allocate our crypto transforms through crypto_alloc_hash(). In our scenario, it then can happen that crypto_alloc_hash() fails with -EINTR from crypto_larval_wait(), thus we bail out and release the socket via sk_common_release(), sctp_destroy_sock() and hit the NULL pointer dereference as soon as we try to access members in the endpoint during sctp_endpoint_free(), since endpoint at that time is still NULL. Now, if we have that case, we do not need to do any cleanup work and just leave the destruction handler.

---
 net/sctp/socket.c |    6 ++++++
 1 file changed, 6 insertions(+)
net/sctp/socket.c +6 -0
@@ -4002,6 +4002,12 @@ SCTP_STATIC void sctp_destroy_sock(struc
 
 	/* Release our hold on the endpoint. */
 	sp = sctp_sk(sk);
+	/* This could happen during socket init, thus we bail out
+	 * early, since the rest of the below is not setup either.
+	 */
+	if (sp->ep == NULL)
+		return;
+
 	if (sp->do_auto_asconf) {
 		sp->do_auto_asconf = 0;
 		list_del(&sp->auto_asconf_list);
author maintainer
#68 lore raw

PATCH 68/95 tuntap: set SOCK_ZEROCOPY flag during open

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 19a6afb23e5d323e1245baa4e62755492b2f1200 ]

Commit 54f968d6efdbf7dec36faa44fc11f01b0e4d1990
(tuntap: move socket to tun_file) forgets to set SOCK_ZEROCOPY flag, which will prevent vhost_net from doing zercopy w/ tap. This patch fixes this by setting it during file open.

---
 drivers/net/tun.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/net/tun.c +2 -0
@@ -2154,6 +2154,8 @@ static int tun_chr_open(struct inode *in
 	set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
 	INIT_LIST_HEAD(&tfile->next);
 
+	sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
+
 	return 0;
 }
 
author maintainer
#69 lore raw

PATCH 69/95 team: check return value of team_get_port_by_index_rcu() for NULL

In reply to Greg Kroah-Hartman

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

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

From: Jiri Pirko <[email protected]>

[ Upstream commit 76c455decbbad31de21c727edb184a963f42b40b ]

team_get_port_by_index_rcu() might return NULL due to race between port removal and skb tx path. Panic is easily triggeable when txing packets and adding/removing port in a loop.

introduced by commit 3d249d4ca "net: introduce ethernet teaming device" and commit 753f993911b "team: introduce random mode" (for random mode)

---
 drivers/net/team/team_mode_roundrobin.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/net/team/team_mode_roundrobin.c +2 -0
@@ -52,6 +52,8 @@ static bool rr_transmit(struct team *tea
 
 	port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
 	port = team_get_port_by_index_rcu(team, port_index);
+	if (unlikely(!port))
+		goto drop;
 	port = __get_first_port_up(team, port);
 	if (unlikely(!port))
 		goto drop;
author maintainer
#70 lore raw

PATCH 70/95 team: move add to port list before port enablement

In reply to Greg Kroah-Hartman

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

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

From: Jiri Pirko <[email protected]>

[ Upstream commit 72df935d985c1575ed44ad2c8c653b28147993fa ]

team_port_enable() adds port to port_hashlist. Reader sees port in team_get_port_by_index_rcu() and returns it, but team_get_first_port_txable_rcu() tries to go through port_list, where the port is not inserted yet -> NULL pointer dereference.
Fix this by reordering port_list and port_hashlist insertion. Panic is easily triggeable when txing packets and adding/removing port in a loop.

Introduced by commit 3d249d4c "net: introduce ethernet teaming device"

---
 drivers/net/team/team.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/team/team.c +1 -1
@@ -1079,8 +1079,8 @@ static int team_port_add(struct team *te
 	}
 
 	port->index = -1;
-	team_port_enable(team, port);
 	list_add_tail_rcu(&port->list, &team->port_list);
+	team_port_enable(team, port);
 	__team_compute_features(team);
 	__team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
 	__team_options_change_check(team);
author maintainer
#71 lore raw

PATCH 71/95 packet: packet_getname_spkt: make sure string is always 0-terminated

In reply to Greg Kroah-Hartman

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

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

From: Daniel Borkmann <[email protected]>

[ Upstream commit 2dc85bf323515e59e15dfa858d1472bb25cad0fe ]

uaddr->sa_data is exactly of size 14, which is hard-coded here and passed as a size argument to strncpy(). A device name can be of size IFNAMSIZ (== 16), meaning we might leave the destination string unterminated. Thus, use strlcpy() and also sizeof() while we're at it. We need to memset the data area beforehand, since strlcpy does not padd the remaining buffer with zeroes for user space, so that we do not possibly leak anything.

---
 net/packet/af_packet.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
net/packet/af_packet.c +2 -3
@@ -2769,12 +2769,11 @@ static int packet_getname_spkt(struct so
 		return -EOPNOTSUPP;
 
 	uaddr->sa_family = AF_PACKET;
+	memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data));
 	rcu_read_lock();
 	dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
 	if (dev)
-		strncpy(uaddr->sa_data, dev->name, 14);
-	else
-		memset(uaddr->sa_data, 0, 14);
+		strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
 	rcu_read_unlock();
 	*uaddr_len = sizeof(*uaddr);
 
author maintainer
#72 lore raw

PATCH 72/95 l2tp: Fix PPP header erasure and memory leak

In reply to Greg Kroah-Hartman

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

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

From: Guillaume Nault <[email protected]>

[ Upstream commit 55b92b7a11690bc377b5d373872a6b650ae88e64 ]

Copy user data after PPP framing header. This prevents erasure of the added PPP header and avoids leaking two bytes of uninitialised memory at the end of skb's data buffer.

---
 net/l2tp/l2tp_ppp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/l2tp/l2tp_ppp.c +2 -2
@@ -346,12 +346,12 @@ static int pppol2tp_sendmsg(struct kiocb
 	skb_put(skb, 2);
 
 	/* Copy user data into skb */
-	error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
+	error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
+				 total_len);
 	if (error < 0) {
 		kfree_skb(skb);
 		goto error_put_sess_tun;
 	}
-	skb_put(skb, total_len);
 
 	l2tp_xmit_skb(session, skb, session->hdr_len);
 
author maintainer
#73 lore raw

PATCH 73/95 l2tp: Fix sendmsg() return value

In reply to Greg Kroah-Hartman

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

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

From: Guillaume Nault <[email protected]>

[ Upstream commit a6f79d0f26704214b5b702bbac525cb72997f984 ]

PPPoL2TP sockets should comply with the standard send*() return values (i.e. return number of bytes sent instead of 0 upon success).

---
 net/l2tp/l2tp_ppp.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/l2tp/l2tp_ppp.c +1 -1
@@ -358,7 +358,7 @@ static int pppol2tp_sendmsg(struct kiocb
 	sock_put(ps->tunnel_sock);
 	sock_put(sk);
 
-	return error;
+	return total_len;
 
 error_put_sess_tun:
 	sock_put(ps->tunnel_sock);
author maintainer
#74 lore raw

PATCH 74/95 sctp: fully initialize sctp_outq in sctp_outq_init

In reply to Greg Kroah-Hartman

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

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

From: Neil Horman <[email protected]>

[ Upstream commit c5c7774d7eb4397891edca9ebdf750ba90977a69 ]

In commit 2f94aabd9f6c925d77aecb3ff020f1cc12ed8f86
(refactor sctp_outq_teardown to insure proper re-initalization) we modified sctp_outq_teardown to use sctp_outq_init to fully re-initalize the outq structure. Steve West recently asked me why I removed the q->error = 0 initalization from sctp_outq_teardown. I did so because I was operating under the impression that sctp_outq_init would properly initalize that value for us, but it doesn't. sctp_outq_init operates under the assumption that the outq struct is all 0's (as it is when called from sctp_association_init), but using it in __sctp_outq_teardown violates that assumption. We should do a memset in sctp_outq_init to ensure that the entire structure is in a known state there instead.

---
 net/sctp/outqueue.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
net/sctp/outqueue.c +2 -6
@@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct
  */
 void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
 {
+	memset(q, 0, sizeof(struct sctp_outq));
+
 	q->asoc = asoc;
 	INIT_LIST_HEAD(&q->out_chunk_list);
 	INIT_LIST_HEAD(&q->control_chunk_list);
@@ -213,13 +215,7 @@ void sctp_outq_init(struct sctp_associat
 	INIT_LIST_HEAD(&q->sacked);
 	INIT_LIST_HEAD(&q->abandoned);
 
-	q->fast_rtx = 0;
-	q->outstanding_bytes = 0;
 	q->empty = 1;
-	q->cork  = 0;
-
-	q->malloced = 0;
-	q->out_qlen = 0;
 }
 
 /* Free the outqueue structure and any related pending chunks.
author maintainer
#75 lore raw

PATCH 75/95 net: sh_eth: fix incorrect RX length error if R8A7740

In reply to Greg Kroah-Hartman

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

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

From: Yoshihiro Shimoda <[email protected]>

[ Upstream commit dd019897358b815f7828dab90b51d51df4d3658d ]

This patch fixes an issue that the driver increments the "RX length error" on every buffer in sh_eth_rx() if the R8A7740.
This patch also adds a description about the Receive Frame Status bits.

---
 drivers/net/ethernet/renesas/sh_eth.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/renesas/sh_eth.c +11 -4
@@ -1100,16 +1100,23 @@ static int sh_eth_rx(struct net_device *
 		desc_status = edmac_to_cpu(mdp, rxdesc->status);
 		pkt_len = rxdesc->frame_length;
 
-#if defined(CONFIG_ARCH_R8A7740)
-		desc_status >>= 16;
-#endif
-
 		if (--boguscnt < 0)
 			break;
 
 		if (!(desc_status & RDFEND))
 			ndev->stats.rx_length_errors++;
 
+#if defined(CONFIG_ARCH_R8A7740)
+		/*
+		 * In case of almost all GETHER/ETHERs, the Receive Frame State
+		 * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
+		 * bit 0. However, in case of the R8A7740's GETHER, the RFS
+		 * bits are from bit 25 to bit 16. So, the driver needs right
+		 * shifting by 16.
+		 */
+		desc_status >>= 16;
+#endif
+
 		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
 				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
 			ndev->stats.rx_errors++;
author maintainer
#76 lore raw

PATCH 76/95 tuntap: correct the return value in tun_set_iff()

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit e8dbad66ef56074eadb41ed5998acd2320447018 ]

commit (3be8fbab tuntap: fix error return code in tun_set_iff()) breaks the creation of multiqueue tuntap since it forbids to create more than one queues for a multiqueue tuntap device. We need return 0 instead -EBUSY here since we don't want to re-initialize the device when one or more queues has been already attached. Add a comment and correct the return value to zero.

---
 drivers/net/tun.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/tun.c +6 -2
@@ -1600,8 +1600,12 @@ static int tun_set_iff(struct net *net,
 			return err;
 
 		if (tun->flags & TUN_TAP_MQ &&
-		    (tun->numqueues + tun->numdisabled > 1))
-			return -EBUSY;
+		    (tun->numqueues + tun->numdisabled > 1)) {
+			/* One or more queue has already been attached, no need
+			 * to initialize the device again.
+			 */
+			return 0;
+		}
 	}
 	else {
 		char *name;
author maintainer
#77 lore raw

PATCH 77/95 macvtap: set transport header before passing skb to lower device

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 9b4d669bc06c215d64f56f1eb0d4eb96e14d689d ]

Set the transport header for 1) some drivers (e.g ixgbe) needs l4 header 2) precise packet length estimation (introduced in 1def9238) needs l4 header to compute header length.

For the packets with partial checksum, the patch just set the transport header to csum_start. Otherwise tries to use skb_flow_dissect() to get l4 offset, if it fails, just pretend no l4 header.

---
 drivers/net/macvtap.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/net/macvtap.c +9 -0
@@ -21,6 +21,7 @@
 #include <net/rtnetlink.h>
 #include <net/sock.h>
 #include <linux/virtio_net.h>
+#include <net/flow_keys.h>
 
 /*
  * A macvtap queue is the central object of this driver, it connects
@@ -645,6 +646,7 @@ static ssize_t macvtap_get_user(struct m
 	int vnet_hdr_len = 0;
 	int copylen = 0;
 	bool zerocopy = false;
+	struct flow_keys keys;
 
 	if (q->flags & IFF_VNET_HDR) {
 		vnet_hdr_len = q->vnet_hdr_sz;
@@ -725,6 +727,13 @@ static ssize_t macvtap_get_user(struct m
 			goto err_kfree;
 	}
 
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
+	else if (skb_flow_dissect(skb, &keys))
+		skb_set_transport_header(skb, keys.thoff);
+	else
+		skb_set_transport_header(skb, ETH_HLEN);
+
 	rcu_read_lock_bh();
 	vlan = rcu_dereference_bh(q->vlan);
 	/* copy skb_ubuf_info for callback when skb has no error */
author maintainer
#78 lore raw

PATCH 78/95 tuntap: set transport header before passing it to kernel

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 38502af77e07b5d6650b9ff99a0b482d86366592 ]

Currently, for the packets receives from tuntap, before doing header check, kernel just reset the transport header in netif_receive_skb() which pretends no l4 header. This is suboptimal for precise packet length estimation (introduced in 1def9238) which needs correct l4 header for gso packets.

So this patch set the transport header to csum_start for partial checksum packets, otherwise it first try skb_flow_dissect(), if it fails, just reset the transport header.

---
 drivers/net/tun.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/net/tun.c +10 -0
@@ -70,6 +70,7 @@
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
+#include <net/flow_keys.h>
 
 /* Uncomment to enable debugging */
 /* #define TUN_DEBUG 1 */
@@ -1051,6 +1052,7 @@ static ssize_t tun_get_user(struct tun_s
 	bool zerocopy = false;
 	int err;
 	u32 rxhash;
+	struct flow_keys keys;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) > total_len)
@@ -1205,6 +1207,14 @@ static ssize_t tun_get_user(struct tun_s
 	}
 
 	skb_reset_network_header(skb);
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
+	else if (skb_flow_dissect(skb, &keys))
+		skb_set_transport_header(skb, keys.thoff);
+	else
+		skb_reset_transport_header(skb);
+
 	rxhash = skb_get_rxhash(skb);
 	netif_rx_ni(skb);
 
author maintainer
#79 lore raw

PATCH 79/95 packet: set transport header before doing xmit

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit c1aad275b0293d2b1905ec95a945422262470684 ]

Set the transport header for 1) some drivers (e.g ixgbe needs l4 header to do atr) 2) precise packet length estimation (introduced in 1def9238) needs l4 header to compute header length.

So this patch first tries to get l4 header for packet socket through skb_flow_dissect(), and pretend no l4 header if skb_flow_dissect() fails.

---
 net/packet/af_packet.c |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
net/packet/af_packet.c +21 -0
@@ -88,6 +88,7 @@
 #include <linux/virtio_net.h>
 #include <linux/errqueue.h>
 #include <linux/net_tstamp.h>
+#include <net/flow_keys.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -1343,6 +1344,7 @@ static int packet_sendmsg_spkt(struct ki
 	__be16 proto = 0;
 	int err;
 	int extra_len = 0;
+	struct flow_keys keys;
 
 	/*
 	 *	Get and verify the address.
@@ -1443,6 +1445,11 @@ retry:
 	if (unlikely(extra_len == 4))
 		skb->no_fcs = 1;
 
+	if (skb_flow_dissect(skb, &keys))
+		skb_set_transport_header(skb, keys.thoff);
+	else
+		skb_reset_transport_header(skb);
+
 	dev_queue_xmit(skb);
 	rcu_read_unlock();
 	return len;
@@ -1849,6 +1856,7 @@ static int tpacket_fill_skb(struct packe
 	struct page *page;
 	void *data;
 	int err;
+	struct flow_keys keys;
 
 	ph.raw = frame;
 
@@ -1874,6 +1882,11 @@ static int tpacket_fill_skb(struct packe
 	skb_reserve(skb, hlen);
 	skb_reset_network_header(skb);
 
+	if (skb_flow_dissect(skb, &keys))
+		skb_set_transport_header(skb, keys.thoff);
+	else
+		skb_reset_transport_header(skb);
+
 	if (po->tp_tx_has_off) {
 		int off_min, off_max, off;
 		off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll);
@@ -2130,6 +2143,7 @@ static int packet_snd(struct socket *soc
 	unsigned short gso_type = 0;
 	int hlen, tlen;
 	int extra_len = 0;
+	struct flow_keys keys;
 
 	/*
 	 *	Get and verify the address.
@@ -2282,6 +2296,13 @@ static int packet_snd(struct socket *soc
 		len += vnet_hdr_len;
 	}
 
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
+	else if (skb_flow_dissect(skb, &keys))
+		skb_set_transport_header(skb, keys.thoff);
+	else
+		skb_set_transport_header(skb, reserve);
+
 	if (unlikely(extra_len == 4))
 		skb->no_fcs = 1;
 
author maintainer
#80 lore raw

PATCH 80/95 netback: set transport header before passing it to kernel

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit f9ca8f74399f9195fd8e01f67a8424a8d33efa55 ]

Currently, for the packets receives from netback, before doing header check, kernel just reset the transport header in netif_receive_skb() which pretends non l4 header. This is suboptimal for precise packet length estimation (introduced in 1def9238: net_sched: more precise pkt_len computation) which needs correct l4 header for gso packets.

The patch just reuse the header probed by netback for partial checksum packets and tries to use skb_flow_dissect() for other cases, if both fail, just pretend no l4 header.

---
 drivers/net/xen-netback/netback.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/net/xen-netback/netback.c +12 -0
@@ -39,6 +39,7 @@
 #include <linux/udp.h>
 
 #include <net/tcp.h>
+#include <net/flow_keys.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
@@ -1352,6 +1353,7 @@ static int checksum_setup(struct xenvif
 	if (th >= skb_tail_pointer(skb))
 		goto out;
 
+	skb_set_transport_header(skb, 4 * iph->ihl);
 	skb->csum_start = th - skb->head;
 	switch (iph->protocol) {
 	case IPPROTO_TCP:
@@ -1665,6 +1667,7 @@ static void xen_netbk_tx_submit(struct x
 
 		skb->dev      = vif->dev;
 		skb->protocol = eth_type_trans(skb, skb->dev);
+		skb_reset_network_header(skb);
 
 		if (checksum_setup(vif, skb)) {
 			netdev_dbg(vif->dev,
@@ -1673,6 +1676,15 @@ static void xen_netbk_tx_submit(struct x
 			continue;
 		}
 
+		if (!skb_transport_header_was_set(skb)) {
+			struct flow_keys keys;
+
+			if (skb_flow_dissect(skb, &keys))
+				skb_set_transport_header(skb, keys.thoff);
+			else
+				skb_reset_transport_header(skb);
+		}
+
 		vif->dev->stats.rx_bytes += skb->len;
 		vif->dev->stats.rx_packets++;
 
author maintainer
#81 lore raw

PATCH 81/95 net_sched: better precise estimation on packet length for untrusted packets

In reply to Greg Kroah-Hartman

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

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

From: Jason Wang <[email protected]>

[ Upstream commit 15e5a030716468dce4032fa0f398d840fa2756f6 ]

gso_segs were reset to zero when kernel receive packets from untrusted source. But we use this zero value to estimate precise packet len which is wrong. So this patch tries to estimate the correct gso_segs value before using it in qdisc_pkt_len_init().

---
 net/core/dev.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
net/core/dev.c +7 -1
@@ -2592,6 +2592,7 @@ static void qdisc_pkt_len_init(struct sk
 	 */
 	if (shinfo->gso_size)  {
 		unsigned int hdr_len;
+		u16 gso_segs = shinfo->gso_segs;
 
 		/* mac layer + network layer */
 		hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
@@ -2601,7 +2602,12 @@ static void qdisc_pkt_len_init(struct sk
 			hdr_len += tcp_hdrlen(skb);
 		else
 			hdr_len += sizeof(struct udphdr);
-		qdisc_skb_cb(skb)->pkt_len += (shinfo->gso_segs - 1) * hdr_len;
+
+		if (shinfo->gso_type & SKB_GSO_DODGY)
+			gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
+						shinfo->gso_size);
+
+		qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len;
 	}
 }
 
author maintainer
#82 lore raw

PATCH 82/95 Input: cyttsp - fix memcpy size param

In reply to Greg Kroah-Hartman

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

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

From: Ferruh Yigit <[email protected]>

commit d2983cdb480157f637df07723f28aaa657b1080d upstream.

memcpy param is wrong because of offset in bl_cmd, this may corrupt the stack which may cause a crash.

---
 drivers/input/touchscreen/cyttsp_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/touchscreen/cyttsp_core.c +1 -1
@@ -133,7 +133,7 @@ static int cyttsp_exit_bl_mode(struct cy
 	memcpy(bl_cmd, bl_command, sizeof(bl_command));
 	if (ts->pdata->bl_keys)
 		memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS],
-			ts->pdata->bl_keys, sizeof(bl_command));
+			ts->pdata->bl_keys, CY_NUM_BL_KEYS);
 
 	error = ttsp_write_block_data(ts, CY_REG_BASE,
 				      sizeof(bl_cmd), bl_cmd);
author maintainer
#83 lore raw

PATCH 83/95 Input: add missing dependencies on CONFIG_HAS_IOMEM

In reply to Greg Kroah-Hartman

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

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

From: Ben Hutchings <[email protected]>

commit 150e5928d6063b273a80d9d6722417ac3c93ff82 upstream.

Several drivers don't build on s390 with CONFIG_PCI disabled as they require MMIO functions.

---
 drivers/input/keyboard/Kconfig |    1 +
 drivers/input/serio/Kconfig    |    1 +
 2 files changed, 2 insertions(+)
drivers/input/keyboard/Kconfig +1 -0
@@ -431,6 +431,7 @@ config KEYBOARD_TEGRA
 
 config KEYBOARD_OPENCORES
 	tristate "OpenCores Keyboard Controller"
+	depends on HAS_IOMEM
 	help
 	  Say Y here if you want to use the OpenCores Keyboard Controller
 	  http://www.opencores.org/project,keyboardcontroller
drivers/input/serio/Kconfig +1 -0
@@ -205,6 +205,7 @@ config SERIO_XILINX_XPS_PS2
 
 config SERIO_ALTERA_PS2
 	tristate "Altera UP PS/2 controller"
+	depends on HAS_IOMEM
 	help
 	  Say Y here if you have Altera University Program PS/2 ports.
 
author maintainer
#84 lore raw

PATCH 84/95 Input: xpad - fix for "Mad Catz Street Fighter IV FightPad" controllers

In reply to Greg Kroah-Hartman

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

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

From: Shawn Joseph <[email protected]>

commit be66227151c0cd4da536098c3ee07809101c6faa upstream.

Added MAP_TRIGGERS_TO_BUTTONS for Mad Catz Street Fighter IV FightPad device. This controller model was already supported by the xpad driver, but none of the buttons work correctly without this change.

Tested on kernel version 3.9.5.

---
 drivers/input/joystick/xpad.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/joystick/xpad.c +1 -1
@@ -137,7 +137,7 @@ static const struct xpad_device {
 	{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
 	{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
-	{ 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", XTYPE_XBOX360 },
+	{ 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 },
author maintainer
#85 lore raw

PATCH 85/95 USB: serial: ti_usb_3410_5052: new device id for Abbot strip port cable

In reply to Greg Kroah-Hartman

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

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

From: Anders Hammarquist <[email protected]>

commit 35a2fbc941accd0e9f1bfadd669311786118d874 upstream.

Add product id for Abbott strip port cable for Precision meter which uses the TI 3410 chip.

---
 drivers/usb/serial/ti_usb_3410_5052.c |    3 ++-
 drivers/usb/serial/ti_usb_3410_5052.h |    4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/usb/serial/ti_usb_3410_5052.c +2 -1
@@ -178,7 +178,8 @@ static struct usb_device_id ti_id_table_
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
-	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
+	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
+	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
 };
 
drivers/usb/serial/ti_usb_3410_5052.h +3 -1
@@ -52,7 +52,9 @@
 
 /* Abbott Diabetics vendor and product ids */
 #define ABBOTT_VENDOR_ID		0x1a61
-#define ABBOTT_PRODUCT_ID		0x3410
+#define ABBOTT_STEREO_PLUG_ID		0x3410
+#define ABBOTT_PRODUCT_ID		ABBOTT_STEREO_PLUG_ID
+#define ABBOTT_STRIP_PORT_ID		0x3420
 
 /* Commands */
 #define TI_GET_VERSION			0x01
author maintainer
#86 lore raw

PATCH 86/95 firmware loader: fix use-after-free by double abort

In reply to Greg Kroah-Hartman

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

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

From: Ming Lei <[email protected]>

commit 875979368eb4cfecff9f0e97625b90cc6009269d upstream.

fw_priv->buf is accessed in both request_firmware_load() and writing to sysfs file of 'loading' context, but not protected by 'fw_lock' entirely. The patch makes sure that access on 'fw_priv->buf' is protected by the lock.

So fixes the double abort problem reported by nirinA raseliarison:

	http://lkml.org/lkml/2013/6/14/188
---
 drivers/base/firmware_class.c |   27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)
drivers/base/firmware_class.c +18 -9
@@ -450,8 +450,18 @@ static void fw_load_abort(struct firmwar
 {
 	struct firmware_buf *buf = fw_priv->buf;
 
+	/*
+	 * There is a small window in which user can write to 'loading'
+	 * between loading done and disappearance of 'loading'
+	 */
+	if (test_bit(FW_STATUS_DONE, &buf->status))
+		return;
+
 	set_bit(FW_STATUS_ABORT, &buf->status);
 	complete_all(&buf->completion);
+
+	/* avoid user action after loading abort */
+	fw_priv->buf = NULL;
 }
 
 #define is_fw_load_aborted(buf)	\
@@ -528,7 +538,12 @@ static ssize_t firmware_loading_show(str
 				     struct device_attribute *attr, char *buf)
 {
 	struct firmware_priv *fw_priv = to_firmware_priv(dev);
-	int loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status);
+	int loading = 0;
+
+	mutex_lock(&fw_lock);
+	if (fw_priv->buf)
+		loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status);
+	mutex_unlock(&fw_lock);
 
 	return sprintf(buf, "%d\n", loading);
 }
@@ -570,12 +585,12 @@ static ssize_t firmware_loading_store(st
 				      const char *buf, size_t count)
 {
 	struct firmware_priv *fw_priv = to_firmware_priv(dev);
-	struct firmware_buf *fw_buf = fw_priv->buf;
+	struct firmware_buf *fw_buf;
 	int loading = simple_strtol(buf, NULL, 10);
 	int i;
 
 	mutex_lock(&fw_lock);
-
+	fw_buf = fw_priv->buf;
 	if (!fw_buf)
 		goto out;
 
@@ -777,10 +792,6 @@ static void firmware_class_timeout_work(
 			struct firmware_priv, timeout_work.work);
 
 	mutex_lock(&fw_lock);
-	if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) {
-		mutex_unlock(&fw_lock);
-		return;
-	}
 	fw_load_abort(fw_priv);
 	mutex_unlock(&fw_lock);
 }
@@ -861,8 +872,6 @@ static int _request_firmware_load(struct
 
 	cancel_delayed_work_sync(&fw_priv->timeout_work);
 
-	fw_priv->buf = NULL;
-
 	device_remove_file(f_dev, &dev_attr_loading);
 err_del_bin_attr:
 	device_remove_bin_file(f_dev, &firmware_attr_data);
author maintainer
#87 lore raw

PATCH 87/95 tcm_qla2xxx: Fix residual for underrun commands that fail

In reply to Greg Kroah-Hartman

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

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

From: Roland Dreier <[email protected]>

commit b5aff3d2747bea08b386edd070941a45611ffe51 upstream.

Suppose an initiator sends a DATA IN command with an allocation length shorter than the FC transfer length -- we get a target message like

    TARGET_CORE[qla2xxx]: Expected Transfer Length: 256 does not match SCSI CDB Length: 0 for SAM Opcode: 0x12

In that case, the target core adjusts the data_length and sets se_cmd->residual_count for the underrun. But now suppose that command fails and we end up in tcm_qla2xxx_queue_status() -- that function unconditionally overwrites residual_count with the already adjusted data_length, and the initiator will burp with a message like

    qla2xxx [0000:00:06.0]-301d:0: Dropped frame(s) detected (0x100 of 0x100 bytes).

Fix this by adding on to the existing underflow residual count instead.

---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/tcm_qla2xxx.c +5 -1
@@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(stru
 		 * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen
 		 * for qla_tgt_xmit_response LLD code
 		 */
+		if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
+			se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT;
+			se_cmd->residual_count = 0;
+		}
 		se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
-		se_cmd->residual_count = se_cmd->data_length;
+		se_cmd->residual_count += se_cmd->data_length;
 
 		cmd->bufflen = 0;
 	}
author maintainer
#88 lore raw

PATCH 88/95 tty: Fix transient pty write() EIO

In reply to Greg Kroah-Hartman

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

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

From: Peter Hurley <[email protected]>

commit 7c61c3d8f44d5d822f758754287af644307b4af9 upstream.

Commit 699390354da6c258b65bf8fa79cfd5feaede50b6
('pty: Ignore slave pty close() if never successfully opened') introduced a bug with ptys whereby a write() in parallel with an open() on an existing pty could mistakenly indicate an I/O error.

Only indicate an I/O error if the condition on open() actually exists.

---
 drivers/tty/pty.c |   13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/tty/pty.c +5 -8
@@ -244,14 +244,9 @@ static void pty_flush_buffer(struct tty_
 
 static int pty_open(struct tty_struct *tty, struct file *filp)
 {
-	int	retval = -ENODEV;
-
 	if (!tty || !tty->link)
-		goto out;
-
-	set_bit(TTY_IO_ERROR, &tty->flags);
+		return -ENODEV;
 
-	retval = -EIO;
 	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 		goto out;
 	if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
@@ -262,9 +257,11 @@ static int pty_open(struct tty_struct *t
 	clear_bit(TTY_IO_ERROR, &tty->flags);
 	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	set_bit(TTY_THROTTLED, &tty->flags);
-	retval = 0;
+	return 0;
+
 out:
-	return retval;
+	set_bit(TTY_IO_ERROR, &tty->flags);
+	return -EIO;
 }
 
 static void pty_set_termios(struct tty_struct *tty,
author maintainer
#89 lore raw

PATCH 89/95 target/iscsi: dont corrupt bh_count in iscsit_stop_time2retain_timer()

In reply to Greg Kroah-Hartman

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

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

From: Joern Engel <[email protected]>

commit 574780fd5e6ec52bd43e0bdb777a19e4c4c6aa9c upstream.

Here is a fun one. Bug seems to have been introduced by commit 140854cb, almost two years ago. I have no idea why we only started seeing it now, but we did.

Rough callgraph:
core_tpg_set_initiator_node_queue_depth()
`-> spin_lock_irqsave(&tpg->session_lock, flags);
`-> lio_tpg_shutdown_session()

    `-> iscsit_stop_time2retain_timer()
        `-> spin_unlock_bh(&se_tpg->session_lock);
        `-> spin_lock_bh(&se_tpg->session_lock);

`-> spin_unlock_irqrestore(&tpg->session_lock, flags);

core_tpg_set_initiator_node_queue_depth() used to call spin_lock_bh(), but 140854cb changed that to spin_lock_irqsave(). However, lio_tpg_shutdown_session() still claims to be called with spin_lock_bh() held, as does iscsit_stop_time2retain_timer():
* Called with spin_lock_bh(&struct se_portal_group->session_lock) held

Stale documentation is mostly annoying, but in this case the dropping the lock with the _bh variant is plain wrong. It is also wrong to drop locks two functions below the lock-holder, but I will ignore that bit for now.

After some more locking and unlocking we eventually hit this backtrace:

------------[ cut here ]------------
WARNING: at kernel/softirq.c:159 local_bh_enable_ip+0xe8/0x100()
Pid: 24645, comm: lio_helper.py Tainted: G           O 3.6.11+
Call Trace:
 [<ffffffff8103e5ff>] warn_slowpath_common+0x7f/0xc0
 [<ffffffffa040ae37>] ? iscsit_inc_conn_usage_count+0x37/0x50 [iscsi_target_mod]
 [<ffffffff8103e65a>] warn_slowpath_null+0x1a/0x20
 [<ffffffff810472f8>] local_bh_enable_ip+0xe8/0x100
 [<ffffffff815b8365>] _raw_spin_unlock_bh+0x15/0x20
 [<ffffffffa040ae37>] iscsit_inc_conn_usage_count+0x37/0x50 [iscsi_target_mod]
 [<ffffffffa041149a>] iscsit_stop_session+0xfa/0x1c0 [iscsi_target_mod]
 [<ffffffffa0417fab>] lio_tpg_shutdown_session+0x7b/0x90 [iscsi_target_mod]
 [<ffffffffa033ede4>] core_tpg_set_initiator_node_queue_depth+0xe4/0x290 [target_core_mod]
 [<ffffffffa0409032>] iscsit_tpg_set_initiator_node_queue_depth+0x12/0x20 [iscsi_target_mod]
 [<ffffffffa0415c29>] lio_target_nacl_store_cmdsn_depth+0xa9/0x180 [iscsi_target_mod]
 [<ffffffffa0331b49>] target_fabric_nacl_base_attr_store+0x39/0x40 [target_core_mod]
 [<ffffffff811b857d>] configfs_write_file+0xbd/0x120
 [<ffffffff81148f36>] vfs_write+0xc6/0x180
 [<ffffffff81149251>] sys_write+0x51/0x90
 [<ffffffff815c0969>] system_call_fastpath+0x16/0x1b
---[ end trace 3747632b9b164652 ]---

As a pure band-aid, this patch drops the _bh.

---
 drivers/target/iscsi/iscsi_target_erl0.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/target/iscsi/iscsi_target_erl0.c +2 -2
@@ -842,11 +842,11 @@ int iscsit_stop_time2retain_timer(struct
 		return 0;
 
 	sess->time2retain_timer_flags |= ISCSI_TF_STOP;
-	spin_unlock_bh(&se_tpg->session_lock);
+	spin_unlock(&se_tpg->session_lock);
 
 	del_timer_sync(&sess->time2retain_timer);
 
-	spin_lock_bh(&se_tpg->session_lock);
+	spin_lock(&se_tpg->session_lock);
 	sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
 	pr_debug("Stopped Time2Retain Timer for SID: %u\n",
 			sess->sid);
author maintainer
#90 lore raw

PATCH 90/95 rbd: use the correct length for format 2 object names

In reply to Greg Kroah-Hartman

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

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

From: Josh Durgin <[email protected]>

commit 3a96d5cd7bdce45d5dded75c3a62d4fb98050280 upstream.

[Backported for 3.9-stable.
'kmalloc(MAX_OBJ_NAME_SIZE + 1, GFP_NOIO)' was changed as 'kmem_cache_alloc(rbd_segment_name_cache, GFP_NOIO)' in 78c2a44 since 3.10-rc1, and 78c2a44 is relied on a big patchset, so restore it as 3.9 did.]

Format 2 objects use 16 characters for the object name suffix to be able to express the full 64-bit range of object numbers. Format 1 images only use 12 characters for this. Using 12-character names for format 2 caused userspace and kernel rbd clients to read differently named objects, which made an image written by one client look empty to the other client.

---
 drivers/block/rbd.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/block/rbd.c +5 -1
@@ -833,12 +833,16 @@ static const char *rbd_segment_name(stru
 	char *name;
 	u64 segment;
 	int ret;
+	char *name_format;
 
 	name = kmalloc(MAX_OBJ_NAME_SIZE + 1, GFP_NOIO);
 	if (!name)
 		return NULL;
 	segment = offset >> rbd_dev->header.obj_order;
-	ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, "%s.%012llx",
+	name_format = "%s.%012llx";
+	if (rbd_dev->image_format == 2)
+		name_format = "%s.%016llx";
+	ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, name_format,
 			rbd_dev->header.object_prefix, segment);
 	if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) {
 		pr_err("error formatting segment name for #%llu (%d)\n",
author maintainer
#91 lore raw

PATCH 91/95 perf: Fix perf mmap bugs

In reply to Greg Kroah-Hartman

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

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

From: Peter Zijlstra <[email protected]>

commit 26cb63ad11e04047a64309362674bcbbd6a6f246 upstream.

Vince reported a problem found by his perf specific trinity fuzzer.

Al noticed 2 problems with perf's mmap():

- it has issues against fork() since we use vma->vm_mm for accounting.
- it has an rb refcount leak on double mmap().

We fix the issues against fork() by using VM_DONTCOPY; I don't think there's code out there that uses this; we didn't hear about weird accounting problems/crashes. If we do need this to work, the previously proposed VM_PINNED could make this work.

Aside from the rb reference leak spotted by Al, Vince's example prog was indeed doing a double mmap() through the use of perf_event_set_output().

This exposes another problem, since we now have 2 events with one buffer, the accounting gets screwy because we account per event. Fix this by making the buffer responsible for its own accounting.

---
 include/linux/perf_event.h |    3 +--
 kernel/events/core.c       |   37 ++++++++++++++++++++-----------------
 kernel/events/internal.h   |    3 +++
 3 files changed, 24 insertions(+), 19 deletions(-)
include/linux/perf_event.h +1 -2
@@ -404,8 +404,7 @@ struct perf_event {
 	/* mmap bits */
 	struct mutex			mmap_mutex;
 	atomic_t			mmap_count;
-	int				mmap_locked;
-	struct user_struct		*mmap_user;
+
 	struct ring_buffer		*rb;
 	struct list_head		rb_entry;
 
kernel/events/core.c +20 -17
@@ -2866,7 +2866,7 @@ static void free_event_rcu(struct rcu_he
 	kfree(event);
 }
 
-static void ring_buffer_put(struct ring_buffer *rb);
+static bool ring_buffer_put(struct ring_buffer *rb);
 
 static void free_event(struct perf_event *event)
 {
@@ -3531,13 +3531,13 @@ static struct ring_buffer *ring_buffer_g
 	return rb;
 }
 
-static void ring_buffer_put(struct ring_buffer *rb)
+static bool ring_buffer_put(struct ring_buffer *rb)
 {
 	struct perf_event *event, *n;
 	unsigned long flags;
 
 	if (!atomic_dec_and_test(&rb->refcount))
-		return;
+		return false;
 
 	spin_lock_irqsave(&rb->event_lock, flags);
 	list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) {
@@ -3547,6 +3547,7 @@ static void ring_buffer_put(struct ring_
 	spin_unlock_irqrestore(&rb->event_lock, flags);
 
 	call_rcu(&rb->rcu_head, rb_free_rcu);
+	return true;
 }
 
 static void perf_mmap_open(struct vm_area_struct *vma)
@@ -3561,18 +3562,20 @@ static void perf_mmap_close(struct vm_ar
 	struct perf_event *event = vma->vm_file->private_data;
 
 	if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
-		unsigned long size = perf_data_size(event->rb);
-		struct user_struct *user = event->mmap_user;
 		struct ring_buffer *rb = event->rb;
+		struct user_struct *mmap_user = rb->mmap_user;
+		int mmap_locked = rb->mmap_locked;
+		unsigned long size = perf_data_size(rb);
 
-		atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
-		vma->vm_mm->pinned_vm -= event->mmap_locked;
 		rcu_assign_pointer(event->rb, NULL);
 		ring_buffer_detach(event, rb);
 		mutex_unlock(&event->mmap_mutex);
 
-		ring_buffer_put(rb);
-		free_uid(user);
+		if (ring_buffer_put(rb)) {
+			atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm);
+			vma->vm_mm->pinned_vm -= mmap_locked;
+			free_uid(mmap_user);
+		}
 	}
 }
 
@@ -3625,9 +3628,7 @@ static int perf_mmap(struct file *file,
 	WARN_ON_ONCE(event->ctx->parent_ctx);
 	mutex_lock(&event->mmap_mutex);
 	if (event->rb) {
-		if (event->rb->nr_pages == nr_pages)
-			atomic_inc(&event->rb->refcount);
-		else
+		if (event->rb->nr_pages != nr_pages)
 			ret = -EINVAL;
 		goto unlock;
 	}
@@ -3669,12 +3670,14 @@ static int perf_mmap(struct file *file,
 		ret = -ENOMEM;
 		goto unlock;
 	}
-	rcu_assign_pointer(event->rb, rb);
+
+	rb->mmap_locked = extra;
+	rb->mmap_user = get_current_user();
 
 	atomic_long_add(user_extra, &user->locked_vm);
-	event->mmap_locked = extra;
-	event->mmap_user = get_current_user();
-	vma->vm_mm->pinned_vm += event->mmap_locked;
+	vma->vm_mm->pinned_vm += extra;
+
+	rcu_assign_pointer(event->rb, rb);
 
 	perf_event_update_userpage(event);
 
@@ -3683,7 +3686,7 @@ unlock:
 		atomic_inc(&event->mmap_count);
 	mutex_unlock(&event->mmap_mutex);
 
-	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+	vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &perf_mmap_vmops;
 
 	return ret;
kernel/events/internal.h +3 -0
@@ -31,6 +31,9 @@ struct ring_buffer {
 	spinlock_t			event_lock;
 	struct list_head		event_list;
 
+	int				mmap_locked;
+	struct user_struct		*mmap_user;
+
 	struct perf_event_mmap_page	*user_page;
 	void				*data_pages[0];
 };
author maintainer
#92 lore raw

PATCH 92/95 perf: Fix mmap() accounting hole

In reply to Greg Kroah-Hartman

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

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

From: Peter Zijlstra <[email protected]>

commit 9bb5d40cd93c9dd4be74834b1dcb1ba03629716b upstream.

Vince's fuzzer once again found holes. This time it spotted a leak in the locked page accounting.

When an event had redirected output and its close() was the last reference to the buffer we didn't have a vm context to undo accounting.

Change the code to destroy the buffer on the last munmap() and detach all redirected events at that time. This provides us the right context to undo the vm accounting.

---
 kernel/events/core.c     |  228 ++++++++++++++++++++++++++++++++---------------
 kernel/events/internal.h |    3 
 2 files changed, 159 insertions(+), 72 deletions(-)
kernel/events/core.c +157 -71
@@ -194,9 +194,6 @@ static void cpu_ctx_sched_in(struct perf
 static void update_context_time(struct perf_event_context *ctx);
 static u64 perf_event_time(struct perf_event *event);
 
-static void ring_buffer_attach(struct perf_event *event,
-			       struct ring_buffer *rb);
-
 void __weak perf_event_print_debug(void)	{ }
 
 extern __weak const char *perf_pmu_name(void)
@@ -2866,7 +2863,8 @@ static void free_event_rcu(struct rcu_he
 	kfree(event);
 }
 
-static bool ring_buffer_put(struct ring_buffer *rb);
+static void ring_buffer_put(struct ring_buffer *rb);
+static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb);
 
 static void free_event(struct perf_event *event)
 {
@@ -2891,15 +2889,30 @@ static void free_event(struct perf_event
 		if (has_branch_stack(event)) {
 			static_key_slow_dec_deferred(&perf_sched_events);
 			/* is system-wide event */
-			if (!(event->attach_state & PERF_ATTACH_TASK))
+			if (!(event->attach_state & PERF_ATTACH_TASK)) {
 				atomic_dec(&per_cpu(perf_branch_stack_events,
 						    event->cpu));
+			}
 		}
 	}
 
 	if (event->rb) {
-		ring_buffer_put(event->rb);
-		event->rb = NULL;
+		struct ring_buffer *rb;
+
+		/*
+		 * Can happen when we close an event with re-directed output.
+		 *
+		 * Since we have a 0 refcount, perf_mmap_close() will skip
+		 * over us; possibly making our ring_buffer_put() the last.
+		 */
+		mutex_lock(&event->mmap_mutex);
+		rb = event->rb;
+		if (rb) {
+			rcu_assign_pointer(event->rb, NULL);
+			ring_buffer_detach(event, rb);
+			ring_buffer_put(rb); /* could be last */
+		}
+		mutex_unlock(&event->mmap_mutex);
 	}
 
 	if (is_cgroup_event(event))
@@ -3137,30 +3150,13 @@ static unsigned int perf_poll(struct fil
 	unsigned int events = POLL_HUP;
 
 	/*
-	 * Race between perf_event_set_output() and perf_poll(): perf_poll()
-	 * grabs the rb reference but perf_event_set_output() overrides it.
-	 * Here is the timeline for two threads T1, T2:
-	 * t0: T1, rb = rcu_dereference(event->rb)
-	 * t1: T2, old_rb = event->rb
-	 * t2: T2, event->rb = new rb
-	 * t3: T2, ring_buffer_detach(old_rb)
-	 * t4: T1, ring_buffer_attach(rb1)
-	 * t5: T1, poll_wait(event->waitq)
-	 *
-	 * To avoid this problem, we grab mmap_mutex in perf_poll()
-	 * thereby ensuring that the assignment of the new ring buffer
-	 * and the detachment of the old buffer appear atomic to perf_poll()
+	 * Pin the event->rb by taking event->mmap_mutex; otherwise
+	 * perf_event_set_output() can swizzle our rb and make us miss wakeups.
 	 */
 	mutex_lock(&event->mmap_mutex);
-
-	rcu_read_lock();
-	rb = rcu_dereference(event->rb);
-	if (rb) {
-		ring_buffer_attach(event, rb);
+	rb = event->rb;
+	if (rb)
 		events = atomic_xchg(&rb->poll, 0);
-	}
-	rcu_read_unlock();
-
 	mutex_unlock(&event->mmap_mutex);
 
 	poll_wait(file, &event->waitq, wait);
@@ -3470,16 +3466,12 @@ static void ring_buffer_attach(struct pe
 		return;
 
 	spin_lock_irqsave(&rb->event_lock, flags);
-	if (!list_empty(&event->rb_entry))
-		goto unlock;
-
-	list_add(&event->rb_entry, &rb->event_list);
-unlock:
+	if (list_empty(&event->rb_entry))
+		list_add(&event->rb_entry, &rb->event_list);
 	spin_unlock_irqrestore(&rb->event_lock, flags);
 }
 
-static void ring_buffer_detach(struct perf_event *event,
-			       struct ring_buffer *rb)
+static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb)
 {
 	unsigned long flags;
 
@@ -3498,13 +3490,10 @@ static void ring_buffer_wakeup(struct pe
 
 	rcu_read_lock();
 	rb = rcu_dereference(event->rb);
-	if (!rb)
-		goto unlock;
-
-	list_for_each_entry_rcu(event, &rb->event_list, rb_entry)
-		wake_up_all(&event->waitq);
-
-unlock:
+	if (rb) {
+		list_for_each_entry_rcu(event, &rb->event_list, rb_entry)
+			wake_up_all(&event->waitq);
+	}
 	rcu_read_unlock();
 }
 
@@ -3531,23 +3520,14 @@ static struct ring_buffer *ring_buffer_g
 	return rb;
 }
 
-static bool ring_buffer_put(struct ring_buffer *rb)
+static void ring_buffer_put(struct ring_buffer *rb)
 {
-	struct perf_event *event, *n;
-	unsigned long flags;
-
 	if (!atomic_dec_and_test(&rb->refcount))
-		return false;
+		return;
 
-	spin_lock_irqsave(&rb->event_lock, flags);
-	list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) {
-		list_del_init(&event->rb_entry);
-		wake_up_all(&event->waitq);
-	}
-	spin_unlock_irqrestore(&rb->event_lock, flags);
+	WARN_ON_ONCE(!list_empty(&rb->event_list));
 
 	call_rcu(&rb->rcu_head, rb_free_rcu);
-	return true;
 }
 
 static void perf_mmap_open(struct vm_area_struct *vma)
@@ -3555,28 +3535,100 @@ static void perf_mmap_open(struct vm_are
 	struct perf_event *event = vma->vm_file->private_data;
 
 	atomic_inc(&event->mmap_count);
+	atomic_inc(&event->rb->mmap_count);
 }
 
+/*
+ * A buffer can be mmap()ed multiple times; either directly through the same
+ * event, or through other events by use of perf_event_set_output().
+ *
+ * In order to undo the VM accounting done by perf_mmap() we need to destroy
+ * the buffer here, where we still have a VM context. This means we need
+ * to detach all events redirecting to us.
+ */
 static void perf_mmap_close(struct vm_area_struct *vma)
 {
 	struct perf_event *event = vma->vm_file->private_data;
 
-	if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
-		struct ring_buffer *rb = event->rb;
-		struct user_struct *mmap_user = rb->mmap_user;
-		int mmap_locked = rb->mmap_locked;
-		unsigned long size = perf_data_size(rb);
+	struct ring_buffer *rb = event->rb;
+	struct user_struct *mmap_user = rb->mmap_user;
+	int mmap_locked = rb->mmap_locked;
+	unsigned long size = perf_data_size(rb);
 
-		rcu_assign_pointer(event->rb, NULL);
-		ring_buffer_detach(event, rb);
-		mutex_unlock(&event->mmap_mutex);
+	atomic_dec(&rb->mmap_count);
+
+	if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex))
+		return;
+
+	/* Detach current event from the buffer. */
+	rcu_assign_pointer(event->rb, NULL);
+	ring_buffer_detach(event, rb);
+	mutex_unlock(&event->mmap_mutex);
+
+	/* If there's still other mmap()s of this buffer, we're done. */
+	if (atomic_read(&rb->mmap_count)) {
+		ring_buffer_put(rb); /* can't be last */
+		return;
+	}
 
-		if (ring_buffer_put(rb)) {
-			atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm);
-			vma->vm_mm->pinned_vm -= mmap_locked;
-			free_uid(mmap_user);
+	/*
+	 * No other mmap()s, detach from all other events that might redirect
+	 * into the now unreachable buffer. Somewhat complicated by the
+	 * fact that rb::event_lock otherwise nests inside mmap_mutex.
+	 */
+again:
+	rcu_read_lock();
+	list_for_each_entry_rcu(event, &rb->event_list, rb_entry) {
+		if (!atomic_long_inc_not_zero(&event->refcount)) {
+			/*
+			 * This event is en-route to free_event() which will
+			 * detach it and remove it from the list.
+			 */
+			continue;
+		}
+		rcu_read_unlock();
+
+		mutex_lock(&event->mmap_mutex);
+		/*
+		 * Check we didn't race with perf_event_set_output() which can
+		 * swizzle the rb from under us while we were waiting to
+		 * acquire mmap_mutex.
+		 *
+		 * If we find a different rb; ignore this event, a next
+		 * iteration will no longer find it on the list. We have to
+		 * still restart the iteration to make sure we're not now
+		 * iterating the wrong list.
+		 */
+		if (event->rb == rb) {
+			rcu_assign_pointer(event->rb, NULL);
+			ring_buffer_detach(event, rb);
+			ring_buffer_put(rb); /* can't be last, we still have one */
 		}
+		mutex_unlock(&event->mmap_mutex);
+		put_event(event);
+
+		/*
+		 * Restart the iteration; either we're on the wrong list or
+		 * destroyed its integrity by doing a deletion.
+		 */
+		goto again;
 	}
+	rcu_read_unlock();
+
+	/*
+	 * It could be there's still a few 0-ref events on the list; they'll
+	 * get cleaned up by free_event() -- they'll also still have their
+	 * ref on the rb and will free it whenever they are done with it.
+	 *
+	 * Aside from that, this buffer is 'fully' detached and unmapped,
+	 * undo the VM accounting.
+	 */
+
+	atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm);
+	vma->vm_mm->pinned_vm -= mmap_locked;
+	free_uid(mmap_user);
+
+	ring_buffer_put(rb); /* could be last */
 }
 
 static const struct vm_operations_struct perf_mmap_vmops = {
@@ -3626,10 +3678,24 @@ static int perf_mmap(struct file *file,
 		return -EINVAL;
 
 	WARN_ON_ONCE(event->ctx->parent_ctx);
+again:
 	mutex_lock(&event->mmap_mutex);
 	if (event->rb) {
-		if (event->rb->nr_pages != nr_pages)
+		if (event->rb->nr_pages != nr_pages) {
 			ret = -EINVAL;
+			goto unlock;
+		}
+
+		if (!atomic_inc_not_zero(&event->rb->mmap_count)) {
+			/*
+			 * Raced against perf_mmap_close() through
+			 * perf_event_set_output(). Try again, hope for better
+			 * luck.
+			 */
+			mutex_unlock(&event->mmap_mutex);
+			goto again;
+		}
+
 		goto unlock;
 	}
 
@@ -3671,12 +3737,14 @@ static int perf_mmap(struct file *file,
 		goto unlock;
 	}
 
+	atomic_set(&rb->mmap_count, 1);
 	rb->mmap_locked = extra;
 	rb->mmap_user = get_current_user();
 
 	atomic_long_add(user_extra, &user->locked_vm);
 	vma->vm_mm->pinned_vm += extra;
 
+	ring_buffer_attach(event, rb);
 	rcu_assign_pointer(event->rb, rb);
 
 	perf_event_update_userpage(event);
@@ -3686,6 +3754,10 @@ unlock:
 		atomic_inc(&event->mmap_count);
 	mutex_unlock(&event->mmap_mutex);
 
+	/*
+	 * Since pinned accounting is per vm we cannot allow fork() to copy our
+	 * vma.
+	 */
 	vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &perf_mmap_vmops;
 
@@ -6417,6 +6489,8 @@ set:
 	if (atomic_read(&event->mmap_count))
 		goto unlock;
 
+	old_rb = event->rb;
+
 	if (output_event) {
 		/* get the rb we want to redirect to */
 		rb = ring_buffer_get(output_event);
@@ -6424,16 +6498,28 @@ set:
 			goto unlock;
 	}
 
-	old_rb = event->rb;
-	rcu_assign_pointer(event->rb, rb);
 	if (old_rb)
 		ring_buffer_detach(event, old_rb);
+
+	if (rb)
+		ring_buffer_attach(event, rb);
+
+	rcu_assign_pointer(event->rb, rb);
+
+	if (old_rb) {
+		ring_buffer_put(old_rb);
+		/*
+		 * Since we detached before setting the new rb, so that we
+		 * could attach the new rb, we could have missed a wakeup.
+		 * Provide it now.
+		 */
+		wake_up_all(&event->waitq);
+	}
+
 	ret = 0;
 unlock:
 	mutex_unlock(&event->mmap_mutex);
 
-	if (old_rb)
-		ring_buffer_put(old_rb);
 out:
 	return ret;
 }
kernel/events/internal.h +2 -1
@@ -31,7 +31,8 @@ struct ring_buffer {
 	spinlock_t			event_lock;
 	struct list_head		event_list;
 
-	int				mmap_locked;
+	atomic_t			mmap_count;
+	unsigned long			mmap_locked;
 	struct user_struct		*mmap_user;
 
 	struct perf_event_mmap_page	*user_page;
author maintainer
#93 lore raw

PATCH 93/95 drivers: uio: Fix UIO device registration failure

In reply to Greg Kroah-Hartman

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

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

From: Damian Hobson-Garcia <[email protected]>

commit 5ed0505c713805f89473cdc0bbfb5110dfd840cb upstream.

Until recently uio_get_minor() returned 0 for success and
a negative value on failure. This became non-negative for suceess and negative for failure. Restore the original return value spec so that we can successfully initialize UIO devices with a non-zero minor device number.

---
 drivers/uio/uio.c |    1 +
 1 file changed, 1 insertion(+)
drivers/uio/uio.c +1 -0
@@ -374,6 +374,7 @@ static int uio_get_minor(struct uio_devi
 	retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL);
 	if (retval >= 0) {
 		idev->minor = retval;
+		retval = 0;
 	} else if (retval == -ENOSPC) {
 		dev_err(idev->dev, "too many uio devices\n");
 		retval = -EINVAL;
author maintainer
#94 lore raw

PATCH 94/95 spi/pxa2xx: use GFP_ATOMIC in sg table allocation

In reply to Greg Kroah-Hartman

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

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

From: Mika Westerberg <[email protected]>

commit 5548f98c46538d1da04eff179a52e50537d11465 upstream.

pxa2xx_spi_map_dma_buffer() gets called in tasklet context so we can't sleep when we allocate a new sg table. Use GFP_ATOMIC here instead.

---
 drivers/spi/spi-pxa2xx-dma.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-pxa2xx-dma.c +1 -1
@@ -59,7 +59,7 @@ static int pxa2xx_spi_map_dma_buffer(str
 		int ret;
 
 		sg_free_table(sgt);
-		ret = sg_alloc_table(sgt, nents, GFP_KERNEL);
+		ret = sg_alloc_table(sgt, nents, GFP_ATOMIC);
 		if (ret)
 			return ret;
 	}
author maintainer
#95 lore raw

PATCH 95/95 spi/pxa2xx: fix memory corruption due to wrong size used in devm_kzalloc()

In reply to Greg Kroah-Hartman

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

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

From: Mika Westerberg <[email protected]>

commit cc0ee9873c6afafb387379ca1df25da78a08c603 upstream.

ACPI part of the driver accidentally used sizeof(*ssp) instead of the correct sizeof(*pdata). This leads to nasty memory corruptions like the one below:

    BUG: unable to handle kernel paging request at 0000000749fd30b8
    IP: [<ffffffff813fe8a1>] __list_del_entry+0x31/0xd0
    PGD 0
    Oops: 0000 [#1] PREEMPT SMP
    Modules linked in:
    CPU: 0 PID: 30 Comm: kworker/0:1 Not tainted 3.10.0-rc6v3.10-rc6_sdhci_modprobe+ #443
    task: ffff8801483a0940 ti: ffff88014839e000 task.ti: ffff88014839e000
    RIP: 0010:[<ffffffff813fe8a1>]  [<ffffffff813fe8a1>] __list_del_entry+0x31/0xd0
    RSP: 0000:ffff88014839fde8  EFLAGS: 00010046
    RAX: ffff880149fd30b0 RBX: ffff880149fd3040 RCX: dead000000200200
    RDX: 0000000749fd30b0 RSI: ffff880149fd3058 RDI: ffff88014834d640
    RBP: ffff88014839fde8 R08: ffff88014834d640 R09: 0000000000000001
    R10: ffff8801483a0940 R11: 0000000000000001 R12: ffff880149fd3040
    R13: ffffffff810e0b30 R14: ffff8801483a0940 R15: ffff88014834d640
    FS:  0000000000000000(0000) GS:ffff880149e00000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000168 CR3: 0000000001e0b000 CR4: 00000000001407f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    Stack:
     ffff88014839fe48 ffffffff810e0baf ffffffff81120abd ffff88014839fe20
     ffff8801483a0940 ffff8801483a0940 ffff8801483a0940 ffff8801486b1c90
     ffff88014834d640 ffffffff810e0b30 0000000000000000 0000000000000000
    Call Trace:
     [<ffffffff810e0baf>] worker_thread+0x7f/0x390
     [<ffffffff81120abd>] ? trace_hardirqs_on+0xd/0x10
     [<ffffffff810e0b30>] ? manage_workers.isra.22+0x2b0/0x2b0
     [<ffffffff810e6c09>] kthread+0xd9/0xe0
     [<ffffffff810f93df>] ? local_clock+0x3f/0x50
     [<ffffffff810e6b30>] ? kthread_create_on_node+0x110/0x110
     [<ffffffff818c5dec>] ret_from_fork+0x7c/0xb0
     [<ffffffff810e6b30>] ? kthread_create_on_node+0x110/0x110

Fix this by using the right structure size in devm_kzalloc().

---
 drivers/spi/spi-pxa2xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-pxa2xx.c +1 -1
@@ -1069,7 +1069,7 @@ pxa2xx_spi_acpi_get_pdata(struct platfor
 	    acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev))
 		return NULL;
 
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL);
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
 		dev_err(&pdev->dev,
 			"failed to allocate memory for platform data\n");
#96 lore raw
In reply to Greg Kroah-Hartman
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.9.8 release. There are 95 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.

Quoted 7 lines

Responses should be made by Thu Jun 27 18:18:29 UTC 2013. 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.9.8-rc1.gz

and the diffstat can be found below.

Build results are as follows. Same as with 3.9.7.

Guenter

---
Build reference: v3.9.7-95-g6a2f14b

Build x86_64:defconfig passed
Build x86_64:allyesconfig passed
Build x86_64:allmodconfig passed
Build x86_64:allnoconfig passed
Build x86_64:alldefconfig passed
Build i386:defconfig passed
Build i386:allyesconfig passed
Build i386:allmodconfig passed
Build i386:allnoconfig passed
Build i386:alldefconfig passed
Build mips:defconfig passed
Build mips:bcm47xx_defconfig passed
Build mips:bcm63xx_defconfig passed
Build mips:nlm_xlp_defconfig passed
Build mips:ath79_defconfig passed
Build mips:ar7_defconfig passed
Build mips:fuloong2e_defconfig passed
Build mips:e55_defconfig passed
Build mips:cavium_octeon_defconfig passed
Build mips:powertv_defconfig passed
Build mips:malta_defconfig passed
Build powerpc:defconfig passed
Build powerpc:allyesconfig failed
Build powerpc:allmodconfig passed
Build powerpc:chroma_defconfig passed
Build powerpc:maple_defconfig passed
Build powerpc:ppc6xx_defconfig passed
Build powerpc:mpc83xx_defconfig passed
Build powerpc:mpc85xx_defconfig passed
Build powerpc:mpc85xx_smp_defconfig passed
Build powerpc:tqm8xx_defconfig passed
Build powerpc:85xx/sbc8548_defconfig passed
Build powerpc:83xx/mpc834x_mds_defconfig passed
Build powerpc:86xx/sbc8641d_defconfig passed
Build arm:defconfig passed
Build arm:allyesconfig failed
Build arm:allmodconfig failed
Build arm:exynos4_defconfig passed
Build arm:multi_v7_defconfig passed
Build arm:kirkwood_defconfig passed
Build arm:omap2plus_defconfig passed
Build arm:tegra_defconfig passed
Build arm:u8500_defconfig passed
Build arm:at91sam9rl_defconfig passed
Build arm:ap4evb_defconfig passed
Build arm:bcm_defconfig passed
Build arm:bonito_defconfig passed
Build arm:pxa910_defconfig passed
Build arm:mvebu_defconfig passed
Build m68k:defconfig passed
Build m68k:m5272c3_defconfig failed
Build m68k:m5307c3_defconfig passed
Build m68k:m5249evb_defconfig passed
Build m68k:m5407c3_defconfig passed
Build m68k:sun3_defconfig passed
Build m68k:mvme16x_defconfig passed
Build sparc:defconfig passed
Build sparc:sparc64_defconfig passed
Build xtensa:defconfig passed
Build xtensa:iss_defconfig passed
Build microblaze:mmu_defconfig passed
Build microblaze:nommu_defconfig passed
Build blackfin:defconfig passed
Build parisc:defconfig passed

-----------------------
Total builds: 64 Total build errors: 4

author maintainer
#97 lore raw
Quoted 6 lines · Guenter Roeck
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.9.8 release. There are 95 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.

Quoted 8 lines
Quoted 7 lines

Responses should be made by Thu Jun 27 18:18:29 UTC 2013. 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.9.8-rc1.gz

and the diffstat can be found below.

Build results are as follows. Same as with 3.9.7.

Thanks for testing and letting us know.

greg k-h