This is the start of the stable review cycle for the 3.12.38 release.
There are 122 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 Wed Feb 18 16:19:34 CET 2015.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.38-rc1.xz
and the diffstat can be found below.
thanks,
js
===============
AceLan Kao (1):
asus-nb-wmi: Add ASUSTeK COMPUTER INC. X200CA
Adam Lee (2):
mmc: sdhci-pci: break out definitions to header file
Bluetooth: ath3k: workaround the compatibility issue with xHCI
controller
Adrian Hunter (6):
mmc: sdhci-acpi: Add device id 80860F16
mmc: sdhci-acpi: Intel SDIO has broken card detect
mmc: sdhci-acpi: Add a HID and UID for a SD Card host controller
mmc: sdhci-acpi: Add ACPI HID INT344D
mmc: sdhci-pci: Fix Braswell eMMC timeout clock frequency
mmc: sdhci-pci: Add support for Intel SPT
Ahmed S. Darwish (4):
can: kvaser_usb: Do not sleep in atomic context
can: kvaser_usb: Send correct context to URB completion
can: kvaser_usb: Retry the first bulk transfer on -ETIMEDOUT
can: kvaser_usb: Fix state handling upon BUS_ERROR events
Alan Cox (1):
mmc: sdhci: Add PCI IDs for Intel Braswell
Alex Elder (1):
rbd: drop an unsafe assertion
Andreas Utterberg (1):
asus-wmi: Set WAPF to 4 for Asus X550CA
Andy Lutomirski (1):
x86,kvm,vmx: Preserve CR4 across VM entry
Andy Shevchenko (1):
spi: dw-mid: fix FIFO size
Ashay Jaiswal (1):
regulator: core: fix race condition in regulator_put()
Austin Lund (1):
[media] media/rc: Send sync space information on the lirc device
Bo Shen (1):
ASoC: atmel_ssc_dai: fix start event for I2S mode
Bob Paauwe (1):
drm/i915: Only fence tiled region of object.
Charlotte Richardson (1):
PCI: Add NEC variants to Stratus ftServer PCIe DMI check
Christoph Hellwig (1):
net: don't OOPS on socket aio
Clemens Ladisch (1):
ALSA: seq-dummy: remove deadlock-causing events on close
Daniel Borkmann (1):
net: sctp: fix slab corruption from use after free on INIT collisions
David Cohen (2):
mmc: sdhci-pci: add broken HS200 quirk for Intel Merrifield
mmc: sdhci: add quirk for broken HS200 support
David Rientjes (1):
net, sunrpc: suppress allocation warning in rpc_malloc()
Dmitry Monakhov (1):
ext4: prevent bugon on race between write/fcntl
Eric Dumazet (4):
net: rps: fix cpu unplug
netxen: fix netxen_nic_poll() logic
tcp: ipv4: initialize unicast_sock sk_pacing_rate
ipv4: tcp: get rid of ugly unicast_sock
Eric Nelson (1):
ASoC: sgtl5000: add delay before first I2C access
Eric Paris (1):
SELinux: fix selinuxfs policy file on big endian systems
Felix Fietkau (1):
MIPS: IRQ: Fix disable_irq on CPU IRQs
Florian Westphal (1):
ppp: deflate: never return len larger than output buffer
Goldwyn Rodrigues (1):
ocfs2: remove filesize checks for sync I/O journal commit
Govindarajulu Varadarajan (1):
bnx2x: fix napi poll return value for repoll
Hagen Paul Pfeifer (1):
ipv6: stop sending PTB packets for MTU < 1280
Hannes Frederic Sowa (2):
ipv4: try to cache dst_entries which would cause a redirect
ipv6: replacing a rt6_info needs to purge possible propagated
rt6_infos too
Hannes Reinecke (2):
tcm_loop: Fix wrong I_T nexus association
dm: do not call dm_sync_table() when creating new devices
Hans de Goede (5):
asus-nb-wmi: Add wapf4 quirk for the X550CL
asus-nb-wmi: Add wapf4 quirk for the X550CC
asus-nb-wmi.c: Rename x401u quirk to wapf4
asus-nb-wmi: Add wapf4 quirk for the U32U
asus-nb-wmi: Add another wapf=4 quirk
Heiko Carstens (1):
ipc/compat_sys_msgrcv: change msgtyp type from long to compat_long_t
Hemmo Nieminen (1):
MIPS: Fix kernel lockup or crash after CPU offline/online
Herbert Xu (1):
udp_diag: Fix socket skipping within chain
Ilya Dryomov (2):
rbd: drop parent_ref in rbd_dev_unprobe() unconditionally
rbd: fix rbd_dev_parent_get() when parent_overlap == 0
James Custer (1):
x86: UV BAU: Avoid NULL pointer reference in ptc_seq_show
Jan Kara (3):
udf: Verify i_size when loading inode
udf: Check path length when reading symlink
udf: Check component length before reading it
Jesse Barnes (1):
x86/early quirk: use gen6 stolen detection for VLV
Jiri Slaby (1):
parport: parport_pc, do not remove parent devices early
Jochen Hein (1):
Input: i8042 - add noloop quirk for Medion Akoya E7225 (MD98857)
Joe Thornber (2):
dm thin: don't allow messages to be sent to a pool target in READ_ONLY
or FAIL mode
dm cache: fix missing ERR_PTR returns and handling
Johan Hovold (2):
gpio: sysfs: fix memory leak in gpiod_export_link
gpio: sysfs: fix memory leak in gpiod_sysfs_set_active_low
Johannes Berg (1):
nl80211: fix per-station group key get/del and memory leak
Lai Jiangshan (1):
smpboot: Add missing get_online_cpus() in
smpboot_register_percpu_thread()
Laurent Dufour (1):
powerpc/xmon: Fix another endiannes issue in RTAS call from xmon
Len Brown (1):
ACPI idle: permit sparse C-state sub-state numbers
Liu ShuoX (3):
pstore: clarify clearing of _read_cnt in ramoops_context
pstore: skip zero size persistent ram buffer in traverse
pstore: Fix NULL pointer fault if get NULL prz in ramoops_get_next_prz
Manfred Spraul (1):
ipc/sem.c: change memory barrier in sem_lock() to smp_rmb()
Mark Rutland (1):
arm64: Fix up /proc/cpuinfo
Martin Walch (1):
kconfig: fix bug in search results string: use strlen(gstr->s), not
gstr->len
Mateusz Guzik (1):
ipc: fix compat msgrcv with negative msgtyp
Mathias Krause (1):
crypto: crc32c - add missing crypto module alias
Mathy Vanhoef (1):
mac80211: properly set CCK flag in radiotap
Maurice Petallo (1):
mmc: sdhci: Preset value not supported in Baytrail eMMC
Micky Ching (1):
mmc: sdhci: add support for realtek rts5250
Mika Westerberg (2):
mmc: sdhci-acpi: add new ACPI ID
spi/pxa2xx: Clear cur_chip pointer before starting next message
Mugunthan V N (1):
drivers: net: cpsw: discard dual emac default vlan configuration
Nadav Amit (7):
KVM: x86: Warn if guest virtual address space is not 48-bits
KVM: x86: Handle errors when RIP is set during far jumps
KVM: x86: Getting rid of grp45 in emulator
KVM: x86: Distinguish between stack operation and near branches
KVM: x86: emulating descriptor load misses long-mode case
KVM: vmx: Inject #GP on invalid PAT CR
KVM: x86: Sysexit emulation does not mask RIP/RSP
Nicholas Bellinger (1):
target: Drop arbitrary maximum I/O size limit
Paul Osmialowski (1):
i2c: s3c2410: fix ABBA deadlock by keeping clock prepared
Peng Tao (1):
nfs: fix dio deadlock when O_DIRECT flag is flipped
Peter Hutterer (1):
Input: synaptics - adjust min/max for Lenovo ThinkPad X1 Carbon 2nd
Peter Kümmel (1):
kconfig: Fix warning "‘jump’ may be used uninitialized"
Peter Ujfalusi (1):
ASoC: omap-mcbsp: Correct CBM_CFS dai format configuration
Randy Wright (1):
ACPI: Fix bug when ACPI reset register is implemented in system memory
Roopa Prabhu (1):
bridge: dont send notification when skb->len == 0 in
rtnl_bridge_notify
Russell King (1):
ARM: DMA: ensure that old section mappings are flushed from the TLB
Ryusuke Konishi (1):
nilfs2: fix deadlock of segment constructor over I_SYNC flag
Sachin Prabhu (1):
Complete oplock break jobs before closing file handle
Saran Maruti Ramanara (1):
net: sctp: fix passing wrong parameter header to param_type2af in
sctp_process_param
Shiraz Hashim (1):
mm: pagewalk: call pte_hole() for VM_PFNMAP during walk_page_range
Stanislaw Gruszka (1):
asus-nb-wmi: Add wapf4 quirk for the X550VB
Steve Dickson (1):
SUNRPC: Ensure call_connect_status() deals correctly with SOFTCONN
tasks
Takashi Iwai (1):
ALSA: ak411x: Fix stall in work callback
Tejun Heo (1):
workqueue: fix subtle pool management issue which can stall whole
worker_pool
Trond Myklebust (7):
NFSv4.1: Fix an Oops in nfs41_walk_client_list
SUNRPC: call_connect_status should recheck bind and connect status on
error
SUNRPC: Ensure xprt_connect_status handles all potential connection
errors
SUNRPC: Handle connect errors ECONNABORTED and EHOSTUNREACH
SUNRPC: Ensure that call_connect times out correctly
SUNRPC: Ensure that we handle ENOBUFS errors correctly.
SUNRPC: Handle EPIPE in xprt_connect_status
Vikas Chaudhary (1):
iscsi_ibft: Fix finding Broadcom specific ibft sign
Willem de Bruijn (1):
ip: zero sockaddr returned on error queue
Zidan Wang (1):
ASoC: wm8960: Fix capture sample rate from 11250 to 11025
karl beldan (2):
lib/checksum.c: fix carry in csum_tcpudp_nofold
lib/checksum.c: fix build for generic csum_tcpudp_nofold
poma (1):
WAPF 4 for ASUSTeK COMPUTER INC. X75VBP WLAN ON.
[email protected] (1):
ping: Fix race in free in receive path
arch/arm/mm/dma-mapping.c | 11 +-
arch/arm64/include/asm/cputype.h | 2 +
arch/arm64/kernel/setup.c | 98 ++++++++---
arch/arm64/kernel/smp.c | 5 +
arch/mips/kernel/irq_cpu.c | 4 +
arch/mips/kernel/smp.c | 2 +-
arch/powerpc/xmon/xmon.c | 1 +
arch/x86/kernel/acpi/cstate.c | 4 +-
arch/x86/kernel/early-quirks.c | 4 +-
arch/x86/kvm/cpuid.c | 19 ++-
arch/x86/kvm/cpuid.h | 2 +-
arch/x86/kvm/emulate.c | 188 +++++++++++++--------
arch/x86/kvm/vmx.c | 18 +-
arch/x86/kvm/x86.c | 5 +-
arch/x86/kvm/x86.h | 2 +
arch/x86/pci/common.c | 16 ++
arch/x86/platform/uv/tlb_uv.c | 4 +
crypto/crc32c.c | 1 +
drivers/acpi/osl.c | 12 ++
drivers/block/rbd.c | 26 +--
drivers/bluetooth/ath3k.c | 8 +
drivers/firmware/iscsi_ibft.c | 1 +
drivers/gpio/gpiolib.c | 3 +-
drivers/gpu/drm/i915/i915_gem.c | 7 +
drivers/i2c/busses/i2c-s3c2410.c | 23 ++-
drivers/input/mouse/synaptics.c | 7 +-
drivers/input/serio/i8042-x86ia64io.h | 8 +
drivers/md/dm-cache-metadata.c | 9 +-
drivers/md/dm-thin.c | 6 +
drivers/md/dm.c | 9 +-
drivers/media/rc/ir-lirc-codec.c | 12 +-
drivers/mmc/host/sdhci-acpi.c | 9 +
drivers/mmc/host/sdhci-pci.c | 148 ++++++++--------
drivers/mmc/host/sdhci-pci.h | 85 ++++++++++
drivers/mmc/host/sdhci.c | 6 +-
drivers/net/can/usb/kvaser_usb.c | 28 +--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +-
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 5 +-
drivers/net/ethernet/ti/cpsw.c | 22 +++
drivers/net/ppp/ppp_deflate.c | 2 +-
drivers/parport/parport_pc.c | 7 +-
drivers/platform/x86/asus-nb-wmi.c | 103 +++++++++--
drivers/regulator/core.c | 4 +-
drivers/spi/spi-dw-mid.c | 1 -
drivers/spi/spi-pxa2xx.c | 2 +-
drivers/target/loopback/tcm_loop.c | 29 ++--
drivers/target/loopback/tcm_loop.h | 7 +-
drivers/target/target_core_device.c | 8 +-
drivers/target/target_core_file.c | 11 +-
drivers/target/target_core_iblock.c | 2 +-
drivers/target/target_core_sbc.c | 15 --
drivers/target/target_core_spc.c | 5 +-
fs/cifs/file.c | 6 +-
fs/ext4/file.c | 8 +-
fs/nfs/direct.c | 6 +
fs/nfs/nfs4client.c | 2 +-
fs/nilfs2/nilfs.h | 2 -
fs/nilfs2/segment.c | 44 ++++-
fs/nilfs2/segment.h | 5 +
fs/ocfs2/file.c | 4 +-
fs/pstore/ram.c | 15 +-
fs/udf/dir.c | 3 +-
fs/udf/inode.c | 18 ++
fs/udf/namei.c | 3 +-
fs/udf/symlink.c | 40 ++++-
fs/udf/udfdecl.h | 3 +-
fs/udf/unicode.c | 28 +--
include/linux/compat.h | 2 +-
include/linux/mmc/sdhci.h | 4 +
include/net/ip.h | 13 +-
include/net/netns/ipv4.h | 1 +
include/sound/ak4113.h | 2 +-
include/sound/ak4114.h | 2 +-
ipc/compat.c | 6 +-
ipc/sem.c | 13 +-
kernel/smpboot.c | 2 +
kernel/workqueue.c | 42 ++---
lib/checksum.c | 12 +-
mm/pagewalk.c | 5 +-
net/core/dev.c | 20 ++-
net/core/rtnetlink.c | 6 +-
net/ipv4/ip_forward.c | 3 +-
net/ipv4/ip_output.c | 29 +---
net/ipv4/ip_sockglue.c | 8 +-
net/ipv4/ping.c | 5 +-
net/ipv4/route.c | 9 +-
net/ipv4/tcp_ipv4.c | 37 +++-
net/ipv4/udp_diag.c | 4 +-
net/ipv6/datagram.c | 10 +-
net/ipv6/ip6_fib.c | 45 ++---
net/ipv6/route.c | 7 +-
net/mac80211/rx.c | 2 +-
net/sctp/associola.c | 1 -
net/sctp/sm_make_chunk.c | 2 +-
net/socket.c | 3 -
net/sunrpc/clnt.c | 25 ++-
net/sunrpc/sched.c | 5 +-
net/sunrpc/xprt.c | 6 +
net/sunrpc/xprtsock.c | 5 +
net/wireless/nl80211.c | 9 +-
scripts/kconfig/menu.c | 6 +-
security/selinux/ss/policydb.c | 3 +-
sound/core/seq/seq_dummy.c | 31 ----
sound/i2c/other/ak4113.c | 17 +-
sound/i2c/other/ak4114.c | 18 +-
sound/soc/atmel/atmel_ssc_dai.c | 18 +-
sound/soc/codecs/sgtl5000.c | 3 +
sound/soc/codecs/wm8960.c | 2 +-
sound/soc/omap/omap-mcbsp.c | 2 +-
109 files changed, 1081 insertions(+), 569 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-pci.h
--
2.2.2
From: Andreas Utterberg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c08db55fe1455202e4bcda416e88bbbc20700dc4 upstream.
The 'asus-nb-wmi' WAPF parameter must be set to 4, so the internal Wireless LAN device is operational.
Signed-off-by: Andreas Utterberg <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 563f59efa669..ddf0eefd862c 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -137,6 +137,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X550CA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"),
+ },
+ .driver_data = &quirk_asus_x401u,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X55A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: poma <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7216e10227c90a388db1ee29b7b89820b81aa8eb upstream.
The 'asus-nb-wmi' WAPF parameter must be set to 4, so the internal Wireless LAN device is operational.
Signed-off-by: poma <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index ddf0eefd862c..d3641e043e47 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -191,6 +191,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X75VBP",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"),
+ },
+ .driver_data = &quirk_asus_x401u,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. 1015E",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: AceLan Kao <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c66263a368490a200a65639ff826f633090936a9 upstream.
BIOS won't light on the wifi-led after S3, so asus-wmi driver needs to
control the wifi and wifi-led status.
But, it'll lead to bt status error if asus-wmi driver controls bt as well.
So, for X200CA, asus-wmi driver controls wifi status only and have to set
wapf to 1.
Signed-off-by: AceLan Kao <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index d3641e043e47..8cbf488df0f3 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -74,6 +74,10 @@ static struct quirk_entry quirk_asus_x401u = {
.wapf = 4,
};
+static struct quirk_entry quirk_asus_x200ca = {
+ .wapf = 2,
+};
+
static int dmi_matched(const struct dmi_system_id *dmi)
{
quirks = dmi->driver_data;
@@ -216,6 +220,15 @@ static struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_asus_x401u,
},
+ {
+ .callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X200CA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"),
+ },
+ .driver_data = &quirk_asus_x200ca,
+ },
{},
};
--
2.2.2
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 22ba58c8abea9e948d406776b9252024a30bd45c upstream.
As reported here: https://bugs.launchpad.net/bugs/1277959
the X550CL needs wapf=4 too.
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 8cbf488df0f3..c5da5b7c4a10 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -150,6 +150,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X550CL",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"),
+ },
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X55A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6d6ded3bdb0ed6f65d1f58d5d84971f6b3a39b70 upstream.
As reported here: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1173681
the X550CC needs wapf=4 too.
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index c5da5b7c4a10..8698c8674d05 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -150,6 +150,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X550CC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"),
+ },
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X550CL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 378008dfc72baed2d9c0f0a40dababc0e8901207 upstream.
The actual x401u does not use the so named x401u quirk but the x55u quirk.
All that the x401u quirk does it setting wapf to 4, so rename it to wapf4 to
stop the confusion.
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 8698c8674d05..12ee6eb181cb 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -70,7 +70,7 @@ static struct quirk_entry quirk_asus_x55u = {
.no_display_toggle = true,
};
-static struct quirk_entry quirk_asus_x401u = {
+static struct quirk_entry quirk_asus_wapf4 = {
.wapf = 4,
};
@@ -101,7 +101,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X401A"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -110,7 +110,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -128,7 +128,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X501A"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -137,7 +137,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -146,7 +146,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -173,7 +173,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X55A"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -182,7 +182,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X55C"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -200,7 +200,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -209,7 +209,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X75A"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -218,7 +218,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -227,7 +227,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
@@ -236,7 +236,7 @@ static struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
},
- .driver_data = &quirk_asus_x401u,
+ .driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
--
2.2.2
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 831a444ea6f8f25fd1a9cc9d7651bc18b5a1f755 upstream.
As reported here: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1173681
the U32U needs wapf=4 too.
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 12ee6eb181cb..c2da4b2118de 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -87,6 +87,20 @@ static int dmi_matched(const struct dmi_system_id *dmi)
static struct dmi_system_id asus_quirks[] = {
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. U32U",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "U32U"),
+ },
+ /*
+ * Note this machine has a Brazos APU, and most Brazos Asus
+ * machines need quirk_asus_x55u / wmi_backlight_power but
+ * here acpi-video seems to work fine for backlight control.
+ */
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X401U",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: Stanislaw Gruszka <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4ec7a45b51a32ee513898e2f1e42bb681b340fcf upstream.
X550VB as many others Asus laptops need wapf4 quirk to make RFKILL
switch be functional. Otherwise system boots with wireless card
disabled and is only possible to enable it by suspend/resume.
Bug report:
http://bugzilla.redhat.com/show_bug.cgi?id=1089731#c23
Reported-and-tested-by: Vratislav Podzimek <[email protected]>
Signed-off-by: Stanislaw Gruszka <[email protected]>
Signed-off-by: Darren Hart <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index c2da4b2118de..ec08ae017f1b 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -182,6 +182,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X550VB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550VB"),
+ },
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X55A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 841e11ccdf90c29a7778a5d5d553bc716c3d477a upstream.
Wifi on this laptop does not work unless asus-nb-wmi.wapf=4 is specified on
the kerne commandline, add a quirk for this.
Cc: [email protected]
BugLink: https://bugs.launchpad.net/bugs/1173681
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Darren Hart <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index ec08ae017f1b..d9c958666784 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -191,6 +191,15 @@ static struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X551CA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"),
+ },
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X55A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.2.2
From: Mateusz Guzik <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e7ca2552369c1dfe0216c626baf82c3d83ec36bb upstream.
Compat function takes msgtyp argument as u32 and passes it down to
do_msgrcv which results in casting to long, thus the sign is lost and we
get a big positive number instead.
Cast the argument to signed type before passing it down.
Signed-off-by: Mateusz Guzik <[email protected]>
Reported-by: Gabriellla Schmidt <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Davidlohr Bueso <[email protected]>
Cc: Manfred Spraul <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
ipc/compat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipc/compat.c b/ipc/compat.c
index 892f6585dd60..d3b376025e9b 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -381,7 +381,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
uptr = compat_ptr(ipck.msgp);
fifth = ipck.msgtyp;
}
- return do_msgrcv(first, uptr, second, fifth, third,
+ return do_msgrcv(first, uptr, second, (s32)fifth, third,
compat_do_msg_fill);
}
case MSGGET:
--
2.2.2
From: Heiko Carstens <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 291fdb0bcebd5e8db6af767c1fdc522167dad73d upstream.
Change the type of compat_sys_msgrcv's msgtyp parameter from long
to compat_long_t, since compat user space passes only a 32 bit signed
value.
Let the compat wrapper do proper sign extension to 64 bit of this
parameter.
Signed-off-by: Heiko Carstens <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/compat.h | 2 +-
ipc/compat.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 0f62cb7a4ff0..afea0d19b37a 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -318,7 +318,7 @@ asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
compat_ssize_t msgsz, int msgflg);
asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
- compat_ssize_t msgsz, long msgtyp, int msgflg);
+ compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
long compat_sys_msgctl(int first, int second, void __user *uptr);
long compat_sys_shmctl(int first, int second, void __user *uptr);
long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
diff --git a/ipc/compat.c b/ipc/compat.c
index d3b376025e9b..e0012184f65e 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -430,9 +430,9 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
}
COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
- compat_ssize_t, msgsz, long, msgtyp, int, msgflg)
+ compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
{
- return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, msgtyp,
+ return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
msgflg, compat_do_msg_fill);
}
--
2.2.2
From: Hannes Reinecke <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 506787a2c7daed45f0a213674ca706cbc83a9089 upstream.
tcm_loop has the I_T nexus associated with the HBA. This causes
commands to become misdirected if the HBA has more than one
target portal group; any command is then being sent to the
first target portal group instead of the correct one.
The nexus needs to be associated with the target portal group
instead.
Signed-off-by: Hannes Reinecke <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/target/loopback/tcm_loop.c | 29 ++++++++++++++---------------
drivers/target/loopback/tcm_loop.h | 7 +------
2 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 0f6d69dabca1..c54dd828431f 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -179,7 +179,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
goto out_done;
}
- tl_nexus = tl_hba->tl_nexus;
+ tl_nexus = tl_tpg->tl_nexus;
if (!tl_nexus) {
scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
" does not exist\n");
@@ -258,20 +258,20 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
*/
tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
/*
+ * Locate the tl_tpg and se_tpg pointers from TargetID in sc->device->id
+ */
+ tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+ se_tpg = &tl_tpg->tl_se_tpg;
+ /*
* Locate the tl_nexus and se_sess pointers
*/
- tl_nexus = tl_hba->tl_nexus;
+ tl_nexus = tl_tpg->tl_nexus;
if (!tl_nexus) {
pr_err("Unable to perform device reset without"
" active I_T Nexus\n");
return FAILED;
}
se_sess = tl_nexus->se_sess;
- /*
- * Locate the tl_tpg and se_tpg pointers from TargetID in sc->device->id
- */
- tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
- se_tpg = &tl_tpg->tl_se_tpg;
tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
if (!tl_cmd) {
@@ -878,8 +878,8 @@ static int tcm_loop_make_nexus(
struct tcm_loop_nexus *tl_nexus;
int ret = -ENOMEM;
- if (tl_tpg->tl_hba->tl_nexus) {
- pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n");
+ if (tl_tpg->tl_nexus) {
+ pr_debug("tl_tpg->tl_nexus already exists\n");
return -EEXIST;
}
se_tpg = &tl_tpg->tl_se_tpg;
@@ -914,7 +914,7 @@ static int tcm_loop_make_nexus(
*/
__transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
tl_nexus->se_sess, tl_nexus);
- tl_tpg->tl_hba->tl_nexus = tl_nexus;
+ tl_tpg->tl_nexus = tl_nexus;
pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
name);
@@ -930,9 +930,8 @@ static int tcm_loop_drop_nexus(
{
struct se_session *se_sess;
struct tcm_loop_nexus *tl_nexus;
- struct tcm_loop_hba *tl_hba = tpg->tl_hba;
- tl_nexus = tpg->tl_hba->tl_nexus;
+ tl_nexus = tpg->tl_nexus;
if (!tl_nexus)
return -ENODEV;
@@ -948,13 +947,13 @@ static int tcm_loop_drop_nexus(
}
pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
- " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
+ " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
tl_nexus->se_sess->se_node_acl->initiatorname);
/*
* Release the SCSI I_T Nexus to the emulated SAS Target Port
*/
transport_deregister_session(tl_nexus->se_sess);
- tpg->tl_hba->tl_nexus = NULL;
+ tpg->tl_nexus = NULL;
kfree(tl_nexus);
return 0;
}
@@ -970,7 +969,7 @@ static ssize_t tcm_loop_tpg_show_nexus(
struct tcm_loop_nexus *tl_nexus;
ssize_t ret;
- tl_nexus = tl_tpg->tl_hba->tl_nexus;
+ tl_nexus = tl_tpg->tl_nexus;
if (!tl_nexus)
return -ENODEV;
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
index dd7a84ee78e1..4ed85886a1ee 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -25,11 +25,6 @@ struct tcm_loop_tmr {
};
struct tcm_loop_nexus {
- int it_nexus_active;
- /*
- * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h
- */
- struct scsi_host *sh;
/*
* Pointer to TCM session for I_T Nexus
*/
@@ -45,6 +40,7 @@ struct tcm_loop_tpg {
atomic_t tl_tpg_port_count;
struct se_portal_group tl_se_tpg;
struct tcm_loop_hba *tl_hba;
+ struct tcm_loop_nexus *tl_nexus;
};
struct tcm_loop_hba {
@@ -53,7 +49,6 @@ struct tcm_loop_hba {
struct se_hba_s *se_hba;
struct se_lun *tl_hba_lun;
struct se_port *tl_hba_lun_sep;
- struct tcm_loop_nexus *tl_nexus;
struct device dev;
struct Scsi_Host *sh;
struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA];
--
2.2.2
From: Nicholas Bellinger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 046ba64285a4389ae5e9a7dfa253c6bff3d7c341 upstream.
This patch drops the arbitrary maximum I/O size limit in sbc_parse_cdb(),
which currently for fabric_max_sectors is hardcoded to 8192 (4 MB for 512
byte sector devices), and for hw_max_sectors is a backend driver dependent
value.
This limit is problematic because Linux initiators have only recently
started to honor block limits MAXIMUM TRANSFER LENGTH, and other non-Linux
based initiators (eg: MSFT Fibre Channel) can also generate I/Os larger
than 4 MB in size.
Currently when this happens, the following message will appear on the
target resulting in I/Os being returned with non recoverable status:
SCSI OP 28h with too big sectors 16384 exceeds fabric_max_sectors: 8192
Instead, drop both [fabric,hw]_max_sector checks in sbc_parse_cdb(),
and convert the existing hw_max_sectors into a purely informational
attribute used to represent the granuality that backend driver and/or
subsystem code is splitting I/Os upon.
Also, update FILEIO with an explicit FD_MAX_BYTES check in fd_execute_rw()
to deal with the one special iovec limitiation case.
v2 changes:
- Drop hw_max_sectors check in sbc_parse_cdb()
Reported-by: Lance Gropper <[email protected]>
Reported-by: Stefan Priebe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Martin K. Petersen <[email protected]>
Cc: Roland Dreier <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/target/target_core_device.c | 8 ++++----
drivers/target/target_core_file.c | 11 ++++++++++-
drivers/target/target_core_iblock.c | 2 +-
drivers/target/target_core_sbc.c | 15 ---------------
drivers/target/target_core_spc.c | 5 +----
5 files changed, 16 insertions(+), 25 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index a3ce91234b77..c67a56e7ee1c 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1066,10 +1066,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)
" changed for TCM/pSCSI\n", dev);
return -EINVAL;
}
- if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) {
+ if (optimal_sectors > dev->dev_attrib.hw_max_sectors) {
pr_err("dev[%p]: Passed optimal_sectors %u cannot be"
- " greater than fabric_max_sectors: %u\n", dev,
- optimal_sectors, dev->dev_attrib.fabric_max_sectors);
+ " greater than hw_max_sectors: %u\n", dev,
+ optimal_sectors, dev->dev_attrib.hw_max_sectors);
return -EINVAL;
}
@@ -1474,7 +1474,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN;
dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS;
- dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS;
return dev;
}
@@ -1507,6 +1506,7 @@ int target_configure_device(struct se_device *dev)
dev->dev_attrib.hw_max_sectors =
se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors,
dev->dev_attrib.hw_block_size);
+ dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors;
dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);
dev->creation_time = get_jiffies_64();
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 55725f5f56a2..174815c88b7c 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -552,7 +552,16 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
{
struct se_device *dev = cmd->se_dev;
int ret = 0;
-
+ /*
+ * We are currently limited by the number of iovecs (2048) per
+ * single vfs_[writev,readv] call.
+ */
+ if (cmd->data_length > FD_MAX_BYTES) {
+ pr_err("FILEIO: Not able to process I/O of %u bytes due to"
+ "FD_MAX_BYTES: %u iovec count limitiation\n",
+ cmd->data_length, FD_MAX_BYTES);
+ return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ }
/*
* Call vectorized fileio functions to map struct scatterlist
* physical memory addresses to struct iovec virtual memory.
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index b9a3394fe479..9c403f6d3317 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -122,7 +122,7 @@ static int iblock_configure_device(struct se_device *dev)
q = bdev_get_queue(bd);
dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd);
- dev->dev_attrib.hw_max_sectors = UINT_MAX;
+ dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
dev->dev_attrib.hw_queue_depth = q->nr_requests;
/*
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 214522282c19..d83aea80d83c 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -829,21 +829,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
unsigned long long end_lba;
- if (sectors > dev->dev_attrib.fabric_max_sectors) {
- printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
- " big sectors %u exceeds fabric_max_sectors:"
- " %u\n", cdb[0], sectors,
- dev->dev_attrib.fabric_max_sectors);
- return TCM_INVALID_CDB_FIELD;
- }
- if (sectors > dev->dev_attrib.hw_max_sectors) {
- printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
- " big sectors %u exceeds backend hw_max_sectors:"
- " %u\n", cdb[0], sectors,
- dev->dev_attrib.hw_max_sectors);
- return TCM_INVALID_CDB_FIELD;
- }
-
end_lba = dev->transport->get_blocks(dev) + 1;
if (cmd->t_task_lba + sectors > end_lba) {
pr_err("cmd exceeds last lba %llu "
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index ee400df1fea2..a8113d44d1e3 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -450,7 +450,6 @@ static sense_reason_t
spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
{
struct se_device *dev = cmd->se_dev;
- u32 max_sectors;
int have_tp = 0;
/*
@@ -480,9 +479,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
/*
* Set MAXIMUM TRANSFER LENGTH
*/
- max_sectors = min(dev->dev_attrib.fabric_max_sectors,
- dev->dev_attrib.hw_max_sectors);
- put_unaligned_be32(max_sectors, &buf[8]);
+ put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]);
/*
* Set OPTIMAL TRANSFER LENGTH
--
2.2.2
From: Mark Rutland <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 44b82b7700d05a52cd983799d3ecde1a976b3bed upstream.
[backport to 3.12.x: fold in missing MIDR_EL1 recording]
Commit d7a49086f263164a (arm64: cpuinfo: print info for all CPUs)
attempted to clean up /proc/cpuinfo, but due to concerns regarding
further changes was reverted in commit 5e39977edf6500fd (Revert "arm64:
cpuinfo: print info for all CPUs").
There are two major issues with the arm64 /proc/cpuinfo format
currently:
* The "Features" line describes (only) the 64-bit hwcaps, which is
problematic for some 32-bit applications which attempt to parse it. As
the same names are used for analogous ISA features (e.g. aes) despite
these generally being architecturally unrelated, it is not possible to
simply append the 64-bit and 32-bit hwcaps in a manner that might not
be misleading to some applications.
Various potential solutions have appeared in vendor kernels. Typically
the format of the Features line varies depending on whether the task
is 32-bit.
* Information is only printed regarding a single CPU. This does not
match the ARM format, and does not provide sufficient information in
big.LITTLE systems where CPUs are heterogeneous. The CPU information
printed is queried from the current CPU's registers, which is racy
w.r.t. cross-cpu migration.
This patch attempts to solve these issues. The following changes are
made:
* When a task with a LINUX32 personality attempts to read /proc/cpuinfo,
the "Features" line contains the decoded 32-bit hwcaps, as with the
arm port. Otherwise, the decoded 64-bit hwcaps are shown. This aligns
with the behaviour of COMPAT_UTS_MACHINE and COMPAT_ELF_PLATFORM. In
the absense of compat support, the Features line is empty.
The set of hwcaps injected into a task's auxval are unaffected.
* Properties are printed per-cpu, as with the ARM port. The per-cpu
information is queried from pre-recorded cpu information (as used by
the sanity checks).
* As with the previous attempt at fixing up /proc/cpuinfo, the hardware
field is removed. The only users so far are 32-bit applications tied
to particular boards, so no portable applications should be affected,
and this should prevent future tying to particular boards.
The following differences remain:
* No model_name is printed, as this cannot be queried from the hardware
and cannot be provided in a stable fashion. Use of the CPU
{implementor,variant,part,revision} fields is sufficient to identify a
CPU and is portable across arm and arm64.
* The following system-wide properties are not provided, as they are not
possible to provide generally. Programs relying on these are already
tied to particular (32-bit only) boards:
- Hardware
- Revision
- Serial
No software has yet been identified for which these remaining
differences are problematic.
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: [email protected] # 3.12.x
Signed-off-by: Mark Rutland <[email protected]>
[Mark: backport to v3.12.x]
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/arm64/include/asm/cputype.h | 2 +
arch/arm64/kernel/setup.c | 98 ++++++++++++++++++++++++++++++----------
arch/arm64/kernel/smp.c | 5 ++
3 files changed, 81 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 5fe138e0b828..cfcf04d22fd2 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -77,6 +77,8 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
return read_cpuid(ID_CTR_EL0);
}
+void cpuinfo_store_cpu(void);
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 055cfb80e05c..24bf1563c3bd 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -41,6 +41,7 @@
#include <linux/memblock.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
+#include <linux/personality.h>
#include <asm/cputype.h>
#include <asm/elf.h>
@@ -97,6 +98,19 @@ void __init early_print(const char *str, ...)
printk("%s", buf);
}
+struct cpuinfo_arm64 {
+ struct cpu cpu;
+ u32 reg_midr;
+};
+
+static DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
+
+void cpuinfo_store_cpu(void)
+{
+ struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
+ info->reg_midr = read_cpuid_id();
+}
+
static void __init setup_processor(void)
{
struct cpu_info *cpu_info;
@@ -127,6 +141,8 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
struct boot_param_header *devtree;
unsigned long dt_root;
+ cpuinfo_store_cpu();
+
/* Check we have a non-NULL DT pointer */
if (!dt_phys) {
early_print("\n"
@@ -285,14 +301,12 @@ static int __init arm64_device_init(void)
}
arch_initcall(arm64_device_init);
-static DEFINE_PER_CPU(struct cpu, cpu_data);
-
static int __init topology_init(void)
{
int i;
for_each_possible_cpu(i) {
- struct cpu *cpu = &per_cpu(cpu_data, i);
+ struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
cpu->hotpluggable = 1;
register_cpu(cpu, i);
}
@@ -307,14 +321,41 @@ static const char *hwcap_str[] = {
NULL
};
+#ifdef CONFIG_COMPAT
+static const char *compat_hwcap_str[] = {
+ "swp",
+ "half",
+ "thumb",
+ "26bit",
+ "fastmult",
+ "fpa",
+ "vfp",
+ "edsp",
+ "java",
+ "iwmmxt",
+ "crunch",
+ "thumbee",
+ "neon",
+ "vfpv3",
+ "vfpv3d16",
+ "tls",
+ "vfpv4",
+ "idiva",
+ "idivt",
+ "vfpd32",
+ "lpae",
+ "evtstrm"
+};
+#endif /* CONFIG_COMPAT */
+
static int c_show(struct seq_file *m, void *v)
{
- int i;
-
- seq_printf(m, "Processor\t: %s rev %d (%s)\n",
- cpu_name, read_cpuid_id() & 15, ELF_PLATFORM);
+ int i, j;
for_each_online_cpu(i) {
+ struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+ u32 midr = cpuinfo->reg_midr;
+
/*
* glibc reads /proc/cpuinfo to determine the number of
* online processors, looking for lines beginning with
@@ -323,24 +364,33 @@ static int c_show(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
seq_printf(m, "processor\t: %d\n", i);
#endif
- }
-
- /* dump out the processor features */
- seq_puts(m, "Features\t: ");
-
- for (i = 0; hwcap_str[i]; i++)
- if (elf_hwcap & (1 << i))
- seq_printf(m, "%s ", hwcap_str[i]);
- seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
- seq_printf(m, "CPU architecture: AArch64\n");
- seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
- seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
- seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
-
- seq_puts(m, "\n");
-
- seq_printf(m, "Hardware\t: %s\n", machine_name);
+ /*
+ * Dump out the common processor features in a single line.
+ * Userspace should read the hwcaps with getauxval(AT_HWCAP)
+ * rather than attempting to parse this, but there's a body of
+ * software which does already (at least for 32-bit).
+ */
+ seq_puts(m, "Features\t:");
+ if (personality(current->personality) == PER_LINUX32) {
+#ifdef CONFIG_COMPAT
+ for (j = 0; compat_hwcap_str[j]; j++)
+ if (COMPAT_ELF_HWCAP & (1 << j))
+ seq_printf(m, " %s", compat_hwcap_str[j]);
+#endif /* CONFIG_COMPAT */
+ } else {
+ for (j = 0; hwcap_str[j]; j++)
+ if (elf_hwcap & (1 << j))
+ seq_printf(m, " %s", hwcap_str[j]);
+ }
+ seq_puts(m, "\n");
+
+ seq_printf(m, "CPU implementer\t: 0x%02x\n", (midr >> 24));
+ seq_printf(m, "CPU architecture: 8\n");
+ seq_printf(m, "CPU variant\t: 0x%x\n", ((midr >> 20) & 0xf));
+ seq_printf(m, "CPU part\t: 0x%03x\n", ((midr >> 4) & 0xfff));
+ seq_printf(m, "CPU revision\t: %d\n\n", (midr & 0xf));
+ }
return 0;
}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 78db90dcc910..8130993a0d8b 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -200,6 +200,11 @@ asmlinkage void secondary_start_kernel(void)
raw_spin_unlock(&boot_lock);
/*
+ * Log the CPU info before it is marked online and might get read.
+ */
+ cpuinfo_store_cpu();
+
+ /*
* OK, now it's safe to let the boot CPU continue. Wait for
* the CPU migration code to notice that the CPU is online
* before we continue.
--
2.2.2
From: Mika Westerberg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 07c001c119c7de92be9c8ad1f1a3e5af459cb3d4 upstream.
Newer Intel PCHs with LPSS have the same SDHCI controller than Haswell but
ACPI ID is different. Add this ID to the driver list.
Signed-off-by: Mika Westerberg <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index cdd4ce0d7c90..d94fa1467c79 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -144,6 +144,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
{ "80860F14" , "3" , &sdhci_acpi_slot_int_sd },
{ "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio },
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
+ { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
{ "PNP0D40" },
{ },
};
@@ -152,6 +153,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
{ "80860F14" },
{ "INT33BB" },
{ "INT33C6" },
+ { "INT3436" },
{ "PNP0D40" },
{ },
};
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit aad95dc49c6dad19b49af7cd90c53473ec0536d1 upstream.
Add ACPI HID 80860F16 as a host controller for a SD card.
Signed-off-by: Adrian Hunter <[email protected]>
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index d94fa1467c79..548bf375c6ae 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -142,6 +142,7 @@ struct sdhci_acpi_uid_slot {
static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
{ "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
{ "80860F14" , "3" , &sdhci_acpi_slot_int_sd },
+ { "80860F16" , NULL, &sdhci_acpi_slot_int_sd },
{ "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio },
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
{ "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
@@ -151,6 +152,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
static const struct acpi_device_id sdhci_acpi_ids[] = {
{ "80860F14" },
+ { "80860F16" },
{ "INT33BB" },
{ "INT33C6" },
{ "INT3436" },
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c67480173f72e883235dd0ad09d90156c8f87600 upstream.
Intel SDIO has broken card detect so add a quirk to reflect that.
Signed-off-by: Adrian Hunter <[email protected]>
Acked-by: Ulf Hansson <[email protected]>
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 548bf375c6ae..e1c37e24323a 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -122,6 +122,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
};
static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
+ .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION,
.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
.caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
.flags = SDHCI_ACPI_RUNTIME_PM,
--
2.2.2
From: Maurice Petallo <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d61b59461b0cd0106f03e566d537b9072029e059 upstream.
"SDHCI_QUIRK2_PRESET_VALUE_BROKEN" quirk is added to prohibit
preset value enabling for Baytrail eMMC controller.
Signed-off-by: Maurice Petallo <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 1 +
drivers/mmc/host/sdhci-pci.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index e1c37e24323a..2f266ff7c917 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -119,6 +119,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | MMC_CAP_HW_RESET,
.caps2 = MMC_CAP2_HC_ERASE_SZ,
.flags = SDHCI_ACPI_RUNTIME_PM,
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
};
static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index b2a4c22507d9..ef91e0ac2dc6 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -356,6 +356,7 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
.allow_runtime_pm = true,
.probe_slot = byt_emmc_probe_slot,
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
};
static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7147eaf3a4fe7e7dbb6e1f89e328ea0507e0c32c upstream.
Add a HID (INT33BB) and UID (3) for a SD Card host controller.
Signed-off-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 2f266ff7c917..7b1e10136762 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -146,6 +146,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
{ "80860F14" , "3" , &sdhci_acpi_slot_int_sd },
{ "80860F16" , NULL, &sdhci_acpi_slot_int_sd },
{ "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio },
+ { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd },
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
{ "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
{ "PNP0D40" },
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d0ed8e6b0ab149421cd1532e7c5ebb0992ad25d0 upstream.
Add ACPI HID INT344D for an Intel SDIO host controller.
Signed-off-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-acpi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 7b1e10136762..854fcfbd7574 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -149,6 +149,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
{ "INT33BB" , "3" , &sdhci_acpi_slot_int_sd },
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
{ "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
+ { "INT344D" , NULL, &sdhci_acpi_slot_int_sdio },
{ "PNP0D40" },
{ },
};
@@ -159,6 +160,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
{ "INT33BB" },
{ "INT33C6" },
{ "INT3436" },
+ { "INT344D" },
{ "PNP0D40" },
{ },
};
--
2.2.2
From: David Cohen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 390145f9adcf2730fcee81c8a51fd7c6c08f705f upstream.
Due to unknown hw issue so far, Merrifield is unable to enable HS200
support. This patch adds quirk to avoid SDHCI to initialize with error
below:
[ 53.850132] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W
3.12.0-rc6-00037-g3d7c8d9-dirty #36
[ 53.850150] Hardware name: Intel Corporation Merrifield/SALT BAY,
BIOS 397 2013.09.12:11.51.40
[ 53.850167] 00000000 00000000 ee409e48 c18816d2 00000000 ee409e78
c123e254 c1acc9b0
[ 53.850227] 00000000 00000000 c1b14148 000003de c16c03bf c16c03bf
ee75b480 ed97c54c
[ 53.850282] ee75b480 ee409e88 c123e292 00000009 00000000 ee409ef8
c16c03bf c1207fac
[ 53.850339] Call Trace:
[ 53.850376] [<c18816d2>] dump_stack+0x4b/0x79
[ 53.850408] [<c123e254>] warn_slowpath_common+0x84/0xa0
[ 53.850436] [<c16c03bf>] ? sdhci_send_command+0xb4f/0xc50
[ 53.850462] [<c16c03bf>] ? sdhci_send_command+0xb4f/0xc50
[ 53.850490] [<c123e292>] warn_slowpath_null+0x22/0x30
[ 53.850516] [<c16c03bf>] sdhci_send_command+0xb4f/0xc50
[ 53.850545] [<c1207fac>] ? native_sched_clock+0x2c/0xb0
[ 53.850575] [<c14c1f93>] ? delay_tsc+0x73/0xb0
[ 53.850601] [<c14c1ebe>] ? __const_udelay+0x1e/0x20
[ 53.850626] [<c16bdeb3>] ? sdhci_reset+0x93/0x190
[ 53.850654] [<c16c05b0>] sdhci_finish_data+0xf0/0x2e0
[ 53.850683] [<c16c130f>] sdhci_irq+0x31f/0x930
[ 53.850713] [<c12cb080>] ? __buffer_unlock_commit+0x10/0x20
[ 53.850740] [<c12cbcd7>] ? trace_buffer_unlock_commit+0x37/0x50
[ 53.850773] [<c1288f3c>] handle_irq_event_percpu+0x5c/0x220
[ 53.850800] [<c128bc96>] ? handle_fasteoi_irq+0x16/0xd0
[ 53.850827] [<c128913a>] handle_irq_event+0x3a/0x60
[ 53.850852] [<c128bc80>] ? unmask_irq+0x30/0x30
[ 53.850878] [<c128bcce>] handle_fasteoi_irq+0x4e/0xd0
[ 53.850895] <IRQ> [<c1890b52>] ? do_IRQ+0x42/0xb0
[ 53.850943] [<c1890a31>] ? common_interrupt+0x31/0x38
[ 53.850973] [<c12b00d8>] ? cgroup_mkdir+0x4e8/0x580
[ 53.851001] [<c1208d32>] ? default_idle+0x22/0xf0
[ 53.851029] [<c1209576>] ? arch_cpu_idle+0x26/0x30
[ 53.851054] [<c1288505>] ? cpu_startup_entry+0x65/0x240
[ 53.851082] [<c18793d5>] ? rest_init+0xb5/0xc0
[ 53.851108] [<c1879320>] ? __read_lock_failed+0x18/0x18
[ 53.851138] [<c1bf6a15>] ? start_kernel+0x31b/0x321
[ 53.851164] [<c1bf652f>] ? repair_env_string+0x51/0x51
[ 53.851190] [<c1bf6363>] ? i386_start_kernel+0x139/0x13c
[ 53.851209] ---[ end trace 92777f5fe48d33f2 ]---
[ 53.853449] mmcblk0: error -84 transferring data, sector 11142162, nr
304, cmd response 0x0, card status 0x0
[ 53.853476] mmcblk0: retrying using single block read
[ 55.937863] sdhci: Timeout waiting for Buffer Read Ready interrupt
during tuning procedure, falling back to fixed sampling clock
[ 56.207951] sdhci: Timeout waiting for Buffer Read Ready interrupt
during tuning procedure, falling back to fixed sampling clock
[ 66.228785] mmc0: Timeout waiting for hardware interrupt.
[ 66.230855] ------------[ cut here ]------------
Signed-off-by: David Cohen <[email protected]>
Reviewed-by: Chuanxiao Dong <[email protected]>
Acked-by: Dong Aisheng <[email protected]>
Cc: stable <[email protected]> # [3.13]
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index ef91e0ac2dc6..a8adccb02183 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -390,6 +390,7 @@ static int intel_mrfl_mmc_probe_slot(struct sdhci_pci_slot *slot)
static const struct sdhci_pci_fixes sdhci_intel_mrfl_mmc = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+ .quirks2 = SDHCI_QUIRK2_BROKEN_HS200,
.probe_slot = intel_mrfl_mmc_probe_slot,
};
--
2.2.2
From: David Cohen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 13868bf20f2f2c305f96e23620b024e167d6f9cb upstream.
This patch defines a quirk for platforms unable to enable HS200 support.
Signed-off-by: David Cohen <[email protected]>
Reviewed-by: Chuanxiao Dong <[email protected]>
Acked-by: Dong Aisheng <[email protected]>
Cc: stable <[email protected]> # [3.13]
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci.c | 3 ++-
include/linux/mmc/sdhci.h | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ff6e822d2b78..cf110751d1c6 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3006,7 +3006,8 @@ int sdhci_add_host(struct sdhci_host *host)
/* SD3.0: SDR104 is supported so (for eMMC) the caps2
* field can be promoted to support HS200.
*/
- mmc->caps2 |= MMC_CAP2_HS200;
+ if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200))
+ mmc->caps2 |= MMC_CAP2_HS200;
} else if (caps[1] & SDHCI_SUPPORT_SDR50)
mmc->caps |= MMC_CAP_UHS_SDR50;
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 3e781b8c0be7..362927c48f97 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -98,6 +98,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4)
/* Controller has a non-standard host control register */
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
+/* Controller does not support HS200 */
+#define SDHCI_QUIRK2_BROKEN_HS200 (1<<6)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
2.2.2
From: Micky Ching <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9107ebbf9652c033eb5dd10a6ea34a132db3cde1 upstream.
Add support for realtek rts5250 pci card reader. The card reader has
some problems with DDR50 mode, so add a new quirks2 for broken ddr50.
Signed-off-by: Micky Ching <[email protected]>
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 20 ++++++++++++++++++++
drivers/mmc/host/sdhci.c | 3 ++-
include/linux/mmc/sdhci.h | 2 ++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index a8adccb02183..98190e4ae144 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -744,6 +744,18 @@ static const struct sdhci_pci_fixes sdhci_via = {
.probe = via_probe,
};
+static int rtsx_probe_slot(struct sdhci_pci_slot *slot)
+{
+ slot->host->mmc->caps2 |= MMC_CAP2_HS200;
+ return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_rtsx = {
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+ SDHCI_QUIRK2_BROKEN_DDR50,
+ .probe_slot = rtsx_probe_slot,
+};
+
static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_RICOH,
@@ -866,6 +878,14 @@ static const struct pci_device_id pci_ids[] = {
},
{
+ .vendor = PCI_VENDOR_ID_REALTEK,
+ .device = 0x5250,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_rtsx,
+ },
+
+ {
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_QRK_SD,
.subvendor = PCI_ANY_ID,
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index cf110751d1c6..bd2538d84f5d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3011,7 +3011,8 @@ int sdhci_add_host(struct sdhci_host *host)
} else if (caps[1] & SDHCI_SUPPORT_SDR50)
mmc->caps |= MMC_CAP_UHS_SDR50;
- if (caps[1] & SDHCI_SUPPORT_DDR50)
+ if ((caps[1] & SDHCI_SUPPORT_DDR50) &&
+ !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
mmc->caps |= MMC_CAP_UHS_DDR50;
/* Does the host need tuning for SDR50? */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 362927c48f97..7be12b883485 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -100,6 +100,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
/* Controller does not support HS200 */
#define SDHCI_QUIRK2_BROKEN_HS200 (1<<6)
+/* Controller does not support DDR50 */
+#define SDHCI_QUIRK2_BROKEN_DDR50 (1<<7)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
2.2.2
From: Adam Lee <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 522624f97ee22684cf1b169b5a490cc3ad87b22c upstream.
Break out definitions in sdhci-pci.c to sdhci-pci.h, for introducing
module files like sdhci-pci-xxx.c
Signed-off-by: Adam Lee <[email protected]>
Signed-off-by: Chris Ball <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 76 +-----------------------------------------
drivers/mmc/host/sdhci-pci.h | 79 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 75 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-pci.h
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 98190e4ae144..29818a189b1c 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -27,81 +27,7 @@
#include <linux/mmc/sdhci-pci-data.h>
#include "sdhci.h"
-
-/*
- * PCI device IDs
- */
-#define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809
-#define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a
-#define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14
-#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15
-#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16
-#define PCI_DEVICE_ID_INTEL_BYT_EMMC2 0x0f50
-#define PCI_DEVICE_ID_INTEL_MRFL_MMC 0x1190
-#define PCI_DEVICE_ID_INTEL_CLV_SDIO0 0x08f9
-#define PCI_DEVICE_ID_INTEL_CLV_SDIO1 0x08fa
-#define PCI_DEVICE_ID_INTEL_CLV_SDIO2 0x08fb
-#define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5
-#define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6
-#define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7
-
-/*
- * PCI registers
- */
-
-#define PCI_SDHCI_IFPIO 0x00
-#define PCI_SDHCI_IFDMA 0x01
-#define PCI_SDHCI_IFVENDOR 0x02
-
-#define PCI_SLOT_INFO 0x40 /* 8 bits */
-#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
-#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07
-
-#define MAX_SLOTS 8
-
-struct sdhci_pci_chip;
-struct sdhci_pci_slot;
-
-struct sdhci_pci_fixes {
- unsigned int quirks;
- unsigned int quirks2;
- bool allow_runtime_pm;
- bool own_cd_for_runtime_pm;
-
- int (*probe) (struct sdhci_pci_chip *);
-
- int (*probe_slot) (struct sdhci_pci_slot *);
- void (*remove_slot) (struct sdhci_pci_slot *, int);
-
- int (*suspend) (struct sdhci_pci_chip *);
- int (*resume) (struct sdhci_pci_chip *);
-};
-
-struct sdhci_pci_slot {
- struct sdhci_pci_chip *chip;
- struct sdhci_host *host;
- struct sdhci_pci_data *data;
-
- int pci_bar;
- int rst_n_gpio;
- int cd_gpio;
- int cd_irq;
-
- void (*hw_reset)(struct sdhci_host *host);
-};
-
-struct sdhci_pci_chip {
- struct pci_dev *pdev;
-
- unsigned int quirks;
- unsigned int quirks2;
- bool allow_runtime_pm;
- const struct sdhci_pci_fixes *fixes;
-
- int num_slots; /* Slots on controller */
- struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */
-};
-
+#include "sdhci-pci.h"
/*****************************************************************************\
* *
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
new file mode 100644
index 000000000000..c101477ef3be
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pci.h
@@ -0,0 +1,79 @@
+#ifndef __SDHCI_PCI_H
+#define __SDHCI_PCI_H
+
+/*
+ * PCI device IDs
+ */
+
+#define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809
+#define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14
+#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15
+#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC2 0x0f50
+#define PCI_DEVICE_ID_INTEL_MRFL_MMC 0x1190
+#define PCI_DEVICE_ID_INTEL_CLV_SDIO0 0x08f9
+#define PCI_DEVICE_ID_INTEL_CLV_SDIO1 0x08fa
+#define PCI_DEVICE_ID_INTEL_CLV_SDIO2 0x08fb
+#define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5
+#define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6
+#define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7
+
+/*
+ * PCI registers
+ */
+
+#define PCI_SDHCI_IFPIO 0x00
+#define PCI_SDHCI_IFDMA 0x01
+#define PCI_SDHCI_IFVENDOR 0x02
+
+#define PCI_SLOT_INFO 0x40 /* 8 bits */
+#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
+#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07
+
+#define MAX_SLOTS 8
+
+struct sdhci_pci_chip;
+struct sdhci_pci_slot;
+
+struct sdhci_pci_fixes {
+ unsigned int quirks;
+ unsigned int quirks2;
+ bool allow_runtime_pm;
+ bool own_cd_for_runtime_pm;
+
+ int (*probe) (struct sdhci_pci_chip *);
+
+ int (*probe_slot) (struct sdhci_pci_slot *);
+ void (*remove_slot) (struct sdhci_pci_slot *, int);
+
+ int (*suspend) (struct sdhci_pci_chip *);
+ int (*resume) (struct sdhci_pci_chip *);
+};
+
+struct sdhci_pci_slot {
+ struct sdhci_pci_chip *chip;
+ struct sdhci_host *host;
+ struct sdhci_pci_data *data;
+
+ int pci_bar;
+ int rst_n_gpio;
+ int cd_gpio;
+ int cd_irq;
+
+ void (*hw_reset)(struct sdhci_host *host);
+};
+
+struct sdhci_pci_chip {
+ struct pci_dev *pdev;
+
+ unsigned int quirks;
+ unsigned int quirks2;
+ bool allow_runtime_pm;
+ const struct sdhci_pci_fixes *fixes;
+
+ int num_slots; /* Slots on controller */
+ struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */
+};
+
+#endif /* __SDHCI_PCI_H */
--
2.2.2
From: Alan Cox <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 066173b6436dfc57a96b2d940f4e727fe8131261 upstream.
The hardware is the same as used in Baytrail. Add these new PCI IDs to the
driver's list of supported IDs.
Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 23 +++++++++++++++++++++++
drivers/mmc/host/sdhci-pci.h | 3 +++
2 files changed, 26 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 29818a189b1c..a130a11d89de 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -931,6 +931,29 @@ static const struct pci_device_id pci_ids[] = {
.driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
},
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_BSW_EMMC,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_BSW_SDIO,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_BSW_SD,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
+ },
{
.vendor = PCI_VENDOR_ID_INTEL,
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
index c101477ef3be..9c1909b2a3ad 100644
--- a/drivers/mmc/host/sdhci-pci.h
+++ b/drivers/mmc/host/sdhci-pci.h
@@ -11,6 +11,9 @@
#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15
#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16
#define PCI_DEVICE_ID_INTEL_BYT_EMMC2 0x0f50
+#define PCI_DEVICE_ID_INTEL_BSW_EMMC 0x2294
+#define PCI_DEVICE_ID_INTEL_BSW_SDIO 0x2295
+#define PCI_DEVICE_ID_INTEL_BSW_SD 0x2296
#define PCI_DEVICE_ID_INTEL_MRFL_MMC 0x1190
#define PCI_DEVICE_ID_INTEL_CLV_SDIO0 0x08f9
#define PCI_DEVICE_ID_INTEL_CLV_SDIO1 0x08fa
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a06586b62db5c63752e2e68daffec4baa275d594 upstream.
Braswell eMMC host controller specifies an incorrect
timeout clock frequncy in the capabilities registers.
The correct value is 1 MHz.
Signed-off-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index a130a11d89de..730527af71d7 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -270,6 +270,8 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
MMC_CAP_HW_RESET;
slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
slot->hw_reset = sdhci_pci_int_hw_reset;
+ if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BSW_EMMC)
+ slot->host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */
return 0;
}
--
2.2.2
From: Adrian Hunter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1f7f26528fb159e71f081df1d1050c218ff1d74d upstream.
Add PCI IDs for SPT eMMC, SDIO and SD card.
Signed-off-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 25 +++++++++++++++++++++++++
drivers/mmc/host/sdhci-pci.h | 3 +++
2 files changed, 28 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 730527af71d7..a49f41b50b16 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1004,6 +1004,31 @@ static const struct pci_device_id pci_ids[] = {
.subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
},
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_SPT_EMMC,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_SPT_SDIO,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_SPT_SD,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
+ },
+
{
.vendor = PCI_VENDOR_ID_O2,
.device = PCI_DEVICE_ID_O2_8120,
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
index 9c1909b2a3ad..3fd813cca3cd 100644
--- a/drivers/mmc/host/sdhci-pci.h
+++ b/drivers/mmc/host/sdhci-pci.h
@@ -21,6 +21,9 @@
#define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5
#define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6
#define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7
+#define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b
+#define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c
+#define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d
/*
* PCI registers
--
2.2.2
From: Andy Shevchenko <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 67bf9cda4b498b8cea4a40be67a470afe57d2e88 upstream.
The FIFO size is 40 accordingly to the specifications, but this means 0x40,
i.e. 64 bytes. This patch fixes the typo and enables FIFO size autodetection
for Intel MID devices.
Fixes: 7063c0d942a1 (spi/dw_spi: add DMA support)
Signed-off-by: Andy Shevchenko <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/spi/spi-dw-mid.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index 0791c92e8c50..1389fefe8814 100644
--- a/drivers/spi/spi-dw-mid.c
+++ b/drivers/spi/spi-dw-mid.c
@@ -222,7 +222,6 @@ int dw_spi_mid_init(struct dw_spi *dws)
iounmap(clk_reg);
dws->num_cs = 16;
- dws->fifo_len = 40; /* FIFO has 40 words buffer */
#ifdef CONFIG_SPI_DW_MID_DMA
dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL);
--
2.2.2
From: Zidan Wang <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 22ee76daddb87f88d2336d1b4737ef27c4f307ac upstream.
wm8960 codec can't support sample rate 11250, it must be 11025.
Signed-off-by: Zidan Wang <[email protected]>
Acked-by: Charles Keepax <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/soc/codecs/wm8960.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f156010e52bc..942ef8427347 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -555,7 +555,7 @@ static struct {
{ 22050, 2 },
{ 24000, 2 },
{ 16000, 3 },
- { 11250, 4 },
+ { 11025, 4 },
{ 12000, 4 },
{ 8000, 5 },
};
--
2.2.2
From: Peter Ujfalusi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 20602e34cd33dd452bc1836fa7c9b59978f75db0 upstream.
We should select FSR also to be driven by McBSP, not only FSX.
Signed-off-by: Peter Ujfalusi <[email protected]>
Acked-by: Jarkko Nikula <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/soc/omap/omap-mcbsp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6c19bba23570..6a339fb55479 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -436,7 +436,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
case SND_SOC_DAIFMT_CBM_CFS:
/* McBSP slave. FS clock as output */
regs->srgr2 |= FSGM;
- regs->pcr0 |= FSXM;
+ regs->pcr0 |= FSXM | FSRM;
break;
case SND_SOC_DAIFMT_CBM_CFM:
/* McBSP slave */
--
2.2.2
From: "Ahmed S. Darwish" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ded5006667318c06df875609535176bd33f243a1 upstream.
Upon receiving a hardware event with the BUS_RESET flag set,
the driver kills all of its anchored URBs and resets all of
its transmit URB contexts.
Unfortunately it does so under the context of URB completion
handler `kvaser_usb_read_bulk_callback()', which is often
called in an atomic context.
While the device is flooded with many received error packets,
usb_kill_urb() typically sleeps/reschedules till the transfer
request of each killed URB in question completes, leading to
the sleep in atomic bug. [3]
In v2 submission of the original driver patch [1], it was
stated that the URBs kill and tx contexts reset was needed
since we don't receive any tx acknowledgments later and thus
such resources will be locked down forever. Fortunately this
is no longer needed since an earlier bugfix in this patch
series is now applied: all tx URB contexts are reset upon CAN
channel close. [2]
Moreover, a BUS_RESET is now treated _exactly_ like a BUS_OFF
event, which is the recommended handling method advised by
the device manufacturer.
[1] http://article.gmane.org/gmane.linux.network/239442
http://www.webcitation.org/6Vr2yagAQ
[2] can: kvaser_usb: Reset all URB tx contexts upon channel close
889b77f7fd2bcc922493d73a4c51d8a851505815
[3] Stacktrace:
<IRQ> [<ffffffff8158de87>] dump_stack+0x45/0x57
[<ffffffff8158b60c>] __schedule_bug+0x41/0x4f
[<ffffffff815904b1>] __schedule+0x5f1/0x700
[<ffffffff8159360a>] ? _raw_spin_unlock_irqrestore+0xa/0x10
[<ffffffff81590684>] schedule+0x24/0x70
[<ffffffff8147d0a5>] usb_kill_urb+0x65/0xa0
[<ffffffff81077970>] ? prepare_to_wait_event+0x110/0x110
[<ffffffff8147d7d8>] usb_kill_anchored_urbs+0x48/0x80
[<ffffffffa01f4028>] kvaser_usb_unlink_tx_urbs+0x18/0x50 [kvaser_usb]
[<ffffffffa01f45d0>] kvaser_usb_rx_error+0xc0/0x400 [kvaser_usb]
[<ffffffff8108b14a>] ? vprintk_default+0x1a/0x20
[<ffffffffa01f5241>] kvaser_usb_read_bulk_callback+0x4c1/0x5f0 [kvaser_usb]
[<ffffffff8147a73e>] __usb_hcd_giveback_urb+0x5e/0xc0
[<ffffffff8147a8a1>] usb_hcd_giveback_urb+0x41/0x110
[<ffffffffa0008748>] finish_urb+0x98/0x180 [ohci_hcd]
[<ffffffff810cd1a7>] ? acct_account_cputime+0x17/0x20
[<ffffffff81069f65>] ? local_clock+0x15/0x30
[<ffffffffa000a36b>] ohci_work+0x1fb/0x5a0 [ohci_hcd]
[<ffffffff814fbb31>] ? process_backlog+0xb1/0x130
[<ffffffffa000cd5b>] ohci_irq+0xeb/0x270 [ohci_hcd]
[<ffffffff81479fc1>] usb_hcd_irq+0x21/0x30
[<ffffffff8108bfd3>] handle_irq_event_percpu+0x43/0x120
[<ffffffff8108c0ed>] handle_irq_event+0x3d/0x60
[<ffffffff8108ec84>] handle_fasteoi_irq+0x74/0x110
[<ffffffff81004dfd>] handle_irq+0x1d/0x30
[<ffffffff81004727>] do_IRQ+0x57/0x100
[<ffffffff8159482a>] common_interrupt+0x6a/0x6a
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/can/usb/kvaser_usb.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 63fb90b006ba..ccdc4cdc496f 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -654,11 +654,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
priv = dev->nets[channel];
stats = &priv->netdev->stats;
- if (status & M16C_STATE_BUS_RESET) {
- kvaser_usb_unlink_tx_urbs(priv);
- return;
- }
-
skb = alloc_can_err_skb(priv->netdev, &cf);
if (!skb) {
stats->rx_dropped++;
@@ -669,7 +664,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status);
- if (status & M16C_STATE_BUS_OFF) {
+ if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
cf->can_id |= CAN_ERR_BUSOFF;
priv->can.can_stats.bus_off++;
--
2.2.2
From: "Ahmed S. Darwish" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3803fa6977f1de15fda4e8646c8fec97c8045cae upstream.
Send expected argument to the URB completion hander: a CAN
netdevice instead of the network interface private context
`kvaser_usb_net_priv'.
This was discovered by having some garbage in the kernel
log in place of the netdevice names: can0 and can1.
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/can/usb/kvaser_usb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index ccdc4cdc496f..b91f58efec93 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -579,7 +579,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
usb_sndbulkpipe(dev->udev,
dev->bulk_out->bEndpointAddress),
buf, msg->len,
- kvaser_usb_simple_msg_callback, priv);
+ kvaser_usb_simple_msg_callback, netdev);
usb_anchor_urb(urb, &priv->tx_submitted);
err = usb_submit_urb(urb, GFP_ATOMIC);
--
2.2.2
From: "Ahmed S. Darwish" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 14c10c2a1dd8eb8e00b750b521753260befa2789 upstream.
On some x86 laptops, plugging a Kvaser device again after an
unplug makes the firmware always ignore the very first command.
For such a case, provide some room for retries instead of
completely exiting the driver init code.
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/can/usb/kvaser_usb.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index b91f58efec93..5ea0de87514b 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -1578,7 +1578,7 @@ static int kvaser_usb_probe(struct usb_interface *intf,
{
struct kvaser_usb *dev;
int err = -ENOMEM;
- int i;
+ int i, retry = 3;
dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -1596,7 +1596,15 @@ static int kvaser_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dev);
- err = kvaser_usb_get_software_info(dev);
+ /* On some x86 laptops, plugging a Kvaser device again after
+ * an unplug makes the firmware always ignore the very first
+ * command. For such a case, provide some room for retries
+ * instead of completely exiting the driver.
+ */
+ do {
+ err = kvaser_usb_get_software_info(dev);
+ } while (--retry && err == -ETIMEDOUT);
+
if (err) {
dev_err(&intf->dev,
"Cannot get software infos, error %d\n", err);
--
2.2.2
From: "Ahmed S. Darwish" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e638642b08c170d2021b706f0b1c4f4ae93d8cbd upstream.
While being in an ERROR_WARNING state, and receiving further
bus error events with error counters still in the ERROR_WARNING
range of 97-127 inclusive, the state handling code erroneously
reverts back to ERROR_ACTIVE.
Per the CAN standard, only revert to ERROR_ACTIVE when the
error counters are less than 96.
Moreover, in certain Kvaser models, the BUS_ERROR flag is
always set along with undefined bits in the M16C status
register. Thus use bitwise operators instead of full equality
for checking that register against bus errors.
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/can/usb/kvaser_usb.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 5ea0de87514b..a3fb8b51038a 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -690,9 +690,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
}
new_state = CAN_STATE_ERROR_PASSIVE;
- }
-
- if (status == M16C_STATE_BUS_ERROR) {
+ } else if (status & M16C_STATE_BUS_ERROR) {
if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
((txerr >= 96) || (rxerr >= 96))) {
cf->can_id |= CAN_ERR_CRTL;
@@ -702,7 +700,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
priv->can.can_stats.error_warning++;
new_state = CAN_STATE_ERROR_WARNING;
- } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) {
+ } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) &&
+ ((txerr < 96) && (rxerr < 96))) {
cf->can_id |= CAN_ERR_PROT;
cf->data[2] = CAN_ERR_PROT_ACTIVE;
--
2.2.2
From: Laurent Dufour <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e6eb2eba494d6f99e69ca3c3748cd37a2544ab38 upstream.
The commit 3b8a3c010969 ("powerpc/pseries: Fix endiannes issue in RTAS
call from xmon") was fixing an endianness issue in the call made from
xmon to RTAS.
However, as Michael Ellerman noticed, this fix was not complete, the
token value was not byte swapped. This lead to call an unexpected and
most of the time unexisting RTAS function, which is silently ignored by
RTAS.
This fix addresses this hole.
Reported-by: Michael Ellerman <[email protected]>
Signed-off-by: Laurent Dufour <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/xmon/xmon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 489820356f2d..eb7ae28009f5 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -288,6 +288,7 @@ static inline void disable_surveillance(void)
args.token = rtas_token("set-indicator");
if (args.token == RTAS_UNKNOWN_SERVICE)
return;
+ args.token = cpu_to_be32(args.token);
args.nargs = cpu_to_be32(3);
args.nret = cpu_to_be32(1);
args.rets = &args.args[3];
--
2.2.2
From: Clemens Ladisch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0767e95bb96d7fdddcd590fb809e6975d93aebc5 upstream.
When the last subscriber to a "Through" port has been removed, the
subscribed destination ports might still be active, so it would be
wrong to send "all sounds off" and "reset controller" events to them.
The proper place for such a shutdown would be the closing of the actual
MIDI port (and close_substream() in rawmidi.c already can do this).
This also fixes a deadlock when dummy_unuse() tries to send events to
its own port that is already locked because it is being freed.
Reported-by: Peter Billam <peter@http://www.pjb.com.au>
Signed-off-by: Clemens Ladisch <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/core/seq/seq_dummy.c | 31 -------------------------------
1 file changed, 31 deletions(-)
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index dbc550716790..f60d81497f28 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -82,36 +82,6 @@ struct snd_seq_dummy_port {
static int my_client = -1;
/*
- * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events
- * to subscribers.
- * Note: this callback is called only after all subscribers are removed.
- */
-static int
-dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_seq_dummy_port *p;
- int i;
- struct snd_seq_event ev;
-
- p = private_data;
- memset(&ev, 0, sizeof(ev));
- if (p->duplex)
- ev.source.port = p->connect;
- else
- ev.source.port = p->port;
- ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
- for (i = 0; i < 16; i++) {
- ev.data.control.channel = i;
- ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF;
- snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
- ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS;
- snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
- }
- return 0;
-}
-
-/*
* event input callback - just redirect events to subscribers
*/
static int
@@ -175,7 +145,6 @@ create_port(int idx, int type)
| SNDRV_SEQ_PORT_TYPE_PORT;
memset(&pcb, 0, sizeof(pcb));
pcb.owner = THIS_MODULE;
- pcb.unuse = dummy_unuse;
pcb.event_input = dummy_input;
pcb.private_free = dummy_free;
pcb.private_data = rec;
--
2.2.2
From: Ilya Dryomov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e69b8d414f948c242ad9f3eb2b7e24fba783dbbd upstream.
This effectively reverts the last hunk of 392a9dad7e77 ("rbd: detect
when clone image is flattened").
The problem with parent_overlap != 0 condition is that it's possible
and completely valid to have an image with parent_overlap == 0 whose
parent state needs to be cleaned up on unmap. The next commit, which
drops the "clone image now standalone" logic, opens up another window
of opportunity to hit this, but even without it
# cat parent-ref.sh
#!/bin/bash
rbd create --image-format 2 --size 1 foo
rbd snap create foo@snap
rbd snap protect foo@snap
rbd clone foo@snap bar
rbd resize --allow-shrink --size 0 bar
rbd resize --size 1 bar
DEV=$(rbd map bar)
rbd unmap $DEV
leaves rbd_device/rbd_spec/etc and rbd_client along with ceph_client
hanging around.
My thinking behind calling rbd_dev_parent_put() unconditionally is that
there shouldn't be any requests in flight at that point in time as we
are deep into unmap sequence. Hence, even if rbd_dev_unparent() caused
by flatten is delayed by in-flight requests, it will have finished by
the time we reach rbd_dev_unprobe() caused by unmap, thus turning
unconditional rbd_dev_parent_put() into a no-op.
Fixes: http://tracker.ceph.com/issues/10352
Signed-off-by: Ilya Dryomov <[email protected]>
Reviewed-by: Josh Durgin <[email protected]>
Reviewed-by: Alex Elder <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/block/rbd.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index a86841886acc..0b78e9eb031f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -4782,10 +4782,7 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
{
struct rbd_image_header *header;
- /* Drop parent reference unless it's already been done (or none) */
-
- if (rbd_dev->parent_overlap)
- rbd_dev_parent_put(rbd_dev);
+ rbd_dev_parent_put(rbd_dev);
/* Free dynamic fields from the header, then zero it out */
--
2.2.2
From: Paul Osmialowski <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 34e81ad5f0b60007c95995eb7803da7e00c6c611 upstream.
This patch solves deadlock between clock prepare mutex and regmap mutex reported
by Tomasz Figa in [1] by implementing solution from [2]: "always leave the clock
of the i2c controller in a prepared state".
[1] https://lkml.org/lkml/2014/7/2/171
[2] https://lkml.org/lkml/2014/7/2/207
On each i2c transfer handled by s3c24xx_i2c_xfer(), clk_prepare_enable() was
called, which calls clk_prepare() then clk_enable(). clk_prepare() takes
prepare_lock mutex before proceeding. Note that i2c transfer functions are
invoked from many places in kernel, typically with some other additional lock
held.
It may happen that function on CPU1 (e.g. regmap_update_bits()) has taken a
mutex (i.e. regmap lock mutex) then it attempts i2c communication in order to
proceed (so it needs to obtain clock related prepare_lock mutex during transfer
preparation stage due to clk_prepare() call). At the same time other task on
CPU0 wants to operate on clock (e.g. to (un)prepare clock for some other reason)
so it has taken prepare_lock mutex.
CPU0: CPU1:
clk_disable_unused() regulator_disable()
clk_prepare_lock() map->lock(map->lock_arg)
regmap_read() s3c24xx_i2c_xfer()
map->lock(map->lock_arg) clk_prepare_lock()
Implemented solution from [2] leaves i2c clock prepared. Preparation is done in
s3c24xx_i2c_probe() function. Without this patch, it is immediately unprepared
by clk_disable_unprepare() call. I've replaced this call with clk_disable() and
I've added clk_unprepare() call in s3c24xx_i2c_remove().
The s3c24xx_i2c_xfer() function now uses clk_enable() instead of
clk_prepare_enable() (and clk_disable() instead of clk_unprepare_disable()).
Signed-off-by: Paul Osmialowski <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/i2c/busses/i2c-s3c2410.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index f7d572363f6c..ce09bf932831 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -711,14 +711,16 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
int ret;
pm_runtime_get_sync(&adap->dev);
- clk_prepare_enable(i2c->clk);
+ ret = clk_enable(i2c->clk);
+ if (ret)
+ return ret;
for (retry = 0; retry < adap->retries; retry++) {
ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
if (ret != -EAGAIN) {
- clk_disable_unprepare(i2c->clk);
+ clk_disable(i2c->clk);
pm_runtime_put(&adap->dev);
return ret;
}
@@ -728,7 +730,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
udelay(100);
}
- clk_disable_unprepare(i2c->clk);
+ clk_disable(i2c->clk);
pm_runtime_put(&adap->dev);
return -EREMOTEIO;
}
@@ -1108,7 +1110,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
clk_prepare_enable(i2c->clk);
ret = s3c24xx_i2c_init(i2c);
- clk_disable_unprepare(i2c->clk);
+ clk_disable(i2c->clk);
if (ret != 0) {
dev_err(&pdev->dev, "I2C controller init failed\n");
return ret;
@@ -1120,6 +1122,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
+ clk_unprepare(i2c->clk);
return ret;
}
@@ -1128,12 +1131,14 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
+ clk_unprepare(i2c->clk);
return ret;
}
ret = s3c24xx_i2c_register_cpufreq(i2c);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
+ clk_unprepare(i2c->clk);
return ret;
}
@@ -1150,6 +1155,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
s3c24xx_i2c_deregister_cpufreq(i2c);
+ clk_unprepare(i2c->clk);
return ret;
}
@@ -1171,6 +1177,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
{
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+ clk_unprepare(i2c->clk);
+
pm_runtime_disable(&i2c->adap.dev);
pm_runtime_disable(&pdev->dev);
@@ -1199,10 +1207,13 @@ static int s3c24xx_i2c_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+ int ret;
- clk_prepare_enable(i2c->clk);
+ ret = clk_enable(i2c->clk);
+ if (ret)
+ return ret;
s3c24xx_i2c_init(i2c);
- clk_disable_unprepare(i2c->clk);
+ clk_disable(i2c->clk);
i2c->suspended = 0;
return 0;
--
2.2.2
From: Peter Hutterer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8543cf1c247909ce85850ca6e2714adba351d6aa upstream.
LEN0037 found in the Lenovo ThinkPad X1 Carbon 2nd (2014 model)
Reported-and-tested-by: Bjoern Olausson <[email protected]>
Signed-off-by: Peter Hutterer <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/mouse/synaptics.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index a3769cf84381..b00e282ef166 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -132,8 +132,9 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
1232, 5710, 1156, 4696
},
{
- (const char * const []){"LEN0034", "LEN0036", "LEN0039",
- "LEN2002", "LEN2004", NULL},
+ (const char * const []){"LEN0034", "LEN0036", "LEN0037",
+ "LEN0039", "LEN2002", "LEN2004",
+ NULL},
1024, 5112, 2024, 4832
},
{
@@ -162,7 +163,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
"LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */
"LEN0035", /* X240 */
"LEN0036", /* T440 */
- "LEN0037",
+ "LEN0037", /* X1 Carbon 2nd */
"LEN0038",
"LEN0039", /* T440s */
"LEN0041",
--
2.2.2
From: Jochen Hein <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1d90d6d5522befa8efa1a7ea406be65cf865ded4 upstream.
Without this the aux port does not get detected, and consequently the touchpad
will not work.
With this patch the touchpad is detected:
$ dmesg | grep -E "(SYN|i8042|serio)"
pnp 00:03: Plug and Play ACPI device, IDs SYN1d22 PNP0f13 (active)
i8042: PNP: PS/2 Controller [PNP0303:PS2K,PNP0f13:PS2M] at 0x60,0x64 irq 1,12
serio: i8042 KBD port at 0x60,0x64 irq 1
serio: i8042 AUX port at 0x60,0x64 irq 12
input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input4
psmouse serio1: synaptics: Touchpad model: 1, fw: 8.1, id: 0x1e2b1, caps: 0xd00123/0x840300/0x126800, board id: 2863, fw id: 1473085
input: SynPS/2 Synaptics TouchPad as /devices/platform/i8042/serio1/input/input6
dmidecode excerpt for this laptop is:
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: Medion
Product Name: Akoya E7225
Version: 1.0
Signed-off-by: Jochen Hein <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/serio/i8042-x86ia64io.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index c1d156aad8fc..0254ed97c16e 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -152,6 +152,14 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
},
},
{
+ /* Medion Akoya E7225 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+ },
+ },
+ {
/* Blue FB5601 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "blue"),
--
2.2.2
From: Peng Tao <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ee8a1a8b160a87dc3a9c81a86796aa4db85ea815 upstream.
We only support swap file calling nfs_direct_IO. However, application
might be able to get to nfs_direct_IO if it toggles O_DIRECT flag
during IO and it can deadlock because we grab inode->i_mutex in
nfs_file_direct_write(). So return 0 for such case. Then the generic
layer will fall back to buffer IO.
Signed-off-by: Peng Tao <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/nfs/direct.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index d751a2383c24..db6245c1cd33 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -123,6 +123,12 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
*/
ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs)
{
+ struct inode *inode = iocb->ki_filp->f_mapping->host;
+
+ /* we only support swap file calling nfs_direct_IO */
+ if (!IS_SWAPFILE(inode))
+ return 0;
+
#ifndef CONFIG_NFS_SWAP
dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n",
iocb->ki_filp->f_path.dentry->d_name.name,
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3175e1dcec40fab1a444c010087f2068b6b04732 upstream.
If we start state recovery on a client that failed to initialise correctly,
then we are very likely to Oops.
Reported-by: "Mkrtchyan, Tigran" <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/nfs/nfs4client.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index ce036f071302..28e1f211600d 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -629,7 +629,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
prev = pos;
status = nfs_wait_client_init_complete(pos);
- if (status == 0) {
+ if (pos->cl_cons_state == NFS_CS_SESSION_INITING) {
nfs4_schedule_lease_recovery(pos);
status = nfs4_wait_clnt_recover(pos);
}
--
2.2.2
From: Mathy Vanhoef <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3a5c5e81d8128a9e43abc52b75dd21d3da7a0cfc upstream.
Fix a regression introduced by commit a5e70697d0c4 ("mac80211: add radiotap flag
and handling for 5/10 MHz") where the IEEE80211_CHAN_CCK channel type flag was
incorrectly replaced by the IEEE80211_CHAN_OFDM flag. This commit fixes that by
using the CCK flag again.
Fixes: a5e70697d0c4 ("mac80211: add radiotap flag and handling for 5/10 MHz")
Signed-off-by: Mathy Vanhoef <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/mac80211/rx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ef3bdba9309e..03146a15f4f9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -261,7 +261,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
else if (rate)
- channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
+ channel_flags |= IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ;
else
channel_flags |= IEEE80211_CHAN_2GHZ;
put_unaligned_le16(channel_flags, pos);
--
2.2.2
From: Johannes Berg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0fa7b39131576dd1baa6ca17fca53c65d7f62249 upstream.
In case userspace attempts to obtain key information for or delete a
unicast key, this is currently erroneously rejected unless the driver
sets the WIPHY_FLAG_IBSS_RSN flag. Apparently enough drivers do so it
was never noticed.
Fix that, and while at it fix a potential memory leak: the error path
in the get_key() function was placed after allocating a message but
didn't free it - move it to a better place. Luckily admin permissions
are needed to call this operation.
Fixes: e31b82136d1ad ("cfg80211/mac80211: allow per-station GTKs")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/wireless/nl80211.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3ef31a96de9..388123667f1e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2659,6 +2659,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->get_key)
return -EOPNOTSUPP;
+ if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+ return -ENOENT;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -2678,10 +2681,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
goto nla_put_failure;
- if (pairwise && mac_addr &&
- !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
- return -ENOENT;
-
err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
get_key_callback);
@@ -2852,7 +2851,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
wdev_lock(dev->ieee80211_ptr);
err = nl80211_key_allowed(dev->ieee80211_ptr);
- if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
+ if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
!(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
err = -ENOENT;
--
2.2.2
From: Joe Thornber <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2a7eaea02b99b6e267b1e89c79acc6e9a51cee3b upstream.
You can't modify the metadata in these modes. It's better to fail these
messages immediately than let the block-manager deny write locks on
metadata blocks. Otherwise these failed metadata changes will trigger
'needs_check' to get set in the metadata superblock -- requiring repair
using the thin_check utility.
Signed-off-by: Joe Thornber <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/dm-thin.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 0396d7fc1d8b..d2b3563129c2 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2507,6 +2507,12 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
struct pool_c *pt = ti->private;
struct pool *pool = pt->pool;
+ if (get_pool_mode(pool) >= PM_READ_ONLY) {
+ DMERR("%s: unable to service pool target messages in READ_ONLY or FAIL mode",
+ dm_device_name(pool->pool_md));
+ return -EINVAL;
+ }
+
if (!strcasecmp(argv[0], "create_thin"))
r = process_create_thin_mesg(argc, argv, pool);
--
2.2.2
From: Joe Thornber <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 766a78882ddf79b162243649d7dfdbac1fb6fb88 upstream.
Commit 9b1cc9f251 ("dm cache: share cache-metadata object across
inactive and active DM tables") mistakenly ignored the use of ERR_PTR
returns. Restore missing IS_ERR checks and ERR_PTR returns where
appropriate.
Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Joe Thornber <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/dm-cache-metadata.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index 0bfd9c0611a0..f86bd4511351 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -664,7 +664,7 @@ static struct dm_cache_metadata *metadata_open(struct block_device *bdev,
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
DMERR("could not allocate metadata struct");
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
atomic_set(&cmd->ref_count, 1);
@@ -726,7 +726,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
return cmd;
cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size);
- if (cmd) {
+ if (!IS_ERR(cmd)) {
mutex_lock(&table_lock);
cmd2 = lookup(bdev);
if (cmd2) {
@@ -761,9 +761,10 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev,
{
struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size,
may_format_device, policy_hint_size);
- if (cmd && !same_params(cmd, data_block_size)) {
+
+ if (!IS_ERR(cmd) && !same_params(cmd, data_block_size)) {
dm_cache_metadata_close(cmd);
- return NULL;
+ return ERR_PTR(-EINVAL);
}
return cmd;
--
2.2.2
From: Mika Westerberg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c957e8f084e0d21febcd6b8a0ea9631eccc92f36 upstream.
Once the current message is finished, the driver notifies SPI core about
this by calling spi_finalize_current_message(). This function queues next
message to be transferred. If there are more messages in the queue, it is
possible that the driver is asked to transfer the next message at this
point.
When spi_finalize_current_message() returns the driver clears the
drv_data->cur_chip pointer to NULL. The problem is that if the driver
already started the next message clearing drv_data->cur_chip will cause
NULL pointer dereference which crashes the kernel like:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
IP: [<ffffffffa0022bc8>] cs_deassert+0x18/0x70 [spi_pxa2xx_platform]
PGD 78bb8067 PUD 37712067 PMD 0
Oops: 0000 [#1] SMP
Modules linked in:
CPU: 1 PID: 11 Comm: ksoftirqd/1 Tainted: G O 3.18.0-rc4-mjo #5
Hardware name: Intel Corp. VALLEYVIEW B3 PLATFORM/NOTEBOOK, BIOS MNW2CRB1.X64.0071.R30.1408131301 08/13/2014
task: ffff880077f9f290 ti: ffff88007a820000 task.ti: ffff88007a820000
RIP: 0010:[<ffffffffa0022bc8>] [<ffffffffa0022bc8>] cs_deassert+0x18/0x70 [spi_pxa2xx_platform]
RSP: 0018:ffff88007a823d08 EFLAGS: 00010202
RAX: 0000000000000008 RBX: ffff8800379a4430 RCX: 0000000000000026
RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff8800379a4430
RBP: ffff88007a823d18 R08: 00000000ffffffff R09: 000000007a9bc65a
R10: 000000000000028f R11: 0000000000000005 R12: ffff880070123e98
R13: ffff880070123de8 R14: 0000000000000100 R15: ffffc90004888000
FS: 0000000000000000(0000) GS:ffff880079a80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000048 CR3: 000000007029b000 CR4: 00000000001007e0
Stack:
ffff88007a823d58 ffff8800379a4430 ffff88007a823d48 ffffffffa0022c89
0000000000000000 ffff8800379a4430 0000000000000000 0000000000000006
ffff88007a823da8 ffffffffa0023be0 ffff88007a823dd8 ffffffff81076204
Call Trace:
[<ffffffffa0022c89>] giveback+0x69/0xa0 [spi_pxa2xx_platform]
[<ffffffffa0023be0>] pump_transfers+0x710/0x740 [spi_pxa2xx_platform]
[<ffffffff81076204>] ? pick_next_task_fair+0x744/0x830
[<ffffffff81049679>] tasklet_action+0xa9/0xe0
[<ffffffff81049a0e>] __do_softirq+0xee/0x280
[<ffffffff81049bc0>] run_ksoftirqd+0x20/0x40
[<ffffffff810646df>] smpboot_thread_fn+0xff/0x1b0
[<ffffffff810645e0>] ? SyS_setgroups+0x150/0x150
[<ffffffff81060f9d>] kthread+0xcd/0xf0
[<ffffffff81060ed0>] ? kthread_create_on_node+0x180/0x180
[<ffffffff8187a82c>] ret_from_fork+0x7c/0xb0
Fix this by clearing drv_data->cur_chip before we call spi_finalize_current_message().
Reported-by: Martin Oldfield <[email protected]>
Signed-off-by: Mika Westerberg <[email protected]>
Acked-by: Robert Jarzmik <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/spi/spi-pxa2xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 5b0e57210066..d01ae4d353d4 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -400,8 +400,8 @@ static void giveback(struct driver_data *drv_data)
cs_deassert(drv_data);
}
- spi_finalize_current_message(drv_data->master);
drv_data->cur_chip = NULL;
+ spi_finalize_current_message(drv_data->master);
}
static void reset_sccr1(struct driver_data *drv_data)
--
2.2.2
From: Ashay Jaiswal <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 83b0302d347a49f951e904184afe57ac3723476e upstream.
The regulator framework maintains a list of consumer regulators
for a regulator device and protects it from concurrent access using
the regulator device's mutex lock.
In the case of regulator_put() the consumer is removed and regulator
device's parameters are updated without holding the regulator device's
mutex. This would lead to a race condition between the regulator_put()
and any function which traverses the consumer list or modifies regulator
device's parameters.
Fix this race condition by holding the regulator device's mutex in case
of regulator_put.
Signed-off-by: Ashay Jaiswal <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/regulator/core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index ea83084cb7d9..a2ce8e86ced7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1474,7 +1474,7 @@ struct regulator *devm_regulator_get_optional(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
-/* Locks held by regulator_put() */
+/* regulator_list_mutex lock held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
{
struct regulator_dev *rdev;
@@ -1489,12 +1489,14 @@ static void _regulator_put(struct regulator *regulator)
/* remove any sysfs entries */
if (regulator->dev)
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
+ mutex_lock(&rdev->mutex);
kfree(regulator->supply_name);
list_del(®ulator->list);
kfree(regulator);
rdev->open_count--;
rdev->exclusive = 0;
+ mutex_unlock(&rdev->mutex);
module_put(rdev->owner);
}
--
2.2.2
From: Mugunthan V N <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 02a54164c52ed6eca3089a0d402170fbf34d6cf5 upstream.
In Dual EMAC, the default VLANs are used to segregate Rx packets between
the ports, so adding the same default VLAN to the switch will affect the
normal packet transfers. So returning error on addition of dual EMAC
default VLANs.
Even if EMAC 0 default port VLAN is added to EMAC 1, it will lead to
break dual EMAC port separations.
Fixes: d9ba8f9e6298 (driver: net: ethernet: cpsw: dual emac interface implementation)
Reported-by: Felipe Balbi <[email protected]>
Signed-off-by: Mugunthan V N <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/ti/cpsw.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 07cd14d586dc..ba25ca049310 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1514,6 +1514,19 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
if (vid == priv->data.default_vlan)
return 0;
+ if (priv->data.dual_emac) {
+ /* In dual EMAC, reserved VLAN id should not be used for
+ * creating VLAN interfaces as this can break the dual
+ * EMAC port separation
+ */
+ int i;
+
+ for (i = 0; i < priv->data.slaves; i++) {
+ if (vid == priv->slaves[i].port_vlan)
+ return -EINVAL;
+ }
+ }
+
dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
return cpsw_add_vlan_ale_entry(priv, vid);
}
@@ -1527,6 +1540,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
if (vid == priv->data.default_vlan)
return 0;
+ if (priv->data.dual_emac) {
+ int i;
+
+ for (i = 0; i < priv->data.slaves; i++) {
+ if (vid == priv->slaves[i].port_vlan)
+ return -EINVAL;
+ }
+ }
+
dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid);
ret = cpsw_ale_del_vlan(priv->ale, vid, 0);
if (ret != 0)
--
2.2.2
From: Bob Paauwe <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit af1a7301c7cf8912dca03065d448c4437c5c239f upstream.
When creating a fence for a tiled object, only fence the area that
makes up the actual tiles. The object may be larger than the tiled
area and if we allow those extra addresses to be fenced, they'll
get converted to addresses beyond where the object is mapped. This
opens up the possiblity of writes beyond the end of object.
To prevent this, we adjust the size of the fence to only encompass
the area that makes up the actual tiles. The extra space is considered
un-tiled and now behaves as if it was a linear object.
Testcase: igt/gem_tiled_fence_overflow
Reported-by: Dan Hettena <[email protected]>
Signed-off-by: Bob Paauwe <[email protected]>
Reviewed-by: Daniel Vetter <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/i915/i915_gem.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7e4e6896fa81..f97d221194a2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2788,6 +2788,13 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
u32 size = i915_gem_obj_ggtt_size(obj);
uint64_t val;
+ /* Adjust fence size to match tiled area */
+ if (obj->tiling_mode != I915_TILING_NONE) {
+ uint32_t row_size = obj->stride *
+ (obj->tiling_mode == I915_TILING_Y ? 32 : 8);
+ size = (size / row_size) * row_size;
+ }
+
val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
0xfffff000) << 32;
val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
--
2.2.2
From: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6b076991dca9817e75c37e2f0db6d52611ea42fa upstream.
When setting up the CMA region, we must ensure that the old section
mappings are flushed from the TLB before replacing them with page
tables, otherwise we can suffer from mismatched aliases if the CPU
speculatively prefetches from these mappings at an inopportune time.
A mismatched alias can occur when the TLB contains a section mapping,
but a subsequent prefetch causes it to load a page table mapping,
resulting in the possibility of the TLB containing two matching
mappings for the same virtual address region.
Acked-by: Will Deacon <[email protected]>
Signed-off-by: Russell King <[email protected]>
Cc: Hou Pengyang <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/arm/mm/dma-mapping.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index a2d0f91c5bd7..79cff8fdbaf3 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -429,12 +429,21 @@ void __init dma_contiguous_remap(void)
map.type = MT_MEMORY_DMA_READY;
/*
- * Clear previous low-memory mapping
+ * Clear previous low-memory mapping to ensure that the
+ * TLB does not see any conflicting entries, then flush
+ * the TLB of the old entries before creating new mappings.
+ *
+ * This ensures that any speculatively loaded TLB entries
+ * (even though they may be rare) can not cause any problems,
+ * and ensures that this code is architecturally compliant.
*/
for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
+ flush_tlb_kernel_range(__phys_to_virt(start),
+ __phys_to_virt(end));
+
iotable_init(&map, 1);
}
}
--
2.2.2
From: Liu ShuoX <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 57fd835385a043577457a385f28c08be693991bf upstream.
*_read_cnt in ramoops_context need to be cleared during pstore ->open to
support mutli times getting the records. The patch added missed
ftrace_read_cnt clearing and removed duplicate clearing in ramoops_probe.
Signed-off-by: Liu ShuoX <[email protected]>
Cc: "Zhang, Yanmin" <[email protected]>
Cc: Colin Cross <[email protected]>
Cc: Kees Cook <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Cc: HuKeping <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index e7d95f959333..36ffe55b579d 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -92,6 +92,7 @@ struct ramoops_context {
struct persistent_ram_ecc_info ecc_info;
unsigned int max_dump_cnt;
unsigned int dump_write_cnt;
+ /* _read_cnt need clear on ramoops_pstore_open */
unsigned int dump_read_cnt;
unsigned int console_read_cnt;
unsigned int ftrace_read_cnt;
@@ -107,6 +108,7 @@ static int ramoops_pstore_open(struct pstore_info *psi)
cxt->dump_read_cnt = 0;
cxt->console_read_cnt = 0;
+ cxt->ftrace_read_cnt = 0;
return 0;
}
@@ -435,7 +437,6 @@ static int ramoops_probe(struct platform_device *pdev)
if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
- cxt->dump_read_cnt = 0;
cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address;
cxt->memtype = pdata->mem_type;
--
2.2.2
From: Liu ShuoX <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit aa9a4a1edfbd3d223af01db833da2f07850bc655 upstream.
In ramoops_pstore_read, a valid prz pointer with zero size buffer will
break traverse of all persistent ram buffers. The latter buffer might be
lost.
Signed-off-by: Liu ShuoX <[email protected]>
Cc: "Zhang, Yanmin" <[email protected]>
Cc: Colin Cross <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Cc: HuKeping <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 36ffe55b579d..808435a9e2e1 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -126,12 +126,12 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
prz = przs[i];
- if (update) {
- /* Update old/shadowed buffer. */
+ /* Update old/shadowed buffer. */
+ if (update)
persistent_ram_save_old(prz);
- if (!persistent_ram_old_size(prz))
- return NULL;
- }
+
+ if (!persistent_ram_old_size(prz))
+ return NULL;
*typep = type;
*id = i;
--
2.2.2
From: Liu ShuoX <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b0aa931fb84431394d995472d0af2a6c2b61064d upstream.
ramoops_get_next_prz get the prz according the paramters. If it get a
uninitialized prz, access its members by following persistent_ram_old_size(prz)
will cause a NULL pointer crash.
Ex: if ftrace_size is 0, fprz will be NULL.
Fix it by return NULL in advance.
Signed-off-by: Liu ShuoX <[email protected]>
Acked-by: Kees Cook <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Cc: HuKeping <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 808435a9e2e1..fe68d8ac4d3d 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -125,6 +125,8 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
return NULL;
prz = przs[i];
+ if (!prz)
+ return NULL;
/* Update old/shadowed buffer. */
if (update)
--
2.2.2
From: Ilya Dryomov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ae43e9d05eb4bd324155292f889fbd001c4faea8 upstream.
The comment for rbd_dev_parent_get() said
* We must get the reference before checking for the overlap to
* coordinate properly with zeroing the parent overlap in
* rbd_dev_v2_parent_info() when an image gets flattened. We
* drop it again if there is no overlap.
but the "drop it again if there is no overlap" part was missing from
the implementation. This lead to absurd parent_ref values for images
with parent_overlap == 0, as parent_ref was incremented for each
img_request and virtually never decremented.
Fix this by leveraging the fact that refresh path calls
rbd_dev_v2_parent_info() under header_rwsem and use it for read in
rbd_dev_parent_get(), instead of messing around with atomics. Get rid
of barriers in rbd_dev_v2_parent_info() while at it - I don't see what
they'd pair with now and I suspect we are in a pretty miserable
situation as far as proper locking goes regardless.
Signed-off-by: Ilya Dryomov <[email protected]>
Reviewed-by: Josh Durgin <[email protected]>
Reviewed-by: Alex Elder <[email protected]>
[[email protected]: backport to 3.14: context]
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/block/rbd.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 0b78e9eb031f..5544f254175d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1945,32 +1945,26 @@ static void rbd_dev_parent_put(struct rbd_device *rbd_dev)
* If an image has a non-zero parent overlap, get a reference to its
* parent.
*
- * We must get the reference before checking for the overlap to
- * coordinate properly with zeroing the parent overlap in
- * rbd_dev_v2_parent_info() when an image gets flattened. We
- * drop it again if there is no overlap.
- *
* Returns true if the rbd device has a parent with a non-zero
* overlap and a reference for it was successfully taken, or
* false otherwise.
*/
static bool rbd_dev_parent_get(struct rbd_device *rbd_dev)
{
- int counter;
+ int counter = 0;
if (!rbd_dev->parent_spec)
return false;
- counter = atomic_inc_return_safe(&rbd_dev->parent_ref);
- if (counter > 0 && rbd_dev->parent_overlap)
- return true;
-
- /* Image was flattened, but parent is not yet torn down */
+ down_read(&rbd_dev->header_rwsem);
+ if (rbd_dev->parent_overlap)
+ counter = atomic_inc_return_safe(&rbd_dev->parent_ref);
+ up_read(&rbd_dev->header_rwsem);
if (counter < 0)
rbd_warn(rbd_dev, "parent reference overflow\n");
- return false;
+ return counter > 0;
}
/*
@@ -3894,7 +3888,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
*/
if (rbd_dev->parent_overlap) {
rbd_dev->parent_overlap = 0;
- smp_mb();
rbd_dev_parent_put(rbd_dev);
pr_info("%s: clone image has been flattened\n",
rbd_dev->disk->disk_name);
@@ -3938,7 +3931,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
* treat it specially.
*/
rbd_dev->parent_overlap = overlap;
- smp_mb();
if (!overlap) {
/* A null parent_spec indicates it's the initial probe */
--
2.2.2
From: Tejun Heo <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 29187a9eeaf362d8422e62e17a22a6e115277a49 upstream.
A worker_pool's forward progress is guaranteed by the fact that the
last idle worker assumes the manager role to create more workers and
summon the rescuers if creating workers doesn't succeed in timely
manner before proceeding to execute work items.
This manager role is implemented in manage_workers(), which indicates
whether the worker may proceed to work item execution with its return
value. This is necessary because multiple workers may contend for the
manager role, and, if there already is a manager, others should
proceed to work item execution.
Unfortunately, the function also indicates that the worker may proceed
to work item execution if need_to_create_worker() is false at the head
of the function. need_to_create_worker() tests the following
conditions.
pending work items && !nr_running && !nr_idle
The first and third conditions are protected by pool->lock and thus
won't change while holding pool->lock; however, nr_running can change
asynchronously as other workers block and resume and while it's likely
to be zero, as someone woke this worker up in the first place, some
other workers could have become runnable inbetween making it non-zero.
If this happens, manage_worker() could return false even with zero
nr_idle making the worker, the last idle one, proceed to execute work
items. If then all workers of the pool end up blocking on a resource
which can only be released by a work item which is pending on that
pool, the whole pool can deadlock as there's no one to create more
workers or summon the rescuers.
This patch fixes the problem by removing the early exit condition from
maybe_create_worker() and making manage_workers() return false iff
there's already another manager, which ensures that the last worker
doesn't start executing work items.
We can leave the early exit condition alone and just ignore the return
value but the only reason it was put there is because the
manage_workers() used to perform both creations and destructions of
workers and thus the function may be invoked while the pool is trying
to reduce the number of workers. Now that manage_workers() is called
only when more workers are needed, the only case this early exit
condition is triggered is rare race conditions rendering it pointless.
Tested with simulated workload and modified workqueue code which
trigger the pool deadlock reliably without this patch.
tj: Updated to v3.14 where manage_workers() is responsible not only
for creating more workers but also destroying surplus ones.
maybe_create_worker() needs to keep its early exit condition to
avoid creating a new worker when manage_workers() is called to
destroy surplus ones. Other than that, the adaptabion is
straight-forward. Both maybe_{create|destroy}_worker() functions
are converted to return void and manage_workers() returns %false
iff it lost manager arbitration.
Signed-off-by: Tejun Heo <[email protected]>
Reported-by: Eric Sandeen <[email protected]>
Link: http://lkml.kernel.org/g/[email protected]
Cc: Dave Chinner <[email protected]>
Cc: Lai Jiangshan <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/workqueue.c | 42 +++++++++++++-----------------------------
1 file changed, 13 insertions(+), 29 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3fafbbb31927..d10cc05bfbc6 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1954,17 +1954,13 @@ static void pool_mayday_timeout(unsigned long __pool)
* spin_lock_irq(pool->lock) which may be released and regrabbed
* multiple times. Does GFP_KERNEL allocations. Called only from
* manager.
- *
- * Return:
- * %false if no action was taken and pool->lock stayed locked, %true
- * otherwise.
*/
-static bool maybe_create_worker(struct worker_pool *pool)
+static void maybe_create_worker(struct worker_pool *pool)
__releases(&pool->lock)
__acquires(&pool->lock)
{
if (!need_to_create_worker(pool))
- return false;
+ return;
restart:
spin_unlock_irq(&pool->lock);
@@ -1981,7 +1977,7 @@ restart:
start_worker(worker);
if (WARN_ON_ONCE(need_to_create_worker(pool)))
goto restart;
- return true;
+ return;
}
if (!need_to_create_worker(pool))
@@ -1998,7 +1994,7 @@ restart:
spin_lock_irq(&pool->lock);
if (need_to_create_worker(pool))
goto restart;
- return true;
+ return;
}
/**
@@ -2011,15 +2007,9 @@ restart:
* LOCKING:
* spin_lock_irq(pool->lock) which may be released and regrabbed
* multiple times. Called only from manager.
- *
- * Return:
- * %false if no action was taken and pool->lock stayed locked, %true
- * otherwise.
*/
-static bool maybe_destroy_workers(struct worker_pool *pool)
+static void maybe_destroy_workers(struct worker_pool *pool)
{
- bool ret = false;
-
while (too_many_workers(pool)) {
struct worker *worker;
unsigned long expires;
@@ -2033,10 +2023,7 @@ static bool maybe_destroy_workers(struct worker_pool *pool)
}
destroy_worker(worker);
- ret = true;
}
-
- return ret;
}
/**
@@ -2056,16 +2043,14 @@ static bool maybe_destroy_workers(struct worker_pool *pool)
* multiple times. Does GFP_KERNEL allocations.
*
* Return:
- * %false if the pool don't need management and the caller can safely start
- * processing works, %true indicates that the function released pool->lock
- * and reacquired it to perform some management function and that the
- * conditions that the caller verified while holding the lock before
- * calling the function might no longer be true.
+ * %false if the pool doesn't need management and the caller can safely
+ * start processing works, %true if management function was performed and
+ * the conditions that the caller verified before calling the function may
+ * no longer be true.
*/
static bool manage_workers(struct worker *worker)
{
struct worker_pool *pool = worker->pool;
- bool ret = false;
/*
* Managership is governed by two mutexes - manager_arb and
@@ -2089,7 +2074,7 @@ static bool manage_workers(struct worker *worker)
* manager_mutex.
*/
if (!mutex_trylock(&pool->manager_arb))
- return ret;
+ return false;
/*
* With manager arbitration won, manager_mutex would be free in
@@ -2099,7 +2084,6 @@ static bool manage_workers(struct worker *worker)
spin_unlock_irq(&pool->lock);
mutex_lock(&pool->manager_mutex);
spin_lock_irq(&pool->lock);
- ret = true;
}
pool->flags &= ~POOL_MANAGE_WORKERS;
@@ -2108,12 +2092,12 @@ static bool manage_workers(struct worker *worker)
* Destroy and then create so that may_start_working() is true
* on return.
*/
- ret |= maybe_destroy_workers(pool);
- ret |= maybe_create_worker(pool);
+ maybe_destroy_workers(pool);
+ maybe_create_worker(pool);
mutex_unlock(&pool->manager_mutex);
mutex_unlock(&pool->manager_arb);
- return ret;
+ return true;
}
/**
--
2.2.2
From: Martin Walch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 503c823048e81cc85c0e9d8c297cc70203e335e5 upstream.
The struct gstr has a capacity that may differ from the actual string length.
However, a string manipulation in the function search_conf made the assumption
that it is the same, which led to messing up some search results, especially
when the content of the gstr in use had not yet reached at least 63 chars.
Signed-off-by: Martin Walch <[email protected]>
Acked-by: Wang YanQing <[email protected]>
Acked-by: Benjamin Poirier <[email protected]>
Reviewed-by: "Yann E. MORIN" <[email protected]>
Signed-off-by: "Yann E. MORIN" <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
scripts/kconfig/menu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index c1d53200c306..2b3317010ba4 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -583,7 +583,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
for (j = 4; --i >= 0; j += 2) {
menu = submenu[i];
if (head && location && menu == location)
- jump->offset = r->len - 1;
+ jump->offset = strlen(r->s);
str_printf(r, "%*c-> %s", j, ' ',
_(menu_get_prompt(menu)));
if (menu->sym) {
--
2.2.2
From: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0f303db08df0df9bd0966443ad6001e63960af16 upstream.
Fix memory leak in the gpio sysfs interface due to failure to drop
reference to device returned by class_find_device when creating a link.
Fixes: a4177ee7f1a8 ("gpiolib: allow exported GPIO nodes to be named using sysfs links")
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpio/gpiolib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e66d1cdb637d..4840c05862e7 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -864,6 +864,7 @@ static int gpiod_export_link(struct device *dev, const char *name,
if (tdev != NULL) {
status = sysfs_create_link(&dev->kobj, &tdev->kobj,
name);
+ put_device(tdev);
} else {
status = -ENODEV;
}
--
2.2.2
From: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 49d2ca84e433dab854c7a866bc6add09cfab682d upstream.
Fix memory leak in the gpio sysfs interface due to failure to drop
reference to device returned by class_find_device when setting the
gpio-line polarity.
Fixes: 0769746183ca ("gpiolib: add support for changing value polarity in sysfs")
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpio/gpiolib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 4840c05862e7..8a9b61adcd87 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -918,7 +918,7 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
}
status = sysfs_set_active_low(desc, dev, value);
-
+ put_device(dev);
unlock:
mutex_unlock(&sysfs_lock);
--
2.2.2
From: Charlotte Richardson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 51ac3d2f0c505ca36ffc9715ffd518d756589ef8 upstream.
NEC OEMs the same platforms as Stratus does, which have multiple devices on
some PCIe buses under downstream ports.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=51331
Fixes: 1278998f8ff6 ("PCI: Work around Stratus ftServer broken PCIe hierarchy (fix DMI check)")
Signed-off-by: Charlotte Richardson <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
CC: Myron Stowe <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/pci/common.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 981c2dbd72cc..88f143d9754e 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -448,6 +448,22 @@ static const struct dmi_system_id pciprobe_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"),
},
},
+ {
+ .callback = set_scan_all,
+ .ident = "Stratus/NEC ftServer",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"),
+ },
+ },
+ {
+ .callback = set_scan_all,
+ .ident = "Stratus/NEC ftServer",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"),
+ },
+ },
{}
};
--
2.2.2
From: Felix Fietkau <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a3e6c1eff54878506b2dddcc202df9cc8180facb upstream.
If the irq_chip does not define .irq_disable, any call to disable_irq
will defer disabling the IRQ until it fires while marked as disabled.
This assumes that the handler function checks for this condition, which
handle_percpu_irq does not. In this case, calling disable_irq leads to
an IRQ storm, if the interrupt fires while disabled.
This optimization is only useful when disabling the IRQ is slow, which
is not true for the MIPS CPU IRQ.
Disable this optimization by implementing .irq_disable and .irq_enable
Signed-off-by: Felix Fietkau <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/8949/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/mips/kernel/irq_cpu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 72ef2d25cbf2..ab941a366012 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -56,6 +56,8 @@ static struct irq_chip mips_cpu_irq_controller = {
.irq_mask_ack = mask_mips_irq,
.irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq,
+ .irq_disable = mask_mips_irq,
+ .irq_enable = unmask_mips_irq,
};
/*
@@ -92,6 +94,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
.irq_mask_ack = mips_mt_cpu_irq_ack,
.irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq,
+ .irq_disable = mask_mips_irq,
+ .irq_enable = unmask_mips_irq,
};
void __init mips_cpu_irq_init(void)
--
2.2.2
From: Hemmo Nieminen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c7754e75100ed5e3068ac5085747f2bfc386c8d6 upstream.
As printk() invocation can cause e.g. a TLB miss, printk() cannot be
called before the exception handlers have been properly initialized.
This can happen e.g. when netconsole has been loaded as a kernel module
and the TLB table has been cleared when a CPU was offline.
Call cpu_report() in start_secondary() only after the exception handlers
have been initialized to fix this.
Without the patch the kernel will randomly either lockup or crash
after a CPU is onlined and the console driver is a module.
Signed-off-by: Hemmo Nieminen <[email protected]>
Signed-off-by: Aaro Koskinen <[email protected]>
Cc: David Daney <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/8953/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/mips/kernel/smp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 5c208ed8f856..57b89cba1624 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -109,10 +109,10 @@ asmlinkage void start_secondary(void)
else
#endif /* CONFIG_MIPS_MT_SMTC */
cpu_probe();
- cpu_report();
per_cpu_trap_init(false);
mips_clockevent_init();
mp_ops->init_secondary();
+ cpu_report();
/*
* XXX parity protection should be folded in here when it's converted
--
2.2.2
From: Sachin Prabhu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ca7df8e0bb2a5ec79691de8a1a4c0e611fe04e60 upstream.
Commit
c11f1df5003d534fd067f0168bfad7befffb3b5c
requires writers to wait for any pending oplock break handler to
complete before proceeding to write. This is done by waiting on bit
CIFS_INODE_PENDING_OPLOCK_BREAK in cifsFileInfo->flags. This bit is
cleared by the oplock break handler job queued on the workqueue once it
has completed handling the oplock break allowing writers to proceed with
writing to the file.
While testing, it was noticed that the filehandle could be closed while
there is a pending oplock break which results in the oplock break
handler on the cifsiod workqueue being cancelled before it has had a
chance to execute and clear the CIFS_INODE_PENDING_OPLOCK_BREAK bit.
Any subsequent attempt to write to this file hangs waiting for the
CIFS_INODE_PENDING_OPLOCK_BREAK bit to be cleared.
We fix this by ensuring that we also clear the bit
CIFS_INODE_PENDING_OPLOCK_BREAK when we remove the oplock break handler
from the workqueue.
The bug was found by Red Hat QA while testing using ltp's fsstress
command.
Signed-off-by: Sachin Prabhu <[email protected]>
Acked-by: Shirish Pargaonkar <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/file.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index f9715276a257..ead2473f6839 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -366,6 +366,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
struct cifsLockInfo *li, *tmp;
struct cifs_fid fid;
struct cifs_pending_open open;
+ bool oplock_break_cancelled;
spin_lock(&cifs_file_list_lock);
if (--cifs_file->count > 0) {
@@ -397,7 +398,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
}
spin_unlock(&cifs_file_list_lock);
- cancel_work_sync(&cifs_file->oplock_break);
+ oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break);
if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
struct TCP_Server_Info *server = tcon->ses->server;
@@ -409,6 +410,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
_free_xid(xid);
}
+ if (oplock_break_cancelled)
+ cifs_done_oplock_break(cifsi);
+
cifs_del_pending_open(&open);
/*
--
2.2.2
From: Shiraz Hashim <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 23aaed6659df9adfabe9c583e67a36b54e21df46 upstream.
walk_page_range() silently skips vma having VM_PFNMAP set, which leads
to undesirable behaviour at client end (who called walk_page_range).
Userspace applications get the wrong data, so the effect is like just
confusing users (if the applications just display the data) or sometimes
killing the processes (if the applications do something with
misunderstanding virtual addresses due to the wrong data.)
For example for pagemap_read, when no callbacks are called against
VM_PFNMAP vma, pagemap_read may prepare pagemap data for next virtual
address range at wrong index.
Eventually userspace may get wrong pagemap data for a task.
Corresponding to a VM_PFNMAP marked vma region, kernel may report
mappings from subsequent vma regions. User space in turn may account
more pages (than really are) to the task.
In my case I was using procmem, procrack (Android utility) which uses
pagemap interface to account RSS pages of a task. Due to this bug it
was giving a wrong picture for vmas (with VM_PFNMAP set).
Fixes: a9ff785e4437 ("mm/pagewalk.c: walk_page_range should avoid VM_PFNMAP areas")
Signed-off-by: Shiraz Hashim <[email protected]>
Acked-by: Naoya Horiguchi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
mm/pagewalk.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 2beeabf502c5..9056d22d2880 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -199,7 +199,10 @@ int walk_page_range(unsigned long addr, unsigned long end,
*/
if ((vma->vm_start <= addr) &&
(vma->vm_flags & VM_PFNMAP)) {
- next = vma->vm_end;
+ if (walk->pte_hole)
+ err = walk->pte_hole(addr, next, walk);
+ if (err)
+ break;
pgd = pgd_offset(walk->mm, next);
continue;
}
--
2.2.2
From: karl beldan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 150ae0e94634714b23919f0c333fee28a5b199d5 upstream.
The carry from the 64->32bits folding was dropped, e.g with:
saddr=0xFFFFFFFF daddr=0xFF0000FF len=0xFFFF proto=0 sum=1,
csum_tcpudp_nofold returned 0 instead of 1.
Signed-off-by: Karl Beldan <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Mike Frysinger <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
lib/checksum.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/checksum.c b/lib/checksum.c
index 129775eb6de6..fcf38943132c 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -47,6 +47,15 @@ static inline unsigned short from32to16(unsigned int x)
return x;
}
+static inline u32 from64to32(u64 x)
+{
+ /* add up 32-bit and 32-bit for 32+c bit */
+ x = (x & 0xffffffff) + (x >> 32);
+ /* add up carry.. */
+ x = (x & 0xffffffff) + (x >> 32);
+ return (u32)x;
+}
+
static unsigned int do_csum(const unsigned char *buff, int len)
{
int odd;
@@ -195,8 +204,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
#else
s += (proto + len) << 8;
#endif
- s += (s >> 32);
- return (__force __wsum)s;
+ return (__force __wsum)from64to32(s);
}
EXPORT_SYMBOL(csum_tcpudp_nofold);
#endif
--
2.2.2
From: Ryusuke Konishi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7ef3ff2fea8bf5e4a21cef47ad87710a3d0fdb52 upstream.
Nilfs2 eventually hangs in a stress test with fsstress program. This
issue was caused by the following deadlock over I_SYNC flag between
nilfs_segctor_thread() and writeback_sb_inodes():
nilfs_segctor_thread()
nilfs_segctor_thread_construct()
nilfs_segctor_unlock()
nilfs_dispose_list()
iput()
iput_final()
evict()
inode_wait_for_writeback() * wait for I_SYNC flag
writeback_sb_inodes()
* set I_SYNC flag on inode->i_state
__writeback_single_inode()
do_writepages()
nilfs_writepages()
nilfs_construct_dsync_segment()
nilfs_segctor_sync()
* wait for completion of segment constructor
inode_sync_complete()
* clear I_SYNC flag after __writeback_single_inode() completed
writeback_sb_inodes() calls do_writepages() for dirty inodes after
setting I_SYNC flag on inode->i_state. do_writepages() in turn calls
nilfs_writepages(), which can run segment constructor and wait for its
completion. On the other hand, segment constructor calls iput(), which
can call evict() and wait for the I_SYNC flag on
inode_wait_for_writeback().
Since segment constructor doesn't know when I_SYNC will be set, it
cannot know whether iput() will block or not unless inode->i_nlink has a
non-zero count. We can prevent evict() from being called in iput() by
implementing sop->drop_inode(), but it's not preferable to leave inodes
with i_nlink == 0 for long periods because it even defers file
truncation and inode deallocation. So, this instead resolves the
deadlock by calling iput() asynchronously with a workqueue for inodes
with i_nlink == 0.
Signed-off-by: Ryusuke Konishi <[email protected]>
Cc: Al Viro <[email protected]>
Tested-by: Ryusuke Konishi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/nilfs2/nilfs.h | 2 --
fs/nilfs2/segment.c | 44 +++++++++++++++++++++++++++++++++++++++-----
fs/nilfs2/segment.h | 5 +++++
3 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 9bc72dec3fa6..b02c202223a6 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -141,7 +141,6 @@ enum {
* @ti_save: Backup of journal_info field of task_struct
* @ti_flags: Flags
* @ti_count: Nest level
- * @ti_garbage: List of inode to be put when releasing semaphore
*/
struct nilfs_transaction_info {
u32 ti_magic;
@@ -150,7 +149,6 @@ struct nilfs_transaction_info {
one of other filesystems has a bug. */
unsigned short ti_flags;
unsigned short ti_count;
- struct list_head ti_garbage;
};
/* ti_magic */
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 0b7d2cad0426..a0c815b71e6a 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -305,7 +305,6 @@ static void nilfs_transaction_lock(struct super_block *sb,
ti->ti_count = 0;
ti->ti_save = cur_ti;
ti->ti_magic = NILFS_TI_MAGIC;
- INIT_LIST_HEAD(&ti->ti_garbage);
current->journal_info = ti;
for (;;) {
@@ -332,8 +331,6 @@ static void nilfs_transaction_unlock(struct super_block *sb)
up_write(&nilfs->ns_segctor_sem);
current->journal_info = ti->ti_save;
- if (!list_empty(&ti->ti_garbage))
- nilfs_dispose_list(nilfs, &ti->ti_garbage, 0);
}
static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
@@ -746,6 +743,15 @@ static void nilfs_dispose_list(struct the_nilfs *nilfs,
}
}
+static void nilfs_iput_work_func(struct work_struct *work)
+{
+ struct nilfs_sc_info *sci = container_of(work, struct nilfs_sc_info,
+ sc_iput_work);
+ struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
+
+ nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 0);
+}
+
static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
struct nilfs_root *root)
{
@@ -1900,8 +1906,8 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
struct the_nilfs *nilfs)
{
- struct nilfs_transaction_info *ti = current->journal_info;
struct nilfs_inode_info *ii, *n;
+ int defer_iput = false;
spin_lock(&nilfs->ns_inode_lock);
list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) {
@@ -1912,9 +1918,24 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
clear_bit(NILFS_I_BUSY, &ii->i_state);
brelse(ii->i_bh);
ii->i_bh = NULL;
- list_move_tail(&ii->i_dirty, &ti->ti_garbage);
+ list_del_init(&ii->i_dirty);
+ if (!ii->vfs_inode.i_nlink) {
+ /*
+ * Defer calling iput() to avoid a deadlock
+ * over I_SYNC flag for inodes with i_nlink == 0
+ */
+ list_add_tail(&ii->i_dirty, &sci->sc_iput_queue);
+ defer_iput = true;
+ } else {
+ spin_unlock(&nilfs->ns_inode_lock);
+ iput(&ii->vfs_inode);
+ spin_lock(&nilfs->ns_inode_lock);
+ }
}
spin_unlock(&nilfs->ns_inode_lock);
+
+ if (defer_iput)
+ schedule_work(&sci->sc_iput_work);
}
/*
@@ -2583,6 +2604,8 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
INIT_LIST_HEAD(&sci->sc_segbufs);
INIT_LIST_HEAD(&sci->sc_write_logs);
INIT_LIST_HEAD(&sci->sc_gc_inodes);
+ INIT_LIST_HEAD(&sci->sc_iput_queue);
+ INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func);
init_timer(&sci->sc_timer);
sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
@@ -2609,6 +2632,8 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
nilfs_transaction_unlock(sci->sc_super);
+ flush_work(&sci->sc_iput_work);
+
} while (ret && retrycount-- > 0);
}
@@ -2633,6 +2658,9 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
|| sci->sc_seq_request != sci->sc_seq_done);
spin_unlock(&sci->sc_state_lock);
+ if (flush_work(&sci->sc_iput_work))
+ flag = true;
+
if (flag || !nilfs_segctor_confirm(sci))
nilfs_segctor_write_out(sci);
@@ -2642,6 +2670,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
}
+ if (!list_empty(&sci->sc_iput_queue)) {
+ nilfs_warning(sci->sc_super, __func__,
+ "iput queue is not empty\n");
+ nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1);
+ }
+
WARN_ON(!list_empty(&sci->sc_segbufs));
WARN_ON(!list_empty(&sci->sc_write_logs));
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 38a1d0013314..a48d6de1e02c 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -26,6 +26,7 @@
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
+#include <linux/workqueue.h>
#include <linux/nilfs2_fs.h>
#include "nilfs.h"
@@ -92,6 +93,8 @@ struct nilfs_segsum_pointer {
* @sc_nblk_inc: Block count of current generation
* @sc_dirty_files: List of files to be written
* @sc_gc_inodes: List of GC inodes having blocks to be written
+ * @sc_iput_queue: list of inodes for which iput should be done
+ * @sc_iput_work: work struct to defer iput call
* @sc_freesegs: array of segment numbers to be freed
* @sc_nfreesegs: number of segments on @sc_freesegs
* @sc_dsync_inode: inode whose data pages are written for a sync operation
@@ -135,6 +138,8 @@ struct nilfs_sc_info {
struct list_head sc_dirty_files;
struct list_head sc_gc_inodes;
+ struct list_head sc_iput_queue;
+ struct work_struct sc_iput_work;
__u64 *sc_freesegs;
size_t sc_nfreesegs;
--
2.2.2
From: Peter Kümmel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2d560306096739e2251329ab5c16059311a151b0 upstream.
Warning:
In file included from scripts/kconfig/zconf.tab.c:2537:0:
scripts/kconfig/menu.c: In function ‘get_symbol_str’:
scripts/kconfig/menu.c:590:18: warning: ‘jump’ may be used uninitialized in this function [-Wmaybe-uninitialized]
jump->offset = strlen(r->s);
Simplifies the test logic because (head && local) means (jump != 0)
and makes GCC happy when checking if the jump pointer was initialized.
Signed-off-by: Peter Kümmel <[email protected]>
Signed-off-by: Michal Marek <[email protected]>
Cc: Sedat Dilek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
scripts/kconfig/menu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 2b3317010ba4..c81f055343b7 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -544,7 +544,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
{
int i, j;
struct menu *submenu[8], *menu, *location = NULL;
- struct jump_key *jump;
+ struct jump_key *jump = NULL;
str_printf(r, _("Prompt: %s\n"), _(prop->text));
menu = prop->menu->parent;
@@ -582,7 +582,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
str_printf(r, _(" Location:\n"));
for (j = 4; --i >= 0; j += 2) {
menu = submenu[i];
- if (head && location && menu == location)
+ if (jump && menu == location)
jump->offset = strlen(r->s);
str_printf(r, "%*c-> %s", j, ' ',
_(menu_get_prompt(menu)));
--
2.2.2
From: Dmitry Monakhov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a41537e69b4aa43f0fea02498c2595a81267383b upstream.
O_DIRECT flags can be toggeled via fcntl(F_SETFL). But this value checked
twice inside ext4_file_write_iter() and __generic_file_write() which
result in BUG_ON inside ext4_direct_IO.
Let's initialize iocb->private unconditionally.
TESTCASE: xfstest:generic/036 https://patchwork.ozlabs.org/patch/402445/
#TYPICAL STACK TRACE:
kernel BUG at fs/ext4/inode.c:2960!
invalid opcode: 0000 [#1] SMP
Modules linked in: brd iTCO_wdt lpc_ich mfd_core igb ptp dm_mirror dm_region_hash dm_log dm_mod
CPU: 6 PID: 5505 Comm: aio-dio-fcntl-r Not tainted 3.17.0-rc2-00176-gff5c017 #161
Hardware name: Intel Corporation W2600CR/W2600CR, BIOS SE5C600.86B.99.99.x028.061320111235 06/13/2011
task: ffff88080e95a7c0 ti: ffff88080f908000 task.ti: ffff88080f908000
RIP: 0010:[<ffffffff811fabf2>] [<ffffffff811fabf2>] ext4_direct_IO+0x162/0x3d0
RSP: 0018:ffff88080f90bb58 EFLAGS: 00010246
RAX: 0000000000000400 RBX: ffff88080fdb2a28 RCX: 00000000a802c818
RDX: 0000040000080000 RSI: ffff88080d8aeb80 RDI: 0000000000000001
RBP: ffff88080f90bbc8 R08: 0000000000000000 R09: 0000000000001581
R10: 0000000000000000 R11: 0000000000000000 R12: ffff88080d8aeb80
R13: ffff88080f90bbf8 R14: ffff88080fdb28c8 R15: ffff88080fdb2a28
FS: 00007f23b2055700(0000) GS:ffff880818400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f23b2045000 CR3: 000000080cedf000 CR4: 00000000000407e0
Stack:
ffff88080f90bb98 0000000000000000 7ffffffffffffffe ffff88080fdb2c30
0000000000000200 0000000000000200 0000000000000001 0000000000000200
ffff88080f90bbc8 ffff88080fdb2c30 ffff88080f90be08 0000000000000200
Call Trace:
[<ffffffff8112ca9d>] generic_file_direct_write+0xed/0x180
[<ffffffff8112f2b2>] __generic_file_write_iter+0x222/0x370
[<ffffffff811f495b>] ext4_file_write_iter+0x34b/0x400
[<ffffffff811bd709>] ? aio_run_iocb+0x239/0x410
[<ffffffff811bd709>] ? aio_run_iocb+0x239/0x410
[<ffffffff810990e5>] ? local_clock+0x25/0x30
[<ffffffff810abd94>] ? __lock_acquire+0x274/0x700
[<ffffffff811f4610>] ? ext4_unwritten_wait+0xb0/0xb0
[<ffffffff811bd756>] aio_run_iocb+0x286/0x410
[<ffffffff810990e5>] ? local_clock+0x25/0x30
[<ffffffff810ac359>] ? lock_release_holdtime+0x29/0x190
[<ffffffff811bc05b>] ? lookup_ioctx+0x4b/0xf0
[<ffffffff811bde3b>] do_io_submit+0x55b/0x740
[<ffffffff811bdcaa>] ? do_io_submit+0x3ca/0x740
[<ffffffff811be030>] SyS_io_submit+0x10/0x20
[<ffffffff815ce192>] system_call_fastpath+0x16/0x1b
Code: 01 48 8b 80 f0 01 00 00 48 8b 18 49 8b 45 10 0f 85 f1 01 00 00 48 03 45 c8 48 3b 43 48 0f 8f e3 01 00 00 49 83 7c
24 18 00 75 04 <0f> 0b eb fe f0 ff 83 ec 01 00 00 49 8b 44 24 18 8b 00 85 c0 89
RIP [<ffffffff811fabf2>] ext4_direct_IO+0x162/0x3d0
RSP <ffff88080f90bb58>
Reported-by: Sasha Levin <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Dmitry Monakhov <[email protected]>
[hujianyang: Backported to 3.10
- Move initialization of iocb->private to ext4_file_write() as we don't
have ext4_file_write_iter(), which is introduced by commit 9b884164.
- Adjust context to make 'overwrite' changes apply to ext4_file_dio_write()
as ext4_file_dio_write() is not move into ext4_file_write()]
Signed-off-by: hujianyang <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ext4/file.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 7b316011bfef..716e9dbb56d5 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -100,7 +100,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
struct blk_plug plug;
int unaligned_aio = 0;
ssize_t ret;
- int overwrite = 0;
+ int *overwrite = iocb->private;
size_t length = iov_length(iov, nr_segs);
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
@@ -118,8 +118,6 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
mutex_lock(&inode->i_mutex);
blk_start_plug(&plug);
- iocb->private = &overwrite;
-
/* check whether we do a DIO overwrite or not */
if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
!file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
@@ -143,7 +141,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
* So we should check these two conditions.
*/
if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
- overwrite = 1;
+ *overwrite = 1;
}
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
@@ -170,6 +168,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
{
struct inode *inode = file_inode(iocb->ki_filp);
ssize_t ret;
+ int overwrite = 0;
/*
* If we have encountered a bitmap-format file, the size limit
@@ -190,6 +189,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
}
}
+ iocb->private = &overwrite;
if (unlikely(iocb->ki_filp->f_flags & O_DIRECT))
ret = ext4_file_dio_write(iocb, iov, nr_segs, pos);
else
--
2.2.2
From: karl beldan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9ce357795ef208faa0d59894d9d119a7434e37f3 upstream.
Fixed commit added from64to32 under _#ifndef do_csum_ but used it
under _#ifndef csum_tcpudp_nofold_, breaking some builds (Fengguang's
robot reported TILEGX's). Move from64to32 under the latter.
Fixes: 150ae0e94634 ("lib/checksum.c: fix carry in csum_tcpudp_nofold")
Reported-by: kbuild test robot <[email protected]>
Signed-off-by: Karl Beldan <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: David S. Miller <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Guenter Roeck <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
lib/checksum.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/lib/checksum.c b/lib/checksum.c
index fcf38943132c..8b39e86dbab5 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -47,15 +47,6 @@ static inline unsigned short from32to16(unsigned int x)
return x;
}
-static inline u32 from64to32(u64 x)
-{
- /* add up 32-bit and 32-bit for 32+c bit */
- x = (x & 0xffffffff) + (x >> 32);
- /* add up carry.. */
- x = (x & 0xffffffff) + (x >> 32);
- return (u32)x;
-}
-
static unsigned int do_csum(const unsigned char *buff, int len)
{
int odd;
@@ -190,6 +181,15 @@ csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
EXPORT_SYMBOL(csum_partial_copy);
#ifndef csum_tcpudp_nofold
+static inline u32 from64to32(u64 x)
+{
+ /* add up 32-bit and 32-bit for 32+c bit */
+ x = (x & 0xffffffff) + (x >> 32);
+ /* add up carry.. */
+ x = (x & 0xffffffff) + (x >> 32);
+ return (u32)x;
+}
+
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
--
2.2.2
From: Bo Shen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a43bd7e125143b875caae6d4f9938855b440faaf upstream.
According to the I2S specification information as following:
- WS = 0, channel 1 (left)
- WS = 1, channel 2 (right)
So, the start event should be TF/RF falling edge.
Reported-by: Songjun Wu <[email protected]>
Signed-off-by: Bo Shen <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/soc/atmel/atmel_ssc_dai.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index bb53dea85b17..eb8fa7c1aeee 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -344,7 +344,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
u32 tfmr, rfmr, tcmr, rcmr;
- int start_event;
int ret;
/*
@@ -451,19 +450,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
* The SSC transmit clock is obtained from the BCLK signal on
* on the TK line, and the SSC receive clock is
* generated from the transmit clock.
- *
- * For single channel data, one sample is transferred
- * on the falling edge of the LRC clock.
- * For two channel data, one sample is
- * transferred on both edges of the LRC clock.
*/
- start_event = ((channels == 1)
- ? SSC_START_FALLING_RF
- : SSC_START_EDGE_RF);
-
rcmr = SSC_BF(RCMR_PERIOD, 0)
| SSC_BF(RCMR_STTDLY, START_DELAY)
- | SSC_BF(RCMR_START, start_event)
+ | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
| SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
@@ -471,14 +461,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
| SSC_BF(RFMR_FSLEN, 0)
- | SSC_BF(RFMR_DATNB, 0)
+ | SSC_BF(RFMR_DATNB, (channels - 1))
| SSC_BIT(RFMR_MSBF)
| SSC_BF(RFMR_LOOP, 0)
| SSC_BF(RFMR_DATLEN, (bits - 1));
tcmr = SSC_BF(TCMR_PERIOD, 0)
| SSC_BF(TCMR_STTDLY, START_DELAY)
- | SSC_BF(TCMR_START, start_event)
+ | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
| SSC_BF(TCMR_CKS, SSC_CKS_PIN);
@@ -487,7 +477,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
| SSC_BF(TFMR_FSDEN, 0)
| SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
| SSC_BF(TFMR_FSLEN, 0)
- | SSC_BF(TFMR_DATNB, 0)
+ | SSC_BF(TFMR_DATNB, (channels - 1))
| SSC_BIT(TFMR_MSBF)
| SSC_BF(TFMR_DATDEF, 0)
| SSC_BF(TFMR_DATLEN, (bits - 1));
--
2.2.2
From: Eric Nelson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 58cc9c9a175885bbf6bae3acf18233d0a8229a84 upstream.
To quote from section 1.3.1 of the data sheet:
The SGTL5000 has an internal reset that is deasserted
8 SYS_MCLK cycles after all power rails have been brought
up. After this time, communication can start
...
1.0us represents 8 SYS_MCLK cycles at the minimum 8.0 MHz SYS_MCLK.
Signed-off-by: Eric Nelson <[email protected]>
Reviewed-by: Fabio Estevam <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/soc/codecs/sgtl5000.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index b76c6b619227..ba73f832e455 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1550,6 +1550,9 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
if (ret)
return ret;
+ /* Need 8 clocks before I2C accesses */
+ udelay(1);
+
/* read chip information */
ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®);
if (ret)
--
2.2.2
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4161b4505f1690358ac0a9ee59845a7887336b21 upstream.
When ak4114 work calls its callback and the callback invokes
ak4114_reinit(), it stalls due to flush_delayed_work(). For avoiding
this, control the reentrance by introducing a refcount. Also
flush_delayed_work() is replaced with cancel_delayed_work_sync().
The exactly same bug is present in ak4113.c and fixed as well.
Reported-by: Pavel Hofman <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Tested-by: Pavel Hofman <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/sound/ak4113.h | 2 +-
include/sound/ak4114.h | 2 +-
sound/i2c/other/ak4113.c | 17 ++++++++---------
sound/i2c/other/ak4114.c | 18 ++++++++----------
4 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h
index 2609048c1d44..3a34f6edc2d1 100644
--- a/include/sound/ak4113.h
+++ b/include/sound/ak4113.h
@@ -286,7 +286,7 @@ struct ak4113 {
ak4113_write_t *write;
ak4113_read_t *read;
void *private_data;
- unsigned int init:1;
+ atomic_t wq_processing;
spinlock_t lock;
unsigned char regmap[AK4113_WRITABLE_REGS];
struct snd_kcontrol *kctls[AK4113_CONTROLS];
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
index 3ce69fd92523..69441161009c 100644
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -168,7 +168,7 @@ struct ak4114 {
ak4114_write_t * write;
ak4114_read_t * read;
void * private_data;
- unsigned int init: 1;
+ atomic_t wq_processing;
spinlock_t lock;
unsigned char regmap[7];
unsigned char txcsb[5];
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index e04e750a77ed..7a9149bb2a38 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -56,8 +56,7 @@ static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
static void snd_ak4113_free(struct ak4113 *chip)
{
- chip->init = 1; /* don't schedule new work */
- mb();
+ atomic_inc(&chip->wq_processing); /* don't schedule new work */
cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
chip->write = write;
chip->private_data = private_data;
INIT_DELAYED_WORK(&chip->work, ak4113_stats);
+ atomic_set(&chip->wq_processing, 0);
for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
chip->regmap[reg] = pgm[reg];
@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak4113 *chip)
void snd_ak4113_reinit(struct ak4113 *chip)
{
- chip->init = 1;
- mb();
- flush_delayed_work(&chip->work);
+ if (atomic_inc_return(&chip->wq_processing) == 1)
+ cancel_delayed_work_sync(&chip->work);
ak4113_init_regs(chip);
/* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
+ if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
}
EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_struct *work)
{
struct ak4113 *chip = container_of(work, struct ak4113, work.work);
- if (!chip->init)
+ if (atomic_inc_return(&chip->wq_processing) == 1)
snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
- schedule_delayed_work(&chip->work, HZ / 10);
+ if (atomic_dec_and_test(&chip->wq_processing))
+ schedule_delayed_work(&chip->work, HZ / 10);
}
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 5bf4fca19e48..84a1ee7af552 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak4114)
static void snd_ak4114_free(struct ak4114 *chip)
{
- chip->init = 1; /* don't schedule new work */
- mb();
+ atomic_inc(&chip->wq_processing); /* don't schedule new work */
cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *card,
chip->write = write;
chip->private_data = private_data;
INIT_DELAYED_WORK(&chip->work, ak4114_stats);
+ atomic_set(&chip->wq_processing, 0);
for (reg = 0; reg < 7; reg++)
chip->regmap[reg] = pgm[reg];
@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak4114 *chip)
void snd_ak4114_reinit(struct ak4114 *chip)
{
- chip->init = 1;
- mb();
- flush_delayed_work(&chip->work);
+ if (atomic_inc_return(&chip->wq_processing) == 1)
+ cancel_delayed_work_sync(&chip->work);
ak4114_init_regs(chip);
/* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
+ if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
}
@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_struct *work)
{
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
- if (!chip->init)
+ if (atomic_inc_return(&chip->wq_processing) == 1)
snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
-
- schedule_delayed_work(&chip->work, HZ / 10);
+ if (atomic_dec_and_test(&chip->wq_processing))
+ schedule_delayed_work(&chip->work, HZ / 10);
}
EXPORT_SYMBOL(snd_ak4114_create);
--
2.2.2
From: Lai Jiangshan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4bee96860a65c3a62d332edac331b3cf936ba3ad upstream.
The following race exists in the smpboot percpu threads management:
CPU0 CPU1
cpu_up(2)
get_online_cpus();
smpboot_create_threads(2);
smpboot_register_percpu_thread();
for_each_online_cpu();
__smpboot_create_thread();
__cpu_up(2);
This results in a missing per cpu thread for the newly onlined cpu2 and
in a NULL pointer dereference on a consecutive offline of that cpu.
Proctect smpboot_register_percpu_thread() with get_online_cpus() to
prevent that.
[ tglx: Massaged changelog and removed the change in
smpboot_unregister_percpu_thread() because that's an
optimization and therefor not stable material. ]
Signed-off-by: Lai Jiangshan <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Srivatsa S. Bhat <[email protected]>
Cc: David Rientjes <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/smpboot.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index eb89e1807408..60d35ac5d3f1 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -279,6 +279,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
unsigned int cpu;
int ret = 0;
+ get_online_cpus();
mutex_lock(&smpboot_threads_lock);
for_each_online_cpu(cpu) {
ret = __smpboot_create_thread(plug_thread, cpu);
@@ -291,6 +292,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
list_add(&plug_thread->list, &hotplug_threads);
out:
mutex_unlock(&smpboot_threads_lock);
+ put_online_cpus();
return ret;
}
EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);
--
2.2.2
From: Andy Lutomirski <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d974baa398f34393db76be45f7d4d04fbdbb4a0a upstream.
CR4 isn't constant; at least the TSD and PCE bits can vary.
TBH, treating CR0 and CR3 as constant scares me a bit, too, but it looks
like it's correct.
This adds a branch and a read from cr4 to each vm entry. Because it is
extremely likely that consecutive entries into the same vcpu will have
the same host cr4 value, this fixes up the vmcs instead of restoring cr4
after the fact. A subsequent patch will add a kernel-wide cr4 shadow,
reducing the overhead in the common case to just two memory reads and a
branch.
Signed-off-by: Andy Lutomirski <[email protected]>
Acked-by: Paolo Bonzini <[email protected]>
Cc: Petr Matousek <[email protected]>
Cc: Gleb Natapov <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[wangkai: Backport to 3.10: adjust context]
Signed-off-by: Wang Kai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/vmx.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c7663b16cdbe..4530a72510b2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -439,6 +439,7 @@ struct vcpu_vmx {
#endif
int gs_ldt_reload_needed;
int fs_reload_needed;
+ unsigned long vmcs_host_cr4; /* May not match real cr4 */
} host_state;
struct {
int vm86_active;
@@ -4127,11 +4128,16 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
u32 low32, high32;
unsigned long tmpl;
struct desc_ptr dt;
+ unsigned long cr4;
vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */
- vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */
vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
+ /* Save the most likely value for this task's CR4 in the VMCS. */
+ cr4 = read_cr4();
+ vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */
+ vmx->host_state.vmcs_host_cr4 = cr4;
+
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
#ifdef CONFIG_X86_64
/*
@@ -7124,7 +7130,7 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- unsigned long debugctlmsr;
+ unsigned long debugctlmsr, cr4;
/* Record the guest's net vcpu time for enforced NMI injections. */
if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
@@ -7145,6 +7151,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
+ cr4 = read_cr4();
+ if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) {
+ vmcs_writel(HOST_CR4, cr4);
+ vmx->host_state.vmcs_host_cr4 = cr4;
+ }
+
/* When single-stepping over STI and MOV SS, we must clear the
* corresponding interruptibility bits in the guest state. Otherwise
* vmentry fails as it then expects bit 14 (BS) in pending debug
--
2.2.2
From: Mathias Krause <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
The backport of commit 5d26a105b5a7 ("crypto: prefix module autoloading
with "crypto-"") lost the MODULE_ALIAS_CRYPTO() annotation of crc32c.c.
Add it to fix the reported filesystem related regressions.
Signed-off-by: Mathias Krause <[email protected]>
Reported-by: Philip Müller <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Rob McCathie <[email protected]>
Cc: Luis Henriques <[email protected]>
Cc: Kamal Mostafa <[email protected]>
Cc: Jiri Slaby <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
crypto/crc32c.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index 06f7018c9d95..238f0e627ef3 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -170,3 +170,4 @@ module_exit(crc32c_mod_fini);
MODULE_AUTHOR("Clay Haapala <[email protected]>");
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("crc32c");
--
2.2.2
From: Willem de Bruijn <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit f812116b174e59a350acc8e4856213a166a91222 ]
The sockaddr is returned in IP(V6)_RECVERR as part of errhdr. That
structure is defined and allocated on the stack as
struct {
struct sock_extended_err ee;
struct sockaddr_in(6) offender;
} errhdr;
The second part is only initialized for certain SO_EE_ORIGIN values.
Always initialize it completely.
An MTU exceeded error on a SOCK_RAW/IPPROTO_RAW is one example that
would return uninitialized bytes.
Signed-off-by: Willem de Bruijn <[email protected]>
----
Also verified that there is no padding between errhdr.ee and
errhdr.offender that could leak additional kernel data.
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/ip_sockglue.c | 8 ++------
net/ipv6/datagram.c | 10 +++-------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 23e6ab0a2dc0..f6603142cb33 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -410,15 +410,11 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
sin = &errhdr.offender;
- sin->sin_family = AF_UNSPEC;
+ memset(sin, 0, sizeof(*sin));
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {
- struct inet_sock *inet = inet_sk(sk);
-
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
- sin->sin_port = 0;
- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
- if (inet->cmsg_flags)
+ if (inet_sk(sk)->cmsg_flags)
ip_cmsg_recv(msg, skb);
}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index c66c6df6e881..9f9ad99fcfdd 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -374,11 +374,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
sin = &errhdr.offender;
- sin->sin6_family = AF_UNSPEC;
+ memset(sin, 0, sizeof(*sin));
+
if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
sin->sin6_family = AF_INET6;
- sin->sin6_flowinfo = 0;
- sin->sin6_port = 0;
if (skb->protocol == htons(ETH_P_IPV6)) {
sin->sin6_addr = ipv6_hdr(skb)->saddr;
if (np->rxopt.all)
@@ -387,12 +386,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
ipv6_iface_scope_id(&sin->sin6_addr,
IP6CB(skb)->iif);
} else {
- struct inet_sock *inet = inet_sk(sk);
-
ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
&sin->sin6_addr);
- sin->sin6_scope_id = 0;
- if (inet->cmsg_flags)
+ if (inet_sk(sk)->cmsg_flags)
ip_cmsg_recv(msg, skb);
}
}
--
2.2.2
From: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit ac64da0b83d82abe62f78b3d0e21cca31aea24fa ]
softnet_data.input_pkt_queue is protected by a spinlock that
we must hold when transferring packets from victim queue to an active
one. This is because other cpus could still be trying to enqueue packets
into victim queue.
A second problem is that when we transfert the NAPI poll_list from
victim to current cpu, we absolutely need to special case the percpu
backlog, because we do not want to add complex locking to protect
process_queue : Only owner cpu is allowed to manipulate it, unless cpu
is offline.
Based on initial patch from Prasad Sodagudi & Subash Abhinov
Kasiviswanathan.
This version is better because we do not slow down packet processing,
only make migration safer.
Reported-by: Prasad Sodagudi <[email protected]>
Reported-by: Subash Abhinov Kasiviswanathan <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Cc: Tom Herbert <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/core/dev.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index ece49db4f265..249ab7d67254 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6405,10 +6405,20 @@ static int dev_cpu_callback(struct notifier_block *nfb,
oldsd->output_queue = NULL;
oldsd->output_queue_tailp = &oldsd->output_queue;
}
- /* Append NAPI poll list from offline CPU. */
- if (!list_empty(&oldsd->poll_list)) {
- list_splice_init(&oldsd->poll_list, &sd->poll_list);
- raise_softirq_irqoff(NET_RX_SOFTIRQ);
+ /* Append NAPI poll list from offline CPU, with one exception :
+ * process_backlog() must be called by cpu owning percpu backlog.
+ * We properly handle process_queue & input_pkt_queue later.
+ */
+ while (!list_empty(&oldsd->poll_list)) {
+ struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
+ struct napi_struct,
+ poll_list);
+
+ list_del_init(&napi->poll_list);
+ if (napi->poll == process_backlog)
+ napi->state = 0;
+ else
+ ____napi_schedule(sd, napi);
}
raise_softirq_irqoff(NET_TX_SOFTIRQ);
@@ -6419,7 +6429,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
netif_rx(skb);
input_queue_head_incr(oldsd);
}
- while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
+ while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
netif_rx(skb);
input_queue_head_incr(oldsd);
}
--
2.2.2
From: Hagen Paul Pfeifer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 9d289715eb5c252ae15bd547cb252ca547a3c4f2 ]
Reduce the attack vector and stop generating IPv6 Fragment Header for
paths with an MTU smaller than the minimum required IPv6 MTU
size (1280 byte) - called atomic fragments.
See IETF I-D "Deprecating the Generation of IPv6 Atomic Fragments" [1]
for more information and how this "feature" can be misused.
[1] https://tools.ietf.org/html/draft-ietf-6man-deprecate-atomfrag-generation-00
Signed-off-by: Fernando Gont <[email protected]>
Signed-off-by: Hagen Paul Pfeifer <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/route.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b4bb6a29aa16..1d0c5d66d637 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1144,12 +1144,9 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct net *net = dev_net(dst->dev);
rt6->rt6i_flags |= RTF_MODIFIED;
- if (mtu < IPV6_MIN_MTU) {
- u32 features = dst_metric(dst, RTAX_FEATURES);
+ if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- features |= RTAX_FEATURE_ALLFRAG;
- dst_metric_set(dst, RTAX_FEATURES, features);
- }
+
dst_metric_set(dst, RTAX_MTU, mtu);
rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires);
}
--
2.2.2
From: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 6088beef3f7517717bd21d90b379714dd0837079 ]
NAPI poll logic now enforces that a poller returns exactly the budget
when it wants to be called again.
If a driver limits TX completion, it has to return budget as well when
the limit is hit, not the number of received packets.
Reported-and-tested-by: Mike Galbraith <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Fixes: d75b1ade567f ("net: less interrupt masking in NAPI")
Cc: Manish Chopra <[email protected]>
Acked-by: Manish Chopra <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index cbd75f97ffb3..03707c1edc2a 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -2366,7 +2366,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
work_done = netxen_process_rcv_ring(sds_ring, budget);
- if ((work_done < budget) && tx_complete) {
+ if (!tx_complete)
+ work_done = budget;
+
+ if (work_done < budget) {
napi_complete(&sds_ring->napi);
if (test_bit(__NX_DEV_UP, &adapter->state))
netxen_nic_enable_int(sds_ring);
--
2.2.2
From: Daniel Borkmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 600ddd6825543962fb807884169e57b580dba208 ]
When hitting an INIT collision case during the 4WHS with AUTH enabled, as
already described in detail in commit 1be9a950c646 ("net: sctp: inherit
auth_capable on INIT collisions"), it can happen that we occasionally
still remotely trigger the following panic on server side which seems to
have been uncovered after the fix from commit 1be9a950c646 ...
[ 533.876389] BUG: unable to handle kernel paging request at 00000000ffffffff
[ 533.913657] IP: [<ffffffff811ac385>] __kmalloc+0x95/0x230
[ 533.940559] PGD 5030f2067 PUD 0
[ 533.957104] Oops: 0000 [#1] SMP
[ 533.974283] Modules linked in: sctp mlx4_en [...]
[ 534.939704] Call Trace:
[ 534.951833] [<ffffffff81294e30>] ? crypto_init_shash_ops+0x60/0xf0
[ 534.984213] [<ffffffff81294e30>] crypto_init_shash_ops+0x60/0xf0
[ 535.015025] [<ffffffff8128c8ed>] __crypto_alloc_tfm+0x6d/0x170
[ 535.045661] [<ffffffff8128d12c>] crypto_alloc_base+0x4c/0xb0
[ 535.074593] [<ffffffff8160bd42>] ? _raw_spin_lock_bh+0x12/0x50
[ 535.105239] [<ffffffffa0418c11>] sctp_inet_listen+0x161/0x1e0 [sctp]
[ 535.138606] [<ffffffff814e43bd>] SyS_listen+0x9d/0xb0
[ 535.166848] [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b
... or depending on the the application, for example this one:
[ 1370.026490] BUG: unable to handle kernel paging request at 00000000ffffffff
[ 1370.026506] IP: [<ffffffff811ab455>] kmem_cache_alloc+0x75/0x1d0
[ 1370.054568] PGD 633c94067 PUD 0
[ 1370.070446] Oops: 0000 [#1] SMP
[ 1370.085010] Modules linked in: sctp kvm_amd kvm [...]
[ 1370.963431] Call Trace:
[ 1370.974632] [<ffffffff8120f7cf>] ? SyS_epoll_ctl+0x53f/0x960
[ 1371.000863] [<ffffffff8120f7cf>] SyS_epoll_ctl+0x53f/0x960
[ 1371.027154] [<ffffffff812100d3>] ? anon_inode_getfile+0xd3/0x170
[ 1371.054679] [<ffffffff811e3d67>] ? __alloc_fd+0xa7/0x130
[ 1371.080183] [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b
With slab debugging enabled, we can see that the poison has been overwritten:
[ 669.826368] BUG kmalloc-128 (Tainted: G W ): Poison overwritten
[ 669.826385] INFO: 0xffff880228b32e50-0xffff880228b32e50. First byte 0x6a instead of 0x6b
[ 669.826414] INFO: Allocated in sctp_auth_create_key+0x23/0x50 [sctp] age=3 cpu=0 pid=18494
[ 669.826424] __slab_alloc+0x4bf/0x566
[ 669.826433] __kmalloc+0x280/0x310
[ 669.826453] sctp_auth_create_key+0x23/0x50 [sctp]
[ 669.826471] sctp_auth_asoc_create_secret+0xcb/0x1e0 [sctp]
[ 669.826488] sctp_auth_asoc_init_active_key+0x68/0xa0 [sctp]
[ 669.826505] sctp_do_sm+0x29d/0x17c0 [sctp] [...]
[ 669.826629] INFO: Freed in kzfree+0x31/0x40 age=1 cpu=0 pid=18494
[ 669.826635] __slab_free+0x39/0x2a8
[ 669.826643] kfree+0x1d6/0x230
[ 669.826650] kzfree+0x31/0x40
[ 669.826666] sctp_auth_key_put+0x19/0x20 [sctp]
[ 669.826681] sctp_assoc_update+0x1ee/0x2d0 [sctp]
[ 669.826695] sctp_do_sm+0x674/0x17c0 [sctp]
Since this only triggers in some collision-cases with AUTH, the problem at
heart is that sctp_auth_key_put() on asoc->asoc_shared_key is called twice
when having refcnt 1, once directly in sctp_assoc_update() and yet again
from within sctp_auth_asoc_init_active_key() via sctp_assoc_update() on
the already kzfree'd memory, which is also consistent with the observation
of the poison decrease from 0x6b to 0x6a (note: the overwrite is detected
at a later point in time when poison is checked on new allocation).
Reference counting of auth keys revisited:
Shared keys for AUTH chunks are being stored in endpoints and associations
in endpoint_shared_keys list. On endpoint creation, a null key is being
added; on association creation, all endpoint shared keys are being cached
and thus cloned over to the association. struct sctp_shared_key only holds
a pointer to the actual key bytes, that is, struct sctp_auth_bytes which
keeps track of users internally through refcounting. Naturally, on assoc
or enpoint destruction, sctp_shared_key are being destroyed directly and
the reference on sctp_auth_bytes dropped.
User space can add keys to either list via setsockopt(2) through struct
sctp_authkey and by passing that to sctp_auth_set_key() which replaces or
adds a new auth key. There, sctp_auth_create_key() creates a new sctp_auth_bytes
with refcount 1 and in case of replacement drops the reference on the old
sctp_auth_bytes. A key can be set active from user space through setsockopt()
on the id via sctp_auth_set_active_key(), which iterates through either
endpoint_shared_keys and in case of an assoc, invokes (one of various places)
sctp_auth_asoc_init_active_key().
sctp_auth_asoc_init_active_key() computes the actual secret from local's
and peer's random, hmac and shared key parameters and returns a new key
directly as sctp_auth_bytes, that is asoc->asoc_shared_key, plus drops
the reference if there was a previous one. The secret, which where we
eventually double drop the ref comes from sctp_auth_asoc_set_secret() with
intitial refcount of 1, which also stays unchanged eventually in
sctp_assoc_update(). This key is later being used for crypto layer to
set the key for the hash in crypto_hash_setkey() from sctp_auth_calculate_hmac().
To close the loop: asoc->asoc_shared_key is freshly allocated secret
material and independant of the sctp_shared_key management keeping track
of only shared keys in endpoints and assocs. Hence, also commit 4184b2a79a76
("net: sctp: fix memory leak in auth key management") is independant of
this bug here since it concerns a different layer (though same structures
being used eventually). asoc->asoc_shared_key is reference dropped correctly
on assoc destruction in sctp_association_free() and when active keys are
being replaced in sctp_auth_asoc_init_active_key(), it always has a refcount
of 1. Hence, it's freed prematurely in sctp_assoc_update(). Simple fix is
to remove that sctp_auth_key_put() from there which fixes these panics.
Fixes: 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing")
Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: Vlad Yasevich <[email protected]>
Acked-by: Neil Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sctp/associola.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 737050f1b2b2..88ca530f1d1a 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1282,7 +1282,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
asoc->peer.peer_hmacs = new->peer.peer_hmacs;
new->peer.peer_hmacs = NULL;
- sctp_auth_key_put(asoc->asoc_shared_key);
sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
}
--
2.2.2
From: Hannes Frederic Sowa <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit df4d92549f23e1c037e83323aff58a21b3de7fe0 ]
Not caching dst_entries which cause redirects could be exploited by hosts
on the same subnet, causing a severe DoS attack. This effect aggravated
since commit f88649721268999 ("ipv4: fix dst race in sk_dst_get()").
Lookups causing redirects will be allocated with DST_NOCACHE set which
will force dst_release to free them via RCU. Unfortunately waiting for
RCU grace period just takes too long, we can end up with >1M dst_entries
waiting to be released and the system will run OOM. rcuos threads cannot
catch up under high softirq load.
Attaching the flag to emit a redirect later on to the specific skb allows
us to cache those dst_entries thus reducing the pressure on allocation
and deallocation.
This issue was discovered by Marcelo Leitner.
Cc: Julian Anastasov <[email protected]>
Signed-off-by: Marcelo Leitner <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: Julian Anastasov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/net/ip.h | 11 ++++++-----
net/ipv4/ip_forward.c | 3 ++-
net/ipv4/route.c | 9 +++++----
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 53573e06cf87..f12cb2f0cddd 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -37,11 +37,12 @@ struct inet_skb_parm {
struct ip_options opt; /* Compiled IP options */
unsigned char flags;
-#define IPSKB_FORWARDED 1
-#define IPSKB_XFRM_TUNNEL_SIZE 2
-#define IPSKB_XFRM_TRANSFORMED 4
-#define IPSKB_FRAG_COMPLETE 8
-#define IPSKB_REROUTED 16
+#define IPSKB_FORWARDED BIT(0)
+#define IPSKB_XFRM_TUNNEL_SIZE BIT(1)
+#define IPSKB_XFRM_TRANSFORMED BIT(2)
+#define IPSKB_FRAG_COMPLETE BIT(3)
+#define IPSKB_REROUTED BIT(4)
+#define IPSKB_DOREDIRECT BIT(5)
u16 frag_max_size;
};
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index bd1c5baf69be..31ee5c6033df 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -175,7 +175,8 @@ int ip_forward(struct sk_buff *skb)
* We now generate an ICMP HOST REDIRECT giving the route
* we calculated.
*/
- if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb))
+ if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr &&
+ !skb_sec_path(skb))
ip_rt_send_redirect(skb);
skb->priority = rt_tos2priority(iph->tos);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f7fe946e534c..3663200b8dba 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1561,11 +1561,10 @@ static int __mkroute_input(struct sk_buff *skb,
do_cache = res->fi && !itag;
if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
+ skb->protocol == htons(ETH_P_IP) &&
(IN_DEV_SHARED_MEDIA(out_dev) ||
- inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) {
- flags |= RTCF_DOREDIRECT;
- do_cache = false;
- }
+ inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
+ IPCB(skb)->flags |= IPSKB_DOREDIRECT;
if (skb->protocol != htons(ETH_P_IP)) {
/* Not IP (i.e. ARP). Do not create route, if it is
@@ -2307,6 +2306,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
if (rt->rt_flags & RTCF_NOTIFY)
r->rtm_flags |= RTM_F_NOTIFY;
+ if (IPCB(skb)->flags & IPSKB_DOREDIRECT)
+ r->rtm_flags |= RTCF_DOREDIRECT;
if (nla_put_be32(skb, RTA_DST, dst))
goto nla_put_failure;
--
2.2.2
From: Herbert Xu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 86f3cddbc3037882414c7308973530167906b7e9 ]
While working on rhashtable walking I noticed that the UDP diag
dumping code is buggy. In particular, the socket skipping within
a chain never happens, even though we record the number of sockets
that should be skipped.
As this code was supposedly copied from TCP, this patch does what
TCP does and resets num before we walk a chain.
Signed-off-by: Herbert Xu <[email protected]>
Acked-by: Pavel Emelyanov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/udp_diag.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 7927db0a9279..4a000f1dd757 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin
s_slot = cb->args[0];
num = s_num = cb->args[1];
- for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) {
+ for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) {
struct sock *sk;
struct hlist_nulls_node *node;
struct udp_hslot *hslot = &table->hash[slot];
+ num = 0;
+
if (hlist_nulls_empty(&hslot->head))
continue;
--
2.2.2
From: "[email protected]" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit fc752f1f43c1c038a2c6ae58cc739ebb5953ccb0 ]
An exception is seen in ICMP ping receive path where the skb
destructor sock_rfree() tries to access a freed socket. This happens
because ping_rcv() releases socket reference with sock_put() and this
internally frees up the socket. Later icmp_rcv() will try to free the
skb and as part of this, skb destructor is called and which leads
to a kernel panic as the socket is freed already in ping_rcv().
-->|exception
-007|sk_mem_uncharge
-007|sock_rfree
-008|skb_release_head_state
-009|skb_release_all
-009|__kfree_skb
-010|kfree_skb
-011|icmp_rcv
-012|ip_local_deliver_finish
Fix this incorrect free by cloning this skb and processing this cloned
skb instead.
This patch was suggested by Eric Dumazet
Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]>
Cc: Eric Dumazet <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/ping.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8bd51f49aa96..81c92f61d77c 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -959,8 +959,11 @@ void ping_rcv(struct sk_buff *skb)
sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
if (sk != NULL) {
+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+
pr_debug("rcv on socket %p\n", sk);
- ping_queue_rcv_skb(sk, skb_get(skb));
+ if (skb2)
+ ping_queue_rcv_skb(sk, skb2);
sock_put(sk);
return;
}
--
2.2.2
From: Hannes Frederic Sowa <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 6e9e16e6143b725662e47026a1d0f270721cdd24 ]
Lubomir Rintel reported that during replacing a route the interface
reference counter isn't correctly decremented.
To quote bug <https://bugzilla.kernel.org/show_bug.cgi?id=91941>:
| [root@rhel7-5 lkundrak]# sh -x lal
| + ip link add dev0 type dummy
| + ip link set dev0 up
| + ip link add dev1 type dummy
| + ip link set dev1 up
| + ip addr add 2001:db8:8086::2/64 dev dev0
| + ip route add 2001:db8:8086::/48 dev dev0 proto static metric 20
| + ip route add 2001:db8:8088::/48 dev dev1 proto static metric 10
| + ip route replace 2001:db8:8086::/48 dev dev1 proto static metric 20
| + ip link del dev0 type dummy
| Message from syslogd@rhel7-5 at Jan 23 10:54:41 ...
| kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2
|
| Message from syslogd@rhel7-5 at Jan 23 10:54:51 ...
| kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2
During replacement of a rt6_info we must walk all parent nodes and check
if the to be replaced rt6_info got propagated. If so, replace it with
an alive one.
Fixes: 4a287eba2de3957 ("IPv6 routing, NLM_F_* flag support: REPLACE and EXCL flags support, warn about missing CREATE flag")
Reported-by: Lubomir Rintel <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Tested-by: Lubomir Rintel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/ip6_fib.c | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 5e30677953d7..c2ef79957ae0 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -638,6 +638,29 @@ static inline bool rt6_qualify_for_ecmp(struct rt6_info *rt)
RTF_GATEWAY;
}
+static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
+ struct net *net)
+{
+ if (atomic_read(&rt->rt6i_ref) != 1) {
+ /* This route is used as dummy address holder in some split
+ * nodes. It is not leaked, but it still holds other resources,
+ * which must be released in time. So, scan ascendant nodes
+ * and replace dummy references to this route with references
+ * to still alive ones.
+ */
+ while (fn) {
+ if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) {
+ fn->leaf = fib6_find_prefix(net, fn);
+ atomic_inc(&fn->leaf->rt6i_ref);
+ rt6_release(rt);
+ }
+ fn = fn->parent;
+ }
+ /* No more references are possible at this point. */
+ BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
+ }
+}
+
/*
* Insert routing information in a node.
*/
@@ -775,11 +798,12 @@ add:
rt->dst.rt6_next = iter->dst.rt6_next;
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
- rt6_release(iter);
if (!(fn->fn_flags & RTN_RTINFO)) {
info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
fn->fn_flags |= RTN_RTINFO;
}
+ fib6_purge_rt(iter, fn, info->nl_net);
+ rt6_release(iter);
}
return 0;
@@ -1284,24 +1308,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
fn = fib6_repair_tree(net, fn);
}
- if (atomic_read(&rt->rt6i_ref) != 1) {
- /* This route is used as dummy address holder in some split
- * nodes. It is not leaked, but it still holds other resources,
- * which must be released in time. So, scan ascendant nodes
- * and replace dummy references to this route with references
- * to still alive ones.
- */
- while (fn) {
- if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) {
- fn->leaf = fib6_find_prefix(net, fn);
- atomic_inc(&fn->leaf->rt6i_ref);
- rt6_release(rt);
- }
- fn = fn->parent;
- }
- /* No more references are possible at this point. */
- BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
- }
+ fib6_purge_rt(rt, fn, net);
inet6_rt_notify(RTM_DELROUTE, rt, info);
rt6_release(rt);
--
2.2.2
From: Govindarajulu Varadarajan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 24e579c8898aa641ede3149234906982290934e5 ]
With the commit d75b1ade567ffab ("net: less interrupt masking in NAPI") napi
repoll is done only when work_done == budget. When in busy_poll is we return 0
in napi_poll. We should return budget.
Signed-off-by: Govindarajulu Varadarajan <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index c3ba4bf20363..d643c18b0f15 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3087,7 +3087,7 @@ int bnx2x_poll(struct napi_struct *napi, int budget)
}
#endif
if (!bnx2x_fp_lock_napi(fp))
- return work_done;
+ return budget;
for_each_cos_in_tx_queue(fp, cos)
if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos]))
--
2.2.2
From: Christoph Hellwig <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 06539d3071067ff146a9bffd1c801fa56d290909 ]
Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/socket.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index c8ca896a9a5a..3afb43efd3e5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -885,9 +885,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
struct sock_iocb *siocb)
{
- if (!is_sync_kiocb(iocb))
- BUG();
-
siocb->kiocb = iocb;
iocb->private = siocb;
return siocb;
--
2.2.2
From: Roopa Prabhu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 59ccaaaa49b5b096cdc1f16706a9f931416b2332 ]
Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
handler does not return any bytes in the skb.
Alternately, the skb->len check can be moved inside rtnl_notify.
For the bridge vlan case described in 92081, there is also a fix needed
in bridge driver to generate a proper notification. Will fix that in
subsequent patch.
v2: rebase patch on net tree
Signed-off-by: Roopa Prabhu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/core/rtnetlink.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f3224755b328..5874dfbb8d90 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2542,12 +2542,16 @@ static int rtnl_bridge_notify(struct net_device *dev, u16 flags)
goto errout;
}
+ if (!skb->len)
+ goto errout;
+
rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
return 0;
errout:
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
- rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+ if (err)
+ rtnl_set_sk_err(net, RTNLGRP_LINK, err);
return err;
}
--
2.2.2
From: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 811230cd853d62f09ed0addd0ce9a1b9b0e13fb5 ]
When I added sk_pacing_rate field, I forgot to initialize its value
in the per cpu unicast_sock used in ip_send_unicast_reply()
This means that for sch_fq users, RST packets, or ACK packets sent
on behalf of TIME_WAIT sockets might be sent to slowly or even dropped
once we reach the per flow limit.
Signed-off-by: Eric Dumazet <[email protected]>
Fixes: 95bd09eb2750 ("tcp: TSO packets automatic sizing")
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/ip_output.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index c2dcee28d071..860c60d94254 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1462,6 +1462,7 @@ static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = {
.sk_wmem_alloc = ATOMIC_INIT(1),
.sk_allocation = GFP_ATOMIC,
.sk_flags = (1UL << SOCK_USE_WRITE_QUEUE),
+ .sk_pacing_rate = ~0U,
},
.pmtudisc = IP_PMTUDISC_WANT,
.uc_ttl = -1,
--
2.2.2
From: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit bdbbb8527b6f6a358dbcb70dac247034d665b8e4 ]
In commit be9f4a44e7d41 ("ipv4: tcp: remove per net tcp_sock")
I tried to address contention on a socket lock, but the solution
I chose was horrible :
commit 3a7c384ffd57e ("ipv4: tcp: unicast_sock should not land outside
of TCP stack") addressed a selinux regression.
commit 0980e56e506b ("ipv4: tcp: set unicast_sock uc_ttl to -1")
took care of another regression.
commit b5ec8eeac46 ("ipv4: fix ip_send_skb()") fixed another regression.
commit 811230cd85 ("tcp: ipv4: initialize unicast_sock sk_pacing_rate")
was another shot in the dark.
Really, just use a proper socket per cpu, and remove the skb_orphan()
call, to re-enable flow control.
This solves a serious problem with FQ packet scheduler when used in
hostile environments, as we do not want to allocate a flow structure
for every RST packet sent in response to a spoofed packet.
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/net/ip.h | 2 +-
include/net/netns/ipv4.h | 1 +
net/ipv4/ip_output.c | 30 +++---------------------------
net/ipv4/tcp_ipv4.c | 37 ++++++++++++++++++++++++++++++++-----
4 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index f12cb2f0cddd..1b1269e13596 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -163,7 +163,7 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
}
-void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
+void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
__be32 saddr, const struct ip_reply_arg *arg,
unsigned int len);
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index bf2ec2202c56..51f347064b53 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -43,6 +43,7 @@ struct netns_ipv4 {
struct inet_peer_base *peers;
struct tcpm_hash_bucket *tcp_metrics_hash;
unsigned int tcp_metrics_hash_log;
+ struct sock * __percpu *tcp_sk;
struct netns_frags frags;
#ifdef CONFIG_NETFILTER
struct xt_table *iptable_filter;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 860c60d94254..52e82e1709e6 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1451,24 +1451,8 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset,
/*
* Generic function to send a packet as reply to another packet.
* Used to send some TCP resets/acks so far.
- *
- * Use a fake percpu inet socket to avoid false sharing and contention.
*/
-static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = {
- .sk = {
- .__sk_common = {
- .skc_refcnt = ATOMIC_INIT(1),
- },
- .sk_wmem_alloc = ATOMIC_INIT(1),
- .sk_allocation = GFP_ATOMIC,
- .sk_flags = (1UL << SOCK_USE_WRITE_QUEUE),
- .sk_pacing_rate = ~0U,
- },
- .pmtudisc = IP_PMTUDISC_WANT,
- .uc_ttl = -1,
-};
-
-void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
+void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
__be32 saddr, const struct ip_reply_arg *arg,
unsigned int len)
{
@@ -1476,9 +1460,8 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
struct ipcm_cookie ipc;
struct flowi4 fl4;
struct rtable *rt = skb_rtable(skb);
+ struct net *net = sock_net(sk);
struct sk_buff *nskb;
- struct sock *sk;
- struct inet_sock *inet;
int err;
if (ip_options_echo(&replyopts.opt.opt, skb))
@@ -1506,15 +1489,11 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
if (IS_ERR(rt))
return;
- inet = &get_cpu_var(unicast_sock);
+ inet_sk(sk)->tos = arg->tos;
- inet->tos = arg->tos;
- sk = &inet->sk;
sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
- sock_net_set(sk, net);
- __skb_queue_head_init(&sk->sk_write_queue);
sk->sk_sndbuf = sysctl_wmem_default;
err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
len, 0, &ipc, &rt, MSG_DONTWAIT);
@@ -1530,13 +1509,10 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
arg->csumoffset) = csum_fold(csum_add(nskb->csum,
arg->csum));
nskb->ip_summed = CHECKSUM_NONE;
- skb_orphan(nskb);
skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
ip_push_pending_frames(sk, &fl4);
}
out:
- put_cpu_var(unicast_sock);
-
ip_rt_put(rt);
}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 45f370302e4d..aae282839bde 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -690,7 +690,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
net = dev_net(skb_dst(skb)->dev);
arg.tos = ip_hdr(skb)->tos;
- ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr,
+ ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
+ skb, ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
@@ -773,7 +774,8 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
if (oif)
arg.bound_dev_if = oif;
arg.tos = tos;
- ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr,
+ ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
+ skb, ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
@@ -2828,14 +2830,39 @@ struct proto tcp_prot = {
};
EXPORT_SYMBOL(tcp_prot);
+static void __net_exit tcp_sk_exit(struct net *net)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu));
+ free_percpu(net->ipv4.tcp_sk);
+}
+
static int __net_init tcp_sk_init(struct net *net)
{
+ int res, cpu;
+
+ net->ipv4.tcp_sk = alloc_percpu(struct sock *);
+ if (!net->ipv4.tcp_sk)
+ return -ENOMEM;
+
+ for_each_possible_cpu(cpu) {
+ struct sock *sk;
+
+ res = inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW,
+ IPPROTO_TCP, net);
+ if (res)
+ goto fail;
+ *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk;
+ }
net->ipv4.sysctl_tcp_ecn = 2;
return 0;
-}
-static void __net_exit tcp_sk_exit(struct net *net)
-{
+fail:
+ tcp_sk_exit(net);
+
+ return res;
}
static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list)
--
2.2.2
From: Florian Westphal <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit e2a4800e75780ccf4e6c2487f82b688ba736eb18 ]
When we've run out of space in the output buffer to store more data, we
will call zlib_deflate with a NULL output buffer until we've consumed
remaining input.
When this happens, olen contains the size the output buffer would have
consumed iff we'd have had enough room.
This can later cause skb_over_panic when ppp_generic skb_put()s
the returned length.
Reported-by: Iain Douglas <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ppp/ppp_deflate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c
index 602c625d95d5..b5edc7f96a39 100644
--- a/drivers/net/ppp/ppp_deflate.c
+++ b/drivers/net/ppp/ppp_deflate.c
@@ -246,7 +246,7 @@ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
/*
* See if we managed to reduce the size of the packet.
*/
- if (olen < isize) {
+ if (olen < isize && olen <= osize) {
state->stats.comp_bytes += olen;
state->stats.comp_packets++;
} else {
--
2.2.2
From: Saran Maruti Ramanara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit cfbf654efc6d78dc9812e030673b86f235bf677d ]
When making use of RFC5061, section 4.2.4. for setting the primary IP
address, we're passing a wrong parameter header to param_type2af(),
resulting always in NULL being returned.
At this point, param.p points to a sctp_addip_param struct, containing
a sctp_paramhdr (type = 0xc004, length = var), and crr_id as a correlation
id. Followed by that, as also presented in RFC5061 section 4.2.4., comes
the actual sctp_addr_param, which also contains a sctp_paramhdr, but
this time with the correct type SCTP_PARAM_IPV{4,6}_ADDRESS that
param_type2af() can make use of. Since we already hold a pointer to
addr_param from previous line, just reuse it for param_type2af().
Fixes: d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT")
Signed-off-by: Saran Maruti Ramanara <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: Vlad Yasevich <[email protected]>
Acked-by: Neil Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sctp/sm_make_chunk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index d800160f974c..eb5012b03cfb 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2621,7 +2621,7 @@ do_addr_param:
addr_param = param.v + sizeof(sctp_addip_param_t);
- af = sctp_get_af_specific(param_type2af(param.p->type));
+ af = sctp_get_af_specific(param_type2af(addr_param->p.type));
if (af == NULL)
break;
--
2.2.2
From: Alex Elder <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 638c323c4d1f8eaf25224946e21ce8818f1bcee1 upstream.
Olivier Bonvalet reported having repeated crashes due to a failed
assertion he was hitting in rbd_img_obj_callback():
Assertion failure in rbd_img_obj_callback() at line 2165:
rbd_assert(which >= img_request->next_completion);
With a lot of help from Olivier with reproducing the problem
we were able to determine the object and image requests had
already been completed (and often freed) at the point the
assertion failed.
There was a great deal of discussion on the ceph-devel mailing list
about this. The problem only arose when there were two (or more)
object requests in an image request, and the problem was always
seen when the second request was being completed.
The problem is due to a race in the window between setting the
"done" flag on an object request and checking the image request's
next completion value. When the first object request completes, it
checks to see if its successor request is marked "done", and if
so, that request is also completed. In the process, the image
request's next_completion value is updated to reflect that both
the first and second requests are completed. By the time the
second request is able to check the next_completion value, it
has been set to a value *greater* than its own "which" value,
which caused an assertion to fail.
Fix this problem by skipping over any completion processing
unless the completing object request is the next one expected.
Test only for inequality (not >=), and eliminate the bad
assertion.
Tested-by: Olivier Bonvalet <[email protected]>
Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Sage Weil <[email protected]>
Reviewed-by: Ilya Dryomov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/block/rbd.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 5544f254175d..2eb4458f4ba8 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2137,7 +2137,6 @@ static void rbd_img_obj_callback(struct rbd_obj_request *obj_request)
rbd_assert(img_request->obj_request_count > 0);
rbd_assert(which != BAD_WHICH);
rbd_assert(which < img_request->obj_request_count);
- rbd_assert(which >= img_request->next_completion);
spin_lock_irq(&img_request->completion_lock);
if (which != img_request->next_completion)
--
2.2.2
From: Austin Lund <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a8f29e89f2b54fbf2c52be341f149bc195b63a8b upstream.
Userspace expects to see a long space before the first pulse is sent on
the lirc device. Currently, if a long time has passed and a new packet
is started, the lirc codec just returns and doesn't send anything. This
makes lircd ignore many perfectly valid signals unless they are sent in
quick sucession. When a reset event is delivered, we cannot know
anything about the duration of the space. But it should be safe to
assume it has been a long time and we just set the duration to maximum.
Signed-off-by: Austin Lund <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/rc/ir-lirc-codec.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index ed2c8a1ed8ca..98893a8332c7 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
return -EINVAL;
/* Packet start */
- if (ev.reset)
- return 0;
+ if (ev.reset) {
+ /* Userspace expects a long space event before the start of
+ * the signal to use as a sync. This may be done with repeat
+ * packets and normal samples. But if a reset has been sent
+ * then we assume that a long time has passed, so we send a
+ * space with the maximum time value. */
+ sample = LIRC_SPACE(LIRC_VALUE_MASK);
+ IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
/* Carrier reports */
- if (ev.carrier_report) {
+ } else if (ev.carrier_report) {
sample = LIRC_FREQUENCY(ev.carrier);
IR_dprintk(2, "carrier report (freq: %d)\n", sample);
--
2.2.2
From: Adam Lee <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c561a5753dd631920c4459a067d22679b3d110d6 upstream.
BugLink: https://bugs.launchpad.net/bugs/1400215
ath3k devices fail to load firmwares on xHCI buses, but work well on
EHCI, this might be a compatibility issue between xHCI and ath3k chips.
As my testing result, those chips will work on xHCI buses again with
this patch.
This workaround is from Qualcomm, they also did some workarounds in
Windows driver.
Signed-off-by: Adam Lee <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/bluetooth/ath3k.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 1685b3c50db1..fa6a79009724 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -168,6 +168,8 @@ static struct usb_device_id ath3k_blist_tbl[] = {
#define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096
#define FW_HDR_SIZE 20
+#define TIMEGAP_USEC_MIN 50
+#define TIMEGAP_USEC_MAX 100
static int ath3k_load_firmware(struct usb_device *udev,
const struct firmware *firmware)
@@ -198,6 +200,9 @@ static int ath3k_load_firmware(struct usb_device *udev,
count -= 20;
while (count) {
+ /* workaround the compatibility issue with xHCI controller*/
+ usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
+
size = min_t(uint, count, BULK_SIZE);
pipe = usb_sndbulkpipe(udev, 0x02);
memcpy(send_buf, firmware->data + sent, size);
@@ -294,6 +299,9 @@ static int ath3k_load_fwfile(struct usb_device *udev,
count -= size;
while (count) {
+ /* workaround the compatibility issue with xHCI controller*/
+ usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
+
size = min_t(uint, count, BULK_SIZE);
pipe = usb_sndbulkpipe(udev, 0x02);
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dd598091de4aabbc8bd7290a04f364e443c03455 upstream.
The KVM emulator code assumes that the guest virtual address space (in 64-bit)
is 48-bits wide. Since we are about to add more code that makes the same
assumption, this patch adds an assertion to make sure guest virtual address
space is indeed 48-bits wide.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Bruce Rogers <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/cpuid.c | 19 ++++++++++++-------
arch/x86/kvm/cpuid.h | 2 +-
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index b110fe6c03d4..b132551528e5 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -23,14 +23,14 @@
#include "mmu.h"
#include "trace.h"
-void kvm_update_cpuid(struct kvm_vcpu *vcpu)
+int kvm_update_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
struct kvm_lapic *apic = vcpu->arch.apic;
best = kvm_find_cpuid_entry(vcpu, 1, 0);
if (!best)
- return;
+ return 0;
/* Update OSXSAVE bit */
if (cpu_has_xsave && best->function == 0x1) {
@@ -46,7 +46,15 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu)
apic->lapic_timer.timer_mode_mask = 1 << 17;
}
+ /* The existing code assumes virtual address is 48-bit in the canonical
+ * address checks; exit if it is ever changed */
+ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+ if (best && ((best->eax & 0xff00) >> 8) != 48 &&
+ ((best->eax & 0xff00) >> 8) != 0)
+ return -EINVAL;
+
kvm_pmu_cpuid_update(vcpu);
+ return 0;
}
static int is_efer_nx(void)
@@ -109,10 +117,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
}
vcpu->arch.cpuid_nent = cpuid->nent;
cpuid_fix_nx_cap(vcpu);
- r = 0;
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
- kvm_update_cpuid(vcpu);
+ r = kvm_update_cpuid(vcpu);
out_free:
vfree(cpuid_entries);
@@ -136,9 +143,7 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
- kvm_update_cpuid(vcpu);
- return 0;
-
+ r = kvm_update_cpuid(vcpu);
out:
return r;
}
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index b7fd07984888..6c458e37defb 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -3,7 +3,7 @@
#include "x86.h"
-void kvm_update_cpuid(struct kvm_vcpu *vcpu);
+int kvm_update_cpuid(struct kvm_vcpu *vcpu);
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
u32 function, u32 index);
int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d1442d85cc30ea75f7d399474ca738e0bc96f715 upstream.
Far jmp/call/ret may fault while loading a new RIP. Currently KVM does not
handle this case, and may result in failed vm-entry once the assignment is
done. The tricky part of doing so is that loading the new CS affects the
VMCS/VMCB state, so if we fail during loading the new RIP, we are left in
unconsistent state. Therefore, this patch saves on 64-bit the old CS
descriptor and restores it if loading RIP failed.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Bruce Rogers <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/emulate.c | 113 +++++++++++++++++++++++++++++++++----------------
1 file changed, 77 insertions(+), 36 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ab1d45928ce7..fe10e13070b0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1443,7 +1443,8 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
/* Does not support long mode */
static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
- u16 selector, int seg)
+ u16 selector, int seg,
+ struct desc_struct *desc)
{
struct desc_struct seg_desc, old_desc;
u8 dpl, rpl, cpl;
@@ -1570,6 +1571,8 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
}
load:
ctxt->ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
+ if (desc)
+ *desc = seg_desc;
return X86EMUL_CONTINUE;
exception:
emulate_exception(ctxt, err_vec, err_code, true);
@@ -1776,7 +1779,7 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = load_segment_descriptor(ctxt, (u16)selector, seg);
+ rc = load_segment_descriptor(ctxt, (u16)selector, seg, NULL);
return rc;
}
@@ -1865,7 +1868,7 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = load_segment_descriptor(ctxt, cs, VCPU_SREG_CS);
+ rc = load_segment_descriptor(ctxt, cs, VCPU_SREG_CS, NULL);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -1931,7 +1934,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
if (rc != X86EMUL_CONTINUE)
return rc;
- rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS);
+ rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, NULL);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -1970,17 +1973,29 @@ static int em_iret(struct x86_emulate_ctxt *ctxt)
static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
{
int rc;
- unsigned short sel;
+ unsigned short sel, old_sel;
+ struct desc_struct old_desc, new_desc;
+ const struct x86_emulate_ops *ops = ctxt->ops;
+
+ /* Assignment of RIP may only fail in 64-bit mode */
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ ops->get_segment(ctxt, &old_sel, &old_desc, NULL,
+ VCPU_SREG_CS);
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
- rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS);
+ rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, &new_desc);
if (rc != X86EMUL_CONTINUE)
return rc;
- ctxt->_eip = 0;
- memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes);
- return X86EMUL_CONTINUE;
+ rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
+ if (rc != X86EMUL_CONTINUE) {
+ WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
+ /* assigning eip failed; restore the old cs */
+ ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
+ return rc;
+ }
+ return rc;
}
static int em_grp45(struct x86_emulate_ctxt *ctxt)
@@ -2044,21 +2059,33 @@ static int em_ret(struct x86_emulate_ctxt *ctxt)
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
{
int rc;
- unsigned long cs;
+ unsigned long eip, cs;
+ u16 old_cs;
int cpl = ctxt->ops->cpl(ctxt);
+ struct desc_struct old_desc, new_desc;
+ const struct x86_emulate_ops *ops = ctxt->ops;
+
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ ops->get_segment(ctxt, &old_cs, &old_desc, NULL,
+ VCPU_SREG_CS);
- rc = emulate_pop(ctxt, &ctxt->_eip, ctxt->op_bytes);
+ rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
return rc;
- if (ctxt->op_bytes == 4)
- ctxt->_eip = (u32)ctxt->_eip;
rc = emulate_pop(ctxt, &cs, ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
return rc;
/* Outer-privilege level return is not implemented */
if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl)
return X86EMUL_UNHANDLEABLE;
- rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS);
+ rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, &new_desc);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+ rc = assign_eip_far(ctxt, eip, new_desc.l);
+ if (rc != X86EMUL_CONTINUE) {
+ WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
+ ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
+ }
return rc;
}
@@ -2099,7 +2126,7 @@ static int em_lseg(struct x86_emulate_ctxt *ctxt)
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
- rc = load_segment_descriptor(ctxt, sel, seg);
+ rc = load_segment_descriptor(ctxt, sel, seg, NULL);
if (rc != X86EMUL_CONTINUE)
return rc;
@@ -2479,19 +2506,19 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
* Now load segment descriptors. If fault happens at this stage
* it is handled in a context of new task
*/
- ret = load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR);
+ ret = load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES);
+ ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS);
+ ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS);
+ ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS);
+ ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
@@ -2620,25 +2647,26 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
* Now load segment descriptors. If fault happenes at this stage
* it is handled in a context of new task
*/
- ret = load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR);
+ ret = load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR,
+ NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES);
+ ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS);
+ ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS);
+ ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS);
+ ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS);
+ ret = load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
- ret = load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS);
+ ret = load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, NULL);
if (ret != X86EMUL_CONTINUE)
return ret;
@@ -2918,24 +2946,37 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
u16 sel, old_cs;
ulong old_eip;
int rc;
+ struct desc_struct old_desc, new_desc;
+ const struct x86_emulate_ops *ops = ctxt->ops;
- old_cs = get_segment_selector(ctxt, VCPU_SREG_CS);
old_eip = ctxt->_eip;
+ ops->get_segment(ctxt, &old_cs, &old_desc, NULL, VCPU_SREG_CS);
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
- if (load_segment_descriptor(ctxt, sel, VCPU_SREG_CS))
+ rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, &new_desc);
+ if (rc != X86EMUL_CONTINUE)
return X86EMUL_CONTINUE;
- ctxt->_eip = 0;
- memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes);
+ rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
+ if (rc != X86EMUL_CONTINUE)
+ goto fail;
ctxt->src.val = old_cs;
rc = em_push(ctxt);
if (rc != X86EMUL_CONTINUE)
- return rc;
+ goto fail;
ctxt->src.val = old_eip;
- return em_push(ctxt);
+ rc = em_push(ctxt);
+ /* If we failed, we tainted the memory, but the very least we should
+ restore cs */
+ if (rc != X86EMUL_CONTINUE)
+ goto fail;
+ return rc;
+fail:
+ ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
+ return rc;
+
}
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
@@ -3081,7 +3122,7 @@ static int em_mov_sreg_rm(struct x86_emulate_ctxt *ctxt)
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
- return load_segment_descriptor(ctxt, sel, ctxt->modrm_reg);
+ return load_segment_descriptor(ctxt, sel, ctxt->modrm_reg, NULL);
}
static int em_lldt(struct x86_emulate_ctxt *ctxt)
@@ -3090,7 +3131,7 @@ static int em_lldt(struct x86_emulate_ctxt *ctxt)
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
- return load_segment_descriptor(ctxt, sel, VCPU_SREG_LDTR);
+ return load_segment_descriptor(ctxt, sel, VCPU_SREG_LDTR, NULL);
}
static int em_ltr(struct x86_emulate_ctxt *ctxt)
@@ -3099,7 +3140,7 @@ static int em_ltr(struct x86_emulate_ctxt *ctxt)
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
- return load_segment_descriptor(ctxt, sel, VCPU_SREG_TR);
+ return load_segment_descriptor(ctxt, sel, VCPU_SREG_TR, NULL);
}
static int em_invlpg(struct x86_emulate_ctxt *ctxt)
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f7784046ab7cfc1645f4110b6ed14fbdffc2abee upstream.
Breaking grp45 to the relevant functions to speed up the emulation and simplify
the code. In addition, it is necassary the next patch will distinguish between
far and near branches according to the flags.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/emulate.c | 45 ++++++++++++++++++---------------------------
1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index fe10e13070b0..4cb80f2c6fdb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1998,31 +1998,22 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
return rc;
}
-static int em_grp45(struct x86_emulate_ctxt *ctxt)
+static int em_jmp_abs(struct x86_emulate_ctxt *ctxt)
{
- int rc = X86EMUL_CONTINUE;
+ return assign_eip_near(ctxt, ctxt->src.val);
+}
- switch (ctxt->modrm_reg) {
- case 2: /* call near abs */ {
- long int old_eip;
- old_eip = ctxt->_eip;
- rc = assign_eip_near(ctxt, ctxt->src.val);
- if (rc != X86EMUL_CONTINUE)
- break;
- ctxt->src.val = old_eip;
- rc = em_push(ctxt);
- break;
- }
- case 4: /* jmp abs */
- rc = assign_eip_near(ctxt, ctxt->src.val);
- break;
- case 5: /* jmp far */
- rc = em_jmp_far(ctxt);
- break;
- case 6: /* push */
- rc = em_push(ctxt);
- break;
- }
+static int em_call_near_abs(struct x86_emulate_ctxt *ctxt)
+{
+ int rc;
+ long int old_eip;
+
+ old_eip = ctxt->_eip;
+ rc = assign_eip_near(ctxt, ctxt->src.val);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+ ctxt->src.val = old_eip;
+ rc = em_push(ctxt);
return rc;
}
@@ -3655,11 +3646,11 @@ static const struct opcode group4[] = {
static const struct opcode group5[] = {
F(DstMem | SrcNone | Lock, em_inc),
F(DstMem | SrcNone | Lock, em_dec),
- I(SrcMem | Stack, em_grp45),
+ I(SrcMem | Stack, em_call_near_abs),
I(SrcMemFAddr | ImplicitOps | Stack, em_call_far),
- I(SrcMem | Stack, em_grp45),
- I(SrcMemFAddr | ImplicitOps, em_grp45),
- I(SrcMem | Stack, em_grp45), D(Undefined),
+ I(SrcMem | Stack, em_jmp_abs),
+ I(SrcMemFAddr | ImplicitOps, em_jmp_far),
+ I(SrcMem | Stack, em_push), D(Undefined),
};
static const struct opcode group6[] = {
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 58b7075d059f7d37ca86c76fb1446fa3447b9f4f upstream.
In 64-bit, stack operations default to 64-bits, but can be overriden (to
16-bit) using opsize override prefix. In contrast, near-branches are always
64-bit. This patch distinguish between the different behaviors.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Bruce Rogers <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/emulate.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4cb80f2c6fdb..987fdb379df6 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -161,6 +161,7 @@
#define Fastop ((u64)1 << 44) /* Use opcode::u.fastop */
#define NoWrite ((u64)1 << 45) /* No writeback */
#define SrcWrite ((u64)1 << 46) /* Write back src operand */
+#define NearBranch ((u64)1 << 52) /* Near branches */
#define DstXacc (DstAccLo | SrcAccHi | SrcWrite)
@@ -3646,9 +3647,9 @@ static const struct opcode group4[] = {
static const struct opcode group5[] = {
F(DstMem | SrcNone | Lock, em_inc),
F(DstMem | SrcNone | Lock, em_dec),
- I(SrcMem | Stack, em_call_near_abs),
+ I(SrcMem | NearBranch, em_call_near_abs),
I(SrcMemFAddr | ImplicitOps | Stack, em_call_far),
- I(SrcMem | Stack, em_jmp_abs),
+ I(SrcMem | NearBranch, em_jmp_abs),
I(SrcMemFAddr | ImplicitOps, em_jmp_far),
I(SrcMem | Stack, em_push), D(Undefined),
};
@@ -3812,7 +3813,7 @@ static const struct opcode opcode_table[256] = {
I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */
I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */
/* 0x70 - 0x7F */
- X16(D(SrcImmByte)),
+ X16(D(SrcImmByte | NearBranch)),
/* 0x80 - 0x87 */
G(ByteOp | DstMem | SrcImm, group1),
G(DstMem | SrcImm, group1),
@@ -3850,8 +3851,8 @@ static const struct opcode opcode_table[256] = {
X8(I(DstReg | SrcImm64 | Mov, em_mov)),
/* 0xC0 - 0xC7 */
G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2),
- I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
- I(ImplicitOps | Stack, em_ret),
+ I(ImplicitOps | NearBranch | SrcImmU16, em_ret_near_imm),
+ I(ImplicitOps | NearBranch, em_ret),
I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg),
I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg),
G(ByteOp, group11), G(0, group11),
@@ -3872,11 +3873,11 @@ static const struct opcode opcode_table[256] = {
N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N,
/* 0xE0 - 0xE7 */
X3(I(SrcImmByte, em_loop)),
- I(SrcImmByte, em_jcxz),
+ I(SrcImmByte | NearBranch, em_jcxz),
I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in),
I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out),
/* 0xE8 - 0xEF */
- I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps),
+ I(SrcImm | NearBranch, em_call), D(SrcImm | ImplicitOps),
I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps),
I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in),
I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out),
@@ -4356,8 +4357,12 @@ done_prefixes:
if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn)
return EMULATION_FAILED;
- if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack))
- ctxt->op_bytes = 8;
+ if (mode == X86EMUL_MODE_PROT64) {
+ if (ctxt->op_bytes == 4 && (ctxt->d & Stack))
+ ctxt->op_bytes = 8;
+ else if (ctxt->d & NearBranch)
+ ctxt->op_bytes = 8;
+ }
if (ctxt->d & Op3264) {
if (mode == X86EMUL_MODE_PROT64)
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 040c8dc8a5afa7364bb8bb5b1b76c30007d6be14 upstream.
In 64-bit mode a #GP should be delivered to the guest "if the code segment
descriptor pointed to by the selector in the 64-bit gate doesn't have the L-bit
set and the D-bit clear." - Intel SDM "Interrupt 13—General Protection
Exception (#GP)".
This patch fixes the behavior of CS loading emulation code. Although the
comment says that segment loading is not supported in long mode, this function
is executed in long mode, so the fix is necassary.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/emulate.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 987fdb379df6..d28104924255 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1533,6 +1533,15 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
if (rpl > cpl || dpl != cpl)
goto exception;
}
+ /* in long-mode d/b must be clear if l is set */
+ if (seg_desc.d && seg_desc.l) {
+ u64 efer = 0;
+
+ ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+ if (efer & EFER_LMA)
+ goto exception;
+ }
+
/* CS(RPL) <- CPL */
selector = (selector & 0xfffc) | cpl;
break;
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4566654bb9be9e8864df417bb72ceee5136b6a6a upstream.
Guest which sets the PAT CR to invalid value should get a #GP. Currently, if
vmx supports loading PAT CR during entry, then the value is not checked. This
patch makes the required check in that case.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Bruce Rogers <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/vmx.c | 2 ++
arch/x86/kvm/x86.c | 5 +++--
arch/x86/kvm/x86.h | 2 ++
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 4530a72510b2..f5ddacc4c885 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2520,6 +2520,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
break;
case MSR_IA32_CR_PAT:
if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
+ if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
+ return 1;
vmcs_write64(GUEST_IA32_PAT, data);
vcpu->arch.pat = data;
break;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 790551bc4f15..fabb62bad47c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1707,7 +1707,7 @@ static bool valid_mtrr_type(unsigned t)
return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */
}
-static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
int i;
@@ -1733,12 +1733,13 @@ static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
/* variable MTRRs */
return valid_mtrr_type(data & 0xff);
}
+EXPORT_SYMBOL_GPL(kvm_mtrr_valid);
static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
- if (!mtrr_valid(vcpu, msr, data))
+ if (!kvm_mtrr_valid(vcpu, msr, data))
return 1;
if (msr == MSR_MTRRdefType) {
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 7626d3efa064..e2968a500c4e 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -132,6 +132,8 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
gva_t addr, void *val, unsigned int bytes,
struct x86_exception *exception);
+bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+
extern u64 host_xcr0;
extern unsigned int min_timer_period_us;
--
2.2.2
From: Nadav Amit <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit bf0b682c9b6a6d6d54adf439bfe953feef7be2e8 upstream.
If the operand size is not 64-bit, then the sysexit instruction should assign
ECX to RSP and EDX to RIP. The current code assigns the full 64-bits.
Fix it by masking.
Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/emulate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d28104924255..8ab43ac68f06 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2372,6 +2372,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
if ((msr_data & 0xfffc) == 0x0)
return emulate_gp(ctxt, 0);
ss_sel = (u16)(msr_data + 24);
+ rcx = (u32)rcx;
+ rdx = (u32)rdx;
break;
case X86EMUL_MODE_PROT64:
cs_sel = (u16)(msr_data + 32);
--
2.2.2
From: Manfred Spraul <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2e094abfd1f29a08a60523b42d4508281b8dee0e upstream.
When I fixed bugs in the sem_lock() logic, I was more conservative than
necessary. Therefore it is safe to replace the smp_mb() with smp_rmb().
And: With smp_rmb(), semop() syscalls are up to 10% faster.
The race we must protect against is:
sem->lock is free
sma->complex_count = 0
sma->sem_perm.lock held by thread B
thread A:
A: spin_lock(&sem->lock)
B: sma->complex_count++; (now 1)
B: spin_unlock(&sma->sem_perm.lock);
A: spin_is_locked(&sma->sem_perm.lock);
A: XXXXX memory barrier
A: if (sma->complex_count == 0)
Thread A must read the increased complex_count value, i.e. the read must
not be reordered with the read of sem_perm.lock done by spin_is_locked().
Since it's about ordering of reads, smp_rmb() is sufficient.
[[email protected]: update sem_lock() comment, from Davidlohr]
Signed-off-by: Manfred Spraul <[email protected]>
Reviewed-by: Davidlohr Bueso <[email protected]>
Acked-by: Rafael Aquini <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
ipc/sem.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/ipc/sem.c b/ipc/sem.c
index db9d241af133..0c312ac04e49 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -326,10 +326,17 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
/* Then check that the global lock is free */
if (!spin_is_locked(&sma->sem_perm.lock)) {
- /* spin_is_locked() is not a memory barrier */
- smp_mb();
+ /*
+ * The ipc object lock check must be visible on all
+ * cores before rechecking the complex count. Otherwise
+ * we can race with another thread that does:
+ * complex_count++;
+ * spin_unlock(sem_perm.lock);
+ */
+ smp_rmb();
- /* Now repeat the test of complex_count:
+ /*
+ * Now repeat the test of complex_count:
* It can't change anymore until we drop sem->lock.
* Thus: if is now 0, then it will stay 0.
*/
--
2.2.2
From: Len Brown <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2194324d8bbbad1b179c08b6095649b06abd62d5 upstream.
Linux uses CPUID.MWAIT.EDX to validate the C-states
reported by ACPI, silently discarding states which
are not supported by the HW.
This test is too restrictive, as some HW now uses
sparse sub-state numbering, so the sub-state number
may be higher than the number of sub-states...
Also, rather than silently ignoring an invalid state,
we should complain about a firmware bug.
In practice...
Bay Trail systems originally supported C6-no-shrink as
MWAIT sub-state 0x58, and in CPUID.MWAIT.EDX 0x03000000
indicated that there were 3 MWAIT-C6 sub-states.
So acpi_idle would discard that C-state because 8 >= 3.
Upon discovering this issue, the ucode was updated so that
C6-no-shrink was also exported as 0x51, and the BIOS was
updated to match. However, systems shipped with 0x58,
will never get a BIOS update, and this patch allows
Linux to see C6-no-shrink on early Bay Trail.
Signed-off-by: Len Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/acpi/cstate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index d2b7f27781bc..40df29f2b87f 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -87,7 +87,9 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
retval = 0;
- if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) {
+ /* If the HW does not support any sub-states in this C-state */
+ if (num_cstate_subtype == 0) {
+ pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part);
retval = -1;
goto out;
}
--
2.2.2
From: David Rientjes <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c6c8fe79a83e1a03e5dd83d0bac178d6ba5ef30a upstream.
rpc_malloc() allocates with GFP_NOWAIT without making any attempt at
reclaim so it easily fails when low on memory. This ends up spamming the
kernel log:
SLAB: Unable to allocate memory on node 0 (gfp=0x4000)
cache: kmalloc-8192, object size: 8192, order: 1
node 0: slabs: 207/207, objs: 207/207, free: 0
rekonq: page allocation failure: order:1, mode:0x204000
CPU: 2 PID: 14321 Comm: rekonq Tainted: G O 3.15.0-rc3-12.gfc9498b-desktop+ #6
Hardware name: System manufacturer System Product Name/M4A785TD-V EVO, BIOS 2105 07/23/2010
0000000000000000 ffff880010ff17d0 ffffffff815e693c 0000000000204000
ffff880010ff1858 ffffffff81137bd2 0000000000000000 0000001000000000
ffff88011ffebc38 0000000000000001 0000000000204000 ffff88011ffea000
Call Trace:
[<ffffffff815e693c>] dump_stack+0x4d/0x6f
[<ffffffff81137bd2>] warn_alloc_failed+0xd2/0x140
[<ffffffff8113be19>] __alloc_pages_nodemask+0x7e9/0xa30
[<ffffffff811824a8>] kmem_getpages+0x58/0x140
[<ffffffff81183de6>] fallback_alloc+0x1d6/0x210
[<ffffffff81183be3>] ____cache_alloc_node+0x123/0x150
[<ffffffff81185953>] __kmalloc+0x203/0x490
[<ffffffffa06b0ee2>] rpc_malloc+0x32/0xa0 [sunrpc]
[<ffffffffa06a6999>] call_allocate+0xb9/0x170 [sunrpc]
[<ffffffffa06b19d8>] __rpc_execute+0x88/0x460 [sunrpc]
[<ffffffffa06b2da9>] rpc_execute+0x59/0xc0 [sunrpc]
[<ffffffffa06a932b>] rpc_run_task+0x6b/0x90 [sunrpc]
[<ffffffffa077b5c1>] nfs4_call_sync_sequence+0x51/0x80 [nfsv4]
[<ffffffffa077d45d>] _nfs4_do_setattr+0x1ed/0x280 [nfsv4]
[<ffffffffa0782a72>] nfs4_do_setattr+0x72/0x180 [nfsv4]
[<ffffffffa078334c>] nfs4_proc_setattr+0xbc/0x140 [nfsv4]
[<ffffffffa074a7e8>] nfs_setattr+0xd8/0x240 [nfs]
[<ffffffff811baa71>] notify_change+0x231/0x380
[<ffffffff8119cf5c>] chmod_common+0xfc/0x120
[<ffffffff8119df80>] SyS_chmod+0x40/0x90
[<ffffffff815f4cfd>] system_call_fastpath+0x1a/0x1f
...
If the allocation fails, simply return NULL and avoid spamming the kernel
log.
Reported-by: Marc Dietrich <[email protected]>
Signed-off-by: David Rientjes <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/sched.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index ff3cc4bf4b24..5fa4850be6f0 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -831,7 +831,8 @@ static void rpc_async_schedule(struct work_struct *work)
* @size: requested byte size
*
* To prevent rpciod from hanging, this allocator never sleeps,
- * returning NULL if the request cannot be serviced immediately.
+ * returning NULL and suppressing warning if the request cannot be serviced
+ * immediately.
* The caller can arrange to sleep in a way that is safe for rpciod.
*
* Most requests are 'small' (under 2KiB) and can be serviced from a
@@ -844,7 +845,7 @@ static void rpc_async_schedule(struct work_struct *work)
void *rpc_malloc(struct rpc_task *task, size_t size)
{
struct rpc_buffer *buf;
- gfp_t gfp = GFP_NOWAIT;
+ gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;
if (RPC_IS_SWAPPER(task))
gfp |= __GFP_MEMALLOC;
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 561ec1603171cd9b38dcf6cac53e8710f437a48d upstream.
Currently, we go directly to call_transmit which sends us to call_status
on error. If we know that the connect attempt failed, we should rather
just jump straight back to call_bind and call_connect.
Ditto for EAGAIN, except do not delay.
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f318a95ec64d..27826e1471ff 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1699,6 +1699,7 @@ call_connect_status(struct rpc_task *task)
dprint_status(task);
trace_rpc_connect_status(task, status);
+ task->tk_status = 0;
switch (status) {
/* if soft mounted, test if we've timed out */
case -ETIMEDOUT:
@@ -1707,12 +1708,14 @@ call_connect_status(struct rpc_task *task)
case -ECONNREFUSED:
case -ECONNRESET:
case -ENETUNREACH:
+ /* retry with existing socket, after a delay */
+ rpc_delay(task, 3*HZ);
if (RPC_IS_SOFTCONN(task))
break;
- /* retry with existing socket, after a delay */
- case 0:
case -EAGAIN:
- task->tk_status = 0;
+ task->tk_action = call_bind;
+ return;
+ case 0:
clnt->cl_stats->netreconn++;
task->tk_action = call_transmit;
return;
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0fe8d04e8c3a1eb49089793e38b60a17cee564e3 upstream.
Currently, xprt_connect_status will convert connection error values such
as ECONNREFUSED, ECONNRESET, ... into EIO, which means that they never
get handled.
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/xprt.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 42ce6bfc729d..92ed62ee5a32 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -745,6 +745,11 @@ static void xprt_connect_status(struct rpc_task *task)
}
switch (task->tk_status) {
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ECONNABORTED:
+ case -ENETUNREACH:
+ case -EHOSTUNREACH:
case -EAGAIN:
dprintk("RPC: %5u xprt_connect_status: retrying\n", task->tk_pid);
break;
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit df2772700c6ee706be7b2fd16c6bf2c1bf63cda0 upstream.
Ensure that call_bind_status, call_connect_status, call_transmit_status and
call_status all are capable of handling ECONNABORTED and EHOSTUNREACH.
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 27826e1471ff..21607ff675c1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1637,6 +1637,7 @@ call_bind_status(struct rpc_task *task)
return;
case -ECONNREFUSED: /* connection problems */
case -ECONNRESET:
+ case -ECONNABORTED:
case -ENOTCONN:
case -EHOSTDOWN:
case -EHOSTUNREACH:
@@ -1707,7 +1708,9 @@ call_connect_status(struct rpc_task *task)
return;
case -ECONNREFUSED:
case -ECONNRESET:
+ case -ECONNABORTED:
case -ENETUNREACH:
+ case -EHOSTUNREACH:
/* retry with existing socket, after a delay */
rpc_delay(task, 3*HZ);
if (RPC_IS_SOFTCONN(task))
@@ -1807,6 +1810,7 @@ call_transmit_status(struct rpc_task *task)
break;
}
case -ECONNRESET:
+ case -ECONNABORTED:
case -ENOTCONN:
case -EPIPE:
rpc_task_force_reencode(task);
@@ -1916,8 +1920,9 @@ call_status(struct rpc_task *task)
xprt_conditional_disconnect(req->rq_xprt,
req->rq_connect_cookie);
break;
- case -ECONNRESET:
case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ECONNABORTED:
rpc_force_rebind(clnt);
rpc_delay(task, 3*HZ);
case -EPIPE:
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 485f2251782f7c44299c491d4676a8a01428d191 upstream.
When the server is unavailable due to a networking error, etc, we want
the RPC client to respect the timeout delays when attempting to reconnect.
Reported-by: Neil Brown <[email protected]>
Fixes: 561ec1603171 (SUNRPC: call_connect_status should recheck bind..)
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 21607ff675c1..9aa12c57f6a7 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1702,10 +1702,6 @@ call_connect_status(struct rpc_task *task)
trace_rpc_connect_status(task, status);
task->tk_status = 0;
switch (status) {
- /* if soft mounted, test if we've timed out */
- case -ETIMEDOUT:
- task->tk_action = call_timeout;
- return;
case -ECONNREFUSED:
case -ECONNRESET:
case -ECONNABORTED:
@@ -1716,7 +1712,9 @@ call_connect_status(struct rpc_task *task)
if (RPC_IS_SOFTCONN(task))
break;
case -EAGAIN:
- task->tk_action = call_bind;
+ /* Check for timeouts before looping back to call_bind */
+ case -ETIMEDOUT:
+ task->tk_action = call_timeout;
return;
case 0:
clnt->cl_stats->netreconn++;
--
2.2.2
From: Steve Dickson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1fa3e2eb9db07f30a605c66d1a2fdde4b24e74d5 upstream.
Don't schedule an rpc_delay before checking to see if the task
is a SOFTCONN because the tk_callback from the delay (__rpc_atrun)
clears the task status before the rpc_exit_task can be run.
Signed-off-by: Steve Dickson <[email protected]>
Fixes: 561ec1603171c (SUNRPC: call_connect_status should recheck...)
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9aa12c57f6a7..285040c71f38 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1707,10 +1707,10 @@ call_connect_status(struct rpc_task *task)
case -ECONNABORTED:
case -ENETUNREACH:
case -EHOSTUNREACH:
- /* retry with existing socket, after a delay */
- rpc_delay(task, 3*HZ);
if (RPC_IS_SOFTCONN(task))
break;
+ /* retry with existing socket, after a delay */
+ rpc_delay(task, 3*HZ);
case -EAGAIN:
/* Check for timeouts before looping back to call_bind */
case -ETIMEDOUT:
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3601c4a91ebbbf1cf69f66a2abeffc6c64a4fe64 upstream.
Currently, an ENOBUFS error will result in a fatal error for the RPC
call. Normally, we will just want to wait and then retry.
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 4 ++++
net/sunrpc/xprtsock.c | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 285040c71f38..07a1d5ad2513 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1642,6 +1642,7 @@ call_bind_status(struct rpc_task *task)
case -EHOSTDOWN:
case -EHOSTUNREACH:
case -ENETUNREACH:
+ case -ENOBUFS:
case -EPIPE:
dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
task->tk_pid, task->tk_status);
@@ -1707,6 +1708,7 @@ call_connect_status(struct rpc_task *task)
case -ECONNABORTED:
case -ENETUNREACH:
case -EHOSTUNREACH:
+ case -ENOBUFS:
if (RPC_IS_SOFTCONN(task))
break;
/* retry with existing socket, after a delay */
@@ -1810,6 +1812,7 @@ call_transmit_status(struct rpc_task *task)
case -ECONNRESET:
case -ECONNABORTED:
case -ENOTCONN:
+ case -ENOBUFS:
case -EPIPE:
rpc_task_force_reencode(task);
}
@@ -1922,6 +1925,7 @@ call_status(struct rpc_task *task)
case -ECONNRESET:
case -ECONNABORTED:
rpc_force_rebind(clnt);
+ case -ENOBUFS:
rpc_delay(task, 3*HZ);
case -EPIPE:
case -ENOTCONN:
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 1d034825fcc3..8f5c4da51a70 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -588,6 +588,7 @@ static int xs_local_send_request(struct rpc_task *task)
}
switch (status) {
+ case -ENOBUFS:
case -EAGAIN:
status = xs_nospace(task);
break;
@@ -655,6 +656,7 @@ static int xs_udp_send_request(struct rpc_task *task)
dprintk("RPC: sendmsg returned unrecognized error %d\n",
-status);
case -ENETUNREACH:
+ case -ENOBUFS:
case -EPIPE:
case -ECONNREFUSED:
/* When the server has died, an ICMP port unreachable message
@@ -752,6 +754,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
status = -ENOTCONN;
/* Should we call xs_close() here? */
break;
+ case -ENOBUFS:
case -EAGAIN:
status = xs_nospace(task);
break;
@@ -1928,6 +1931,7 @@ static int xs_local_setup_socket(struct sock_xprt *transport)
dprintk("RPC: xprt %p connected to %s\n",
xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);
xprt_set_connected(xprt);
+ case -ENOBUFS:
break;
case -ENOENT:
dprintk("RPC: xprt %p: socket %s does not exist\n",
@@ -2251,6 +2255,7 @@ static void xs_tcp_setup_socket(struct work_struct *work)
case -ECONNREFUSED:
case -ECONNRESET:
case -ENETUNREACH:
+ case -ENOBUFS:
/* retry with existing socket, after a delay */
goto out;
}
--
2.2.2
From: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2fc193cf924ea6eb74f6a0cf73b94b2e62938ae5 upstream.
The callback handler xs_error_report() can end up propagating an EPIPE
error by means of the call to xprt_wake_pending_tasks(). Ensure that
xprt_connect_status() does not automatically convert this into an
EIO error.
Reported-by: Weston Andros Adamson <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/clnt.c | 1 +
net/sunrpc/xprt.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 07a1d5ad2513..8724ef857360 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1709,6 +1709,7 @@ call_connect_status(struct rpc_task *task)
case -ENETUNREACH:
case -EHOSTUNREACH:
case -ENOBUFS:
+ case -EPIPE:
if (RPC_IS_SOFTCONN(task))
break;
/* retry with existing socket, after a delay */
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 92ed62ee5a32..8615b9df4968 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -750,6 +750,7 @@ static void xprt_connect_status(struct rpc_task *task)
case -ECONNABORTED:
case -ENETUNREACH:
case -EHOSTUNREACH:
+ case -EPIPE:
case -EAGAIN:
dprintk("RPC: %5u xprt_connect_status: retrying\n", task->tk_pid);
break;
--
2.2.2
From: Goldwyn Rodrigues <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 86b9c6f3f891019b26f8e5bb11a6faa96bba54a8 upstream.
Filesize is not a good indication that the file needs to be synced.
An example where this breaks is:
1. Open the file in O_SYNC|O_RDWR
2. Read a small portion of the file (say 64 bytes)
3. Lseek to starting of the file
4. Write 64 bytes
If the node crashes, it is not written out to disk because this was not
committed in the journal and the other node which reads the file after
recovery reads stale data (even if the write on the other node was
successful)
Signed-off-by: Goldwyn Rodrigues <[email protected]>
Reviewed-by: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ocfs2/file.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f07941160515..cc6e925749de 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2376,9 +2376,7 @@ out_dio:
if (ret < 0)
written = ret;
- if (!ret && ((old_size != i_size_read(inode)) ||
- (old_clusters != OCFS2_I(inode)->ip_clusters) ||
- has_refcount)) {
+ if (!ret) {
ret = jbd2_journal_force_commit(osb->journal->j_journal);
if (ret < 0)
written = ret;
--
2.2.2
From: Jan Kara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e159332b9af4b04d882dbcfe1bb0117f0a6d4b58 upstream.
Verify that inode size is sane when loading inode with data stored in
ICB. Otherwise we may get confused later when working with the inode and
inode size is too big.
CC: [email protected]
Reported-by: Carl Henrik Lunde <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/udf/inode.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 47cacfd2c9af..6ba11cdfbc0b 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1495,6 +1495,24 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
}
+ /* Sanity checks for files in ICB so that we don't get confused later */
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+ /*
+ * For file in ICB data is stored in allocation descriptor
+ * so sizes should match
+ */
+ if (iinfo->i_lenAlloc != inode->i_size) {
+ make_bad_inode(inode);
+ return;
+ }
+ /* File in ICB has to fit in there... */
+ if (inode->i_size > inode->i_sb->s_blocksize -
+ udf_file_entry_alloc_offset(inode)) {
+ make_bad_inode(inode);
+ return;
+ }
+ }
+
switch (fe->icbTag.fileType) {
case ICBTAG_FILE_TYPE_DIRECTORY:
inode->i_op = &udf_dir_inode_operations;
--
2.2.2
From: Jan Kara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0e5cc9a40ada6046e6bc3bdfcd0c0d7e4b706b14 upstream.
Symlink reading code does not check whether the resulting path fits into
the page provided by the generic code. This isn't as easy as just
checking the symlink size because of various encoding conversions we
perform on path. So we have to check whether there is still enough space
in the buffer on the fly.
CC: [email protected]
Reported-by: Carl Henrik Lunde <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/udf/dir.c | 3 ++-
fs/udf/namei.c | 3 ++-
fs/udf/symlink.c | 31 ++++++++++++++++++++++++++-----
fs/udf/udfdecl.h | 3 ++-
fs/udf/unicode.c | 28 ++++++++++++++++------------
5 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index a012c51caffd..a7690b46ce0a 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -167,7 +167,8 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
continue;
}
- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
+ UDF_NAME_LEN);
if (!flen)
continue;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 5f6fc17d6bc5..6de89a4347e1 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -233,7 +233,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
if (!lfi)
continue;
- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
+ UDF_NAME_LEN);
if (flen && udf_match(flen, fname, child->len, child->name))
goto out_ok;
}
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index d89f324bc387..2d0c3720e9af 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -30,13 +30,16 @@
#include <linux/buffer_head.h>
#include "udf_i.h"
-static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
- int fromlen, unsigned char *to)
+static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
+ int fromlen, unsigned char *to, int tolen)
{
struct pathComponent *pc;
int elen = 0;
+ int comp_len;
unsigned char *p = to;
+ /* Reserve one byte for terminating \0 */
+ tolen--;
while (elen < fromlen) {
pc = (struct pathComponent *)(from + elen);
switch (pc->componentType) {
@@ -49,22 +52,37 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
break;
/* Fall through */
case 2:
+ if (tolen == 0)
+ return -ENAMETOOLONG;
p = to;
*p++ = '/';
+ tolen--;
break;
case 3:
+ if (tolen < 3)
+ return -ENAMETOOLONG;
memcpy(p, "../", 3);
p += 3;
+ tolen -= 3;
break;
case 4:
+ if (tolen < 2)
+ return -ENAMETOOLONG;
memcpy(p, "./", 2);
p += 2;
+ tolen -= 2;
/* that would be . - just ignore */
break;
case 5:
- p += udf_get_filename(sb, pc->componentIdent, p,
- pc->lengthComponentIdent);
+ comp_len = udf_get_filename(sb, pc->componentIdent,
+ pc->lengthComponentIdent,
+ p, tolen);
+ p += comp_len;
+ tolen -= comp_len;
+ if (tolen == 0)
+ return -ENAMETOOLONG;
*p++ = '/';
+ tolen--;
break;
}
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
@@ -73,6 +91,7 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
p[-1] = '\0';
else
p[0] = '\0';
+ return 0;
}
static int udf_symlink_filler(struct file *file, struct page *page)
@@ -108,8 +127,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
symlink = bh->b_data;
}
- udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
+ err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE);
brelse(bh);
+ if (err)
+ goto out_unlock_inode;
up_read(&iinfo->i_data_sem);
SetPageUptodate(page);
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index be7dabbbcb49..55d1d194d472 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -201,7 +201,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
}
/* unicode.c */
-extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
+extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *,
+ int);
extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
int);
extern int udf_build_ustr(struct ustr *, dstring *, int);
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 44b815e57f94..d29c06fbf4ce 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -28,7 +28,8 @@
#include "udf_sb.h"
-static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
+static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *,
+ int);
static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
{
@@ -333,8 +334,8 @@ try_again:
return u_len + 1;
}
-int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
- int flen)
+int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
+ uint8_t *dname, int dlen)
{
struct ustr *filename, *unifilename;
int len = 0;
@@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
if (!unifilename)
goto out1;
- if (udf_build_ustr_exact(unifilename, sname, flen))
+ if (udf_build_ustr_exact(unifilename, sname, slen))
goto out2;
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
@@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
} else
goto out2;
- len = udf_translate_to_linux(dname, filename->u_name, filename->u_len,
+ len = udf_translate_to_linux(dname, dlen,
+ filename->u_name, filename->u_len,
unifilename->u_name, unifilename->u_len);
out2:
kfree(unifilename);
@@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname,
#define EXT_MARK '.'
#define CRC_MARK '#'
#define EXT_SIZE 5
+/* Number of chars we need to store generated CRC to make filename unique */
+#define CRC_LEN 5
-static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
- int udfLen, uint8_t *fidName,
- int fidNameLen)
+static int udf_translate_to_linux(uint8_t *newName, int newLen,
+ uint8_t *udfName, int udfLen,
+ uint8_t *fidName, int fidNameLen)
{
int index, newIndex = 0, needsCRC = 0;
int extIndex = 0, newExtIndex = 0, hasExt = 0;
@@ -440,7 +444,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
newExtIndex = newIndex;
}
}
- if (newIndex < 256)
+ if (newIndex < newLen)
newName[newIndex++] = curr;
else
needsCRC = 1;
@@ -468,13 +472,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
}
ext[localExtIndex++] = curr;
}
- maxFilenameLen = 250 - localExtIndex;
+ maxFilenameLen = newLen - CRC_LEN - localExtIndex;
if (newIndex > maxFilenameLen)
newIndex = maxFilenameLen;
else
newIndex = newExtIndex;
- } else if (newIndex > 250)
- newIndex = 250;
+ } else if (newIndex > newLen - CRC_LEN)
+ newIndex = newLen - CRC_LEN;
newName[newIndex++] = CRC_MARK;
valueCRC = crc_itu_t(0, fidName, fidNameLen);
newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
--
2.2.2
From: Jan Kara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e237ec37ec154564f8690c5bd1795339955eeef9 upstream.
Check that length specified in a component of a symlink fits in the
input buffer we are reading. Also properly ignore component length for
component types that do not use it. Otherwise we read memory after end
of buffer for corrupted udf image.
Reported-by: Carl Henrik Lunde <[email protected]>
CC: [email protected]
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/udf/symlink.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 2d0c3720e9af..0422b7b8369f 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -42,14 +42,17 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
tolen--;
while (elen < fromlen) {
pc = (struct pathComponent *)(from + elen);
+ elen += sizeof(struct pathComponent);
switch (pc->componentType) {
case 1:
/*
* Symlink points to some place which should be agreed
* upon between originator and receiver of the media. Ignore.
*/
- if (pc->lengthComponentIdent > 0)
+ if (pc->lengthComponentIdent > 0) {
+ elen += pc->lengthComponentIdent;
break;
+ }
/* Fall through */
case 2:
if (tolen == 0)
@@ -74,6 +77,9 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
/* that would be . - just ignore */
break;
case 5:
+ elen += pc->lengthComponentIdent;
+ if (elen > fromlen)
+ return -EIO;
comp_len = udf_get_filename(sb, pc->componentIdent,
pc->lengthComponentIdent,
p, tolen);
@@ -85,7 +91,6 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
tolen--;
break;
}
- elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
}
if (p > to + 1)
p[-1] = '\0';
--
2.2.2
From: Jesse Barnes <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7bd40c16ccb2cb6877dd00b0e66249c171e6fa43 upstream.
We've always been able to use either method on VLV, but it appears more
recent BIOSes only support the gen6 method, so switch over to that.
References: https://bugs.freedesktop.org/show_bug.cgi?id=71370
Signed-off-by: Jesse Barnes <[email protected]>
Reviewed-by: Ville Syrjälä <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/early-quirks.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 7eb30af8c7a2..69b06c7411ab 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -317,8 +317,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = {
INTEL_I915GM_IDS(gen3_stolen_size),
INTEL_I945G_IDS(gen3_stolen_size),
INTEL_I945GM_IDS(gen3_stolen_size),
- INTEL_VLV_M_IDS(gen3_stolen_size),
- INTEL_VLV_D_IDS(gen3_stolen_size),
+ INTEL_VLV_M_IDS(gen6_stolen_size),
+ INTEL_VLV_D_IDS(gen6_stolen_size),
INTEL_PINEVIEW_IDS(gen3_stolen_size),
INTEL_I965G_IDS(gen3_stolen_size),
INTEL_G33_IDS(gen3_stolen_size),
--
2.2.2
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 91905b6f4afe51e23a3f58df93e4cdc5e49cf40c upstream.
When the parport_pc module is removed from the system, all parport
devices are iterated in parport_pc_exit and removed by a call to
parport_pc_unregister_port. Note that some parport devices have its
'struct device' parent, known as port->dev. And when port->dev is a
platform device, it is destroyed in parport_pc_exit too.
Now, when parport_pc_unregister_port is called for a going port,
drv->detach(port) is called for every parport driver in the system.
ppdev can be one of them. ppdev's detach() tears down its per-port
sysfs directory, which established port->dev as a parent earlier.
But since parport_pc_exit kills port->dev parents before unregisters
ports proper, ppdev's sysfs directory has no living parent anymore.
This results in the following warning:
WARNING: CPU: 1 PID: 785 at fs/sysfs/group.c:219 sysfs_remove_group+0x9b/0xa0
sysfs group ffffffff81c69e20 not found for kobject 'parport1'
Modules linked in: parport_pc(E-) ppdev(E) [last unloaded: ppdev]
CPU: 1 PID: 785 Comm: rmmod Tainted: G W E 3.18.0-rc5-next-20141120+ #824
...
Call Trace:
...
[<ffffffff810aff76>] warn_slowpath_fmt+0x46/0x50
[<ffffffff8123d81b>] sysfs_remove_group+0x9b/0xa0
[<ffffffff814c27e7>] dpm_sysfs_remove+0x57/0x60
[<ffffffff814b6ac9>] device_del+0x49/0x240
[<ffffffff814b6ce2>] device_unregister+0x22/0x70
[<ffffffff814b6dac>] device_destroy+0x3c/0x50
[<ffffffffc012209a>] pp_detach+0x4a/0x60 [ppdev]
[<ffffffff814b32dd>] parport_remove_port+0x11d/0x150
[<ffffffffc0137328>] parport_pc_unregister_port+0x28/0xf0 [parport_pc]
[<ffffffffc0138c0e>] parport_pc_exit+0x76/0x468 [parport_pc]
[<ffffffff81128dbc>] SyS_delete_module+0x18c/0x230
It is also easily reproducible on qemu with two dummy ports '-parallel
/dev/null -parallel /dev/null'.
So switch the order of killing the two structures. But since port is
freed by parport_pc_unregister_port, we have to remember port->dev
in a local variable.
Perhaps nothing worse than the warning happens thanks to the device
refcounting. We *should* be on the safe side.
Signed-off-by: Jiri Slaby <[email protected]>
Reviewed-by: Takashi Iwai <[email protected]>
Tested-by: Martin Pluskal <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/parport/parport_pc.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index b0a0d5389f41..ae50d99883cf 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3312,13 +3312,14 @@ static void __exit parport_pc_exit(void)
while (!list_empty(&ports_list)) {
struct parport_pc_private *priv;
struct parport *port;
+ struct device *dev;
priv = list_entry(ports_list.next,
struct parport_pc_private, list);
port = priv->port;
- if (port->dev && port->dev->bus == &platform_bus_type)
- platform_device_unregister(
- to_platform_device(port->dev));
+ dev = port->dev;
parport_pc_unregister_port(port);
+ if (dev && dev->bus == &platform_bus_type)
+ platform_device_unregister(to_platform_device(dev));
}
}
--
2.2.2
From: Hannes Reinecke <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 41abc4e1af369bb5438eaee398e3beee690cc8ca upstream.
When creating new devices dm_sync_table() calls
synchronize_rcu_expedited(), causing _all_ pending RCU pointers to be
flushed. This causes a latency overhead that is especially noticeable
when creating lots of devices.
And all of this is pointless as there are no old maps to be
disconnected, and hence no stale pointers which would need to be
cleared up.
Signed-off-by: Hannes Reinecke <[email protected]>
Reviewed-by: Mikulas Patocka <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/dm.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index a562d5a4fa9d..2f03e8e10c24 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2253,7 +2253,8 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
set_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
else
clear_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
- dm_sync_table(md);
+ if (old_map)
+ dm_sync_table(md);
return old_map;
}
@@ -2694,7 +2695,8 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
* flush_workqueue(md->wq).
*/
set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
- synchronize_srcu(&md->io_barrier);
+ if (map)
+ synchronize_srcu(&md->io_barrier);
/*
* Stop md->queue before flushing md->wq in case request-based
@@ -2714,7 +2716,8 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
if (noflush)
clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
- synchronize_srcu(&md->io_barrier);
+ if (map)
+ synchronize_srcu(&md->io_barrier);
/* were we interrupted ? */
if (r < 0) {
--
2.2.2
From: Eric Paris <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b138004ea0382bdc6d02599c39392651b4f63889 upstream.
The /sys/fs/selinux/policy file is not valid on big endian systems like
ppc64 or s390. Let's see why:
static int hashtab_cnt(void *key, void *data, void *ptr)
{
int *cnt = ptr;
*cnt = *cnt + 1;
return 0;
}
static int range_write(struct policydb *p, void *fp)
{
size_t nel;
[...]
/* count the number of entries in the hashtab */
nel = 0;
rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
if (rc)
return rc;
buf[0] = cpu_to_le32(nel);
rc = put_entry(buf, sizeof(u32), 1, fp);
So size_t is 64 bits. But then we pass a pointer to it as we do to
hashtab_cnt. hashtab_cnt thinks it is a 32 bit int and only deals with
the first 4 bytes. On x86_64 which is little endian, those first 4
bytes and the least significant, so this works out fine. On ppc64/s390
those first 4 bytes of memory are the high order bits. So at the end of
the call to hashtab_map nel has a HUGE number. But the least
significant 32 bits are all 0's.
We then pass that 64 bit number to cpu_to_le32() which happily truncates
it to a 32 bit number and does endian swapping. But the low 32 bits are
all 0's. So no matter how many entries are in the hashtab, big endian
systems always say there are 0 entries because I screwed up the
counting.
The fix is easy. Use a 32 bit int, as the hashtab_cnt expects, for nel.
Signed-off-by: Eric Paris <[email protected]>
Signed-off-by: Paul Moore <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
security/selinux/ss/policydb.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 4d35eb75f129..ee53ddca587b 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3215,9 +3215,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
static int range_write(struct policydb *p, void *fp)
{
- size_t nel;
__le32 buf[1];
- int rc;
+ int rc, nel;
struct policy_data pd;
pd.p = p;
--
2.2.2
From: James Custer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fa2a79ce6aef5de35a4d50487da35deb6b634944 upstream.
In init_per_cpu(), when get_cpu_topology() fails, init_per_cpu_tunables()
is not called afterwards. This means that bau_control->statp is NULL.
If a user then reads /proc/sgi_uv/ptc_statistics ptc_seq_show() references
a NULL pointer. Therefore, since uv_bau_init calls set_bau_off when
init_per_cpu() fails, we add code that detects when the bau is off in
ptc_seq_show() to avoid referencing a NULL pointer.
Signed-off-by: James Custer <[email protected]>
Cc: Russ Anderson <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/platform/uv/tlb_uv.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index efe4d7220397..a6b5affb024a 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -1367,6 +1367,10 @@ static int ptc_seq_show(struct seq_file *file, void *data)
}
if (cpu < num_possible_cpus() && cpu_online(cpu)) {
bcp = &per_cpu(bau_control, cpu);
+ if (bcp->nobau) {
+ seq_printf(file, "cpu %d bau disabled\n", cpu);
+ return 0;
+ }
stat = bcp->statp;
/* source side statistics */
seq_printf(file,
--
2.2.2
From: Randy Wright <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a4714a898e85205e1118ec923cde43d88eb105f6 upstream.
Use acpi_os_map_generic_address to pre-map the reset register if it is
memory mapped, thereby preventing the BUG_ON() in line 1319 of
mm/vmalloc.c from triggering during panic-triggered reboots.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=77131
Signed-off-by: Randy Wright <[email protected]>
Signed-off-by: David E. Box <[email protected]>
[rjw: Changelog, simplified code]
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/acpi/osl.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d73f85247272..ebe0ea2dff69 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1748,6 +1748,16 @@ acpi_status __init acpi_os_initialize(void)
acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
+ if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) {
+ /*
+ * Use acpi_os_map_generic_address to pre-map the reset
+ * register if it's in system memory.
+ */
+ int rv;
+
+ rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
+ pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
+ }
return AE_OK;
}
@@ -1776,6 +1786,8 @@ acpi_status acpi_os_terminate(void)
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
+ if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)
+ acpi_os_unmap_generic_address(&acpi_gbl_FADT.reset_register);
destroy_workqueue(kacpid_wq);
destroy_workqueue(kacpi_notify_wq);
--
2.2.2
From: Vikas Chaudhary <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 629c27aa0c930b9c67188cfc625bf6cdd2af6764 upstream.
Search for Broadcom specific ibft sign "BIFT"
along with other possible values on UEFI
This patch is fix for regression introduced in
“935a9fee51c945b8942be2d7b4bae069167b4886”.
https://lkml.org/lkml/2011/12/16/353
This impacts Broadcom CNA for iSCSI Boot on UEFI platform.
Signed-off-by: Vikas Chaudhary <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Acked-by: Mike Christie <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/firmware/iscsi_ibft.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 3ee852c9925b..071c2c969eec 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -756,6 +756,7 @@ static const struct {
*/
{ ACPI_SIG_IBFT },
{ "iBFT" },
+ { "BIFT" }, /* Broadcom iSCSI Offload */
};
static void __init acpi_find_ibft_region(void)
--
2.2.2
> +static inline u32 from64to32(u64 x)
> +{
> + /* add up 32-bit and 32-bit for 32+c bit */
> + x = (x & 0xffffffff) + (x >> 32);
> + /* add up carry.. */
> + x = (x & 0xffffffff) + (x >> 32);
> + return (u32)x;
> +}
As a matter of interest, does the compiler optimise away the
second (x & 0xffffffff) ?
The code could just be:
x = (x & 0xffffffff) + (x >> 32);
return x + (x >> 32);
David
On 02/17/2015 04:34 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.38 release.
> There are 122 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 Wed Feb 18 16:19:34 CET 2015.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.38-rc1.xz
> and the diffstat can be found below.
>
> thanks,
> js
>
Compiled and booted on my test systems. No dmesg regressions.
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
[email protected] | (970) 217-8978
On 02/17/2015 03:34 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.38 release.
> There are 122 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 Wed Feb 18 16:19:34 CET 2015.
> Anything received after that time might be too late.
>
Build results:
total: 121 pass: 121 fail: 0
Qemu tests:
total: 27 pass: 27 fail: 0
Details are available at http://server.roeck-us.net:8010/builders.
Guenter
On Tue, Feb 17, 2015 at 12:04:22PM +0000, David Laight wrote:
> > +static inline u32 from64to32(u64 x)
> > +{
> > + /* add up 32-bit and 32-bit for 32+c bit */
> > + x = (x & 0xffffffff) + (x >> 32);
> > + /* add up carry.. */
> > + x = (x & 0xffffffff) + (x >> 32);
> > + return (u32)x;
> > +}
>
> As a matter of interest, does the compiler optimise away the
> second (x & 0xffffffff) ?
> The code could just be:
> x = (x & 0xffffffff) + (x >> 32);
> return x + (x >> 32);
>
On my side, from what I've seen so far, your version results in better
assembly, esp. with clang, but my first version
http://article.gmane.org/gmane.linux.kernel/1875407:
x += (x << 32) + (x >> 32);
return (__force __wsum)(x >> 32);
resulted in even better assembly, I just verified with gcc/clang,
x86_64/ARM and -O1,2,3.
Karl
From: Karl Beldan
> On Tue, Feb 17, 2015 at 12:04:22PM +0000, David Laight wrote:
> > > +static inline u32 from64to32(u64 x)
> > > +{
> > > + /* add up 32-bit and 32-bit for 32+c bit */
> > > + x = (x & 0xffffffff) + (x >> 32);
> > > + /* add up carry.. */
> > > + x = (x & 0xffffffff) + (x >> 32);
> > > + return (u32)x;
> > > +}
> >
> > As a matter of interest, does the compiler optimise away the
> > second (x & 0xffffffff) ?
> > The code could just be:
> > x = (x & 0xffffffff) + (x >> 32);
> > return x + (x >> 32);
> >
>
> On my side, from what I've seen so far, your version results in better
> assembly, esp. with clang, but my first version
> http://article.gmane.org/gmane.linux.kernel/1875407:
> x += (x << 32) + (x >> 32);
> return (__force __wsum)(x >> 32);
> resulted in even better assembly, I just verified with gcc/clang,
> x86_64/ARM and -O1,2,3.
The latter looks to have a shorter dependency chain as well.
Although I'd definitely include a comment saying that it is equivalent
to the two lines in the current patch.
Does either compiler manage to use a rotate for the two shifts?
Using '(x << 32) | (x >> 32)' might convince it to do so.
That would reduce it to three 'real' instructions and a register rename.
David
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
On 02/17/2015, 04:03 PM, Shuah Khan wrote:
> On 02/17/2015 04:34 AM, Jiri Slaby wrote:
>> This is the start of the stable review cycle for the 3.12.38 release.
>> There are 122 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 Wed Feb 18 16:19:34 CET 2015.
>> Anything received after that time might be too late.
>>
>> The whole patch series can be found in one patch at:
>> http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.38-rc1.xz
>> and the diffstat can be found below.
>>
>> thanks,
>> js
>>
>
> Compiled and booted on my test systems. No dmesg regressions.
On 02/17/2015, 06:08 PM, Guenter Roeck wrote:> Build results:
> total: 121 pass: 121 fail: 0
> Qemu tests:
> total: 27 pass: 27 fail: 0
>
> Details are available at http://server.roeck-us.net:8010/builders.
Thank you both!
--
js
suse labs
On Wed, Feb 18, 2015 at 09:40:23AM +0000, David Laight wrote:
> From: Karl Beldan
> > On Tue, Feb 17, 2015 at 12:04:22PM +0000, David Laight wrote:
> > > > +static inline u32 from64to32(u64 x)
> > > > +{
> > > > + /* add up 32-bit and 32-bit for 32+c bit */
> > > > + x = (x & 0xffffffff) + (x >> 32);
> > > > + /* add up carry.. */
> > > > + x = (x & 0xffffffff) + (x >> 32);
> > > > + return (u32)x;
> > > > +}
> > >
> > > As a matter of interest, does the compiler optimise away the
> > > second (x & 0xffffffff) ?
> > > The code could just be:
> > > x = (x & 0xffffffff) + (x >> 32);
> > > return x + (x >> 32);
> > >
> >
> > On my side, from what I've seen so far, your version results in better
> > assembly, esp. with clang, but my first version
> > http://article.gmane.org/gmane.linux.kernel/1875407:
> > x += (x << 32) + (x >> 32);
> > return (__force __wsum)(x >> 32);
> > resulted in even better assembly, I just verified with gcc/clang,
> > x86_64/ARM and -O1,2,3.
>
> The latter looks to have a shorter dependency chain as well.
> Although I'd definitely include a comment saying that it is equivalent
> to the two lines in the current patch.
>
> Does either compiler manage to use a rotate for the two shifts?
> Using '(x << 32) | (x >> 32)' might convince it to do so.
> That would reduce it to three 'real' instructions and a register rename.
>
gcc and clang rotate for tile (just checked gcc) and x86_64, not for arm
(and IMHO rightly so).
Both '|' and '+' yielded the same asm for those 3 archs.
Karl