This is the start of the stable review cycle for the 4.13.4 release.
There are 109 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 Tue Sep 26 20:33:30 UTC 2017.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.13.4-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.13.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.13.4-rc1
Thomas Gleixner <[email protected]>
genirq: Fix cpumask check in __irq_startup_managed()
John Keeping <[email protected]>
genirq/msi: Fix populating multiple interrupts
Thomas Gleixner <[email protected]>
genirq: Make sparse_irq_lock protect what it should protect
Johannes Berg <[email protected]>
mac80211: fix deadlock in driver-managed RX BA session start
Avraham Stern <[email protected]>
mac80211: flush hw_roc_start work before cancelling the ROC
Beni Lev <[email protected]>
mac80211_hwsim: Use proper TX power
Johannes Berg <[email protected]>
mac80211: fix VLAN handling with TXQs
Luca Coelho <[email protected]>
iwlwifi: add workaround to disable wide channels in 5GHz
Peter Zijlstra <[email protected]>
sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs
Michael Lyle <[email protected]>
bcache: fix bch_hprint crash and improve output
Tang Junhui <[email protected]>
bcache: fix for gc and write-back race
Tang Junhui <[email protected]>
bcache: fix sequential large write IO bypass
Tony Asleson <[email protected]>
bcache: Correct return value for sysfs attach errors
Tang Junhui <[email protected]>
bcache: correct cache_dirty_target in __update_writeback_rate()
Tang Junhui <[email protected]>
bcache: do not subtract sectors_to_gc for bypassed IO
Jan Kara <[email protected]>
bcache: Fix leak of bdev reference
Tang Junhui <[email protected]>
bcache: initialize dirty stripes in flash_dev_run()
Takashi Iwai <[email protected]>
ALSA: seq: Cancel pending autoload work at unbinding device
Chanwoo Choi <[email protected]>
PM / devfreq: Fix memory leak when fail to register device
Ulrich Hecht <[email protected]>
media: adv7180: add missing adv7180cp, adv7180st i2c device IDs
Guenter Roeck <[email protected]>
media: uvcvideo: Prevent heap overflow when accessing mapped controls
Gustavo A. R. Silva <[email protected]>
media: venus: fix copy/paste error in return_buf_error
Sean Young <[email protected]>
media: Revert "[media] lirc_dev: remove superfluous get/put_device() calls"
Daniel Mentz <[email protected]>
media: v4l2-compat-ioctl32: Fix timespec conversion
Martin Schwidefsky <[email protected]>
s390/mm: fix race on mm->context.flush_mm
Martin Schwidefsky <[email protected]>
s390/mm: fix local TLB flushing vs. detach of an mm address space
Manfred Spraul <[email protected]>
net/netfilter/nf_conntrack_core: Fix net_conntrack_lock()
Keith Busch <[email protected]>
PCI: pciehp: Report power fault only once until we clear it
Aleksandr Bezzubikov <[email protected]>
PCI: shpchp: Enable bridge bus mastering if MSI is enabled
Jose Abreu <[email protected]>
ARC: Re-enable MMU upon Machine Check exception
Baohong Liu <[email protected]>
tracing: Apply trace_clock changes to instance max buffer
Chunyu Hu <[email protected]>
tracing: Fix clear of RECORDED_TGID flag when disabling trace event
Steven Rostedt (VMware) <[email protected]>
tracing: Add barrier to trace_printk() buffer nesting modification
Steven Rostedt (VMware) <[email protected]>
ftrace: Fix memleak when unregistering dynamic ops when tracing disabled
Steven Rostedt (VMware) <[email protected]>
ftrace: Fix selftest goto location on error
Zev Weiss <[email protected]>
ftrace: Fix debug preempt config name in stack_tracer_{en,dis}able
Anup Patel <[email protected]>
mailbox: bcm-flexrm-mailbox: Fix mask used in CMPL_START_ADDR_VALUE()
Dan Carpenter <[email protected]>
scsi: qla2xxx: Fix an integer overflow in sysfs code
Quinn Tran <[email protected]>
scsi: qla2xxx: Use fabric name for Get Port Speed command
Sawan Chandak <[email protected]>
scsi: qla2xxx: Use BIT_6 to acquire FAWWPN from switch
Michael Hernandez <[email protected]>
scsi: qla2xxx: Fix target multiqueue configuration
Joe Carnuccio <[email protected]>
scsi: qla2xxx: Correction to vha->vref_count timeout
[email protected] <[email protected]>
scsi: qla2xxx: Update fw_started flags at qpair creation.
Hannes Reinecke <[email protected]>
scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE
Hannes Reinecke <[email protected]>
scsi: sg: factor out sg_fill_request_table()
Long Li <[email protected]>
scsi: storvsc: fix memory leak on ring buffer busy
Shivasharan S <[email protected]>
scsi: megaraid_sas: Return pended IOCTLs with cmd_status MFI_STAT_WRONG_STATE in case adapter is dead
Shivasharan S <[email protected]>
scsi: megaraid_sas: Check valid aen class range to avoid kernel panic
Shivasharan S <[email protected]>
scsi: megaraid_sas: set minimum value of resetwaittime to be 1 secs
Shivasharan S <[email protected]>
scsi: megaraid_sas: mismatch of allocated MFI frame size and length exposed in MFI MPT pass through command
Brian King <[email protected]>
scsi: aacraid: Fix command send race condition
Dan Carpenter <[email protected]>
scsi: qedi: off by one in qedi_get_cmd_from_tid()
Steffen Maier <[email protected]>
scsi: zfcp: trace high part of "new" 64 bit SCSI LUN
Steffen Maier <[email protected]>
scsi: zfcp: trace HBA FSF response by default on dismiss or timedout late response
Steffen Maier <[email protected]>
scsi: zfcp: fix payload with full FCP_RSP IU in SCSI trace records
Steffen Maier <[email protected]>
scsi: zfcp: fix missing trace records for early returns in TMF eh handlers
Steffen Maier <[email protected]>
scsi: zfcp: fix passing fsf_req to SCSI trace on TMF to correlate with HBA
Steffen Maier <[email protected]>
scsi: zfcp: fix capping of unsuccessful GPN_FT SAN response trace records
Benjamin Block <[email protected]>
scsi: zfcp: add handling for FCP_RESID_OVER to the fcp ingress path
Steffen Maier <[email protected]>
scsi: zfcp: fix queuecommand for scsi_eh commands when DIX enabled
Bart Van Assche <[email protected]>
skd: Submit requests to firmware before triggering the doorbell
Bart Van Assche <[email protected]>
skd: Avoid that module unloading triggers a use-after-free
NeilBrown <[email protected]>
md/bitmap: disable bitmap_resize for file-backed bitmaps.
Shaohua Li <[email protected]>
md/bitmap: copy correct data for bitmap super
Jens Axboe <[email protected]>
block: directly insert blk-mq request from blk_insert_cloned_request()
Bart Van Assche <[email protected]>
block: Relax a check in blk_start_queue()
Michael Ellerman <[email protected]>
powerpc: Fix DAR reporting when alignment handler faults
John Allen <[email protected]>
powerpc/pseries: Don't attempt to acquire drc during memory hot add for assigned lmbs
Alistair Popple <[email protected]>
powerpc/powernv/npu: Move tlb flush before launching ATSD
Frederic Barrat <[email protected]>
cxl: Fix driver use count
zhangyi (F) <[email protected]>
ext4: fix quota inconsistency during orphan cleanup for read-only mounts
zhangyi (F) <[email protected]>
ext4: fix incorrect quotaoff if the quota feature is enabled
Darrick J. Wong <[email protected]>
ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets
Bjorn Andersson <[email protected]>
wcn36xx: Introduce mutual exclusion of fw configuration
Sebastian Reichel <[email protected]>
regulator: cpcap: Fix standby mode
Stephan Mueller <[email protected]>
crypto: AF_ALG - remove SGL terminator indicator when chaining
Horia Geantă <[email protected]>
crypto: caam/qi - properly set IV after {en,de}crypt
Horia Geantă <[email protected]>
crypto: caam/qi - fix typo in authenc alg driver name
Ard Biesheuvel <[email protected]>
crypto: scompress - don't sleep with preemption disabled
Gary R Hook <[email protected]>
crypto: ccp - Fix XTS-AES-128 support on v5 CCPs
Zhouyi Zhou <[email protected]>
docs: disable KASLR when debugging kernel
Douglas Leung <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.D: Fix accuracy (64-bit case)
Douglas Leung <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.S: Fix accuracy (32-bit case)
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Clean up "maddf_flags" enumeration
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of zero inputs
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of infinite inputs
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
Aleksandar Markovic <[email protected]>
MIPS: math-emu: MINA.<D|S>: Fix some cases of infinity and zero inputs
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of both infinite inputs
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of input values with opposite signs
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MIN>.<D|S>: Fix cases of both inputs negative
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero
Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation
Kai-Heng Feng <[email protected]>
Input: i8042 - add Gigabyte P57 to the keyboard reset table
Daniel Drake <[email protected]>
pinctrl/amd: save pin registers over suspend/resume
Krzysztof Kozlowski <[email protected]>
pinctrl: samsung: Fix NULL pointer exception on external interrupts on S3C24xx
Krzysztof Kozlowski <[email protected]>
pinctrl: samsung: Fix invalid register offset used for Exynos5433 external interrupts
Arnd Bergmann <[email protected]>
tty: fix __tty_insert_flip_char regression
Arnd Bergmann <[email protected]>
tty: improve tty_insert_flip_char() slow path
Arnd Bergmann <[email protected]>
tty: improve tty_insert_flip_char() fast path
Zhang, Jerry <[email protected]>
drm/amdgpu: read reg in each iterator of psp_wait_for loop
Cameron Gutman <[email protected]>
Input: xpad - validate USB endpoint type during probe
Ethan Barnes <[email protected]>
smp/hotplug: Handle removal correctly in cpuhp_store_callbacks()
Paul E. McKenney <[email protected]>
srcu: Provide ordering for CPU not involved in grace period
Majd Dibbiny <[email protected]>
IB/mlx5: Fix cached MR allocation flow
Mike Marciniszyn <[email protected]>
IB/{qib, hfi1}: Avoid flow control testing for RDMA write operation
Alex Estrin <[email protected]>
IB/hfi1: Revert egress pkey check enforcement
Bart Van Assche <[email protected]>
<linux/uaccess.h>: Fix copy_in_user() declaration
Jan Kara <[email protected]>
orangefs: Don't clear SGID when inheriting ACLs
-------------
Diffstat:
Documentation/dev-tools/gdb-kernel-debugging.rst | 6 +-
Makefile | 4 +-
arch/arc/kernel/entry.S | 6 +
arch/arc/mm/tlb.c | 3 -
arch/mips/math-emu/dp_fmax.c | 84 +++++--
arch/mips/math-emu/dp_fmin.c | 86 +++++--
arch/mips/math-emu/dp_maddf.c | 246 +++++++++++++--------
arch/mips/math-emu/ieee754int.h | 4 +
arch/mips/math-emu/ieee754sp.h | 4 +
arch/mips/math-emu/sp_fmax.c | 84 +++++--
arch/mips/math-emu/sp_fmin.c | 86 +++++--
arch/mips/math-emu/sp_maddf.c | 229 +++++++++----------
arch/powerpc/kernel/align.c | 119 ++++++----
arch/powerpc/platforms/powernv/npu-dma.c | 12 +-
arch/powerpc/platforms/pseries/hotplug-memory.c | 4 +
arch/s390/include/asm/mmu.h | 2 +
arch/s390/include/asm/mmu_context.h | 8 +-
arch/s390/include/asm/tlbflush.h | 30 +--
block/blk-core.c | 9 +-
block/blk-mq.c | 16 ++
block/blk-mq.h | 1 +
crypto/algif_skcipher.c | 4 +-
crypto/scompress.c | 4 +-
drivers/block/skd_main.c | 21 +-
drivers/crypto/caam/caamalg_qi.c | 11 +-
drivers/crypto/ccp/ccp-crypto-aes-xts.c | 4 +-
drivers/crypto/ccp/ccp-dev-v5.c | 2 +
drivers/crypto/ccp/ccp-dev.h | 2 +
drivers/crypto/ccp/ccp-ops.c | 43 +++-
drivers/devfreq/devfreq.c | 5 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +-
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 2 -
drivers/infiniband/hw/hfi1/init.c | 1 -
drivers/infiniband/hw/hfi1/rc.c | 3 +-
drivers/infiniband/hw/mlx5/mr.c | 18 +-
drivers/infiniband/hw/qib/qib_rc.c | 4 +-
drivers/input/joystick/xpad.c | 10 +-
drivers/input/serio/i8042-x86ia64io.h | 7 +
drivers/mailbox/bcm-flexrm-mailbox.c | 2 +-
drivers/md/bcache/bcache.h | 1 +
drivers/md/bcache/request.c | 12 +-
drivers/md/bcache/super.c | 7 +-
drivers/md/bcache/sysfs.c | 4 +-
drivers/md/bcache/util.c | 50 +++--
drivers/md/bcache/writeback.c | 20 +-
drivers/md/bcache/writeback.h | 21 +-
drivers/md/bitmap.c | 9 +-
drivers/media/i2c/adv7180.c | 2 +
drivers/media/platform/qcom/venus/helpers.c | 2 +-
drivers/media/rc/lirc_dev.c | 4 +
drivers/media/usb/uvc/uvc_ctrl.c | 7 +
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 +-
drivers/misc/cxl/api.c | 4 +
drivers/misc/cxl/file.c | 8 +-
drivers/net/wireless/ath/wcn36xx/main.c | 52 ++++-
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 3 +
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 62 +++++-
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | 3 +-
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 3 +-
drivers/net/wireless/mac80211_hwsim.c | 2 -
drivers/pci/hotplug/pciehp_hpc.c | 8 +
drivers/pci/hotplug/shpchp_hpc.c | 2 +
drivers/pinctrl/pinctrl-amd.c | 75 +++++++
drivers/pinctrl/pinctrl-amd.h | 1 +
drivers/pinctrl/samsung/pinctrl-exynos.c | 8 +-
drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 37 ++--
drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 40 ++--
drivers/pinctrl/samsung/pinctrl-samsung.c | 6 +
drivers/pinctrl/samsung/pinctrl-samsung.h | 5 +
drivers/regulator/cpcap-regulator.c | 8 +-
drivers/s390/scsi/zfcp_dbf.c | 33 ++-
drivers/s390/scsi/zfcp_dbf.h | 17 +-
drivers/s390/scsi/zfcp_fc.h | 6 +-
drivers/s390/scsi/zfcp_fsf.c | 7 +-
drivers/s390/scsi/zfcp_scsi.c | 16 +-
drivers/scsi/aacraid/aachba.c | 54 ++---
drivers/scsi/megaraid/megaraid_sas_base.c | 16 +-
drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
drivers/scsi/qedi/qedi_main.c | 2 +-
drivers/scsi/qla2xxx/qla_attr.c | 8 +-
drivers/scsi/qla2xxx/qla_gs.c | 2 +-
drivers/scsi/qla2xxx/qla_init.c | 1 +
drivers/scsi/qla2xxx/qla_isr.c | 2 +-
drivers/scsi/qla2xxx/qla_mbx.c | 3 +-
drivers/scsi/qla2xxx/qla_mid.c | 2 +-
drivers/scsi/qla2xxx/qla_target.c | 2 +-
drivers/scsi/sg.c | 64 +++---
drivers/scsi/storvsc_drv.c | 2 +
drivers/tty/tty_buffer.c | 26 +++
fs/ext4/file.c | 4 +-
fs/ext4/super.c | 38 +++-
fs/orangefs/acl.c | 48 ++--
include/linux/ccp.h | 3 +-
include/linux/cpuset.h | 6 +
include/linux/ftrace.h | 4 +-
include/linux/tty_flip.h | 3 +-
include/linux/uaccess.h | 2 +-
include/net/mac80211.h | 15 +-
kernel/cgroup/cpuset.c | 16 +-
kernel/cpu.c | 12 +-
kernel/irq/chip.c | 2 +-
kernel/irq/irqdesc.c | 24 +-
kernel/irq/msi.c | 5 +-
kernel/power/process.c | 5 +-
kernel/rcu/srcutree.c | 9 +
kernel/sched/core.c | 7 +-
kernel/trace/ftrace.c | 10 +-
kernel/trace/trace.c | 10 +-
kernel/trace/trace_events.c | 2 +-
kernel/trace/trace_selftest.c | 2 +-
net/mac80211/agg-rx.c | 32 ++-
net/mac80211/ht.c | 6 +-
net/mac80211/ieee80211_i.h | 4 +
net/mac80211/iface.c | 17 +-
net/mac80211/offchannel.c | 2 +
net/mac80211/tx.c | 36 ++-
net/netfilter/nf_conntrack_core.c | 52 +++--
sound/core/seq_device.c | 3 +
118 files changed, 1550 insertions(+), 752 deletions(-)
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 8a5a90a2a477b86a3dc2eaa5a706db9bfdd647ca upstream.
Sergey noticed a small but fatal mistake in __tty_insert_flip_char,
leading to an oops in an interrupt handler when using any serial
port.
The problem is that I accidentally took the tty_buffer pointer
before calling __tty_buffer_request_room(), which replaces the
buffer. This moves the pointer lookup to the right place after
allocating the new buffer space.
Fixes: 979990c62848 ("tty: improve tty_insert_flip_char() fast path")
Reported-by: Sergey Senozhatsky <[email protected]>
Tested-by: Sergey Senozhatsky <[email protected]>
Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_buffer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -372,12 +372,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fla
*/
int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
{
- struct tty_buffer *tb = port->buf.tail;
+ struct tty_buffer *tb;
int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
if (!__tty_buffer_request_room(port, 1, flags))
return 0;
+ tb = port->buf.tail;
if (~tb->flags & TTYB_NORMAL)
*flag_buf_ptr(tb, tb->used) = flag;
*char_buf_ptr(tb, tb->used++) = ch;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Drake <[email protected]>
commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
unresponsive after suspend/resume. The following error appears during
resume:
i2c_hid i2c-ELAN1300:00: failed to reset device.
The problem here is that i2c_hid does not notice the interrupt being
generated at this point, because the GPIO is no longer configured
for interrupts.
Fix this by saving pinctrl-amd pin registers during suspend and
restoring them at resume time.
Based on code from pinctrl-intel.
Signed-off-by: Daniel Drake <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pinctrl/pinctrl-amd.c | 75 ++++++++++++++++++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-amd.h | 1
2 files changed, 76 insertions(+)
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -36,6 +36,7 @@
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
+#include "core.h"
#include "pinctrl-utils.h"
#include "pinctrl-amd.h"
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
.pin_config_group_set = amd_pinconf_group_set,
};
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{
+ const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+ if (!pd)
+ return false;
+
+ /*
+ * Only restore the pin if it is actually in use by the kernel (or
+ * by userspace).
+ */
+ if (pd->mux_owner || pd->gpio_owner ||
+ gpiochip_line_is_irq(&gpio_dev->gc, pin))
+ return true;
+
+ return false;
+}
+
+int amd_gpio_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
+ struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+ int i;
+
+ for (i = 0; i < desc->npins; i++) {
+ int pin = desc->pins[i].number;
+
+ if (!amd_gpio_should_save(gpio_dev, pin))
+ continue;
+
+ gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4);
+ }
+
+ return 0;
+}
+
+int amd_gpio_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
+ struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+ int i;
+
+ for (i = 0; i < desc->npins; i++) {
+ int pin = desc->pins[i].number;
+
+ if (!amd_gpio_should_save(gpio_dev, pin))
+ continue;
+
+ writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops amd_gpio_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(amd_gpio_suspend,
+ amd_gpio_resume)
+};
+#endif
+
static struct pinctrl_desc amd_pinctrl_desc = {
.pins = kerncz_pins,
.npins = ARRAY_SIZE(kerncz_pins),
@@ -764,6 +828,14 @@ static int amd_gpio_probe(struct platfor
return -EINVAL;
}
+#ifdef CONFIG_PM_SLEEP
+ gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
+ sizeof(*gpio_dev->saved_regs),
+ GFP_KERNEL);
+ if (!gpio_dev->saved_regs)
+ return -ENOMEM;
+#endif
+
gpio_dev->pdev = pdev;
gpio_dev->gc.direction_input = amd_gpio_direction_input;
gpio_dev->gc.direction_output = amd_gpio_direction_output;
@@ -853,6 +925,9 @@ static struct platform_driver amd_gpio_d
.driver = {
.name = "amd_gpio",
.acpi_match_table = ACPI_PTR(amd_gpio_acpi_match),
+#ifdef CONFIG_PM_SLEEP
+ .pm = &amd_gpio_pm_ops,
+#endif
},
.probe = amd_gpio_probe,
.remove = amd_gpio_remove,
--- a/drivers/pinctrl/pinctrl-amd.h
+++ b/drivers/pinctrl/pinctrl-amd.h
@@ -97,6 +97,7 @@ struct amd_gpio {
unsigned int hwbank_num;
struct resource *res;
struct platform_device *pdev;
+ u32 *saved_regs;
};
/* KERNCZ configuration*/
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit af0b0baa89953aed07034725023371b2fa50a1e6 upstream.
When setting the pin function for external interrupts, the driver used
wrong IO memory address base. The pin function register is always under
pctl_base, not the eint_base.
By updating wrong register, the external interrupts for chosen GPIO
would not work at all and some other GPIO might be configured to wrong
value. For example on Exynos5433-based boards, the external interrupts
for gpf{1-5}-X GPIOs should not work at all (driver toggled reserved
registers from ALIVE bank instead).
Platforms other than Exynos5433 should not be affected as eint_base
equals pctl_base in such case.
Fixes: 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank")
Reported-by: Tomasz Figa <[email protected]>
Signed-off-by: Krzysztof Kozlowski <[email protected]>
Reviewed-by: Sylwester Nawrocki <[email protected]>
Tested-by: Sylwester Nawrocki <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pinctrl/samsung/pinctrl-exynos.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -174,10 +174,10 @@ static int exynos_irq_request_resources(
spin_lock_irqsave(&bank->slock, flags);
- con = readl(bank->eint_base + reg_con);
+ con = readl(bank->pctl_base + reg_con);
con &= ~(mask << shift);
con |= EXYNOS_EINT_FUNC << shift;
- writel(con, bank->eint_base + reg_con);
+ writel(con, bank->pctl_base + reg_con);
spin_unlock_irqrestore(&bank->slock, flags);
@@ -202,10 +202,10 @@ static void exynos_irq_release_resources
spin_lock_irqsave(&bank->slock, flags);
- con = readl(bank->eint_base + reg_con);
+ con = readl(bank->pctl_base + reg_con);
con &= ~(mask << shift);
con |= FUNC_INPUT << shift;
- writel(con, bank->eint_base + reg_con);
+ writel(con, bank->pctl_base + reg_con);
spin_unlock_irqrestore(&bank->slock, flags);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit f58e76c1c551c7577b25a6fe493d82f5214331b7 upstream.
copy_in_user() copies data from user-space address @from to user-
space address @to. Hence declare both @from and @to as user-space
pointers.
Fixes: commit d597580d3737 ("generic ...copy_..._user primitives")
Signed-off-by: Bart Van Assche <[email protected]>
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/uaccess.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -156,7 +156,7 @@ copy_to_user(void __user *to, const void
}
#ifdef CONFIG_COMPAT
static __always_inline unsigned long __must_check
-copy_in_user(void __user *to, const void *from, unsigned long n)
+copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
might_fault();
if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n))
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 3444c4eb534c20e44f0d6670b34263efaf8b531f upstream.
Fix the value returned by <MAXA|MINA>.<D|S> fd,fs,ft, if both inputs
are infinite. The previous implementation returned always the value
contained in ft in such cases. The correct behavior is specified
in Mips instruction set manual and is as follows:
fs ft MAXA MINA
---------------------------------
inf inf inf inf
inf -inf inf -inf
-inf inf inf -inf
-inf -inf -inf -inf
A relevant example:
MAXA.S fd,fs,ft:
If fs contains +inf, and ft contains -inf, fd is going to contain
+inf (without this patch, it used to contain -inf).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16884/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmax.c | 4 +++-
arch/mips/math-emu/dp_fmin.c | 4 +++-
arch/mips/math-emu/sp_fmax.c | 4 +++-
arch/mips/math-emu/sp_fmin.c | 4 +++-
4 files changed, 12 insertions(+), 4 deletions(-)
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ie
/*
* Infinity and zero handling
*/
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754dp_inf(xs & ys);
+
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ie
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
return x;
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmina(union ie
/*
* Infinity and zero handling
*/
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754dp_inf(xs | ys);
+
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmina(union ie
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
return x;
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ie
/*
* Infinity and zero handling
*/
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754sp_inf(xs & ys);
+
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ie
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
return x;
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmina(union ie
/*
* Infinity and zero handling
*/
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754sp_inf(xs | ys);
+
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmina(union ie
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
return x;
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Majd Dibbiny <[email protected]>
commit 4c25b7a39005c9243a492b577c3e940eeac36a25 upstream.
When we have a miss in one order of the mkey cache, we try to get
an mkey from a higher order.
We still need to check that the higher order can be used with UMR
before using it. Otherwise, we will get an mkey with 0 entries and
the post send operation that is used to fill it will complete with
the following error:
mlx5_0:dump_cqe:275:(pid 0): dump error cqe
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 0f007806 25000025 49ce59d2
Fixes: 49780d42dfc9 ("IB/mlx5: Expose MR cache for mlx5_ib")
Signed-off-by: Majd Dibbiny <[email protected]>
Reviewed-by: Ilya Lesokhin <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/hw/mlx5/mr.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -48,6 +48,7 @@ enum {
#define MLX5_UMR_ALIGN 2048
static int clean_mr(struct mlx5_ib_mr *mr);
+static int max_umr_order(struct mlx5_ib_dev *dev);
static int use_umr(struct mlx5_ib_dev *dev, int order);
static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
@@ -491,16 +492,18 @@ static struct mlx5_ib_mr *alloc_cached_m
struct mlx5_mr_cache *cache = &dev->cache;
struct mlx5_ib_mr *mr = NULL;
struct mlx5_cache_ent *ent;
+ int last_umr_cache_entry;
int c;
int i;
c = order2idx(dev, order);
- if (c < 0 || c > MAX_UMR_CACHE_ENTRY) {
+ last_umr_cache_entry = order2idx(dev, max_umr_order(dev));
+ if (c < 0 || c > last_umr_cache_entry) {
mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c);
return NULL;
}
- for (i = c; i < MAX_UMR_CACHE_ENTRY; i++) {
+ for (i = c; i <= last_umr_cache_entry; i++) {
ent = &cache->ent[i];
mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
@@ -816,11 +819,16 @@ static int get_octo_len(u64 addr, u64 le
return (npages + 1) / 2;
}
-static int use_umr(struct mlx5_ib_dev *dev, int order)
+static int max_umr_order(struct mlx5_ib_dev *dev)
{
if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset))
- return order <= MAX_UMR_CACHE_ENTRY + 2;
- return order <= MLX5_MAX_UMR_SHIFT;
+ return MAX_UMR_CACHE_ENTRY + 2;
+ return MLX5_MAX_UMR_SHIFT;
+}
+
+static int use_umr(struct mlx5_ib_dev *dev, int order)
+{
+ return order <= max_umr_order(dev);
}
static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Barnes <[email protected]>
commit 0c96b27305faf06c068b45e07d28336c80dac286 upstream.
If cpuhp_store_callbacks() is called for CPUHP_AP_ONLINE_DYN or
CPUHP_BP_PREPARE_DYN, which are the indicators for dynamically allocated
states, then cpuhp_store_callbacks() allocates a new dynamic state. The
first allocation in each range returns CPUHP_AP_ONLINE_DYN or
CPUHP_BP_PREPARE_DYN.
If cpuhp_remove_state() is invoked for one of these states, then there is
no protection against the allocation mechanism. So the removal, which
should clear the callbacks and the name, gets a new state assigned and
clears that one.
As a consequence the state which should be cleared stays initialized. A
consecutive CPU hotplug operation dereferences the state callbacks and
accesses either freed or reused memory, resulting in crashes.
Add a protection against this by checking the name argument for NULL. If
it's NULL it's a removal. If not, it's an allocation.
[ tglx: Added a comment and massaged changelog ]
Fixes: 5b7aa87e0482 ("cpu/hotplug: Implement setup/removal interface")
Signed-off-by: Ethan Barnes <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: "Srivatsa S. Bhat" <[email protected]>
Cc: Sebastian Siewior <[email protected]>
Cc: Paul McKenney <[email protected]>
Link: http://lkml.kernel.org/r/DM2PR04MB398242FC7776D603D9F99C894A60@DM2PR04MB398.namprd04.prod.outlook.com
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/cpu.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1252,7 +1252,17 @@ static int cpuhp_store_callbacks(enum cp
struct cpuhp_step *sp;
int ret = 0;
- if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) {
+ /*
+ * If name is NULL, then the state gets removed.
+ *
+ * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on
+ * the first allocation from these dynamic ranges, so the removal
+ * would trigger a new allocation and clear the wrong (already
+ * empty) state, leaving the callbacks of the to be cleared state
+ * dangling, which causes wreckage on the next hotplug operation.
+ */
+ if (name && (state == CPUHP_AP_ONLINE_DYN ||
+ state == CPUHP_BP_PREPARE_DYN)) {
ret = cpuhp_reserve_state(state);
if (ret < 0)
return ret;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Estrin <[email protected]>
commit ecdb19f4b513033e6f2c4326cd5b81e04393e5e1 upstream.
Current code has some serious flaws. Disarm the flag
pending an appropriate patch.
Fixes: 53526500f301 ("IB/hfi1: Permanently enable P_Key checking in HFI")
Reviewed-by: Mike Marciniszyn <[email protected]>
Signed-off-by: Alex Estrin <[email protected]>
Signed-off-by: Dennis Dalessandro <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/hw/hfi1/init.c | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -483,7 +483,6 @@ void hfi1_init_pportdata(struct pci_dev
ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY;
ppd->part_enforce |= HFI1_PART_ENFORCE_IN;
- ppd->part_enforce |= HFI1_PART_ENFORCE_OUT;
if (loopback) {
hfi1_early_err(&pdev->dev,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Reichel <[email protected]>
commit 91a024e80336528d12b67b5a2e636b9e4467d3ec upstream.
The original patch from Tony uses standby mode bit inverted, which is
not correct. This fixes all instances in the driver code for get & set
mode. This did not yet make problems, since mode has not been changed
by any mainline driver so far.
Fixes: 0ad4c07edd41 ("regulator: cpcap: Add basic regulator support")
Acked-by: Tony Lindgren <[email protected]>
Signed-off-by: Sebastian Reichel <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/regulator/cpcap-regulator.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/regulator/cpcap-regulator.c
+++ b/drivers/regulator/cpcap-regulator.c
@@ -77,6 +77,8 @@
#define CPCAP_BIT_VAUDIO_MODE0 BIT(1)
#define CPCAP_BIT_V_AUDIO_EN BIT(0)
+#define CPCAP_BIT_AUDIO_NORMAL_MODE 0x00
+
/*
* Off mode configuration bit. Used currently only by SW5 on omap4. There's
* the following comment in Motorola Linux kernel tree for it:
@@ -217,7 +219,7 @@ static unsigned int cpcap_regulator_get_
regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
- if (!(value & CPCAP_BIT_AUDIO_LOW_PWR))
+ if (value & CPCAP_BIT_AUDIO_LOW_PWR)
return REGULATOR_MODE_STANDBY;
return REGULATOR_MODE_NORMAL;
@@ -230,10 +232,10 @@ static int cpcap_regulator_set_mode(stru
switch (mode) {
case REGULATOR_MODE_NORMAL:
- value = CPCAP_BIT_AUDIO_LOW_PWR;
+ value = CPCAP_BIT_AUDIO_NORMAL_MODE;
break;
case REGULATOR_MODE_STANDBY:
- value = 0;
+ value = CPCAP_BIT_AUDIO_LOW_PWR;
break;
default:
return -EINVAL;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: zhangyi (F) <[email protected]>
commit b0a5a9589decd07db755d6a8d9c0910d96ff7992 upstream.
Current ext4 quota should always "usage enabled" if the
quota feautre is enabled. But in ext4_orphan_cleanup(), it
turn quotas off directly (used for the older journaled
quota), so we cannot turn it on again via "quotaon" unless
umount and remount ext4.
Simple reproduce:
mkfs.ext4 -O project,quota /dev/vdb1
mount -o prjquota /dev/vdb1 /mnt
chattr -p 123 /mnt
chattr +P /mnt
touch /mnt/aa /mnt/bb
exec 100<>/mnt/aa
rm -f /mnt/aa
sync
echo c > /proc/sysrq-trigger
#reboot and mount
mount -o prjquota /dev/vdb1 /mnt
#query status
quotaon -Ppv /dev/vdb1
#output
quotaon: Cannot find mountpoint for device /dev/vdb1
quotaon: No correct mountpoint specified.
This patch add check for journaled quotas to avoid incorrect
quotaoff when ext4 has quota feautre.
Signed-off-by: zhangyi (F) <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ext4/super.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2442,7 +2442,7 @@ static void ext4_orphan_cleanup(struct s
#ifdef CONFIG_QUOTA
/* Needed for iput() to work correctly and not trash data */
sb->s_flags |= MS_ACTIVE;
- /* Turn on quotas so that they are updated correctly */
+ /* Turn on journaled quotas so that they are updated correctly */
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
if (EXT4_SB(sb)->s_qf_names[i]) {
int ret = ext4_quota_on_mount(sb, i);
@@ -2510,9 +2510,9 @@ static void ext4_orphan_cleanup(struct s
ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
PLURAL(nr_truncates));
#ifdef CONFIG_QUOTA
- /* Turn quotas off */
+ /* Turn off journaled quotas if they were enabled for orphan cleanup */
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
- if (sb_dqopt(sb)->files[i])
+ if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
dquot_quota_off(sb, i);
}
#endif
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Barrat <[email protected]>
commit 197267d0356004a31c4d6b6336598f5dff3301e1 upstream.
cxl keeps a driver use count, which is used with the hash memory model
on p8 to know when to upgrade local TLBIs to global and to trigger
callbacks to manage the MMU for PSL8.
If a process opens a context and closes without attaching or fails the
attachment, the driver use count is never decremented. As a
consequence, TLB invalidations remain global, even if there are no
active cxl contexts.
We should increment the driver use count when the process is attaching
to the cxl adapter, and not on open. It's not needed before the
adapter starts using the context and the use count is decremented on
the detach path, so it makes more sense.
It affects only the user api. The kernel api is already doing The
Right Thing.
Signed-off-by: Frederic Barrat <[email protected]>
Fixes: 7bb5d91a4dda ("cxl: Rework context lifetimes")
Acked-by: Andrew Donnellan <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/misc/cxl/api.c | 4 ++++
drivers/misc/cxl/file.c | 8 +++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -336,6 +336,10 @@ int cxl_start_context(struct cxl_context
mmput(ctx->mm);
}
+ /*
+ * Increment driver use count. Enables global TLBIs for hash
+ * and callbacks to handle the segment table
+ */
cxl_ctx_get();
if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -95,7 +95,6 @@ static int __afu_open(struct inode *inod
pr_devel("afu_open pe: %i\n", ctx->pe);
file->private_data = ctx;
- cxl_ctx_get();
/* indicate success */
rc = 0;
@@ -225,6 +224,12 @@ static long afu_ioctl_start_work(struct
if (ctx->mm)
mmput(ctx->mm);
+ /*
+ * Increment driver use count. Enables global TLBIs for hash
+ * and callbacks to handle the segment table
+ */
+ cxl_ctx_get();
+
trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
@@ -233,6 +238,7 @@ static long afu_ioctl_start_work(struct
cxl_adapter_context_put(ctx->afu->adapter);
put_pid(ctx->pid);
ctx->pid = NULL;
+ cxl_ctx_put();
cxl_context_mm_count_put(ctx);
goto out;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Allen <[email protected]>
commit afb5519fdb346201728040cab4e08ce53e7ff4fd upstream.
Check if an LMB is assigned before attempting to call dlpar_acquire_drc
in order to avoid any unnecessary rtas calls. This substantially
reduces the running time of memory hot add on lpars with large amounts
of memory.
[mpe: We need to explicitly set rc to 0 in the success case, otherwise
the compiler might think we use rc without initialising it.]
Fixes: c21f515c7436 ("powerpc/pseries: Make the acquire/release of the drc for memory a seperate step")
Signed-off-by: John Allen <[email protected]>
Reviewed-by: Nathan Fontenot <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -817,6 +817,9 @@ static int dlpar_memory_add_by_count(u32
return -EINVAL;
for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) {
+ if (lmbs[i].flags & DRCONF_MEM_ASSIGNED)
+ continue;
+
rc = dlpar_acquire_drc(lmbs[i].drc_index);
if (rc)
continue;
@@ -859,6 +862,7 @@ static int dlpar_memory_add_by_count(u32
lmbs[i].base_addr, lmbs[i].drc_index);
lmbs[i].reserved = 0;
}
+ rc = 0;
}
return rc;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 4ddd56b003f251091a67c15ae3fe4a5c5c5e390a upstream.
Calling blk_start_queue() from interrupt context with the queue
lock held and without disabling IRQs, as the skd driver does, is
safe. This patch avoids that loading the skd driver triggers the
following warning:
WARNING: CPU: 11 PID: 1348 at block/blk-core.c:283 blk_start_queue+0x84/0xa0
RIP: 0010:blk_start_queue+0x84/0xa0
Call Trace:
skd_unquiesce_dev+0x12a/0x1d0 [skd]
skd_complete_internal+0x1e7/0x5a0 [skd]
skd_complete_other+0xc2/0xd0 [skd]
skd_isr_completion_posted.isra.30+0x2a5/0x470 [skd]
skd_isr+0x14f/0x180 [skd]
irq_forced_thread_fn+0x2a/0x70
irq_thread+0x144/0x1a0
kthread+0x125/0x140
ret_from_fork+0x2a/0x40
Fixes: commit a038e2536472 ("[PATCH] blk_start_queue() must be called with irq disabled - add warning")
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Paolo 'Blaisorblade' Giarrusso <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Johannes Thumshirn <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
block/blk-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async);
void blk_start_queue(struct request_queue *q)
{
lockdep_assert_held(q->queue_lock);
- WARN_ON(!irqs_disabled());
+ WARN_ON(!in_interrupt() && !irqs_disabled());
WARN_ON_ONCE(q->mq_ops);
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 157f377beb710e84bd8bc7a3c4475c0674ebebd7 upstream.
A NULL pointer crash was reported for the case of having the BFQ IO
scheduler attached to the underlying blk-mq paths of a DM multipath
device. The crash occured in blk_mq_sched_insert_request()'s call to
e->type->ops.mq.insert_requests().
Paolo Valente correctly summarized why the crash occured with:
"the call chain (dm_mq_queue_rq -> map_request -> setup_clone ->
blk_rq_prep_clone) creates a cloned request without invoking
e->type->ops.mq.prepare_request for the target elevator e. The cloned
request is therefore not initialized for the scheduler, but it is
however inserted into the scheduler by blk_mq_sched_insert_request."
All said, a request-based DM multipath device's IO scheduler should be
the only one used -- when the original requests are issued to the
underlying paths as cloned requests they are inserted directly in the
underlying dispatch queue(s) rather than through an additional elevator.
But commit bd166ef18 ("blk-mq-sched: add framework for MQ capable IO
schedulers") switched blk_insert_cloned_request() from using
blk_mq_insert_request() to blk_mq_sched_insert_request(). Which
incorrectly added elevator machinery into a call chain that isn't
supposed to have any.
To fix this introduce a blk-mq private blk_mq_request_bypass_insert()
that blk_insert_cloned_request() calls to insert the request without
involving any elevator that may be attached to the cloned request's
request_queue.
Fixes: bd166ef183c2 ("blk-mq-sched: add framework for MQ capable IO schedulers")
Reported-by: Bart Van Assche <[email protected]>
Tested-by: Mike Snitzer <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
block/blk-core.c | 7 ++++++-
block/blk-mq.c | 16 ++++++++++++++++
block/blk-mq.h | 1 +
3 files changed, 23 insertions(+), 1 deletion(-)
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2330,7 +2330,12 @@ blk_status_t blk_insert_cloned_request(s
if (q->mq_ops) {
if (blk_queue_io_stat(q))
blk_account_io_start(rq, true);
- blk_mq_sched_insert_request(rq, false, true, false, false);
+ /*
+ * Since we have a scheduler attached on the top device,
+ * bypass a potential scheduler on the bottom device for
+ * insert.
+ */
+ blk_mq_request_bypass_insert(rq);
return BLK_STS_OK;
}
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1357,6 +1357,22 @@ void __blk_mq_insert_request(struct blk_
blk_mq_hctx_mark_pending(hctx, ctx);
}
+/*
+ * Should only be used carefully, when the caller knows we want to
+ * bypass a potential IO scheduler on the target device.
+ */
+void blk_mq_request_bypass_insert(struct request *rq)
+{
+ struct blk_mq_ctx *ctx = rq->mq_ctx;
+ struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(rq->q, ctx->cpu);
+
+ spin_lock(&hctx->lock);
+ list_add_tail(&rq->queuelist, &hctx->dispatch);
+ spin_unlock(&hctx->lock);
+
+ blk_mq_run_hw_queue(hctx, false);
+}
+
void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
struct list_head *list)
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -54,6 +54,7 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_s
*/
void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
bool at_head);
+void blk_mq_request_bypass_insert(struct request *rq);
void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
struct list_head *list);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit e8a27f836f165c26f867ece7f31eb5c811692319 upstream.
bitmap_resize() does not work for file-backed bitmaps.
The buffer_heads are allocated and initialized when
the bitmap is read from the file, but resize doesn't
read from the file, it loads from the internal bitmap.
When it comes time to write the new bitmap, the bh is
non-existent and we crash.
The common case when growing an array involves making the array larger,
and that normally means making the bitmap larger. Doing
that inside the kernel is possible, but would need more code.
It is probably easier to require people who use file-backed
bitmaps to remove them and re-add after a reshape.
So this patch disables the resizing of arrays which have
file-backed bitmaps. This is better than crashing.
Reported-by: Zhilong Liu <[email protected]>
Fixes: d60b479d177a ("md/bitmap: add bitmap_resize function to allow bitmap resizing.")
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Shaohua Li <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bitmap.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -2058,6 +2058,11 @@ int bitmap_resize(struct bitmap *bitmap,
long pages;
struct bitmap_page *new_bp;
+ if (bitmap->storage.file && !init) {
+ pr_info("md: cannot resize file-based bitmap\n");
+ return -EINVAL;
+ }
+
if (chunksize == 0) {
/* If there is enough space, leave the chunk size unchanged,
* else increase by factor of two until there is enough space.
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 7277cc67b3916eed47558c64f9c9c0de00a35cda upstream.
Since put_disk() triggers a disk_release() call and since that
last function calls blk_put_queue() if disk->queue != NULL, clear
the disk->queue pointer before calling put_disk(). This avoids
that unloading the skd kernel module triggers the following
use-after-free:
WARNING: CPU: 8 PID: 297 at lib/refcount.c:128 refcount_sub_and_test+0x70/0x80
refcount_t: underflow; use-after-free.
CPU: 8 PID: 297 Comm: kworker/8:1 Not tainted 4.11.10-300.fc26.x86_64 #1
Workqueue: events work_for_cpu_fn
Call Trace:
dump_stack+0x63/0x84
__warn+0xcb/0xf0
warn_slowpath_fmt+0x5a/0x80
refcount_sub_and_test+0x70/0x80
refcount_dec_and_test+0x11/0x20
kobject_put+0x1f/0x50
blk_put_queue+0x15/0x20
disk_release+0xae/0xf0
device_release+0x32/0x90
kobject_release+0x67/0x170
kobject_put+0x2b/0x50
put_disk+0x17/0x20
skd_destruct+0x5c/0x890 [skd]
skd_pci_probe+0x124d/0x13a0 [skd]
local_pci_probe+0x42/0xa0
work_for_cpu_fn+0x14/0x20
process_one_work+0x19e/0x470
worker_thread+0x1dc/0x4a0
kthread+0x125/0x140
ret_from_fork+0x25/0x30
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Johannes Thumshirn <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/block/skd_main.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -4539,15 +4539,16 @@ static void skd_free_disk(struct skd_dev
{
struct gendisk *disk = skdev->disk;
- if (disk != NULL) {
- struct request_queue *q = disk->queue;
+ if (disk && (disk->flags & GENHD_FL_UP))
+ del_gendisk(disk);
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
- if (q)
- blk_cleanup_queue(q);
- put_disk(disk);
+ if (skdev->queue) {
+ blk_cleanup_queue(skdev->queue);
+ skdev->queue = NULL;
+ disk->queue = NULL;
}
+
+ put_disk(disk);
skdev->disk = NULL;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 71b8e45da51a7b64a23378221c0a5868bd79da4f upstream.
Since commit db007fc5e20c ("[SCSI] Command protection operation"),
scsi_eh_prep_cmnd() saves scmd->prot_op and temporarily resets it to
SCSI_PROT_NORMAL.
Other FCP LLDDs such as qla2xxx and lpfc shield their queuecommand()
to only access any of scsi_prot_sg...() if
(scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL).
Do the same thing for zfcp, which introduced DIX support with
commit ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for
DIF/DIX").
Otherwise, TUR SCSI commands as part of scsi_eh likely fail in zfcp,
because the regular SCSI command with DIX protection data, that scsi_eh
re-uses in scsi_send_eh_cmnd(), of course still has
(scsi_prot_sg_count() != 0) and so zfcp sends down bogus requests to the
FCP channel hardware.
This causes scsi_eh_test_devices() to have (finish_cmds == 0)
[not SCSI device is online or not scsi_eh_tur() failed]
so regular SCSI commands, that caused / were affected by scsi_eh,
are moved to work_q and scsi_eh_test_devices() itself returns false.
In turn, it unnecessarily escalates in our case in scsi_eh_ready_devs()
beyond host reset to finally scsi_eh_offline_sdevs()
which sets affected SCSI devices offline with the following kernel message:
"kernel: sd H:0:T:L: Device offlined - not ready after error recovery"
Signed-off-by: Steffen Maier <[email protected]>
Fixes: ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for DIF/DIX")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_fsf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2258,7 +2258,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *
fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
- if (scsi_prot_sg_count(scsi_cmnd)) {
+ if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
+ scsi_prot_sg_count(scsi_cmnd)) {
zfcp_qdio_set_data_div(qdio, &req->qdio_req,
scsi_prot_sg_count(scsi_cmnd));
retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 9fe5d2b2fd30aa8c7827ec62cbbe6d30df4fe3e3 upstream.
Without this fix we get SCSI trace records on task management functions
which cannot be correlated to HBA trace records because all fields
related to the FSF request are empty (zero).
Also, the FCP_RSP_IU is missing as well as any sense data if available.
This was caused by v2.6.14 commit 8a36e4532ea1 ("[SCSI] zfcp: enhancement
of zfcp debug features") introducing trace records for TMFs but
hard coding NULL for a possibly existing TMF FSF request.
The scsi_cmnd scribble is also zero or unrelated for the TMF request
so it also could not lookup a suitable FSF request from there.
A broken example trace record formatted with zfcpdbf from the s390-tools
package:
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : lr_fail
Request ID : 0x0000000000000000
^^^^^^^^^^^^^^^^ no correlation to HBA record
SCSI ID : 0x<scsitarget>
SCSI LUN : 0x<scsilun>
SCSI result : 0x000e0000
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x0000000000000000
SCSI opcode : 2a000017 3bb80000 08000000 00000000
FCP rsp inf cod: 0x00
^^ no TMF response
FCP rsp IU : 00000000 00000000 00000000 00000000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00000000 00000000
^^^^^^^^^^^^^^^^^ no interesting FCP_RSP_IU
Sense len : ...
^^^^^^^^^^^^^^^^^^^^ no sense data length
Sense info : ...
^^^^^^^^^^^^^^^^^^^^ no sense data content, even if present
There are some true cases where we really do not have an FSF request:
"rsl_fai" from zfcp_dbf_scsi_fail_send() called for early
returns / completions in zfcp_scsi_queuecommand(),
"abrt_or", "abrt_bl", "abrt_ru", "abrt_ar" from
zfcp_scsi_eh_abort_handler() where we did not get as far,
"lr_nres", "tr_nres" from zfcp_task_mgmt_function() where we're
successful and do not need to do anything because adapter stopped.
For these cases it's correct to pass NULL for fsf_req to _zfcp_dbf_scsi().
Signed-off-by: Steffen Maier <[email protected]>
Fixes: 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.h | 7 ++++---
drivers/s390/scsi/zfcp_scsi.c | 8 ++++----
2 files changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -2,7 +2,7 @@
* zfcp device driver
* debug feature declarations
*
- * Copyright IBM Corp. 2008, 2016
+ * Copyright IBM Corp. 2008, 2017
*/
#ifndef ZFCP_DBF_H
@@ -401,7 +401,8 @@ void zfcp_dbf_scsi_abort(char *tag, stru
* @flag: indicates type of reset (Target Reset, Logical Unit Reset)
*/
static inline
-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
+void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag,
+ struct zfcp_fsf_req *fsf_req)
{
char tmp_tag[ZFCP_DBF_TAG_LEN];
@@ -411,7 +412,7 @@ void zfcp_dbf_scsi_devreset(char *tag, s
memcpy(tmp_tag, "lr_", 3);
memcpy(&tmp_tag[3], tag, 4);
- _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
+ _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req);
}
/**
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -3,7 +3,7 @@
*
* Interface to Linux SCSI midlayer.
*
- * Copyright IBM Corp. 2002, 2016
+ * Copyright IBM Corp. 2002, 2017
*/
#define KMSG_COMPONENT "zfcp"
@@ -278,7 +278,7 @@ static int zfcp_task_mgmt_function(struc
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
- zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags);
+ zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL);
return SUCCESS;
}
}
@@ -288,10 +288,10 @@ static int zfcp_task_mgmt_function(struc
wait_for_completion(&fsf_req->completion);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
- zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
+ zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req);
retval = FAILED;
} else {
- zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
+ zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req);
zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit fdb7cee3b9e3c561502e58137a837341f10cbf8b upstream.
At the default trace level, we only trace unsuccessful events including
FSF responses.
zfcp_dbf_hba_fsf_response() only used protocol status and FSF status to
decide on an unsuccessful response. However, this is only one of multiple
possible sources determining a failed struct zfcp_fsf_req.
An FSF request can also "fail" if its response runs into an ERP timeout
or if it gets dismissed because a higher level recovery was triggered
[trace tags "erscf_1" or "erscf_2" in zfcp_erp_strategy_check_fsfreq()].
FSF requests with ERP timeout are:
FSF_QTCB_EXCHANGE_CONFIG_DATA, FSF_QTCB_EXCHANGE_PORT_DATA,
FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT or
FSF_QTCB_CLOSE_PHYSICAL_PORT for target ports,
FSF_QTCB_OPEN_LUN, FSF_QTCB_CLOSE_LUN.
One example is slow queue processing which can cause follow-on errors,
e.g. FSF_PORT_ALREADY_OPEN after FSF_QTCB_OPEN_PORT_WITH_DID timed out.
In order to see the root cause, we need to see late responses even if the
channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD.
Example trace records formatted with zfcpdbf from the s390-tools package:
Timestamp : ...
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : fcegpf1
LUN : 0xffffffffffffffff
WWPN : 0x<WWPN>
D_ID : 0x00<D_ID>
Adapter status : 0x5400050b
Port status : 0x41200000
LUN status : 0x00000000
Ready count : 0x00000001
Running count : 0x...
ERP want : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
ERP need : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
|
Timestamp : ... 30 seconds later
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : ...
Record ID : 2
Tag : erscf_2
LUN : 0xffffffffffffffff
WWPN : 0x<WWPN>
D_ID : 0x00<D_ID>
Adapter status : 0x5400050b
Port status : 0x41200000
LUN status : 0x00000000
Request ID : 0x<request_ID>
ERP status : 0x10000000 ZFCP_STATUS_ERP_TIMEDOUT
ERP step : 0x0800 ZFCP_ERP_STEP_PORT_OPENING
ERP action : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
ERP count : 0x00
|
Timestamp : ... later than previous record
Area : HBA
Subarea : 00
Level : 5 > default level => 3 <= default level
Exception : -
CPU ID : 00
Caller : ...
Record ID : 1
Tag : fs_qtcb => fs_rerr
Request ID : 0x<request_ID>
Request status : 0x00001010 ZFCP_STATUS_FSFREQ_DISMISSED
| ZFCP_STATUS_FSFREQ_CLEANUP
FSF cmnd : 0x00000005
FSF sequence no: 0x...
FSF issued : ... > 30 seconds ago
FSF stat : 0x00000000 FSF_GOOD
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001 FSF_PROT_GOOD
Prot stat qual : 00000000 00000000 00000000 00000000
Port handle : 0x...
LUN handle : 0x00000000
QTCB log length: ...
QTCB log info : ...
In case of problems detecting that new responses are waiting on the input
queue, we sooner or later trigger adapter recovery due to an FSF request
timeout (trace tag "fsrth_1").
FSF requests with FSF request timeout are:
typically FSF_QTCB_ABORT_FCP_CMND; but theoretically also
FSF_QTCB_EXCHANGE_CONFIG_DATA or FSF_QTCB_EXCHANGE_PORT_DATA via sysfs,
FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT for WKA ports,
FSF_QTCB_FCP_CMND for task management function (LUN / target reset).
One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD
because the channel filled in the response via DMA into the request's QTCB.
In a theroretical case, inject code can create an erroneous FSF request
on purpose. If data router is enabled, it uses deferred error reporting.
A READ SCSI command can succeed with FSF_PROT_GOOD, FSF_GOOD, and
SAM_STAT_GOOD. But on writing the read data to host memory via DMA,
it can still fail, e.g. if an intentionally wrong scatter list does not
provide enough space. Rather than getting an unsuccessful response,
we get a QDIO activate check which in turn triggers adapter recovery.
One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD
because the channel filled in the response via DMA into the request's QTCB.
Example trace records formatted with zfcpdbf from the s390-tools package:
Timestamp : ...
Area : HBA
Subarea : 00
Level : 6 > default level => 3 <= default level
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : fs_norm => fs_rerr
Request ID : 0x<request_ID2>
Request status : 0x00001010 ZFCP_STATUS_FSFREQ_DISMISSED
| ZFCP_STATUS_FSFREQ_CLEANUP
FSF cmnd : 0x00000001
FSF sequence no: 0x...
FSF issued : ...
FSF stat : 0x00000000 FSF_GOOD
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001 FSF_PROT_GOOD
Prot stat qual : ........ ........ 00000000 00000000
Port handle : 0x...
LUN handle : 0x...
|
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : rsl_err
Request ID : 0x<request_ID2>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x000e0000 DID_TRANSPORT_DISRUPTED
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_ID2>
SCSI opcode : 28... Read(10)
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000000 00000000
^^ SAM_STAT_GOOD
00000000 00000000
Only with luck in both above cases, we could see a follow-on trace record
of an unsuccesful event following a successful but late FSF response with
FSF_PROT_GOOD and FSF_GOOD. Typically this was the case for I/O requests
resulting in a SCSI trace record "rsl_err" with DID_TRANSPORT_DISRUPTED
[On ZFCP_STATUS_FSFREQ_DISMISSED, zfcp_fsf_protstatus_eval() sets
ZFCP_STATUS_FSFREQ_ERROR seen by the request handler functions as failure].
However, the reason for this follow-on trace was invisible because the
corresponding HBA trace record was missing at the default trace level
(by default hidden records with tags "fs_norm", "fs_qtcb", or "fs_open").
On adapter recovery, after we had shut down the QDIO queues, we perform
unsuccessful pseudo completions with flag ZFCP_STATUS_FSFREQ_DISMISSED
for each pending FSF request in zfcp_fsf_req_dismiss_all().
In order to find the root cause, we need to see all pseudo responses even
if the channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD.
Therefore, check zfcp_fsf_req.status for ZFCP_STATUS_FSFREQ_DISMISSED
or ZFCP_STATUS_FSFREQ_ERROR and trace with a new tag "fs_rerr".
It does not matter that there are numerous places which set
ZFCP_STATUS_FSFREQ_ERROR after the location where we trace an FSF response
early. These cases are based on protocol status != FSF_PROT_GOOD or
== FSF_PROT_FSF_STATUS_PRESENTED and are thus already traced by default
as trace tag "fs_perr" or "fs_ferr" respectively.
NB: The trace record with tag "fssrh_1" for status read buffers on dismiss
all remains. zfcp_fsf_req_complete() handles this and returns early.
All other FSF request types are handled separately and as described above.
Signed-off-by: Steffen Maier <[email protected]>
Fixes: 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
Fixes: 2e261af84cdb ("[SCSI] zfcp: Only collect FSF/HBA debug data for matching trace levels")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -323,7 +323,11 @@ void zfcp_dbf_hba_fsf_response(struct zf
{
struct fsf_qtcb *qtcb = req->qtcb;
- if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+ if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
+ ZFCP_STATUS_FSFREQ_ERROR))) {
+ zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req);
+
+ } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
(qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 5d4a3d0a2ff23799b956e5962b886287614e7fad upstream.
Complements debugging aspects of the otherwise functionally complete
v3.17 commit 9cb78c16f5da ("scsi: use 64-bit LUNs").
While I don't have access to a target exporting 3 or 4 level LUNs,
I did test it by explicitly attaching a non-existent fake 4 level LUN
by means of zfcp sysfs attribute "unit_add".
In order to see corresponding trace records of otherwise successful
events, we had to increase the trace level of area SCSI and HBA to 6.
$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_scsi/level
$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_hba/level
$ echo 0x4011402240334044 > \
/sys/bus/ccw/drivers/zfcp/0.0.1880/0x50050763031bd327/unit_add
Example output formatted by an updated zfcpdbf from the s390-tools
package interspersed with kernel messages at scsi_logging_level=4605:
Timestamp : ...
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : scsla_1
LUN : 0x4011402240334044
WWPN : 0x50050763031bd327
D_ID : 0x00......
Adapter status : 0x5400050b
Port status : 0x54000001
LUN status : 0x41000000
Ready count : 0x00000001
Running count : 0x00000000
ERP want : 0x01
ERP need : 0x01
scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 1 length 36
scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0
Timestamp : ...
Area : HBA
Subarea : 00
Level : 6
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : fs_norm
Request ID : 0x<inquiry2-req-id>
Request status : 0x00000010
FSF cmnd : 0x00000001
FSF sequence no: 0x...
FSF issued : ...
FSF stat : 0x00000000
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001
Prot stat qual : ........ ........ 00000000 00000000
Port handle : 0x...
LUN handle : 0x...
|
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 6
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_nor
Request ID : 0x<inquiry2-req-id>
SCSI ID : 0x00000000
SCSI LUN : 0x40224011
SCSI LUN high : 0x40444033 <=======================
SCSI result : 0x00000000
SCSI retries : 0x00
SCSI allowed : 0x03
SCSI scribble : 0x<inquiry2-req-id>
SCSI opcode : 12000000 a4000000 00000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000000 00000000
00000000 00000000
scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 2 length 164
scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0
scsi 2:0:0:4630896905707208721: scsi scan: peripheral device type of 31, \
no device added
Signed-off-by: Steffen Maier <[email protected]>
Fixes: 9cb78c16f5da ("scsi: use 64-bit LUNs")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Jens Remus <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 2 +-
drivers/s390/scsi/zfcp_dbf.h | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -563,8 +563,8 @@ void zfcp_dbf_scsi(char *tag, int level,
rec->scsi_retries = sc->retries;
rec->scsi_allowed = sc->allowed;
rec->scsi_id = sc->device->id;
- /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */
rec->scsi_lun = (u32)sc->device->lun;
+ rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
rec->host_scribble = (unsigned long)sc->host_scribble;
memcpy(rec->scsi_opcode, sc->cmnd,
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -204,7 +204,7 @@ enum zfcp_dbf_scsi_id {
* @id: unique number of recovery record type
* @tag: identifier string specifying the location of initiation
* @scsi_id: scsi device id
- * @scsi_lun: scsi device logical unit number
+ * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit
* @scsi_result: scsi result
* @scsi_retries: current retry number of scsi request
* @scsi_allowed: allowed retries
@@ -214,6 +214,7 @@ enum zfcp_dbf_scsi_id {
* @host_scribble: LLD specific data attached to SCSI request
* @pl_len: length of paload stored as zfcp_dbf_pay
* @fsf_rsp: response for fsf request
+ * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit
*/
struct zfcp_dbf_scsi {
u8 id;
@@ -230,6 +231,7 @@ struct zfcp_dbf_scsi {
u64 host_scribble;
u16 pl_len;
struct fcp_resp_with_ext fcp_rsp;
+ u32 scsi_lun_64_hi;
} __packed;
/**
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivasharan S <[email protected]>
commit eb3fe263a48b0d27b229c213929c4cb3b1b39a0f upstream.
After a kill adapter, since the cmd_status is not set, the IOCTLs will
be hung in driver resulting in application hang. Set cmd_status
MFI_STAT_WRONG_STATE when completing pended IOCTLs.
Signed-off-by: Kashyap Desai <[email protected]>
Signed-off-by: Shivasharan S <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/megaraid/megaraid_sas_base.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1995,9 +1995,12 @@ static void megasas_complete_outstanding
if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
if (cmd_mfi->sync_cmd &&
- cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)
+ (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
+ cmd_mfi->frame->hdr.cmd_status =
+ MFI_STAT_WRONG_STATE;
megasas_complete_cmd(instance,
cmd_mfi, DID_OK);
+ }
}
}
} else {
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivasharan S <[email protected]>
commit e636a7a430f41efb0ff2727960ce61ef9f8f6769 upstream.
Setting resetwaittime to 0 during a FW fault will result in driver not
calling the OCR.
Signed-off-by: Kashyap Desai <[email protected]>
Signed-off-by: Shivasharan S <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/megaraid/megaraid_sas_base.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5478,7 +5478,8 @@ static int megasas_init_fw(struct megasa
instance->throttlequeuedepth =
MEGASAS_THROTTLE_QUEUE_DEPTH;
- if (resetwaittime > MEGASAS_RESET_WAIT_TIME)
+ if ((resetwaittime < 1) ||
+ (resetwaittime > MEGASAS_RESET_WAIT_TIME))
resetwaittime = MEGASAS_RESET_WAIT_TIME;
if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary R Hook <[email protected]>
commit e652399edba99a5497f0d80f240c9075d3b43493 upstream.
Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.
Signed-off-by: Gary R Hook <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/crypto/ccp/ccp-crypto-aes-xts.c | 4 ++
drivers/crypto/ccp/ccp-dev-v5.c | 2 +
drivers/crypto/ccp/ccp-dev.h | 2 +
drivers/crypto/ccp/ccp-ops.c | 43 +++++++++++++++++++++++++-------
include/linux/ccp.h | 3 +-
5 files changed, 43 insertions(+), 11 deletions(-)
--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -1,8 +1,9 @@
/*
* AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
*
+ * Author: Gary R Hook <[email protected]>
* Author: Tom Lendacky <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablk
memset(&rctx->cmd, 0, sizeof(rctx->cmd));
INIT_LIST_HEAD(&rctx->cmd.entry);
rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
+ rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
: CCP_AES_ACTION_DECRYPT;
rctx->cmd.u.xts.unit_size = unit_size;
--- a/drivers/crypto/ccp/ccp-dev-v5.c
+++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -145,6 +145,7 @@ union ccp_function {
#define CCP_AES_MODE(p) ((p)->aes.mode)
#define CCP_AES_TYPE(p) ((p)->aes.type)
#define CCP_XTS_SIZE(p) ((p)->aes_xts.size)
+#define CCP_XTS_TYPE(p) ((p)->aes_xts.type)
#define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt)
#define CCP_DES3_SIZE(p) ((p)->des3.size)
#define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt)
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct c
CCP5_CMD_PROT(&desc) = 0;
function.raw = 0;
+ CCP_XTS_TYPE(&function) = op->u.xts.type;
CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
CCP5_CMD_FUNCTION(&desc) = function.raw;
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -192,6 +192,7 @@
#define CCP_AES_CTX_SB_COUNT 1
#define CCP_XTS_AES_KEY_SB_COUNT 1
+#define CCP5_XTS_AES_KEY_SB_COUNT 2
#define CCP_XTS_AES_CTX_SB_COUNT 1
#define CCP_DES3_KEY_SB_COUNT 1
@@ -497,6 +498,7 @@ struct ccp_aes_op {
};
struct ccp_xts_aes_op {
+ enum ccp_aes_type type;
enum ccp_aes_action action;
enum ccp_xts_aes_unit_size unit_size;
};
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct cc
struct ccp_op op;
unsigned int unit_size, dm_offset;
bool in_place = false;
+ unsigned int sb_count;
+ enum ccp_aes_type aestype;
int ret;
switch (xts->unit_size) {
@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct cc
return -EINVAL;
}
- if (xts->key_len != AES_KEYSIZE_128)
+ if (xts->key_len == AES_KEYSIZE_128)
+ aestype = CCP_AES_TYPE_128;
+ else
return -EINVAL;
if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct cc
op.sb_key = cmd_q->sb_key;
op.sb_ctx = cmd_q->sb_ctx;
op.init = 1;
+ op.u.xts.type = aestype;
op.u.xts.action = xts->action;
op.u.xts.unit_size = xts->unit_size;
- /* All supported key sizes fit in a single (32-byte) SB entry
- * and must be in little endian format. Use the 256-bit byte
- * swap passthru option to convert from big endian to little
- * endian.
+ /* A version 3 device only supports 128-bit keys, which fits into a
+ * single SB entry. A version 5 device uses a 512-bit vector, so two
+ * SB entries.
*/
+ if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
+ sb_count = CCP_XTS_AES_KEY_SB_COUNT;
+ else
+ sb_count = CCP5_XTS_AES_KEY_SB_COUNT;
ret = ccp_init_dm_workarea(&key, cmd_q,
- CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES,
+ sb_count * CCP_SB_BYTES,
DMA_TO_DEVICE);
if (ret)
return ret;
- dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
- ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
- ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len);
+ if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) {
+ /* All supported key sizes must be in little endian format.
+ * Use the 256-bit byte swap passthru option to convert from
+ * big endian to little endian.
+ */
+ dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
+ ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
+ ccp_set_dm_area(&key, 0, xts->key, xts->key_len, xts->key_len);
+ } else {
+ /* Version 5 CCPs use a 512-bit space for the key: each portion
+ * occupies 256 bits, or one entire slot, and is zero-padded.
+ */
+ unsigned int pad;
+
+ dm_offset = CCP_SB_BYTES;
+ pad = dm_offset - xts->key_len;
+ ccp_set_dm_area(&key, pad, xts->key, 0, xts->key_len);
+ ccp_set_dm_area(&key, dm_offset + pad, xts->key, xts->key_len,
+ xts->key_len);
+ }
ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key,
CCP_PASSTHRU_BYTESWAP_256BIT);
if (ret) {
--- a/include/linux/ccp.h
+++ b/include/linux/ccp.h
@@ -1,7 +1,7 @@
/*
* AMD Cryptographic Coprocessor (CCP) driver
*
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
*
* Author: Tom Lendacky <[email protected]>
* Author: Gary R Hook <[email protected]>
@@ -231,6 +231,7 @@ enum ccp_xts_aes_unit_size {
* AES operation the new IV overwrites the old IV.
*/
struct ccp_xts_aes_engine {
+ enum ccp_aes_type type;
enum ccp_aes_action action;
enum ccp_xts_aes_unit_size unit_size;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit 0208eeaa650c5c866a3242201678a19e6dc4a14e upstream.
When storvsc is sending I/O to Hyper-v, it may allocate a bigger buffer
descriptor for large data payload that can't fit into a pre-allocated
buffer descriptor. This bigger buffer is freed on return path.
If I/O request to Hyper-v fails due to ring buffer busy, the storvsc
allocated buffer descriptor should also be freed.
[mkp: applied by hand]
Fixes: be0cf6ca301c ("scsi: storvsc: Set the tablesize based on the information given by the host")
Signed-off-by: Long Li <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/storvsc_drv.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1640,6 +1640,8 @@ static int storvsc_queuecommand(struct S
put_cpu();
if (ret == -EAGAIN) {
+ if (payload_sz > sizeof(cmd_request->mpb))
+ kfree(payload);
/* no more space */
return SCSI_MLQUEUE_DEVICE_BUSY;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Mueller <[email protected]>
Fixed differently upstream as commit 2d97591ef43d ("crypto: af_alg - consolidation of duplicate code")
The SGL is MAX_SGL_ENTS + 1 in size. The last SG entry is used for the
chaining and is properly updated with the sg_chain invocation. During
the filling-in of the initial SG entries, sg_mark_end is called for each
SG entry. This is appropriate as long as no additional SGL is chained
with the current SGL. However, when a new SGL is chained and the last
SG entry is updated with sg_chain, the last but one entry still contains
the end marker from the sg_mark_end. This end marker must be removed as
otherwise a walk of the chained SGLs will cause a NULL pointer
dereference at the last but one SG entry, because sg_next will return
NULL.
The patch only applies to all kernels up to and including 4.13. The
patch 2d97591ef43d0587be22ad1b0d758d6df4999a0b added to 4.14-rc1
introduced a complete new code base which addresses this bug in
a different way. Yet, that patch is too invasive for stable kernels
and was therefore not marked for stable.
Fixes: 8ff590903d5fc ("crypto: algif_skcipher - User-space interface for skcipher operations")
Signed-off-by: Stephan Mueller <[email protected]>
Acked-by: Herbert Xu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
crypto/algif_skcipher.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -144,8 +144,10 @@ static int skcipher_alloc_sgl(struct soc
sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
sgl->cur = 0;
- if (sg)
+ if (sg) {
sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+ sg_unmark_end(sg + (MAX_SGL_ENTS - 1));
+ }
list_add_tail(&sgl->list, &ctx->tsgl);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 7cf64ce4d37f1b4f44365fcf77f565d523819dcd upstream.
Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is
+0 or -0, and the third input is also +0 or -0. Depending on the signs
of inputs, certain special cases must be handled.
A relevant example:
MADDF.S fd,fs,ft:
If fs contains +0.0, ft contains -0.0, and fd contains 0.0, fd is
going to contain +0.0 (without this patch, it used to contain -0.0).
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16888/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_maddf.c | 18 +++++++++++++++++-
arch/mips/math-emu/sp_maddf.c | 18 +++++++++++++++++-
2 files changed, 34 insertions(+), 2 deletions(-)
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -113,7 +113,23 @@ static union ieee754dp _dp_maddf(union i
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
if (zc == IEEE754_CLASS_INF)
return ieee754dp_inf(zs);
- /* Multiplication is 0 so just return z */
+ if (zc == IEEE754_CLASS_ZERO) {
+ /* Handle cases +0 + (-0) and similar ones. */
+ if ((!(flags & maddf_negate_product)
+ && (zs == (xs ^ ys))) ||
+ ((flags & maddf_negate_product)
+ && (zs != (xs ^ ys))))
+ /*
+ * Cases of addition of zeros of equal signs
+ * or subtraction of zeroes of opposite signs.
+ * The sign of the resulting zero is in any
+ * such case determined only by the sign of z.
+ */
+ return z;
+
+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
+ }
+ /* x*y is here 0, and z is not 0, so just return z */
return z;
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -114,7 +114,23 @@ static union ieee754sp _sp_maddf(union i
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
if (zc == IEEE754_CLASS_INF)
return ieee754sp_inf(zs);
- /* Multiplication is 0 so just return z */
+ if (zc == IEEE754_CLASS_ZERO) {
+ /* Handle cases +0 + (-0) and similar ones. */
+ if ((!(flags & maddf_negate_product)
+ && (zs == (xs ^ ys))) ||
+ ((flags & maddf_negate_product)
+ && (zs != (xs ^ ys))))
+ /*
+ * Cases of addition of zeros of equal signs
+ * or subtraction of zeroes of opposite signs.
+ * The sign of the resulting zero is in any
+ * such case determined only by the sign of z.
+ */
+ return z;
+
+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
+ }
+ /* x*y is here 0, and z is not 0, so just return z */
return z;
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) <[email protected]>
commit edb096e00724f02db5f6ec7900f3bbd465c6c76f upstream.
If function tracing is disabled by the user via the function-trace option or
the proc sysctl file, and a ftrace_ops that was allocated on the heap is
unregistered, then the shutdown code exits out without doing the proper
clean up. This was found via kmemleak and running the ftrace selftests, as
one of the tests unregisters with function tracing disabled.
# cat kmemleak
unreferenced object 0xffffffffa0020000 (size 4096):
comm "swapper/0", pid 1, jiffies 4294668889 (age 569.209s)
hex dump (first 32 bytes):
55 ff 74 24 10 55 48 89 e5 ff 74 24 18 55 48 89 U.t$.UH...t$.UH.
e5 48 81 ec a8 00 00 00 48 89 44 24 50 48 89 4c .H......H.D$PH.L
backtrace:
[<ffffffff81d64665>] kmemleak_vmalloc+0x85/0xf0
[<ffffffff81355631>] __vmalloc_node_range+0x281/0x3e0
[<ffffffff8109697f>] module_alloc+0x4f/0x90
[<ffffffff81091170>] arch_ftrace_update_trampoline+0x160/0x420
[<ffffffff81249947>] ftrace_startup+0xe7/0x300
[<ffffffff81249bd2>] register_ftrace_function+0x72/0x90
[<ffffffff81263786>] trace_selftest_ops+0x204/0x397
[<ffffffff82bb8971>] trace_selftest_startup_function+0x394/0x624
[<ffffffff81263a75>] run_tracer_selftest+0x15c/0x1d7
[<ffffffff82bb83f1>] init_trace_selftests+0x75/0x192
[<ffffffff81002230>] do_one_initcall+0x90/0x1e2
[<ffffffff82b7d620>] kernel_init_freeable+0x350/0x3fe
[<ffffffff81d61ec3>] kernel_init+0x13/0x122
[<ffffffff81d72c6a>] ret_from_fork+0x2a/0x40
[<ffffffffffffffff>] 0xffffffffffffffff
Fixes: 12cce594fa ("ftrace/x86: Allow !CONFIG_PREEMPT dynamic ops to use allocated trampolines")
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/trace/ftrace.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2828,13 +2828,14 @@ static int ftrace_shutdown(struct ftrace
if (!command || !ftrace_enabled) {
/*
- * If these are per_cpu ops, they still need their
- * per_cpu field freed. Since, function tracing is
+ * If these are dynamic or per_cpu ops, they still
+ * need their data freed. Since, function tracing is
* not currently active, we can just free them
* without synchronizing all CPUs.
*/
- if (ops->flags & FTRACE_OPS_FL_PER_CPU)
- per_cpu_ops_free(ops);
+ if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_PER_CPU))
+ goto free_ops;
+
return 0;
}
@@ -2900,6 +2901,7 @@ static int ftrace_shutdown(struct ftrace
if (IS_ENABLED(CONFIG_PREEMPT))
synchronize_rcu_tasks();
+ free_ops:
arch_ftrace_trampoline_free(ops);
if (ops->flags & FTRACE_OPS_FL_PER_CPU)
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) <[email protected]>
commit 3d9622c12c8873911f4cc0ccdabd0362c2fca06b upstream.
trace_printk() uses 4 buffers, one for each context (normal, softirq, irq
and NMI), such that it does not need to worry about one context preempting
the other. There's a nesting counter that gets incremented to figure out
which buffer to use. If the context gets preempted by another context which
calls trace_printk() it will increment the counter and use the next buffer,
and restore the counter when it is finished.
The problem is that gcc may optimize the modification of the buffer nesting
counter and it may not be incremented in memory before the buffer is used.
If this happens, and the context gets interrupted by another context, it
could pick the same buffer and corrupt the one that is being used.
Compiler barriers need to be added after the nesting variable is incremented
and before it is decremented to prevent usage of the context buffers by more
than one context at the same time.
Cc: Andy Lutomirski <[email protected]>
Fixes: e2ace00117 ("tracing: Choose static tp_printk buffer by explicit nesting count")
Hat-tip-to: Peter Zijlstra <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/trace/trace.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2799,11 +2799,17 @@ static char *get_trace_buf(void)
if (!buffer || buffer->nesting >= 4)
return NULL;
- return &buffer->buffer[buffer->nesting++][0];
+ buffer->nesting++;
+
+ /* Interrupts must see nesting incremented before we use the buffer */
+ barrier();
+ return &buffer->buffer[buffer->nesting][0];
}
static void put_trace_buf(void)
{
+ /* Don't let the decrement of nesting leak before this */
+ barrier();
this_cpu_dec(trace_percpu_buffer->nesting);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Abreu <[email protected]>
commit 1ee55a8f7f6b7ca4c0c59e0b4b4e3584a085c2d3 upstream.
I recently came upon a scenario where I would get a double fault
machine check exception tiriggered by a kernel module.
However the ensuing crash stacktrace (ksym lookup) was not working
correctly.
Turns out that machine check auto-disables MMU while modules are allocated
in kernel vaddr spapce.
This patch re-enables the MMU before start printing the stacktrace
making stacktracing of modules work upon a fatal exception.
Signed-off-by: Jose Abreu <[email protected]>
Reviewed-by: Alexey Brodkin <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
[vgupta: moved code into low level handler to avoid in 2 places]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arc/kernel/entry.S | 6 ++++++
arch/arc/mm/tlb.c | 3 ---
2 files changed, 6 insertions(+), 3 deletions(-)
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck)
lr r0, [efa]
mov r1, sp
+ ; hardware auto-disables MMU, re-enable it to allow kernel vaddr
+ ; access for say stack unwinding of modules for crash dumps
+ lr r3, [ARC_REG_PID]
+ or r3, r3, MMU_ENABLE
+ sr r3, [ARC_REG_PID]
+
lsr r3, r2, 8
bmsk r3, r3, 7
brne r3, ECR_C_MCHK_DUP_TLB, 1f
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -908,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long
local_irq_save(flags);
- /* re-enable the MMU */
- write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID));
-
/* loop thru all sets of TLB */
for (set = 0; set < mmu->sets; set++) {
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Schwidefsky <[email protected]>
commit b3e5dc45fd1ec2aa1de6b80008f9295eb17e0659 upstream.
The local TLB flushing code keeps an additional mask in the mm.context,
the cpu_attach_mask. At the time a global flush of an address space is
done the cpu_attach_mask is copied to the mm_cpumask in order to avoid
future global flushes in case the mm is used by a single CPU only after
the flush.
Trouble is that the reset of the mm_cpumask is racy against the detach
of an mm address space by switch_mm. The current order is first the
global TLB flush and then the copy of the cpu_attach_mask to the
mm_cpumask. The order needs to be the other way around.
Reviewed-by: Heiko Carstens <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/s390/include/asm/mmu_context.h | 4 ++--
arch/s390/include/asm/tlbflush.h | 26 +++++---------------------
2 files changed, 7 insertions(+), 23 deletions(-)
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -102,7 +102,6 @@ static inline void switch_mm(struct mm_s
if (prev == next)
return;
cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
- cpumask_set_cpu(cpu, mm_cpumask(next));
/* Clear old ASCE by loading the kernel ASCE. */
__ctl_load(S390_lowcore.kernel_asce, 1, 1);
__ctl_load(S390_lowcore.kernel_asce, 7, 7);
@@ -120,7 +119,7 @@ static inline void finish_arch_post_lock
preempt_disable();
while (atomic_read(&mm->context.flush_count))
cpu_relax();
-
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
if (mm->context.flush_mm)
__tlb_flush_mm(mm);
preempt_enable();
@@ -135,6 +134,7 @@ static inline void activate_mm(struct mm
struct mm_struct *next)
{
switch_mm(prev, next, current);
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
set_user_asce(next);
}
--- a/arch/s390/include/asm/tlbflush.h
+++ b/arch/s390/include/asm/tlbflush.h
@@ -43,23 +43,6 @@ static inline void __tlb_flush_global(vo
* Flush TLB entries for a specific mm on all CPUs (in case gmap is used
* this implicates multiple ASCEs!).
*/
-static inline void __tlb_flush_full(struct mm_struct *mm)
-{
- preempt_disable();
- atomic_inc(&mm->context.flush_count);
- if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
- /* Local TLB flush */
- __tlb_flush_local();
- } else {
- /* Global TLB flush */
- __tlb_flush_global();
- /* Reset TLB flush mask */
- cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
- }
- atomic_dec(&mm->context.flush_count);
- preempt_enable();
-}
-
static inline void __tlb_flush_mm(struct mm_struct *mm)
{
unsigned long gmap_asce;
@@ -71,16 +54,18 @@ static inline void __tlb_flush_mm(struct
*/
preempt_disable();
atomic_inc(&mm->context.flush_count);
+ /* Reset TLB flush mask */
+ cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
+ barrier();
gmap_asce = READ_ONCE(mm->context.gmap_asce);
if (MACHINE_HAS_IDTE && gmap_asce != -1UL) {
if (gmap_asce)
__tlb_flush_idte(gmap_asce);
__tlb_flush_idte(mm->context.asce);
} else {
- __tlb_flush_full(mm);
+ /* Global TLB flush */
+ __tlb_flush_global();
}
- /* Reset TLB flush mask */
- cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
atomic_dec(&mm->context.flush_count);
preempt_enable();
}
@@ -94,7 +79,6 @@ static inline void __tlb_flush_kernel(vo
}
#else
#define __tlb_flush_global() __tlb_flush_local()
-#define __tlb_flush_full(mm) __tlb_flush_local()
/*
* Flush TLB entries for a specific ASCE on all CPUs.
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Mentz <[email protected]>
commit 9c7ba1d7634cef490b85bc64c4091ff004821bfd upstream.
Certain syscalls like recvmmsg support 64 bit timespec values for the
X32 ABI. The helper function compat_put_timespec converts a timespec
value to a 32 bit or 64 bit value depending on what ABI is used. The
v4l2 compat layer, however, is not designed to support 64 bit timespec
values and always uses 32 bit values. Hence, compat_put_timespec must
not be used.
Without this patch, user space will be provided with bad timestamp
values from the VIDIOC_DQEVENT ioctl. Also, fields of the struct
v4l2_event32 that come immediately after timestamp get overwritten,
namely the field named id.
Fixes: 81993e81a994 ("compat: Get rid of (get|put)_compat_time(val|spec)")
Cc: H. Peter Anvin <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Tiffany Lin <[email protected]>
Cc: Ricardo Ribalda Delgado <[email protected]>
Cc: Sakari Ailus <[email protected]>
Signed-off-by: Daniel Mentz <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -796,7 +796,8 @@ static int put_v4l2_event32(struct v4l2_
copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
put_user(kp->pending, &up->pending) ||
put_user(kp->sequence, &up->sequence) ||
- compat_put_timespec(&kp->timestamp, &up->timestamp) ||
+ put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+ put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
put_user(kp->id, &up->id) ||
copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
return -EFAULT;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
commit 7e09f7d5c790278ab98e5f2c22307ebe8ad6e8ba upstream.
The size of uvc_control_mapping is user controlled leading to a
potential heap overflow in the uvc driver. This adds a check to verify
the user provided size fits within the bounds of the defined buffer
size.
Originally-from: Richard Simmons <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/usb/uvc/uvc_ctrl.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -2002,6 +2002,13 @@ int uvc_ctrl_add_mapping(struct uvc_vide
goto done;
}
+ /* Validate the user-provided bit-size and offset */
+ if (mapping->size > 32 ||
+ mapping->offset + mapping->size > ctrl->info.size * 8) {
+ ret = -EINVAL;
+ goto done;
+ }
+
list_for_each_entry(map, &ctrl->info.mappings, list) {
if (mapping->id == map->id) {
uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', "
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chanwoo Choi <[email protected]>
commit 9e14de1077e9c34f141cf98bdba60cdd5193d962 upstream.
When the devfreq_add_device fails to register deivce, the memory
leak of devfreq instance happen. So, this patch fix the memory
leak issue. Before freeing the devfreq instance checks whether
devfreq instance is NULL or not because the device_unregister()
frees the devfreq instance when jumping to the 'err_init'.
It is to prevent the duplicate the kfee(devfreq).
Fixes: ac4b281176a5 ("PM / devfreq: fix duplicated kfree on devfreq pointer")
Signed-off-by: Chanwoo Choi <[email protected]>
Signed-off-by: MyungJoo Ham <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/devfreq/devfreq.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -564,7 +564,7 @@ struct devfreq *devfreq_add_device(struc
err = device_register(&devfreq->dev);
if (err) {
mutex_unlock(&devfreq->lock);
- goto err_out;
+ goto err_dev;
}
devfreq->trans_table = devm_kzalloc(&devfreq->dev,
@@ -610,6 +610,9 @@ err_init:
mutex_unlock(&devfreq_list_lock);
device_unregister(&devfreq->dev);
+err_dev:
+ if (devfreq)
+ kfree(devfreq);
err_out:
return ERR_PTR(err);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 4b758df21ee7081ab41448d21d60367efaa625b3 upstream.
If blkdev_get_by_path() in register_bcache() fails, we try to lookup the
block device using lookup_bdev() to detect which situation we are in to
properly report error. However we never drop the reference returned to
us from lookup_bdev(). Fix that.
Signed-off-by: Jan Kara <[email protected]>
Acked-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/super.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1965,6 +1965,8 @@ static ssize_t register_bcache(struct ko
else
err = "device busy";
mutex_unlock(&bch_register_lock);
+ if (!IS_ERR(bdev))
+ bdput(bdev);
if (attr == &ksysfs_register_quiet)
goto out;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tang Junhui <[email protected]>
commit 69daf03adef5f7bc13e0ac86b4b8007df1767aab upstream.
Since bypassed IOs use no bucket, so do not subtract sectors_to_gc to
trigger gc thread.
Signed-off-by: tang.junhui <[email protected]>
Acked-by: Coly Li <[email protected]>
Reviewed-by: Eric Wheeler <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/request.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -196,12 +196,12 @@ static void bch_data_insert_start(struct
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
struct bio *bio = op->bio, *n;
- if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0)
- wake_up_gc(op->c);
-
if (op->bypass)
return bch_data_invalidate(cl);
+ if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0)
+ wake_up_gc(op->c);
+
/*
* Journal writes are marked REQ_PREFLUSH; if the original write was a
* flush, it'll wait on the journal write.
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Asleson <[email protected]>
commit 77fa100f27475d08a569b9d51c17722130f089e7 upstream.
If you encounter any errors in bch_cached_dev_attach it will return
a negative error code. The variable 'v' which stores the result is
unsigned, thus user space sees a very large value returned for bytes
written which can cause incorrect user space behavior. Utilize 1
signed variable to use throughout the function to preserve error return
capability.
Signed-off-by: Tony Asleson <[email protected]>
Acked-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/sysfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -192,7 +192,7 @@ STORE(__cached_dev)
{
struct cached_dev *dc = container_of(kobj, struct cached_dev,
disk.kobj);
- unsigned v = size;
+ ssize_t v = size;
struct cache_set *c;
struct kobj_uevent_env *env;
@@ -227,7 +227,7 @@ STORE(__cached_dev)
bch_cached_dev_run(dc);
if (attr == &sysfs_cache_mode) {
- ssize_t v = bch_read_string_list(buf, bch_cache_modes + 1);
+ v = bch_read_string_list(buf, bch_cache_modes + 1);
if (v < 0)
return v;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit fc27fe7e8deef2f37cba3f2be2d52b6ca5eb9d57 upstream.
ALSA sequencer core has a mechanism to load the enumerated devices
automatically, and it's performed in an off-load work. This seems
causing some race when a sequencer is removed while the pending
autoload work is running. As syzkaller spotted, it may lead to some
use-after-free:
BUG: KASAN: use-after-free in snd_rawmidi_dev_seq_free+0x69/0x70
sound/core/rawmidi.c:1617
Write of size 8 at addr ffff88006c611d90 by task kworker/2:1/567
CPU: 2 PID: 567 Comm: kworker/2:1 Not tainted 4.13.0+ #29
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: events autoload_drivers
Call Trace:
__dump_stack lib/dump_stack.c:16 [inline]
dump_stack+0x192/0x22c lib/dump_stack.c:52
print_address_description+0x78/0x280 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351 [inline]
kasan_report+0x230/0x340 mm/kasan/report.c:409
__asan_report_store8_noabort+0x1c/0x20 mm/kasan/report.c:435
snd_rawmidi_dev_seq_free+0x69/0x70 sound/core/rawmidi.c:1617
snd_seq_dev_release+0x4f/0x70 sound/core/seq_device.c:192
device_release+0x13f/0x210 drivers/base/core.c:814
kobject_cleanup lib/kobject.c:648 [inline]
kobject_release lib/kobject.c:677 [inline]
kref_put include/linux/kref.h:70 [inline]
kobject_put+0x145/0x240 lib/kobject.c:694
put_device+0x25/0x30 drivers/base/core.c:1799
klist_devices_put+0x36/0x40 drivers/base/bus.c:827
klist_next+0x264/0x4a0 lib/klist.c:403
next_device drivers/base/bus.c:270 [inline]
bus_for_each_dev+0x17e/0x210 drivers/base/bus.c:312
autoload_drivers+0x3b/0x50 sound/core/seq_device.c:117
process_one_work+0x9fb/0x1570 kernel/workqueue.c:2097
worker_thread+0x1e4/0x1350 kernel/workqueue.c:2231
kthread+0x324/0x3f0 kernel/kthread.c:231
ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:425
The fix is simply to assure canceling the autoload work at removing
the device.
Reported-by: Andrey Konovalov <[email protected]>
Tested-by: Andrey Konovalov <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/core/seq_device.c | 3 +++
1 file changed, 3 insertions(+)
--- a/sound/core/seq_device.c
+++ b/sound/core/seq_device.c
@@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void)
flush_work(&autoload_work);
}
EXPORT_SYMBOL(snd_seq_device_load_drivers);
+#define cancel_autoload_drivers() cancel_work_sync(&autoload_work)
#else
#define queue_autoload_drivers() /* NOP */
+#define cancel_autoload_drivers() /* NOP */
#endif
/*
@@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struc
{
struct snd_seq_device *dev = device->device_data;
+ cancel_autoload_drivers();
put_device(&dev->dev);
return 0;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tang Junhui <[email protected]>
commit 9baf30972b5568d8b5bc8b3c46a6ec5b58100463 upstream.
gc and write-back get raced (see the email "bcache get stucked" I sended
before):
gc thread write-back thread
| |bch_writeback_thread()
|bch_gc_thread() |
| |==>read_dirty()
|==>bch_btree_gc() |
|==>btree_root() //get btree root |
| //node write locker |
|==>bch_btree_gc_root() |
| |==>read_dirty_submit()
| |==>write_dirty()
| |==>continue_at(cl,
| | write_dirty_finish,
| | system_wq);
| |==>write_dirty_finish()//excute
| | //in system_wq
| |==>bch_btree_insert()
| |==>bch_btree_map_leaf_nodes()
| |==>__bch_btree_map_nodes()
| |==>btree_root //try to get btree
| | //root node read
| | //lock
| |-----stuck here
|==>bch_btree_set_root()
|==>bch_journal_meta()
|==>bch_journal()
|==>journal_try_write()
|==>journal_write_unlocked() //journal_full(&c->journal)
| //condition satisfied
|==>continue_at(cl, journal_write, system_wq); //try to excute
| //journal_write in system_wq
| //but work queue is excuting
| //write_dirty_finish()
|==>closure_sync(); //wait journal_write execute
| //over and wake up gc,
|-------------stuck here
|==>release root node write locker
This patch alloc a separate work-queue for write-back thread to avoid such
race.
(Commit log re-organized by Coly Li to pass checkpatch.pl checking)
Signed-off-by: Tang Junhui <[email protected]>
Acked-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/bcache.h | 1 +
drivers/md/bcache/super.c | 2 ++
drivers/md/bcache/writeback.c | 9 +++++++--
3 files changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -333,6 +333,7 @@ struct cached_dev {
/* Limit number of writeback bios in flight */
struct semaphore in_flight;
struct task_struct *writeback_thread;
+ struct workqueue_struct *writeback_write_wq;
struct keybuf writeback_keys;
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1059,6 +1059,8 @@ static void cached_dev_free(struct closu
cancel_delayed_work_sync(&dc->writeback_rate_update);
if (!IS_ERR_OR_NULL(dc->writeback_thread))
kthread_stop(dc->writeback_thread);
+ if (dc->writeback_write_wq)
+ destroy_workqueue(dc->writeback_write_wq);
mutex_lock(&bch_register_lock);
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -187,7 +187,7 @@ static void write_dirty(struct closure *
closure_bio_submit(&io->bio, cl);
- continue_at(cl, write_dirty_finish, system_wq);
+ continue_at(cl, write_dirty_finish, io->dc->writeback_write_wq);
}
static void read_dirty_endio(struct bio *bio)
@@ -207,7 +207,7 @@ static void read_dirty_submit(struct clo
closure_bio_submit(&io->bio, cl);
- continue_at(cl, write_dirty, system_wq);
+ continue_at(cl, write_dirty, io->dc->writeback_write_wq);
}
static void read_dirty(struct cached_dev *dc)
@@ -517,6 +517,11 @@ void bch_cached_dev_writeback_init(struc
int bch_cached_dev_writeback_start(struct cached_dev *dc)
{
+ dc->writeback_write_wq = alloc_workqueue("bcache_writeback_wq",
+ WQ_MEM_RECLAIM, 0);
+ if (!dc->writeback_write_wq)
+ return -ENOMEM;
+
dc->writeback_thread = kthread_create(bch_writeback_thread, dc,
"bcache_writeback");
if (IS_ERR(dc->writeback_thread))
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit 50e76632339d4655859523a39249dd95ee5e93e7 upstream.
Cpusets vs. suspend-resume is _completely_ broken. And it got noticed
because it now resulted in non-cpuset usage breaking too.
On suspend cpuset_cpu_inactive() doesn't call into
cpuset_update_active_cpus() because it doesn't want to move tasks about,
there is no need, all tasks are frozen and won't run again until after
we've resumed everything.
But this means that when we finally do call into
cpuset_update_active_cpus() after resuming the last frozen cpu in
cpuset_cpu_active(), the top_cpuset will not have any difference with
the cpu_active_mask and this it will not in fact do _anything_.
So the cpuset configuration will not be restored. This was largely
hidden because we would unconditionally create identity domains and
mobile users would not in fact use cpusets much. And servers what do use
cpusets tend to not suspend-resume much.
An addition problem is that we'd not in fact wait for the cpuset work to
finish before resuming the tasks, allowing spurious migrations outside
of the specified domains.
Fix the rebuild by introducing cpuset_force_rebuild() and fix the
ordering with cpuset_wait_for_hotplug().
Reported-by: Andy Lutomirski <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Fixes: deb7aa308ea2 ("cpuset: reorganize CPU / memory hotplug handling")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/cpuset.h | 6 ++++++
kernel/cgroup/cpuset.c | 16 +++++++++++++++-
kernel/power/process.c | 5 ++++-
kernel/sched/core.c | 7 +++----
4 files changed, 28 insertions(+), 6 deletions(-)
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -57,7 +57,9 @@ static inline void cpuset_dec(void)
extern int cpuset_init(void);
extern void cpuset_init_smp(void);
+extern void cpuset_force_rebuild(void);
extern void cpuset_update_active_cpus(void);
+extern void cpuset_wait_for_hotplug(void);
extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
extern void cpuset_cpus_allowed_fallback(struct task_struct *p);
extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
@@ -170,11 +172,15 @@ static inline bool cpusets_enabled(void)
static inline int cpuset_init(void) { return 0; }
static inline void cpuset_init_smp(void) {}
+static inline void cpuset_force_rebuild(void) { }
+
static inline void cpuset_update_active_cpus(void)
{
partition_sched_domains(1, NULL, NULL);
}
+static inline void cpuset_wait_for_hotplug(void) { }
+
static inline void cpuset_cpus_allowed(struct task_struct *p,
struct cpumask *mask)
{
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -2260,6 +2260,13 @@ retry:
mutex_unlock(&cpuset_mutex);
}
+static bool force_rebuild;
+
+void cpuset_force_rebuild(void)
+{
+ force_rebuild = true;
+}
+
/**
* cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset
*
@@ -2334,8 +2341,10 @@ static void cpuset_hotplug_workfn(struct
}
/* rebuild sched domains if cpus_allowed has changed */
- if (cpus_updated)
+ if (cpus_updated || force_rebuild) {
+ force_rebuild = false;
rebuild_sched_domains();
+ }
}
void cpuset_update_active_cpus(void)
@@ -2354,6 +2363,11 @@ void cpuset_update_active_cpus(void)
schedule_work(&cpuset_hotplug_work);
}
+void cpuset_wait_for_hotplug(void)
+{
+ flush_work(&cpuset_hotplug_work);
+}
+
/*
* Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY].
* Call this routine anytime after node_states[N_MEMORY] changes.
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -20,8 +20,9 @@
#include <linux/workqueue.h>
#include <linux/kmod.h>
#include <trace/events/power.h>
+#include <linux/cpuset.h>
-/*
+/*
* Timeout for stopping processes
*/
unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
@@ -202,6 +203,8 @@ void thaw_processes(void)
__usermodehelper_set_disable_depth(UMH_FREEZING);
thaw_workqueues();
+ cpuset_wait_for_hotplug();
+
read_lock(&tasklist_lock);
for_each_process_thread(g, p) {
/* No other threads should have PF_SUSPEND_TASK set */
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5538,16 +5538,15 @@ static void cpuset_cpu_active(void)
* operation in the resume sequence, just build a single sched
* domain, ignoring cpusets.
*/
- num_cpus_frozen--;
- if (likely(num_cpus_frozen)) {
- partition_sched_domains(1, NULL, NULL);
+ partition_sched_domains(1, NULL, NULL);
+ if (--num_cpus_frozen)
return;
- }
/*
* This is the last CPU online operation. So fall through and
* restore the original sched domains by considering the
* cpuset configurations.
*/
+ cpuset_force_rebuild();
}
cpuset_update_active_cpus();
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 53168215909281a09d3afc6fb51a9d4f81f74d39 upstream.
With TXQs, the AP_VLAN interfaces are resolved to their owner AP
interface when enqueuing the frame, which makes sense since the
frame really goes out on that as far as the driver is concerned.
However, this introduces a problem: frames to be encrypted with
a VLAN-specific GTK will now be encrypted with the AP GTK, since
the information about which virtual interface to use to select
the key is taken from the TXQ.
Fix this by preserving info->control.vif and using that in the
dequeue function. This now requires doing the driver-mapping
in the dequeue as well.
Since there's no way to filter the frames that are sitting on a
TXQ, drop all frames, which may affect other interfaces, when an
AP_VLAN is removed.
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/net/mac80211.h | 15 ++-------------
net/mac80211/iface.c | 17 +++++++++++++++--
net/mac80211/tx.c | 36 +++++++++++++++++++++++++++++-------
3 files changed, 46 insertions(+), 22 deletions(-)
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -919,21 +919,10 @@ struct ieee80211_tx_info {
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
- union {
- /* NB: vif can be NULL for injected frames */
- struct ieee80211_vif *vif;
-
- /* When packets are enqueued on txq it's easy
- * to re-construct the vif pointer. There's no
- * more space in tx_info so it can be used to
- * store the necessary enqueue time for packet
- * sojourn time computation.
- */
- codel_time_t enqueue_time;
- };
+ struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
u32 flags;
- /* 4 bytes free */
+ codel_time_t enqueue_time;
} control;
struct {
u64 cookie;
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -792,6 +792,7 @@ static int ieee80211_open(struct net_dev
static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
bool going_down)
{
+ struct ieee80211_sub_if_data *txq_sdata = sdata;
struct ieee80211_local *local = sdata->local;
struct fq *fq = &local->fq;
unsigned long flags;
@@ -937,6 +938,9 @@ static void ieee80211_do_stop(struct iee
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
+ txq_sdata = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+
mutex_lock(&local->mtx);
list_del(&sdata->u.vlan.list);
mutex_unlock(&local->mtx);
@@ -1007,8 +1011,17 @@ static void ieee80211_do_stop(struct iee
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
- if (sdata->vif.txq) {
- struct txq_info *txqi = to_txq_info(sdata->vif.txq);
+ if (txq_sdata->vif.txq) {
+ struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
+
+ /*
+ * FIXME FIXME
+ *
+ * We really shouldn't purge the *entire* txqi since that
+ * contains frames for the other AP_VLANs (and possibly
+ * the AP itself) as well, but there's no API in FQ now
+ * to be able to filter.
+ */
spin_lock_bh(&fq->lock);
ieee80211_txq_purge(local, txqi);
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1276,11 +1276,6 @@ static void ieee80211_set_skb_enqueue_ti
IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
}
-static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi)
-{
- IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif;
-}
-
static u32 codel_skb_len_func(const struct sk_buff *skb)
{
return skb->len;
@@ -3414,6 +3409,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
struct ieee80211_tx_info *info;
struct ieee80211_tx_data tx;
ieee80211_tx_result r;
+ struct ieee80211_vif *vif;
spin_lock_bh(&fq->lock);
@@ -3430,8 +3426,6 @@ begin:
if (!skb)
goto out;
- ieee80211_set_skb_vif(skb, txqi);
-
hdr = (struct ieee80211_hdr *)skb->data;
info = IEEE80211_SKB_CB(skb);
@@ -3488,6 +3482,34 @@ begin:
}
}
+ switch (tx.sdata->vif.type) {
+ case NL80211_IFTYPE_MONITOR:
+ if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
+ vif = &tx.sdata->vif;
+ break;
+ }
+ tx.sdata = rcu_dereference(local->monitor_sdata);
+ if (tx.sdata) {
+ vif = &tx.sdata->vif;
+ info->hw_queue =
+ vif->hw_queue[skb_get_queue_mapping(skb)];
+ } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
+ ieee80211_free_txskb(&local->hw, skb);
+ goto begin;
+ } else {
+ vif = NULL;
+ }
+ break;
+ case NL80211_IFTYPE_AP_VLAN:
+ tx.sdata = container_of(tx.sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+ /* fall through */
+ default:
+ vif = &tx.sdata->vif;
+ break;
+ }
+
+ IEEE80211_SKB_CB(skb)->control.vif = vif;
out:
spin_unlock_bh(&fq->lock);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sawan Chandak <[email protected]>
commit fcc5b5cd726c0779cd689362aea82cc9d5a61346 upstream.
If FA-WWPN feature disabled on the switch side and enabled for the
adapter, then driver would update the port name with switch port name.
This patch fixes issue by checking correct BIT flag to validate.
Fixes: 41dc529a4602 ("qla2xxx: Improve RSCN handling in driver")
Signed-off-by: Sawan Chandak <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_mbx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3690,7 +3690,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
if (qla_ini_mode_enabled(vha) &&
ha->flags.fawwpn_enabled &&
(rptid_entry->u.f1.flags &
- VP_FLAGS_NAME_VALID)) {
+ BIT_6)) {
memcpy(vha->port_name,
rptid_entry->u.f1.port_name,
WWN_SIZE);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Hernandez <[email protected]>
commit b7edfa235effb4b4a9816c2345620b11609c123e upstream.
Following error will be logged in to message file while trying to
configure target with multiqueue.
"Cmd 0x1f aborted with timeout since ISP Abort is pending"
"qla25xx_init_queues Rsp que: 1 init failed."
Fixes: 82de802ad46e ("scsi: qla2xxx: Preparation for Target MQ.")
Signed-off-by: Quinn Tran <[email protected]>
Signed-off-by: Michael Hernandez <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_isr.c | 2 +-
drivers/scsi/qla2xxx/qla_mbx.c | 1 +
drivers/scsi/qla2xxx/qla_target.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3429,7 +3429,7 @@ msix_register_fail:
}
/* Enable MSI-X vector for response queue update for queue 0 */
- if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+ if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
if (ha->msixbase && ha->mqiobase &&
(ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||
ql2xmqsupport))
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -54,6 +54,7 @@ static struct rom_cmd {
{ MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
{ MBC_GET_RETRY_COUNT },
{ MBC_TRACE_CONTROL },
+ { MBC_INITIALIZE_MULTIQ },
};
static int is_rom_cmd(uint16_t cmd)
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -6796,7 +6796,7 @@ qlt_probe_one_stage1(struct scsi_qla_hos
if (!QLA_TGT_MODE_ENABLED())
return;
- if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+ if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in;
ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out;
} else {
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit e6f77540c067b48dee10f1e33678415bfcc89017 upstream.
The value of "size" comes from the user. When we add "start + size" it
could lead to an integer overflow bug.
It means we vmalloc() a lot more memory than we had intended. I believe
that on 64 bit systems vmalloc() can succeed even if we ask it to
allocate huge 4GB buffers. So we would get memory corruption and likely
a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().
Only root can trigger this bug.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=194061
Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
Reported-by: shqking <[email protected]>
Signed-off-by: Dan Carpenter <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_attr.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
return -EINVAL;
if (start > ha->optrom_size)
return -EINVAL;
+ if (size > ha->optrom_size - start)
+ size = ha->optrom_size - start;
mutex_lock(&ha->optrom_mutex);
switch (val) {
@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
}
ha->optrom_region_start = start;
- ha->optrom_region_size = start + size > ha->optrom_size ?
- ha->optrom_size - start : size;
+ ha->optrom_region_size = start + size;
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
@@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
}
ha->optrom_region_start = start;
- ha->optrom_region_size = start + size > ha->optrom_size ?
- ha->optrom_size - start : size;
+ ha->optrom_region_size = start + size;
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zev Weiss <[email protected]>
commit 60361e12d01676e23a8de89a5ef4a349ae97f616 upstream.
stack_tracer_disable()/stack_tracer_enable() had been using the wrong
name for the config symbol to enable their preempt-debugging checks --
fix with a word swap.
Link: http://lkml.kernel.org/r/[email protected]
Fixes: 8aaf1ee70e ("tracing: Rename trace_active to disable_stack_tracer and inline its modification")
Signed-off-by: Zev Weiss <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 6383115e9d2c..2e028854bac7 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -307,7 +307,7 @@ DECLARE_PER_CPU(int, disable_stack_tracer);
static inline void stack_tracer_disable(void)
{
/* Preemption or interupts must be disabled */
- if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
this_cpu_inc(disable_stack_tracer);
}
@@ -320,7 +320,7 @@ static inline void stack_tracer_disable(void)
*/
static inline void stack_tracer_enable(void)
{
- if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
this_cpu_dec(disable_stack_tracer);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
commit 4759df905a474d245752c9dc94288e779b8734dd upstream.
Factor out sg_fill_request_table() for better readability.
[mkp: typos, applied by hand]
Signed-off-by: Hannes Reinecke <[email protected]>
Reviewed-by: Bart Van Assche <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/sg.c | 61 ++++++++++++++++++++++++++++++------------------------
1 file changed, 35 insertions(+), 26 deletions(-)
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -828,6 +828,40 @@ static int max_sectors_bytes(struct requ
return max_sectors << 9;
}
+static void
+sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo)
+{
+ Sg_request *srp;
+ int val;
+ unsigned int ms;
+
+ val = 0;
+ list_for_each_entry(srp, &sfp->rq_list, entry) {
+ if (val > SG_MAX_QUEUE)
+ break;
+ memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+ rinfo[val].req_state = srp->done + 1;
+ rinfo[val].problem =
+ srp->header.masked_status &
+ srp->header.host_status &
+ srp->header.driver_status;
+ if (srp->done)
+ rinfo[val].duration =
+ srp->header.duration;
+ else {
+ ms = jiffies_to_msecs(jiffies);
+ rinfo[val].duration =
+ (ms > srp->header.duration) ?
+ (ms - srp->header.duration) : 0;
+ }
+ rinfo[val].orphan = srp->orphan;
+ rinfo[val].sg_io_owned = srp->sg_io_owned;
+ rinfo[val].pack_id = srp->header.pack_id;
+ rinfo[val].usr_ptr = srp->header.usr_ptr;
+ val++;
+ }
+}
+
static long
sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
@@ -1012,38 +1046,13 @@ sg_ioctl(struct file *filp, unsigned int
return -EFAULT;
else {
sg_req_info_t *rinfo;
- unsigned int ms;
rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
GFP_KERNEL);
if (!rinfo)
return -ENOMEM;
read_lock_irqsave(&sfp->rq_list_lock, iflags);
- val = 0;
- list_for_each_entry(srp, &sfp->rq_list, entry) {
- if (val >= SG_MAX_QUEUE)
- break;
- memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
- rinfo[val].req_state = srp->done + 1;
- rinfo[val].problem =
- srp->header.masked_status &
- srp->header.host_status &
- srp->header.driver_status;
- if (srp->done)
- rinfo[val].duration =
- srp->header.duration;
- else {
- ms = jiffies_to_msecs(jiffies);
- rinfo[val].duration =
- (ms > srp->header.duration) ?
- (ms - srp->header.duration) : 0;
- }
- rinfo[val].orphan = srp->orphan;
- rinfo[val].sg_io_owned = srp->sg_io_owned;
- rinfo[val].pack_id = srp->header.pack_id;
- rinfo[val].usr_ptr = srp->header.usr_ptr;
- val++;
- }
+ sg_fill_request_table(sfp, rinfo);
read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
result = __copy_to_user(p, rinfo,
SZ_SG_REQ_INFO * SG_MAX_QUEUE);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 upstream.
for_each_active_irq() iterates the sparse irq allocation bitmap. The caller
must hold sparse_irq_lock. Several code pathes expect that an active bit in
the sparse bitmap also has a valid interrupt descriptor.
Unfortunately that's not true. The (de)allocation is a two step process,
which holds the sparse_irq_lock only across the queue/remove from the radix
tree and the set/clear in the allocation bitmap.
If a iteration locks sparse_irq_lock between the two steps, then it might
see an active bit but the corresponding irq descriptor is NULL. If that is
dereferenced unconditionally, then the kernel oopses. Of course, all
iterator sites could be audited and fixed, but....
There is no reason why the sparse_irq_lock needs to be dropped between the
two steps, in fact the code becomes simpler when the mutex is held across
both and the semantics become more straight forward, so future problems of
missing NULL pointer checks in the iteration are avoided and all existing
sites are fixed in one go.
Expand the lock held sections so both operations are covered and the bitmap
and the radixtree are in sync.
Fixes: a05a900a51c7 ("genirq: Make sparse_lock a mutex")
Reported-and-tested-by: Huang Ying <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/irq/irqdesc.c | 24 +++++++-----------------
1 file changed, 7 insertions(+), 17 deletions(-)
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -421,10 +421,8 @@ static void free_desc(unsigned int irq)
* The sysfs entry must be serialized against a concurrent
* irq_sysfs_init() as well.
*/
- mutex_lock(&sparse_irq_lock);
kobject_del(&desc->kobj);
delete_irq_desc(irq);
- mutex_unlock(&sparse_irq_lock);
/*
* We free the descriptor, masks and stat fields via RCU. That
@@ -462,20 +460,15 @@ static int alloc_descs(unsigned int star
desc = alloc_desc(start + i, node, flags, mask, owner);
if (!desc)
goto err;
- mutex_lock(&sparse_irq_lock);
irq_insert_desc(start + i, desc);
irq_sysfs_add(start + i, desc);
- mutex_unlock(&sparse_irq_lock);
}
+ bitmap_set(allocated_irqs, start, cnt);
return start;
err:
for (i--; i >= 0; i--)
free_desc(start + i);
-
- mutex_lock(&sparse_irq_lock);
- bitmap_clear(allocated_irqs, start, cnt);
- mutex_unlock(&sparse_irq_lock);
return -ENOMEM;
}
@@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned i
desc->owner = owner;
}
+ bitmap_set(allocated_irqs, start, cnt);
return start;
}
@@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, u
if (from >= nr_irqs || (from + cnt) > nr_irqs)
return;
+ mutex_lock(&sparse_irq_lock);
for (i = 0; i < cnt; i++)
free_desc(from + i);
- mutex_lock(&sparse_irq_lock);
bitmap_clear(allocated_irqs, from, cnt);
mutex_unlock(&sparse_irq_lock);
}
@@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int
from, cnt, 0);
ret = -EEXIST;
if (irq >=0 && start != irq)
- goto err;
+ goto unlock;
if (start + cnt > nr_irqs) {
ret = irq_expand_nr_irqs(start + cnt);
if (ret)
- goto err;
+ goto unlock;
}
-
- bitmap_set(allocated_irqs, start, cnt);
- mutex_unlock(&sparse_irq_lock);
- return alloc_descs(start, cnt, node, affinity, owner);
-
-err:
+ ret = alloc_descs(start, cnt, node, affinity, owner);
+unlock:
mutex_unlock(&sparse_irq_lock);
return ret;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit bde59c475e0883e4c4294bcd9b9c7e08ae18c828 upstream.
When an RX BA session is started by the driver, and it has to tell
mac80211 about it, the corresponding bit in tid_rx_manage_offl gets
set and the BA session work is scheduled. Upon testing this bit, it
will call __ieee80211_start_rx_ba_session(), thus deadlocking as it
already holds the ampdu_mlme.mtx, which that acquires again.
Fix this by adding ___ieee80211_start_rx_ba_session(), a version of
the function that requires the mutex already held.
Fixes: 699cb58c8a52 ("mac80211: manage RX BA session offload without SKB queue")
Reported-by: Matteo Croce <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/mac80211/agg-rx.c | 32 +++++++++++++++++++++-----------
net/mac80211/ht.c | 6 +++---
net/mac80211/ieee80211_i.h | 4 ++++
3 files changed, 28 insertions(+), 14 deletions(-)
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(st
ieee80211_tx_skb(sdata, skb);
}
-void __ieee80211_start_rx_ba_session(struct sta_info *sta,
- u8 dialog_token, u16 timeout,
- u16 start_seq_num, u16 ba_policy, u16 tid,
- u16 buf_size, bool tx, bool auto_seq)
+void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
+ u8 dialog_token, u16 timeout,
+ u16 start_seq_num, u16 ba_policy, u16 tid,
+ u16 buf_size, bool tx, bool auto_seq)
{
struct ieee80211_local *local = sta->sdata->local;
struct tid_ampdu_rx *tid_agg_rx;
@@ -267,7 +267,7 @@ void __ieee80211_start_rx_ba_session(str
ht_dbg(sta->sdata,
"STA %pM requests BA session on unsupported tid %d\n",
sta->sta.addr, tid);
- goto end_no_lock;
+ goto end;
}
if (!sta->sta.ht_cap.ht_supported) {
@@ -275,14 +275,14 @@ void __ieee80211_start_rx_ba_session(str
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
sta->sta.addr, tid);
/* send a response anyway, it's an error case if we get here */
- goto end_no_lock;
+ goto end;
}
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
ht_dbg(sta->sdata,
"Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
sta->sta.addr, tid);
- goto end_no_lock;
+ goto end;
}
/* sanity check for incoming parameters:
@@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(str
ht_dbg_ratelimited(sta->sdata,
"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
sta->sta.addr, tid, ba_policy, buf_size);
- goto end_no_lock;
+ goto end;
}
/* determine default buffer size */
if (buf_size == 0)
@@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(str
buf_size, sta->sta.addr);
/* examine state machine */
- mutex_lock(&sta->ampdu_mlme.mtx);
+ lockdep_assert_held(&sta->ampdu_mlme.mtx);
if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
@@ -415,15 +415,25 @@ end:
__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
}
- mutex_unlock(&sta->ampdu_mlme.mtx);
-end_no_lock:
if (tx)
ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
dialog_token, status, 1, buf_size,
timeout);
}
+void __ieee80211_start_rx_ba_session(struct sta_info *sta,
+ u8 dialog_token, u16 timeout,
+ u16 start_seq_num, u16 ba_policy, u16 tid,
+ u16 buf_size, bool tx, bool auto_seq)
+{
+ mutex_lock(&sta->ampdu_mlme.mtx);
+ ___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
+ start_seq_num, ba_policy, tid,
+ buf_size, tx, auto_seq);
+ mutex_unlock(&sta->ampdu_mlme.mtx);
+}
+
void ieee80211_process_addba_request(struct ieee80211_local *local,
struct sta_info *sta,
struct ieee80211_mgmt *mgmt,
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -333,9 +333,9 @@ void ieee80211_ba_session_work(struct wo
if (test_and_clear_bit(tid,
sta->ampdu_mlme.tid_rx_manage_offl))
- __ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
- IEEE80211_MAX_AMPDU_BUF,
- false, true);
+ ___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
+ IEEE80211_MAX_AMPDU_BUF,
+ false, true);
if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS,
sta->ampdu_mlme.tid_rx_manage_offl))
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(str
u8 dialog_token, u16 timeout,
u16 start_seq_num, u16 ba_policy, u16 tid,
u16 buf_size, bool tx, bool auto_seq);
+void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
+ u8 dialog_token, u16 timeout,
+ u16 start_seq_num, u16 ba_policy, u16 tid,
+ u16 buf_size, bool tx, bool auto_seq);
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
enum ieee80211_agg_stop_reason reason);
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
commit 596a7a1d0989c621c3ae49be73a1d1f9de22eb5a upstream.
On allocating the interrupts routed via a wire-to-MSI bridge, the allocator
iterates over the MSI descriptors to build the hierarchy, but fails to use
the descriptor interrupt number, and instead uses the base number,
generating the wrong IRQ domain mappings.
The fix is to use the MSI descriptor interrupt number when setting up
the interrupt instead of the base interrupt for the allocation range.
The only saving grace is that although the MSI descriptors are allocated
in bulk, the wired interrupts are only allocated one by one (so
desc->irq == virq) and the bug went unnoticed so far.
Fixes: 2145ac9310b60 ("genirq/msi: Add msi_domain_populate_irqs")
Signed-off-by: John Keeping <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Marc Zyngier <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/irq/msi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -315,11 +315,12 @@ int msi_domain_populate_irqs(struct irq_
ops->set_desc(arg, desc);
/* Assumes the domain mutex is held! */
- ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg);
+ ret = irq_domain_alloc_irqs_hierarchy(domain, desc->irq, 1,
+ arg);
if (ret)
break;
- irq_set_msi_desc_off(virq, 0, desc);
+ irq_set_msi_desc_off(desc->irq, 0, desc);
}
if (ret) {
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 9cb067ef8a10bb13112e4d1c0ea996ec96527422 upstream.
The result of cpumask_any_and() is invalid when result greater or equal
nr_cpu_ids. The current check is checking for greater only. Fix it.
Fixes: 761ea388e8c4 ("genirq: Handle managed irqs gracefully in irq_startup()")
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Boris Ostrovsky <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Chen Yu <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Alok Kataria <[email protected]>
Cc: Joerg Roedel <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Rui Zhang <[email protected]>
Cc: "K. Y. Srinivasan" <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Len Brown <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/irq/chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -202,7 +202,7 @@ __irq_startup_managed(struct irq_desc *d
irqd_clr_managed_shutdown(d);
- if (cpumask_any_and(aff, cpu_online_mask) > nr_cpu_ids) {
+ if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
/*
* Catch code which fiddles with enable_irq() on a managed
* and potentially shutdown IRQ. Chained interrupt
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anup Patel <[email protected]>
commit 6d2061b981af165d3e45462e0804b5a1f2f4c7bc upstream.
The mask used in CMPL_START_ADDR_VALUE() should be 27bits instead of
26bits. This incorrect mask was causing completion writes to 40bits
physical address fail.
This patch fixes mask used in CMPL_START_ADDR_VALUE() macro.
Fixes: dbc049eee730 ("mailbox: Add driver for Broadcom FlexRM
ring manager")
Signed-off-by: Anup Patel <[email protected]>
Reviewed-by: Ray Jui <[email protected]>
Reviewed-by: Scott Branden <[email protected]>
Signed-off-by: Jassi Brar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/mailbox/bcm-flexrm-mailbox.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -95,7 +95,7 @@
/* Register RING_CMPL_START_ADDR fields */
#define CMPL_START_ADDR_VALUE(pa) \
- ((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x03ffffff))
+ ((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x07ffffff))
/* Register RING_CONTROL fields */
#define CONTROL_MASK_DISABLE_CONTROL 12
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quinn Tran <[email protected]>
commit b2e8ae3f0e342a3308b4573790bd42528e51885a upstream.
The Get Port Speed switch command needs the fabric port name of the
remote device. Current code uses the registered WWPN.
Fixes: 726b85487067d ("qla2xxx: Add framework for async fabric discovery")
Cc: <[email protected]> # 4.10+
Signed-off-by: Quinn Tran <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_gs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3080,7 +3080,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *
GPSC_RSP_SIZE);
/* GPSC req */
- memcpy(ct_req->req.gpsc.port_name, fcport->port_name,
+ memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
WWN_SIZE);
sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avraham Stern <[email protected]>
commit 6e46d8ce894374fc135c96a8d1057c6af1fef237 upstream.
When HW ROC is supported it is possible that after the HW notified
that the ROC has started, the ROC was cancelled and another ROC was
added while the hw_roc_start worker is waiting on the mutex (since
cancelling the ROC and adding another one also holds the same mutex).
As a result, the hw_roc_start worker will continue to run after the
new ROC is added but before it is actually started by the HW.
This may result in notifying userspace that the ROC has started before
it actually does, or in case of management tx ROC, in an attempt to
tx while not on the right channel.
In addition, when the driver will notify mac80211 that the second ROC
has started, mac80211 will warn that this ROC has already been
notified.
Fix this by flushing the hw_roc_start work before cancelling an ROC.
Cc: [email protected]
Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/mac80211/offchannel.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct i
if (!cookie)
return -ENOENT;
+ flush_work(&local->hw_roc_start);
+
mutex_lock(&local->mtx);
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
if (!mgmt_tx && roc->cookie != cookie)
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beni Lev <[email protected]>
commit 9de981f507474f326e42117858dc9a9321331ae5 upstream.
In struct ieee80211_tx_info, control.vif pointer and rate_driver_data[0]
falls on the same place, depending on the union usage.
During the whole TX process, the union is referred to as a control struct,
which holds the vif that is later used in the tx flow, especially in order
to derive the used tx power.
Referring direcly to rate_driver_data[0] and assigning a value to it,
overwrites the vif pointer, hence making all later references irrelevant.
Moreover, rate_driver_data[0] isn't used later in the flow in order to
retrieve the channel that it is pointing to.
Signed-off-by: Beni Lev <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1362,8 +1362,6 @@ static void mac80211_hwsim_tx(struct iee
txi->control.rates,
ARRAY_SIZE(txi->control.rates));
- txi->rate_driver_data[0] = channel;
-
if (skb->len >= 24 + 8 &&
ieee80211_is_probe_resp(hdr->frame_control)) {
/* fake header transmission time */
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Coelho <[email protected]>
commit 01a9c948a09348950515bf2abb6113ed83e696d8 upstream.
The OTP in some SKUs have erroneously allowed 40MHz and 80MHz channels
in the 5.2GHz band. The firmware has been modified to not allow this
in those SKUs, so the driver needs to do the same otherwise the
firmware will assert when we try to use it.
Signed-off-by: Luca Coelho <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 62 +++++++++++++++++----
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | 3 -
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 3 -
3 files changed, 56 insertions(+), 12 deletions(-)
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -79,6 +79,7 @@
/* NVM offsets (in words) definitions */
enum wkp_nvm_offsets {
/* NVM HW-Section offset (in words) definitions */
+ SUBSYSTEM_ID = 0x0A,
HW_ADDR = 0x15,
/* NVM SW-Section offset (in words) definitions */
@@ -254,13 +255,12 @@ static u32 iwl_get_channel_flags(u8 ch_n
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 * const nvm_ch_flags,
- bool lar_supported)
+ bool lar_supported, bool no_wide_in_5ghz)
{
int ch_idx;
int n_channels = 0;
struct ieee80211_channel *channel;
u16 ch_flags;
- bool is_5ghz;
int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan;
@@ -275,12 +275,20 @@ static int iwl_init_channel_map(struct d
}
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
+ bool is_5ghz = (ch_idx >= num_2ghz_channels);
+
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
- if (ch_idx >= num_2ghz_channels &&
- !data->sku_cap_band_52GHz_enable)
+ if (is_5ghz && !data->sku_cap_band_52GHz_enable)
continue;
+ /* workaround to disable wide channels in 5GHz */
+ if (no_wide_in_5ghz && is_5ghz) {
+ ch_flags &= ~(NVM_CHANNEL_40MHZ |
+ NVM_CHANNEL_80MHZ |
+ NVM_CHANNEL_160MHZ);
+ }
+
if (ch_flags & NVM_CHANNEL_160MHZ)
data->vht160_supported = true;
@@ -303,8 +311,8 @@ static int iwl_init_channel_map(struct d
n_channels++;
channel->hw_value = nvm_chan[ch_idx];
- channel->band = (ch_idx < num_2ghz_channels) ?
- NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+ channel->band = is_5ghz ?
+ NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
channel->center_freq =
ieee80211_channel_to_frequency(
channel->hw_value, channel->band);
@@ -316,7 +324,6 @@ static int iwl_init_channel_map(struct d
* is not used in mvm, and is used for backwards compatibility
*/
channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
- is_5ghz = channel->band == NL80211_BAND_5GHZ;
/* don't put limitations in case we're using LAR */
if (!lar_supported)
@@ -432,14 +439,15 @@ static void iwl_init_vht_hw_capab(const
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
- u8 tx_chains, u8 rx_chains, bool lar_supported)
+ u8 tx_chains, u8 rx_chains, bool lar_supported,
+ bool no_wide_in_5ghz)
{
int n_channels;
int n_used = 0;
struct ieee80211_supported_band *sband;
n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
- lar_supported);
+ lar_supported, no_wide_in_5ghz);
sband = &data->bands[NL80211_BAND_2GHZ];
sband->band = NL80211_BAND_2GHZ;
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -645,6 +653,39 @@ static int iwl_set_hw_address(struct iwl
return 0;
}
+static bool
+iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
+ const __le16 *nvm_hw)
+{
+ /*
+ * Workaround a bug in Indonesia SKUs where the regulatory in
+ * some 7000-family OTPs erroneously allow wide channels in
+ * 5GHz. To check for Indonesia, we take the SKU value from
+ * bits 1-4 in the subsystem ID and check if it is either 5 or
+ * 9. In those cases, we need to force-disable wide channels
+ * in 5GHz otherwise the FW will throw a sysassert when we try
+ * to use them.
+ */
+ if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ /*
+ * Unlike the other sections in the NVM, the hw
+ * section uses big-endian.
+ */
+ u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw
+ + SUBSYSTEM_ID);
+ u8 sku = (subsystem_id & 0x1e) >> 1;
+
+ if (sku == 5 || sku == 9) {
+ IWL_DEBUG_EEPROM(dev,
+ "disabling wide channels in 5GHz (0x%0x %d)\n",
+ subsystem_id, sku);
+ return true;
+ }
+ }
+
+ return false;
+}
+
struct iwl_nvm_data *
iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw,
@@ -655,6 +696,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
struct device *dev = trans->dev;
struct iwl_nvm_data *data;
bool lar_enabled;
+ bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
u32 sku, radio_cfg;
u16 lar_config;
const __le16 *ch_section;
@@ -725,7 +767,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
}
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
- lar_fw_supported && lar_enabled);
+ lar_fw_supported && lar_enabled, no_wide_in_5ghz);
data->calib_version = 255;
return data;
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
@@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct
*/
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
- u8 tx_chains, u8 rx_chains, bool lar_supported);
+ u8 tx_chains, u8 rx_chains, bool lar_supported,
+ bool no_wide_in_5ghz);
/**
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -628,7 +628,8 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_m
rsp->regulatory.channel_profile,
mvm->nvm_data->valid_tx_ant & mvm->fw->valid_tx_ant,
mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant,
- rsp->regulatory.lar_enabled && lar_fw_supported);
+ rsp->regulatory.lar_enabled && lar_fw_supported,
+ false);
iwl_free_resp(&hcmd);
return 0;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Lyle <[email protected]>
commit 9276717b9e297a62d1151a43d1cd286213f68eb7 upstream.
Most importantly, solve a crash where %llu was used to format signed
numbers. This would cause a buffer overflow when reading sysfs
writeback_rate_debug, as only 20 bytes were allocated for this and
%llu writes 20 characters plus a null.
Always use the units mechanism rather than having different output
paths for simplicity.
Also, correct problems with display output where 1.10 was a larger
number than 1.09, by multiplying by 10 and then dividing by 1024 instead
of dividing by 100. (Remainders of >= 1000 would print as .10).
Minor changes: Always display the decimal point instead of trying to
omit it based on number of digits shown. Decide what units to use
based on 1000 as a threshold, not 1024 (in other words, always print
at most 3 digits before the decimal point).
Signed-off-by: Michael Lyle <[email protected]>
Reported-by: Dmitry Yu Okunev <[email protected]>
Acked-by: Kent Overstreet <[email protected]>
Reviewed-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/util.c | 46 +++++++++++++++++++++++++++++++++-------------
1 file changed, 33 insertions(+), 13 deletions(-)
--- a/drivers/md/bcache/util.c
+++ b/drivers/md/bcache/util.c
@@ -74,24 +74,44 @@ STRTO_H(strtouint, unsigned int)
STRTO_H(strtoll, long long)
STRTO_H(strtoull, unsigned long long)
+/**
+ * bch_hprint() - formats @v to human readable string for sysfs.
+ *
+ * @v - signed 64 bit integer
+ * @buf - the (at least 8 byte) buffer to format the result into.
+ *
+ * Returns the number of bytes used by format.
+ */
ssize_t bch_hprint(char *buf, int64_t v)
{
static const char units[] = "?kMGTPEZY";
- char dec[4] = "";
- int u, t = 0;
+ int u = 0, t;
- for (u = 0; v >= 1024 || v <= -1024; u++) {
- t = v & ~(~0 << 10);
- v >>= 10;
- }
+ uint64_t q;
- if (!u)
- return sprintf(buf, "%llu", v);
-
- if (v < 100 && v > -100)
- snprintf(dec, sizeof(dec), ".%i", t / 100);
-
- return sprintf(buf, "%lli%s%c", v, dec, units[u]);
+ if (v < 0)
+ q = -v;
+ else
+ q = v;
+
+ /* For as long as the number is more than 3 digits, but at least
+ * once, shift right / divide by 1024. Keep the remainder for
+ * a digit after the decimal point.
+ */
+ do {
+ u++;
+
+ t = q & ~(~0 << 10);
+ q >>= 10;
+ } while (q >= 1000);
+
+ if (v < 0)
+ /* '-', up to 3 digits, '.', 1 digit, 1 character, null;
+ * yields 8 bytes.
+ */
+ return sprintf(buf, "-%llu.%i%c", q, t * 10 / 1024, units[u]);
+ else
+ return sprintf(buf, "%llu.%i%c", q, t * 10 / 1024, units[u]);
}
ssize_t bch_snprint_string_list(char *buf, size_t size, const char * const list[],
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tang Junhui <[email protected]>
commit a8394090a9129b40f9d90dcb7f4a49d60c727ca6 upstream.
__update_write_rate() uses a Proportion-Differentiation Controller
algorithm to control writeback rate. A dirty target number is used in
this PD controller to control writeback rate. A larger target number
will make the writeback rate smaller, on the versus, a smaller target
number will make the writeback rate larger.
bcache uses the following steps to calculate the target number,
1) cache_sectors = all-buckets-of-cache-set * buckets-size
2) cache_dirty_target = cache_sectors * cached-device-writeback_percent
3) target = cache_dirty_target *
(sectors-of-cached-device/sectors-of-all-cached-devices-of-this-cache-set)
The calculation at step 1) for cache_sectors is incorrect, which does
not consider dirty blocks occupied by flash only volume.
A flash only volume can be took as a bcache device without cached
device. All data sectors allocated for it are persistent on cache device
and marked dirty, they are not touched by bcache writeback and garbage
collection code. So data blocks of flash only volume should be ignore
when calculating cache_sectors of cache set.
Current code does not subtract dirty sectors of flash only volume, which
results a larger target number from the above 3 steps. And in sequence
the cache device's writeback rate is smaller then a correct value,
writeback speed is slower on all cached devices.
This patch fixes the incorrect slower writeback rate by subtracting
dirty sectors of flash only volumes in __update_writeback_rate().
(Commit log composed by Coly Li to pass checkpatch.pl checking)
Signed-off-by: Tang Junhui <[email protected]>
Reviewed-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/writeback.c | 3 ++-
drivers/md/bcache/writeback.h | 19 +++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -21,7 +21,8 @@
static void __update_writeback_rate(struct cached_dev *dc)
{
struct cache_set *c = dc->disk.c;
- uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size;
+ uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size -
+ bcache_flash_devs_sectors_dirty(c);
uint64_t cache_dirty_target =
div_u64(cache_sectors * dc->writeback_percent, 100);
--- a/drivers/md/bcache/writeback.h
+++ b/drivers/md/bcache/writeback.h
@@ -14,6 +14,25 @@ static inline uint64_t bcache_dev_sector
return ret;
}
+static inline uint64_t bcache_flash_devs_sectors_dirty(struct cache_set *c)
+{
+ uint64_t i, ret = 0;
+
+ mutex_lock(&bch_register_lock);
+
+ for (i = 0; i < c->nr_uuids; i++) {
+ struct bcache_device *d = c->devices[i];
+
+ if (!d || !UUID_FLASH_ONLY(&c->uuids[i]))
+ continue;
+ ret += bcache_dev_sectors_dirty(d);
+ }
+
+ mutex_unlock(&bch_register_lock);
+
+ return ret;
+}
+
static inline unsigned offset_to_stripe(struct bcache_device *d,
uint64_t offset)
{
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Carnuccio <[email protected]>
commit 6e98095f8fb6d98da34c4e6c34e69e7c638d79c0 upstream.
Fix incorrect second argument for wait_event_timeout()
Fixes: c4a9b538ab2a ("qla2xxx: Allow vref count to timeout on vport delete.")
Signed-off-by: Joe Carnuccio <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_mid.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -74,7 +74,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t
* ensures no active vp_list traversal while the vport is removed
* from the queue)
*/
- wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count),
+ wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
10*HZ);
spin_lock_irqsave(&ha->vport_slock, flags);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tang Junhui <[email protected]>
commit 175206cf9ab63161dec74d9cd7f9992e062491f5 upstream.
bcache uses a Proportion-Differentiation Controller algorithm to control
writeback rate to cached devices. In the PD controller algorithm, dirty
stripes of thin flash device should not be counted in, because flash only
volumes never write back dirty data.
Currently dirty stripe counter for thin flash device is not initialized
when the thin flash device starts. Which means the following calculation
in PD controller will reference an undefined dirty stripes number, and
all cached devices attached to the same cache set where the thin flash
device lies on may have an inaccurate writeback rate.
This patch calles bch_sectors_dirty_init() in flash_dev_run(), to
correctly initialize dirty stripe counter when the thin flash device
starts to run. This patch also does following parameter data type change,
-void bch_sectors_dirty_init(struct cached_dev *dc);
+void bch_sectors_dirty_init(struct bcache_device *);
to call this function conveniently in flash_dev_run().
(Commit log is composed by Coly Li)
Signed-off-by: Tang Junhui <[email protected]>
Reviewed-by: Coly Li <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bcache/super.c | 3 ++-
drivers/md/bcache/writeback.c | 8 ++++----
drivers/md/bcache/writeback.h | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1026,7 +1026,7 @@ int bch_cached_dev_attach(struct cached_
}
if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
- bch_sectors_dirty_init(dc);
+ bch_sectors_dirty_init(&dc->disk);
atomic_set(&dc->has_dirty, 1);
atomic_inc(&dc->count);
bch_writeback_queue(dc);
@@ -1228,6 +1228,7 @@ static int flash_dev_run(struct cache_se
goto err;
bcache_device_attach(d, c, u - c->uuids);
+ bch_sectors_dirty_init(d);
bch_flash_dev_request_init(d);
add_disk(d->disk);
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -482,17 +482,17 @@ static int sectors_dirty_init_fn(struct
return MAP_CONTINUE;
}
-void bch_sectors_dirty_init(struct cached_dev *dc)
+void bch_sectors_dirty_init(struct bcache_device *d)
{
struct sectors_dirty_init op;
bch_btree_op_init(&op.op, -1);
- op.inode = dc->disk.id;
+ op.inode = d->id;
- bch_btree_map_keys(&op.op, dc->disk.c, &KEY(op.inode, 0, 0),
+ bch_btree_map_keys(&op.op, d->c, &KEY(op.inode, 0, 0),
sectors_dirty_init_fn, 0);
- dc->disk.sectors_dirty_last = bcache_dev_sectors_dirty(&dc->disk);
+ d->sectors_dirty_last = bcache_dev_sectors_dirty(d);
}
void bch_cached_dev_writeback_init(struct cached_dev *dc)
--- a/drivers/md/bcache/writeback.h
+++ b/drivers/md/bcache/writeback.h
@@ -84,7 +84,7 @@ static inline void bch_writeback_add(str
void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
-void bch_sectors_dirty_init(struct cached_dev *dc);
+void bch_sectors_dirty_init(struct bcache_device *);
void bch_cached_dev_writeback_init(struct cached_dev *);
int bch_cached_dev_writeback_start(struct cached_dev *);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ulrich Hecht <[email protected]>
commit 281ddc3cdc10413b98531d701ab5323c4f3ff1f4 upstream.
Fixes a crash on Renesas R8A7793 Gose board that uses these "compatible"
entries.
Signed-off-by: Ulrich Hecht <[email protected]>
Tested-by: Geert Uytterhoeven <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/i2c/adv7180.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1402,6 +1402,8 @@ static int adv7180_remove(struct i2c_cli
static const struct i2c_device_id adv7180_id[] = {
{ "adv7180", (kernel_ulong_t)&adv7180_info },
+ { "adv7180cp", (kernel_ulong_t)&adv7180_info },
+ { "adv7180st", (kernel_ulong_t)&adv7180_info },
{ "adv7182", (kernel_ulong_t)&adv7182_info },
{ "adv7280", (kernel_ulong_t)&adv7280_info },
{ "adv7280-m", (kernel_ulong_t)&adv7280_m_info },
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young <[email protected]>
commit a607f51e5a4c421e2097077db88105402099c528 upstream.
This reverts commit 5be2b76a9ca4ea5fd3e221114d62eeb0d78267ca.
Only when the lirc device is freed, should we drop our reference to
rc_dev, else we the rc_dev is freed to early. If userspace has
a file descriptor open during unplug, it goes bang.
==================================================================
BUG: KASAN: use-after-free in __lock_acquire+0x7bb/0x1e10
Read of size 8 at addr ffff8801d7d61ed0 by task ir-rec/2609
-snip-
mutex_lock_nested+0x1b/0x20
? mutex_lock_nested+0x1b/0x20
rc_close.part.6+0x20/0x60 [rc_core]
rc_close+0x13/0x20 [rc_core]
lirc_dev_fop_close+0x62/0xd0 [lirc_dev]
__fput+0x236/0x410
? fput+0xb0/0xb0
? do_raw_spin_trylock+0x110/0x110
? set_rq_offline.part.70+0xa0/0xa0
____fput+0xe/0x10
task_work_run+0x116/0x180
? task_work_cancel+0x170/0x170
? _raw_spin_unlock+0x27/0x40
? switch_task_namespaces+0x5f/0x90
do_exit+0x68b/0xe80
Fixes: 5be2b76a9ca4 ("[media] lirc_dev: remove superfluous get/put_device() calls")
Signed-off-by: Sean Young <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/rc/lirc_dev.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -59,6 +59,8 @@ static void lirc_release(struct device *
{
struct irctl *ir = container_of(ld, struct irctl, dev);
+ put_device(ir->dev.parent);
+
if (ir->buf_internal) {
lirc_buffer_free(ir->buf);
kfree(ir->buf);
@@ -218,6 +220,8 @@ int lirc_register_driver(struct lirc_dri
mutex_unlock(&lirc_dev_lock);
+ get_device(ir->dev.parent);
+
dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
ir->d.name, ir->d.minor);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva <[email protected]>
commit 0de0ef6c3f2dd7e9965270683445917e10384ab0 upstream.
Call function v4l2_m2m_dst_buf_remove_by_buf() instead of
v4l2_m2m_src_buf_remove_by_buf()
Addresses-Coverity-ID: 1415317
Signed-off-by: Gustavo A. R. Silva <[email protected]>
Acked-by: Stanimir Varbanov <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/platform/qcom/venus/helpers.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -243,7 +243,7 @@ static void return_buf_error(struct venu
if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf);
else
- v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf);
+ v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf);
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Schwidefsky <[email protected]>
commit 60f07c8ec5fae06c23e9fd7bab67dabce92b3414 upstream.
The order in __tlb_flush_mm_lazy is to flush TLB first and then clear
the mm->context.flush_mm bit. This can lead to missed flushes as the
bit can be set anytime, the order needs to be the other way aronud.
But this leads to a different race, __tlb_flush_mm_lazy may be called
on two CPUs concurrently. If mm->context.flush_mm is cleared first then
another CPU can bypass __tlb_flush_mm_lazy although the first CPU has
not done the flush yet. In a virtualized environment the time until the
flush is finally completed can be arbitrarily long.
Add a spinlock to serialize __tlb_flush_mm_lazy and use the function
in finish_arch_post_lock_switch as well.
Reviewed-by: Heiko Carstens <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/s390/include/asm/mmu.h | 2 ++
arch/s390/include/asm/mmu_context.h | 4 ++--
arch/s390/include/asm/tlbflush.h | 4 +++-
3 files changed, 7 insertions(+), 3 deletions(-)
--- a/arch/s390/include/asm/mmu.h
+++ b/arch/s390/include/asm/mmu.h
@@ -5,6 +5,7 @@
#include <linux/errno.h>
typedef struct {
+ spinlock_t lock;
cpumask_t cpu_attach_mask;
atomic_t flush_count;
unsigned int flush_mm;
@@ -27,6 +28,7 @@ typedef struct {
} mm_context_t;
#define INIT_MM_CONTEXT(name) \
+ .context.lock = __SPIN_LOCK_UNLOCKED(name.context.lock), \
.context.pgtable_lock = \
__SPIN_LOCK_UNLOCKED(name.context.pgtable_lock), \
.context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list), \
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -16,6 +16,7 @@
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
{
+ spin_lock_init(&mm->context.lock);
spin_lock_init(&mm->context.pgtable_lock);
INIT_LIST_HEAD(&mm->context.pgtable_list);
spin_lock_init(&mm->context.gmap_lock);
@@ -120,8 +121,7 @@ static inline void finish_arch_post_lock
while (atomic_read(&mm->context.flush_count))
cpu_relax();
cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
- if (mm->context.flush_mm)
- __tlb_flush_mm(mm);
+ __tlb_flush_mm_lazy(mm);
preempt_enable();
}
set_fs(current->thread.mm_segment);
--- a/arch/s390/include/asm/tlbflush.h
+++ b/arch/s390/include/asm/tlbflush.h
@@ -96,10 +96,12 @@ static inline void __tlb_flush_kernel(vo
static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)
{
+ spin_lock(&mm->context.lock);
if (mm->context.flush_mm) {
- __tlb_flush_mm(mm);
mm->context.flush_mm = 0;
+ __tlb_flush_mm(mm);
}
+ spin_unlock(&mm->context.lock);
}
/*
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: [email protected] <[email protected]>
commit e6373f33a6bba0de9f543f4a7faeaaa536c62997 upstream.
Fixes: 4b60c82736d0 ("scsi: qla2xxx: Add fw_started flags to qpair")
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qla2xxx/qla_init.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7804,6 +7804,7 @@ struct qla_qpair *qla2xxx_create_qpair(s
ha->queue_pair_map[qpair_id] = qpair;
qpair->id = qpair_id;
qpair->vp_idx = vp_idx;
+ qpair->fw_started = ha->flags.fw_started;
INIT_LIST_HEAD(&qpair->hints_list);
qpair->chip_reset = ha->base_qpair->chip_reset;
qpair->enable_class_2 = ha->base_qpair->enable_class_2;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
commit 7612b3b28c0b900dcbcdf5e9b9747cc20a1e2455 upstream.
When a power fault occurs, the power controller sets Power Fault Detected
in the Slot Status register, and pciehp_isr() queues an INT_POWER_FAULT
event to handle it.
It also clears Power Fault Detected, but since nothing has yet changed to
correct the power fault, the power controller will likely set it again
immediately, which may cause an infinite loop when pcie_isr() rechecks
Slot Status.
Fix that by masking off Power Fault Detected from new events if the driver
hasn't seen the power fault clear from the previous handling attempt.
Fixes: fad214b0aa72 ("PCI: pciehp: Process all hotplug events before looking for new ones")
Signed-off-by: Keith Busch <[email protected]>
[bhelgaas: changelog, pull test out and add comment]
Signed-off-by: Bjorn Helgaas <[email protected]>
Cc: Mayurkumar Patel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pci/hotplug/pciehp_hpc.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -586,6 +586,14 @@ static irqreturn_t pciehp_isr(int irq, v
events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC |
PCI_EXP_SLTSTA_DLLSC);
+
+ /*
+ * If we've already reported a power fault, don't report it again
+ * until we've done something to handle it.
+ */
+ if (ctrl->power_fault_detected)
+ events &= ~PCI_EXP_SLTSTA_PFD;
+
if (!events)
return IRQ_NONE;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <[email protected]>
commit 3ef0c7a730de0bae03d86c19570af764fa3c4445 upstream.
As we want to remove spin_unlock_wait() and replace it with explicit
spin_lock()/spin_unlock() calls, we can use this to simplify the
locking.
In addition:
- Reading nf_conntrack_locks_all needs ACQUIRE memory ordering.
- The new code avoids the backwards loop.
Only slightly tested, I did not manage to trigger calls to
nf_conntrack_all_lock().
V2: With improved comments, to clearly show how the barriers
pair.
Fixes: b16c29191dc8 ("netfilter: nf_conntrack: use safer way to lock all buckets")
Signed-off-by: Manfred Spraul <[email protected]>
Cc: Alan Stern <[email protected]>
Cc: Sasha Levin <[email protected]>
Cc: Pablo Neira Ayuso <[email protected]>
Cc: [email protected]
Signed-off-by: Paul E. McKenney <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/netfilter/nf_conntrack_core.c | 52 +++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 23 deletions(-)
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -96,19 +96,26 @@ static struct conntrack_gc_work conntrac
void nf_conntrack_lock(spinlock_t *lock) __acquires(lock)
{
+ /* 1) Acquire the lock */
spin_lock(lock);
- while (unlikely(nf_conntrack_locks_all)) {
- spin_unlock(lock);
- /*
- * Order the 'nf_conntrack_locks_all' load vs. the
- * spin_unlock_wait() loads below, to ensure
- * that 'nf_conntrack_locks_all_lock' is indeed held:
- */
- smp_rmb(); /* spin_lock(&nf_conntrack_locks_all_lock) */
- spin_unlock_wait(&nf_conntrack_locks_all_lock);
- spin_lock(lock);
- }
+ /* 2) read nf_conntrack_locks_all, with ACQUIRE semantics
+ * It pairs with the smp_store_release() in nf_conntrack_all_unlock()
+ */
+ if (likely(smp_load_acquire(&nf_conntrack_locks_all) == false))
+ return;
+
+ /* fast path failed, unlock */
+ spin_unlock(lock);
+
+ /* Slow path 1) get global lock */
+ spin_lock(&nf_conntrack_locks_all_lock);
+
+ /* Slow path 2) get the lock we want */
+ spin_lock(lock);
+
+ /* Slow path 3) release the global lock */
+ spin_unlock(&nf_conntrack_locks_all_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
@@ -149,28 +156,27 @@ static void nf_conntrack_all_lock(void)
int i;
spin_lock(&nf_conntrack_locks_all_lock);
- nf_conntrack_locks_all = true;
- /*
- * Order the above store of 'nf_conntrack_locks_all' against
- * the spin_unlock_wait() loads below, such that if
- * nf_conntrack_lock() observes 'nf_conntrack_locks_all'
- * we must observe nf_conntrack_locks[] held:
- */
- smp_mb(); /* spin_lock(&nf_conntrack_locks_all_lock) */
+ nf_conntrack_locks_all = true;
for (i = 0; i < CONNTRACK_LOCKS; i++) {
- spin_unlock_wait(&nf_conntrack_locks[i]);
+ spin_lock(&nf_conntrack_locks[i]);
+
+ /* This spin_unlock provides the "release" to ensure that
+ * nf_conntrack_locks_all==true is visible to everyone that
+ * acquired spin_lock(&nf_conntrack_locks[]).
+ */
+ spin_unlock(&nf_conntrack_locks[i]);
}
}
static void nf_conntrack_all_unlock(void)
{
- /*
- * All prior stores must be complete before we clear
+ /* All prior stores must be complete before we clear
* 'nf_conntrack_locks_all'. Otherwise nf_conntrack_lock()
* might observe the false value but not the entire
- * critical section:
+ * critical section.
+ * It pairs with the smp_load_acquire() in nf_conntrack_lock()
*/
smp_store_release(&nf_conntrack_locks_all, false);
spin_unlock(&nf_conntrack_locks_all_lock);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Bezzubikov <[email protected]>
commit 48b79a14505349a29b3e20f03619ada9b33c4b17 upstream.
An SHPC may generate MSIs to notify software about slot or controller
events (SHPC spec r1.0, sec 4.7). A PCI device can only generate an MSI if
it has bus mastering enabled.
Enable bus mastering if the bridge contains an SHPC that uses MSI for event
notifications.
Signed-off-by: Aleksandr Bezzubikov <[email protected]>
[bhelgaas: changelog]
Signed-off-by: Bjorn Helgaas <[email protected]>
Reviewed-by: Marcel Apfelbaum <[email protected]>
Acked-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pci/hotplug/shpchp_hpc.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1062,6 +1062,8 @@ int shpc_init(struct controller *ctrl, s
if (rc) {
ctrl_info(ctrl, "Can't get msi for the hotplug controller\n");
ctrl_info(ctrl, "Use INTx for the hotplug controller\n");
+ } else {
+ pci_set_master(pdev);
}
rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunyu Hu <[email protected]>
commit 7685ab6c58557c6234f3540260195ecbee7fc4b3 upstream.
When disabling one trace event, the RECORDED_TGID flag in the event
file is not correctly cleared. It's clearing RECORDED_CMD flag when
it should clear RECORDED_TGID flag.
Link: http://lkml.kernel.org/r/[email protected]
Cc: Joel Fernandes <[email protected]>
Fixes: d914ba37d7 ("tracing: Add support for recording tgid of tasks")
Signed-off-by: Chunyu Hu <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/trace/trace_events.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -406,7 +406,7 @@ static int __ftrace_event_enable_disable
if (file->flags & EVENT_FILE_FL_RECORDED_TGID) {
tracing_stop_tgid_record();
- clear_bit(EVENT_FILE_FL_RECORDED_CMD_BIT, &file->flags);
+ clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags);
}
call->class->reg(call, TRACE_REG_UNREGISTER, file);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baohong Liu <[email protected]>
commit 170b3b1050e28d1ba0700e262f0899ffa4fccc52 upstream.
Currently trace_clock timestamps are applied to both regular and max
buffers only for global trace. For instance trace, trace_clock
timestamps are applied only to regular buffer. But, regular and max
buffers can be swapped, for example, following a snapshot. So, for
instance trace, bad timestamps can be seen following a snapshot.
Let's apply trace_clock timestamps to instance max buffer as well.
Link: http://lkml.kernel.org/r/ebdb168d0be042dcdf51f81e696b17fabe3609c1.1504642143.git.tom.zanussi@linux.intel.com
Fixes: 277ba0446 ("tracing: Add interface to allow multiple trace buffers")
Signed-off-by: Baohong Liu <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/trace/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6226,7 +6226,7 @@ static int tracing_set_clock(struct trac
tracing_reset_online_cpus(&tr->trace_buffer);
#ifdef CONFIG_TRACER_MAX_TRACE
- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer)
+ if (tr->max_buffer.buffer)
ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func);
tracing_reset_online_cpus(&tr->max_buffer);
#endif
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
commit 3e0097499839e0fe3af380410eababe5a47c4cf9 upstream.
When calling SG_GET_REQUEST_TABLE ioctl only a half-filled table is
returned; the remaining part will then contain stale kernel memory
information. This patch zeroes out the entire table to avoid this
issue.
Signed-off-by: Hannes Reinecke <[email protected]>
Reviewed-by: Bart Van Assche <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/sg.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -839,7 +839,6 @@ sg_fill_request_table(Sg_fd *sfp, sg_req
list_for_each_entry(srp, &sfp->rq_list, entry) {
if (val > SG_MAX_QUEUE)
break;
- memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
rinfo[val].req_state = srp->done + 1;
rinfo[val].problem =
srp->header.masked_status &
@@ -1047,8 +1046,8 @@ sg_ioctl(struct file *filp, unsigned int
else {
sg_req_info_t *rinfo;
- rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
- GFP_KERNEL);
+ rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+ GFP_KERNEL);
if (!rinfo)
return -ENOMEM;
read_lock_irqsave(&sfp->rq_list_lock, iflags);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) <[email protected]>
commit 46320a6acc4fb58f04bcf78c4c942cc43b20f986 upstream.
In the second iteration of trace_selftest_ops(), the error goto label is
wrong in the case where trace_selftest_test_global_cnt is off. In the
case of error, it leaks the dynamic ops that was allocated.
Fixes: 95950c2e ("ftrace: Add self-tests for multiple function trace users")
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/trace/trace_selftest.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -273,7 +273,7 @@ static int trace_selftest_ops(struct tra
goto out_free;
if (cnt > 1) {
if (trace_selftest_test_global_cnt == 0)
- goto out;
+ goto out_free;
}
if (trace_selftest_test_dyn_cnt == 0)
goto out_free;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 3c08377262880afc1621ab9cb6dbe7df47a6033d upstream.
Due to the use of per-CPU buffers, scomp_acomp_comp_decomp() executes
with preemption disabled, and so whether the CRYPTO_TFM_REQ_MAY_SLEEP
flag is set is irrelevant, since we cannot sleep anyway. So disregard
the flag, and use GFP_ATOMIC unconditionally.
Signed-off-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
crypto/scompress.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/crypto/scompress.c
+++ b/crypto/scompress.c
@@ -211,9 +211,7 @@ static int scomp_acomp_comp_decomp(struc
scratch_dst, &req->dlen, *ctx);
if (!ret) {
if (!req->dst) {
- req->dst = crypto_scomp_sg_alloc(req->dlen,
- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
- GFP_KERNEL : GFP_ATOMIC);
+ req->dst = crypto_scomp_sg_alloc(req->dlen, GFP_ATOMIC);
if (!req->dst)
goto out;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhouyi Zhou <[email protected]>
commit e604f1cb85367d2e5fd4cf253296d190996da81a upstream.
commit 6807c84652b0 ("x86: Enable KASLR by default") enables KASLR
by default on x86. While KASLR will confuse gdb which resolve kernel
symbol address from symbol table of vmlinux. We should turn off KASLR for
kernel debugging.
Signed-off-by: Zhouyi Zhou <[email protected]>
Reviewed-by: Kieran Bingham <[email protected]>
Acked-by: Jan Kiszka <[email protected]>
Signed-off-by: Jonathan Corbet <[email protected]>
Cc: Natale Patriciello <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/dev-tools/gdb-kernel-debugging.rst | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/Documentation/dev-tools/gdb-kernel-debugging.rst
+++ b/Documentation/dev-tools/gdb-kernel-debugging.rst
@@ -31,11 +31,13 @@ Setup
CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports
CONFIG_FRAME_POINTER, keep it enabled.
-- Install that kernel on the guest.
+- Install that kernel on the guest, turn off KASLR if necessary by adding
+ "nokaslr" to the kernel command line.
Alternatively, QEMU allows to boot the kernel directly using -kernel,
-append, -initrd command line switches. This is generally only useful if
you do not depend on modules. See QEMU documentation for more details on
- this mode.
+ this mode. In this case, you should build the kernel with
+ CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.
- Enable the gdb stub of QEMU/KVM, either
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivasharan S <[email protected]>
commit 91b3d9f0069c8307d0b3a4c6843b65a439183318 upstream.
Signed-off-by: Kashyap Desai <[email protected]>
Signed-off-by: Shivasharan S <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/megaraid/megaraid_sas_base.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5650,6 +5650,14 @@ megasas_register_aen(struct megasas_inst
prev_aen.word =
le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
+ if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) ||
+ (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) {
+ dev_info(&instance->pdev->dev,
+ "%s %d out of range class %d send by application\n",
+ __func__, __LINE__, curr_aen.members.class);
+ return 0;
+ }
+
/*
* A class whose enum value is smaller is inclusive of all
* higher values. If a PROGRESS (= -1) was previously
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivasharan S <[email protected]>
commit ed2983f458bed9dc827ec60c8486253b1669bb52 upstream.
Driver allocated 256 byte MFI frames bytes but while sending MFI frame
(embedded inside chain frame of MPT frame) to firmware, driver sets the
length as 4k. This results in DMA read error messages during boot.
Signed-off-by: Kashyap Desai <[email protected]>
Signed-off-by: Shivasharan S <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3287,7 +3287,7 @@ build_mpt_mfi_pass_thru(struct megasas_i
mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
- mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
+ mpi25_ieee_chain->Length = cpu_to_le32(instance->mfi_frame_size);
}
/**
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit fa2d9d6e894e096678a50ef0f65f7a8c3d8a40b8 upstream.
The > here should be >= or we end up reading one element beyond the end
of the qedi->itt_map[] array. The qedi->itt_map[] array is allocated in
qedi_alloc_itt().
Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.")
Signed-off-by: Dan Carpenter <[email protected]>
Acked-by: Manish Rangankar <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/qedi/qedi_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -1575,7 +1575,7 @@ struct qedi_cmd *qedi_get_cmd_from_tid(s
{
struct qedi_cmd *cmd = NULL;
- if (tid > MAX_ISCSI_TASK_ENTRIES)
+ if (tid >= MAX_ISCSI_TASK_ENTRIES)
return NULL;
cmd = qedi->itt_map[tid].p_cmd;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit 1ae948fa4f00f3a2823e7cb19a3049ef27dd6947 upstream.
This fixes a potential race condition observed on Power systems.
Several places throughout the aacraid driver call aac_fib_send or
similar to send a command to the aacraid adapter, then check the return
code to determine if the command was actually sent to the adapter, then
update the phase field in the scsi command scratch pad area to track
that the firmware now owns this command. However, there is nothing that
ensures that by the time the aac_fib_send function returns and we go to
write to the scsi command, that the command hasn't already completed and
the scsi command has been freed. This was causing random crashes in the
TCP stack which was tracked down to be caused by memory that had been a
struct request + scsi_cmnd being now used for an skbuff. Memory
poisoning was enabled in the kernel to debug this which showed that the
last owner of the memory that had been freed was aacraid and that it was
a struct request. The memory that was corrupted was the exact data
pattern of AAC_OWNER_FIRMWARE and it was at the same offset that aacraid
writes, which is scsicmd->SCp.phase. The patch below resolves this
issue.
Signed-off-by: Brian King <[email protected]>
Tested-by: Wen Xiong <[email protected]>
Reviewed-by: Dave Carroll <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/aacraid/aachba.c | 54 ++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 33 deletions(-)
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -594,6 +594,7 @@ static int aac_get_container_name(struct
aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_READ_NAME);
@@ -611,10 +612,8 @@ static int aac_get_container_name(struct
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
@@ -725,6 +724,7 @@ static void _aac_probe_container1(void *
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand,
fibptr,
@@ -736,9 +736,7 @@ static void _aac_probe_container1(void *
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS)
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
- else if (status < 0) {
+ if (status < 0 && status != -EINPROGRESS) {
/* Inherit results from VM_NameServe, if any */
dresp->status = cpu_to_le32(ST_OK);
_aac_probe_container2(context, fibptr);
@@ -766,6 +764,7 @@ static int _aac_probe_container(struct s
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.ptr = (char *)callback;
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand,
fibptr,
@@ -777,10 +776,9 @@ static int _aac_probe_container(struct s
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
+
if (status < 0) {
scsicmd->SCp.ptr = NULL;
aac_fib_complete(fibptr);
@@ -1126,6 +1124,7 @@ static int aac_get_container_serial(stru
dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand,
cmd_fibcontext,
@@ -1138,10 +1137,8 @@ static int aac_get_container_serial(stru
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
@@ -2335,16 +2332,14 @@ static int aac_read(struct scsi_cmnd * s
* Alocate and initialize a Fib
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
/*
@@ -2429,16 +2424,14 @@ static int aac_write(struct scsi_cmnd *
* Allocate and initialize a Fib then setup a BlockWrite command
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status);
/*
@@ -2588,6 +2581,7 @@ static int aac_synchronize(struct scsi_c
synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
synchronizecmd->count =
cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
/*
* Now send the Fib to the adapter
@@ -2603,10 +2597,8 @@ static int aac_synchronize(struct scsi_c
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING
"aac_synchronize: aac_fib_send failed with status: %d.\n", status);
@@ -2666,6 +2658,7 @@ static int aac_start_stop(struct scsi_cm
pmcmd->cid = cpu_to_le32(sdev_id(sdev));
pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
/*
* Now send the Fib to the adapter
@@ -2681,10 +2674,8 @@ static int aac_start_stop(struct scsi_cm
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
aac_fib_complete(cmd_fibcontext);
aac_fib_free(cmd_fibcontext);
@@ -3692,16 +3683,14 @@ static int aac_send_srb_fib(struct scsi_
* Allocate and initialize a Fib then setup a BlockWrite command
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status);
aac_fib_complete(cmd_fibcontext);
@@ -3739,15 +3728,14 @@ static int aac_send_hba_fib(struct scsi_
if (!cmd_fibcontext)
return -1;
+ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
status = aac_adapter_hba(cmd_fibcontext, scsicmd);
/*
* Check that the command queued to the controller
*/
- if (status == -EINPROGRESS) {
- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+ if (status == -EINPROGRESS)
return 0;
- }
pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n",
status);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 1a5d999ebfc7bfe28deb48931bb57faa8e4102b6 upstream.
For problem determination we need to see that we were in scsi_eh
as well as whether and why we were successful or not.
The following commits introduced new early returns without adding
a trace record:
v2.6.35 commit a1dbfddd02d2
("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh")
on fc_block_scsi_eh() returning != 0 which is FAST_IO_FAIL,
v2.6.30 commit 63caf367e1c9
("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp")
on not having gotten an FSF request after the maximum number of retry
attempts and thus could not issue a TMF and has to return FAILED.
Signed-off-by: Steffen Maier <[email protected]>
Fixes: a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh")
Fixes: 63caf367e1c9 ("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_scsi.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -273,8 +273,10 @@ static int zfcp_task_mgmt_function(struc
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
- if (ret)
+ if (ret) {
+ zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL);
return ret;
+ }
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
@@ -282,8 +284,10 @@ static int zfcp_task_mgmt_function(struc
return SUCCESS;
}
}
- if (!fsf_req)
+ if (!fsf_req) {
+ zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL);
return FAILED;
+ }
wait_for_completion(&fsf_req->completion);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Leung <[email protected]>
commit 2cfa58259f4b65b33ebe8f167019a1f89c6c3289 upstream.
Implement fused multiply-add with correct accuracy.
Fused multiply-add operation has better accuracy than respective
sequential execution of multiply and add operations applied on the
same inputs. This is because accuracy errors accumulate in latter
case.
This patch implements fused multiply-add with the same accuracy
as it is implemented in hardware, using 128-bit intermediate
calculations.
One test case example (raw bits) that this patch fixes:
MADDF.D fd,fs,ft:
fd = 0x00000ca000000000
fs = ft = 0x3f40624dd2f1a9fc
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
Signed-off-by: Douglas Leung <[email protected]>
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16891/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_maddf.c | 133 +++++++++++++++++++++++++++++-------------
1 file changed, 94 insertions(+), 39 deletions(-)
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -15,18 +15,44 @@
#include "ieee754dp.h"
+/* 128 bits shift right logical with rounding. */
+void srl128(u64 *hptr, u64 *lptr, int count)
+{
+ u64 low;
+
+ if (count >= 128) {
+ *lptr = *hptr != 0 || *lptr != 0;
+ *hptr = 0;
+ } else if (count >= 64) {
+ if (count == 64) {
+ *lptr = *hptr | (*lptr != 0);
+ } else {
+ low = *lptr;
+ *lptr = *hptr >> (count - 64);
+ *lptr |= (*hptr << (128 - count)) != 0 || low != 0;
+ }
+ *hptr = 0;
+ } else {
+ low = *lptr;
+ *lptr = low >> count | *hptr << (64 - count);
+ *lptr |= (low << (64 - count)) != 0;
+ *hptr = *hptr >> count;
+ }
+}
+
static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
union ieee754dp y, enum maddf_flags flags)
{
int re;
int rs;
- u64 rm;
unsigned lxm;
unsigned hxm;
unsigned lym;
unsigned hym;
u64 lrm;
u64 hrm;
+ u64 lzm;
+ u64 hzm;
u64 t;
u64 at;
int s;
@@ -172,7 +198,7 @@ static union ieee754dp _dp_maddf(union i
ym <<= 64 - (DP_FBITS + 1);
/*
- * Multiply 64 bits xm, ym to give high 64 bits rm with stickness.
+ * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
*/
/* 32 * 32 => 64 */
@@ -202,81 +228,110 @@ static union ieee754dp _dp_maddf(union i
hrm = hrm + (t >> 32);
- rm = hrm | (lrm != 0);
-
- /*
- * Sticky shift down to normal rounding precision.
- */
- if ((s64) rm < 0) {
- rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
- ((rm << (DP_FBITS + 1 + 3)) != 0);
+ /* Put explicit bit at bit 126 if necessary */
+ if ((int64_t)hrm < 0) {
+ lrm = (hrm << 63) | (lrm >> 1);
+ hrm = hrm >> 1;
re++;
- } else {
- rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
- ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
}
- assert(rm & (DP_HIDDEN_BIT << 3));
- if (zc == IEEE754_CLASS_ZERO)
- return ieee754dp_format(rs, re, rm);
+ assert(hrm & (1 << 62));
- /* And now the addition */
- assert(zm & DP_HIDDEN_BIT);
+ if (zc == IEEE754_CLASS_ZERO) {
+ /*
+ * Move explicit bit from bit 126 to bit 55 since the
+ * ieee754dp_format code expects the mantissa to be
+ * 56 bits wide (53 + 3 rounding bits).
+ */
+ srl128(&hrm, &lrm, (126 - 55));
+ return ieee754dp_format(rs, re, lrm);
+ }
- /*
- * Provide guard,round and stick bit space.
- */
- zm <<= 3;
+ /* Move explicit bit from bit 52 to bit 126 */
+ lzm = 0;
+ hzm = zm << 10;
+ assert(hzm & (1 << 62));
+ /* Make the exponents the same */
if (ze > re) {
/*
* Have to shift y fraction right to align.
*/
s = ze - re;
- rm = XDPSRS(rm, s);
+ srl128(&hrm, &lrm, s);
re += s;
} else if (re > ze) {
/*
* Have to shift x fraction right to align.
*/
s = re - ze;
- zm = XDPSRS(zm, s);
+ srl128(&hzm, &lzm, s);
ze += s;
}
assert(ze == re);
assert(ze <= DP_EMAX);
+ /* Do the addition */
if (zs == rs) {
/*
- * Generate 28 bit result of adding two 27 bit numbers
- * leaving result in xm, xs and xe.
+ * Generate 128 bit result by adding two 127 bit numbers
+ * leaving result in hzm:lzm, zs and ze.
*/
- zm = zm + rm;
-
- if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */
- zm = XDPSRS1(zm);
+ hzm = hzm + hrm + (lzm > (lzm + lrm));
+ lzm = lzm + lrm;
+ if ((int64_t)hzm < 0) { /* carry out */
+ srl128(&hzm, &lzm, 1);
ze++;
}
} else {
- if (zm >= rm) {
- zm = zm - rm;
+ if (hzm > hrm || (hzm == hrm && lzm >= lrm)) {
+ hzm = hzm - hrm - (lzm < lrm);
+ lzm = lzm - lrm;
} else {
- zm = rm - zm;
+ hzm = hrm - hzm - (lrm < lzm);
+ lzm = lrm - lzm;
zs = rs;
}
- if (zm == 0)
+ if (lzm == 0 && hzm == 0)
return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
/*
- * Normalize to rounding precision.
+ * Put explicit bit at bit 126 if necessary.
*/
- while ((zm >> (DP_FBITS + 3)) == 0) {
- zm <<= 1;
- ze--;
+ if (hzm == 0) {
+ /* left shift by 63 or 64 bits */
+ if ((int64_t)lzm < 0) {
+ /* MSB of lzm is the explicit bit */
+ hzm = lzm >> 1;
+ lzm = lzm << 63;
+ ze -= 63;
+ } else {
+ hzm = lzm;
+ lzm = 0;
+ ze -= 64;
+ }
+ }
+
+ t = 0;
+ while ((hzm >> (62 - t)) == 0)
+ t++;
+
+ assert(t <= 62);
+ if (t) {
+ hzm = hzm << t | lzm >> (64 - t);
+ lzm = lzm << t;
+ ze -= t;
}
}
- return ieee754dp_format(zs, ze, zm);
+ /*
+ * Move explicit bit from bit 126 to bit 55 since the
+ * ieee754dp_format code expects the mantissa to be
+ * 56 bits wide (53 + 3 rounding bits).
+ */
+ srl128(&hzm, &lzm, (126 - 55));
+
+ return ieee754dp_format(zs, ze, lzm);
}
union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 12c3e5754c8022a4f2fd1e9f00d19e99ee0d3cc1 upstream.
If the FCP_RSP UI has optional parts (FCP_SNS_INFO or FCP_RSP_INFO) and
thus does not fit into the fsp_rsp field built into a SCSI trace record,
trace the full FCP_RSP UI with all optional parts as payload record
instead of just FCP_SNS_INFO as payload and
a 1 byte RSP_INFO_CODE part of FCP_RSP_INFO built into the SCSI record.
That way we would also get the full FCP_SNS_INFO in case a
target would ever send more than
min(SCSI_SENSE_BUFFERSIZE==96, ZFCP_DBF_PAY_MAX_REC==256)==96.
The mandatory part of FCP_RSP IU is only 24 bytes.
PAYload costs at least one full PAY record of 256 bytes anyway.
We cap to the hardware response size which is only FSF_FCP_RSP_SIZE==128.
So we can just put the whole FCP_RSP IU with any optional parts into
PAYload similarly as we do for SAN PAY since v4.9 commit aceeffbb59bb
("zfcp: trace full payload of all SAN records (req,resp,iels)").
This does not cause any additional trace records wasting memory.
Decoded trace records were confusing because they showed a hard-coded
sense data length of 96 even if the FCP_RSP_IU field FCP_SNS_LEN showed
actually less.
Since the same commit, we set pl_len for SAN traces to the full length of a
request/response even if we cap the corresponding trace.
In contrast, here for SCSI traces we set pl_len to the pre-computed
length of FCP_RSP IU considering SNS_LEN or RSP_LEN if valid.
Nonetheless we trace a hardcoded payload of length FSF_FCP_RSP_SIZE==128
if there were optional parts.
This makes it easier for the zfcpdbf tool to format only the relevant
part of the long FCP_RSP UI buffer. And any trailing information is still
available in the payload trace record just in case.
Rename the payload record tag from "fcp_sns" to "fcp_riu" to make the new
content explicit to zfcpdbf which can then pick a suitable field name such
as "FCP rsp IU all:" instead of "Sense info :"
Also, the same zfcpdbf can still be backwards compatible with "fcp_sns".
Old example trace record before this fix, formatted with the tool zfcpdbf
from s390-tools:
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU id : ..
Caller : 0x...
Record id : 1
Tag : rsl_err
Request id : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000002
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_id>
SCSI opcode : 00000000 00000000 00000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000202 00000000
^^==FCP_SNS_LEN_VALID
00000020 00000000
^^^^^^^^==FCP_SNS_LEN==32
Sense len : 96 <==min(SCSI_SENSE_BUFFERSIZE,ZFCP_DBF_PAY_MAX_REC)
Sense info : 70000600 00000018 00000000 29000000
00000400 00000000 00000000 00000000
00000000 00000000 00000000 00000000<==superfluous
00000000 00000000 00000000 00000000<==superfluous
00000000 00000000 00000000 00000000<==superfluous
00000000 00000000 00000000 00000000<==superfluous
New example trace records with this fix:
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_err
Request ID : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000002
SCSI retries : 0x00
SCSI allowed : 0x03
SCSI scribble : 0x<request_id>
SCSI opcode : a30c0112 00000000 02000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000a02 00000200
00000020 00000000
FCP rsp IU len : 56
FCP rsp IU all : 00000000 00000000 00000a02 00000200
^^=FCP_RESID_UNDER|FCP_SNS_LEN_VALID
00000020 00000000 70000500 00000018
^^^^^^^^==FCP_SNS_LEN
^^^^^^^^^^^^^^^^^
00000000 240000cb 00011100 00000000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00000000 00000000
^^^^^^^^^^^^^^^^^==FCP_SNS_INFO
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : lr_okay
Request ID : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000000
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_id>
SCSI opcode : <CDB of unrelated SCSI command passed to eh handler>
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000100 00000000
00000000 00000008
FCP rsp IU len : 32
FCP rsp IU all : 00000000 00000000 00000100 00000000
^^==FCP_RSP_LEN_VALID
00000000 00000008 00000000 00000000
^^^^^^^^==FCP_RSP_LEN
^^^^^^^^^^^^^^^^^==FCP_RSP_INFO
Signed-off-by: Steffen Maier <[email protected]>
Fixes: 250a1352b95e ("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -572,19 +572,32 @@ void zfcp_dbf_scsi(char *tag, int level,
if (fsf) {
rec->fsf_req_id = fsf->req_id;
+ rec->pl_len = FCP_RESP_WITH_EXT;
fcp_rsp = (struct fcp_resp_with_ext *)
&(fsf->qtcb->bottom.io.fcp_rsp);
+ /* mandatory parts of FCP_RSP IU in this SCSI record */
memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
+ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
}
if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
- rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
- (u16)ZFCP_DBF_PAY_MAX_REC);
- zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
- "fcp_sns", fsf->req_id);
+ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len);
}
+ /* complete FCP_RSP IU in associated PAYload record
+ * but only if there are optional parts
+ */
+ if (fcp_rsp->resp.fr_flags != 0)
+ zfcp_dbf_pl_write(
+ dbf, fcp_rsp,
+ /* at least one full PAY record
+ * but not beyond hardware response field
+ */
+ min_t(u16, max_t(u16, rec->pl_len,
+ ZFCP_DBF_PAY_MAX_REC),
+ FSF_FCP_RSP_SIZE),
+ "fcp_riu", fsf->req_id);
}
debug_event(dbf->scsi, level, rec, sizeof(*rec));
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Maier <[email protected]>
commit 975171b4461be296a35e83ebd748946b81cf0635 upstream.
v4.9 commit aceeffbb59bb ("zfcp: trace full payload of all SAN records
(req,resp,iels)") fixed trace data loss of 2.6.38 commit 2c55b750a884
("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
necessary for problem determination, e.g. to see the
currently active zone set during automatic port scan.
While it already saves space by not dumping any empty residual entries
of the large successful GPN_FT response (4 pages), there are seldom cases
where the GPN_FT response is unsuccessful and likely does not have
FC_NS_FID_LAST set in fp_flags so we did not cap the trace record.
We typically see such case for an initiator WWPN, which is not in any zone.
Cap unsuccessful responses to at least the actual basic CT_IU response
plus whatever fits the SAN trace record built-in "payload" buffer
just in case there's trailing information
of which we would at least see the existence and its beginning.
In order not to erroneously cap successful responses, we need to swap
calling the trace function and setting the CT / ELS status to success (0).
Example trace record pair formatted with zfcpdbf:
Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : fssct_1
Request ID : 0x<request_id>
Destination ID : 0x00fffffc
SAN req short : 01000000 fc020000 01720ffc 00000000
00000008
SAN req length : 20
|
Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 2
Tag : fsscth2
Request ID : 0x<request_id>
Destination ID : 0x00fffffc
SAN resp short : 01000000 fc020000 80010000 00090700
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
SAN resp length: 16384
San resp info : 01000000 fc020000 80010000 00090700
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
00000000 00000000 00000000 00000000 [trailing info]
The fix saves all but one of the previously associated 64 PAYload trace
record chunks of size 256 bytes each.
Signed-off-by: Steffen Maier <[email protected]>
Fixes: aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)")
Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 10 +++++++++-
drivers/s390/scsi/zfcp_fsf.c | 4 ++--
2 files changed, 11 insertions(+), 3 deletions(-)
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -3,7 +3,7 @@
*
* Debug traces for zfcp.
*
- * Copyright IBM Corp. 2002, 2016
+ * Copyright IBM Corp. 2002, 2017
*/
#define KMSG_COMPONENT "zfcp"
@@ -447,6 +447,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
struct fc_ct_hdr *reqh = sg_virt(ct_els->req);
struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1);
struct scatterlist *resp_entry = ct_els->resp;
+ struct fc_ct_hdr *resph;
struct fc_gpn_ft_resp *acc;
int max_entries, x, last = 0;
@@ -473,6 +474,13 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
return len; /* not GPN_FT response so do not cap */
acc = sg_virt(resp_entry);
+
+ /* cap all but accept CT responses to at least the CT header */
+ resph = (struct fc_ct_hdr *)acc;
+ if ((ct_els->status) ||
+ (resph->ct_cmd != cpu_to_be16(FC_FS_ACC)))
+ return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD);
+
max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp))
+ 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one
* to account for header as 1st pseudo "entry" */;
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -928,8 +928,8 @@ static void zfcp_fsf_send_ct_handler(str
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_dbf_san_res("fsscth2", req);
ct->status = 0;
+ zfcp_dbf_san_res("fsscth2", req);
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
zfcp_fsf_class_not_supp(req);
@@ -1109,8 +1109,8 @@ static void zfcp_fsf_send_els_handler(st
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_dbf_san_res("fsselh1", req);
send_els->status = 0;
+ zfcp_dbf_san_res("fsselh1", req);
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
zfcp_fsf_class_not_supp(req);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Block <[email protected]>
commit a099b7b1fc1f0418ab8d79ecf98153e1e134656e upstream.
Up until now zfcp would just ignore the FCP_RESID_OVER flag in the FCP
response IU. When this flag is set, it is possible, in regards to the
FCP standard, that the storage-server processes the command normally, up
to the point where data is missing and simply ignores those.
In this case no CHECK CONDITION would be set, and because we ignored the
FCP_RESID_OVER flag we resulted in at least a data loss or even
-corruption as a follow-up error, depending on how the
applications/layers on top behave. To prevent this, we now set the
host-byte of the corresponding scsi_cmnd to DID_ERROR.
Other storage-behaviors, where the same condition results in a CHECK
CONDITION set in the answer, don't need to be changed as they are
handled in the mid-layer already.
Following is an example trace record decoded with zfcpdbf from the
s390-tools package. We forcefully injected a fc_dl which is one byte too
small:
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_err
Request ID : 0x...
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00070000
^^DID_ERROR
SCSI retries : 0x..
SCSI allowed : 0x..
SCSI scribble : 0x...
SCSI opcode : 2a000000 00000000 08000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000400 00000001
^^fr_flags==FCP_RESID_OVER
^^fr_status==SAM_STAT_GOOD
^^^^^^^^fr_resid
00000000 00000000
As of now, we don't actively handle to possibility that a response IU
has both flags - FCP_RESID_OVER and FCP_RESID_UNDER - set at once.
Reported-by: Luke M. Hopkins <[email protected]>
Reviewed-by: Steffen Maier <[email protected]>
Fixes: 553448f6c483 ("[SCSI] zfcp: Message cleanup")
Fixes: ea127f975424 ("[PATCH] s390 (7/7): zfcp host adapter.") (tglx/history.git)
Signed-off-by: Benjamin Block <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/scsi/zfcp_fc.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -4,7 +4,7 @@
* Fibre Channel related definitions and inline functions for the zfcp
* device driver
*
- * Copyright IBM Corp. 2009
+ * Copyright IBM Corp. 2009, 2017
*/
#ifndef ZFCP_FC_H
@@ -279,6 +279,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_res
!(rsp_flags & FCP_SNS_LEN_VAL) &&
fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
set_host_byte(scsi, DID_ERROR);
+ } else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
+ /* FCP_DL was not sufficient for SCSI data length */
+ if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+ set_host_byte(scsi, DID_ERROR);
}
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 5fbd545cd3fd311ea1d6e8be4cedddd0ee5684c7 upstream.
Ensure that the members of struct skd_msg_buf have been transferred
to the PCIe adapter before the doorbell is triggered. This patch
avoids that I/O fails sporadically and that the following error
message is reported:
(skd0:STM000196603:[0000:00:09.0]): Completion mismatch comp_id=0x0000 skreq=0x0400 new=0x0000
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Johannes Thumshirn <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/block/skd_main.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -2160,6 +2160,9 @@ static void skd_send_fitmsg(struct skd_d
*/
qcmd |= FIT_QCMD_MSGSIZE_64;
+ /* Make sure skd_msg_buf is written before the doorbell is triggered. */
+ smp_wmb();
+
SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
}
@@ -2202,6 +2205,9 @@ static void skd_send_special_fitmsg(stru
qcmd = skspcl->mb_dma_address;
qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128;
+ /* Make sure skd_msg_buf is written before the doorbell is triggered. */
+ smp_wmb();
+
SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shaohua Li <[email protected]>
commit 8031c3ddc70ab93099e7d1814382dba39f57b43e upstream.
raid5 cache could write bitmap superblock before bitmap superblock is
initialized. The bitmap superblock is less than 512B. The current code will
only copy the superblock to a new page and write the whole 512B, which will
zero the the data after the superblock. Unfortunately the data could include
bitmap, which we should preserve. The patch will make superblock read do 4k
chunk and we always copy the 4k data to new page, so the superblock write will
old data to disk and we don't change the bitmap.
Reported-by: Song Liu <[email protected]>
Reviewed-by: Song Liu <[email protected]>
Signed-off-by: Shaohua Li <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/md/bitmap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -625,7 +625,7 @@ re_read:
err = read_sb_page(bitmap->mddev,
offset,
sb_page,
- 0, sizeof(bitmap_super_t));
+ 0, PAGE_SIZE);
}
if (err)
return err;
@@ -2118,7 +2118,7 @@ int bitmap_resize(struct bitmap *bitmap,
if (store.sb_page && bitmap->storage.sb_page)
memcpy(page_address(store.sb_page),
page_address(bitmap->storage.sb_page),
- sizeof(bitmap_super_t));
+ PAGE_SIZE);
bitmap_file_unmap(&bitmap->storage);
bitmap->storage = store;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Leung <[email protected]>
commit b3b8e1eb27c523e32b6a8aa7ec8ac4754456af57 upstream.
Implement fused multiply-add with correct accuracy.
Fused multiply-add operation has better accuracy than respective
sequential execution of multiply and add operations applied on the
same inputs. This is because accuracy errors accumulate in latter
case.
This patch implements fused multiply-add with the same accuracy
as it is implemented in hardware, using 64-bit intermediate
calculations.
One test case example (raw bits) that this patch fixes:
MADDF.S fd,fs,ft:
fd = 0x22575225
fs = ft = 0x3727c5ac
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
Signed-off-by: Douglas Leung <[email protected]>
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16890/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/ieee754sp.h | 4 +
arch/mips/math-emu/sp_maddf.c | 116 ++++++++++++++++-------------------------
2 files changed, 50 insertions(+), 70 deletions(-)
--- a/arch/mips/math-emu/ieee754sp.h
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union
return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
}
+/* 64 bit right shift with rounding */
+#define XSPSRS64(v, rs) \
+ (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0))
+
/* 3bit extended single precision sticky right shift */
#define XSPSRS(v, rs) \
((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -21,14 +21,8 @@ static union ieee754sp _sp_maddf(union i
int re;
int rs;
unsigned rm;
- unsigned short lxm;
- unsigned short hxm;
- unsigned short lym;
- unsigned short hym;
- unsigned lrm;
- unsigned hrm;
- unsigned t;
- unsigned at;
+ uint64_t rm64;
+ uint64_t zm64;
int s;
COMPXSP;
@@ -170,108 +164,90 @@ static union ieee754sp _sp_maddf(union i
if (flags & MADDF_NEGATE_PRODUCT)
rs ^= 1;
- /* shunt to top of word */
- xm <<= 32 - (SP_FBITS + 1);
- ym <<= 32 - (SP_FBITS + 1);
+ /* Multiple 24 bit xm and ym to give 48 bit results */
+ rm64 = (uint64_t)xm * ym;
- /*
- * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
- */
- lxm = xm & 0xffff;
- hxm = xm >> 16;
- lym = ym & 0xffff;
- hym = ym >> 16;
-
- lrm = lxm * lym; /* 16 * 16 => 32 */
- hrm = hxm * hym; /* 16 * 16 => 32 */
-
- t = lxm * hym; /* 16 * 16 => 32 */
- at = lrm + (t << 16);
- hrm += at < lrm;
- lrm = at;
- hrm = hrm + (t >> 16);
-
- t = hxm * lym; /* 16 * 16 => 32 */
- at = lrm + (t << 16);
- hrm += at < lrm;
- lrm = at;
- hrm = hrm + (t >> 16);
-
- rm = hrm | (lrm != 0);
+ /* Shunt to top of word */
+ rm64 = rm64 << 16;
- /*
- * Sticky shift down to normal rounding precision.
- */
- if ((int) rm < 0) {
- rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
- ((rm << (SP_FBITS + 1 + 3)) != 0);
+ /* Put explicit bit at bit 62 if necessary */
+ if ((int64_t) rm64 < 0) {
+ rm64 = rm64 >> 1;
re++;
- } else {
- rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
- ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
}
- assert(rm & (SP_HIDDEN_BIT << 3));
-
- if (zc == IEEE754_CLASS_ZERO)
- return ieee754sp_format(rs, re, rm);
- /* And now the addition */
+ assert(rm64 & (1 << 62));
- assert(zm & SP_HIDDEN_BIT);
+ if (zc == IEEE754_CLASS_ZERO) {
+ /*
+ * Move explicit bit from bit 62 to bit 26 since the
+ * ieee754sp_format code expects the mantissa to be
+ * 27 bits wide (24 + 3 rounding bits).
+ */
+ rm = XSPSRS64(rm64, (62 - 26));
+ return ieee754sp_format(rs, re, rm);
+ }
- /*
- * Provide guard,round and stick bit space.
- */
- zm <<= 3;
+ /* Move explicit bit from bit 23 to bit 62 */
+ zm64 = (uint64_t)zm << (62 - 23);
+ assert(zm64 & (1 << 62));
+ /* Make the exponents the same */
if (ze > re) {
/*
* Have to shift r fraction right to align.
*/
s = ze - re;
- rm = XSPSRS(rm, s);
+ rm64 = XSPSRS64(rm64, s);
re += s;
} else if (re > ze) {
/*
* Have to shift z fraction right to align.
*/
s = re - ze;
- zm = XSPSRS(zm, s);
+ zm64 = XSPSRS64(zm64, s);
ze += s;
}
assert(ze == re);
assert(ze <= SP_EMAX);
+ /* Do the addition */
if (zs == rs) {
/*
- * Generate 28 bit result of adding two 27 bit numbers
- * leaving result in zm, zs and ze.
+ * Generate 64 bit result by adding two 63 bit numbers
+ * leaving result in zm64, zs and ze.
*/
- zm = zm + rm;
-
- if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
- zm = XSPSRS1(zm);
+ zm64 = zm64 + rm64;
+ if ((int64_t)zm64 < 0) { /* carry out */
+ zm64 = XSPSRS1(zm64);
ze++;
}
} else {
- if (zm >= rm) {
- zm = zm - rm;
+ if (zm64 >= rm64) {
+ zm64 = zm64 - rm64;
} else {
- zm = rm - zm;
+ zm64 = rm64 - zm64;
zs = rs;
}
- if (zm == 0)
+ if (zm64 == 0)
return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
/*
- * Normalize in extended single precision
+ * Put explicit bit at bit 62 if necessary.
*/
- while ((zm >> (SP_MBITS + 3)) == 0) {
- zm <<= 1;
+ while ((zm64 >> 62) == 0) {
+ zm64 <<= 1;
ze--;
}
-
}
+
+ /*
+ * Move explicit bit from bit 62 to bit 26 since the
+ * ieee754sp_format code expects the mantissa to be
+ * 27 bits wide (24 + 3 rounding bits).
+ */
+ zm = XSPSRS64(zm64, (62 - 26));
+
return ieee754sp_format(zs, ze, zm);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
commit f9effe925039cf54489b5c04e0d40073bb3a123d upstream.
Anton noticed that if we fault part way through emulating an unaligned
instruction, we don't update the DAR to reflect that.
The DAR value is eventually reported back to userspace as the address
in the SEGV signal, and if userspace is using that value to demand
fault then it can be confused by us not setting the value correctly.
This patch is ugly as hell, but is intended to be the minimal fix and
back ports easily.
Signed-off-by: Michael Ellerman <[email protected]>
Reviewed-by: Paul Mackerras <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/kernel/align.c | 119 +++++++++++++++++++++++++++-----------------
1 file changed, 74 insertions(+), 45 deletions(-)
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -235,6 +235,28 @@ static int emulate_dcbz(struct pt_regs *
#define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz))
+#define __get_user_or_set_dar(_regs, _dest, _addr) \
+ ({ \
+ int rc = 0; \
+ typeof(_addr) __addr = (_addr); \
+ if (__get_user_inatomic(_dest, __addr)) { \
+ _regs->dar = (unsigned long)__addr; \
+ rc = -EFAULT; \
+ } \
+ rc; \
+ })
+
+#define __put_user_or_set_dar(_regs, _src, _addr) \
+ ({ \
+ int rc = 0; \
+ typeof(_addr) __addr = (_addr); \
+ if (__put_user_inatomic(_src, __addr)) { \
+ _regs->dar = (unsigned long)__addr; \
+ rc = -EFAULT; \
+ } \
+ rc; \
+ })
+
static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
unsigned int reg, unsigned int nb,
unsigned int flags, unsigned int instr,
@@ -263,9 +285,10 @@ static int emulate_multiple(struct pt_re
} else {
unsigned long pc = regs->nip ^ (swiz & 4);
- if (__get_user_inatomic(instr,
- (unsigned int __user *)pc))
+ if (__get_user_or_set_dar(regs, instr,
+ (unsigned int __user *)pc))
return -EFAULT;
+
if (swiz == 0 && (flags & SW))
instr = cpu_to_le32(instr);
nb = (instr >> 11) & 0x1f;
@@ -309,31 +332,31 @@ static int emulate_multiple(struct pt_re
((nb0 + 3) / 4) * sizeof(unsigned long));
for (i = 0; i < nb; ++i, ++p)
- if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz),
- SWIZ_PTR(p)))
+ if (__get_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),
+ SWIZ_PTR(p)))
return -EFAULT;
if (nb0 > 0) {
rptr = ®s->gpr[0];
addr += nb;
for (i = 0; i < nb0; ++i, ++p)
- if (__get_user_inatomic(REG_BYTE(rptr,
- i ^ bswiz),
- SWIZ_PTR(p)))
+ if (__get_user_or_set_dar(regs,
+ REG_BYTE(rptr, i ^ bswiz),
+ SWIZ_PTR(p)))
return -EFAULT;
}
} else {
for (i = 0; i < nb; ++i, ++p)
- if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz),
- SWIZ_PTR(p)))
+ if (__put_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),
+ SWIZ_PTR(p)))
return -EFAULT;
if (nb0 > 0) {
rptr = ®s->gpr[0];
addr += nb;
for (i = 0; i < nb0; ++i, ++p)
- if (__put_user_inatomic(REG_BYTE(rptr,
- i ^ bswiz),
- SWIZ_PTR(p)))
+ if (__put_user_or_set_dar(regs,
+ REG_BYTE(rptr, i ^ bswiz),
+ SWIZ_PTR(p)))
return -EFAULT;
}
}
@@ -345,29 +368,32 @@ static int emulate_multiple(struct pt_re
* Only POWER6 has these instructions, and it does true little-endian,
* so we don't need the address swizzling.
*/
-static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,
- unsigned int flags)
+static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr,
+ unsigned int reg, unsigned int flags)
{
char *ptr0 = (char *) ¤t->thread.TS_FPR(reg);
char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1);
- int i, ret, sw = 0;
+ int i, sw = 0;
if (reg & 1)
return 0; /* invalid form: FRS/FRT must be even */
if (flags & SW)
sw = 7;
- ret = 0;
+
for (i = 0; i < 8; ++i) {
if (!(flags & ST)) {
- ret |= __get_user(ptr0[i^sw], addr + i);
- ret |= __get_user(ptr1[i^sw], addr + i + 8);
+ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+ return -EFAULT;
+ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+ return -EFAULT;
} else {
- ret |= __put_user(ptr0[i^sw], addr + i);
- ret |= __put_user(ptr1[i^sw], addr + i + 8);
+ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+ return -EFAULT;
+ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+ return -EFAULT;
}
}
- if (ret)
- return -EFAULT;
+
return 1; /* exception handled and fixed up */
}
@@ -377,24 +403,27 @@ static int emulate_lq_stq(struct pt_regs
{
char *ptr0 = (char *)®s->gpr[reg];
char *ptr1 = (char *)®s->gpr[reg+1];
- int i, ret, sw = 0;
+ int i, sw = 0;
if (reg & 1)
return 0; /* invalid form: GPR must be even */
if (flags & SW)
sw = 7;
- ret = 0;
+
for (i = 0; i < 8; ++i) {
if (!(flags & ST)) {
- ret |= __get_user(ptr0[i^sw], addr + i);
- ret |= __get_user(ptr1[i^sw], addr + i + 8);
+ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+ return -EFAULT;
+ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+ return -EFAULT;
} else {
- ret |= __put_user(ptr0[i^sw], addr + i);
- ret |= __put_user(ptr1[i^sw], addr + i + 8);
+ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+ return -EFAULT;
+ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+ return -EFAULT;
}
}
- if (ret)
- return -EFAULT;
+
return 1; /* exception handled and fixed up */
}
#endif /* CONFIG_PPC64 */
@@ -687,9 +716,14 @@ static int emulate_vsx(unsigned char __u
for (j = 0; j < length; j += elsize) {
for (i = 0; i < elsize; ++i) {
if (flags & ST)
- ret |= __put_user(ptr[i^sw], addr + i);
+ ret = __put_user_or_set_dar(regs, ptr[i^sw],
+ addr + i);
else
- ret |= __get_user(ptr[i^sw], addr + i);
+ ret = __get_user_or_set_dar(regs, ptr[i^sw],
+ addr + i);
+
+ if (ret)
+ return ret;
}
ptr += elsize;
#ifdef __LITTLE_ENDIAN__
@@ -739,7 +773,7 @@ int fix_alignment(struct pt_regs *regs)
unsigned int dsisr;
unsigned char __user *addr;
unsigned long p, swiz;
- int ret, i;
+ int i;
union data {
u64 ll;
double dd;
@@ -936,7 +970,7 @@ int fix_alignment(struct pt_regs *regs)
if (flags & F) {
/* Special case for 16-byte FP loads and stores */
PPC_WARN_ALIGNMENT(fp_pair, regs);
- return emulate_fp_pair(addr, reg, flags);
+ return emulate_fp_pair(regs, addr, reg, flags);
} else {
#ifdef CONFIG_PPC64
/* Special case for 16-byte loads and stores */
@@ -966,15 +1000,12 @@ int fix_alignment(struct pt_regs *regs)
}
data.ll = 0;
- ret = 0;
p = (unsigned long)addr;
for (i = 0; i < nb; i++)
- ret |= __get_user_inatomic(data.v[start + i],
- SWIZ_PTR(p++));
-
- if (unlikely(ret))
- return -EFAULT;
+ if (__get_user_or_set_dar(regs, data.v[start + i],
+ SWIZ_PTR(p++)))
+ return -EFAULT;
} else if (flags & F) {
data.ll = current->thread.TS_FPR(reg);
@@ -1046,15 +1077,13 @@ int fix_alignment(struct pt_regs *regs)
break;
}
- ret = 0;
p = (unsigned long)addr;
for (i = 0; i < nb; i++)
- ret |= __put_user_inatomic(data.v[start + i],
- SWIZ_PTR(p++));
+ if (__put_user_or_set_dar(regs, data.v[start + i],
+ SWIZ_PTR(p++)))
+ return -EFAULT;
- if (unlikely(ret))
- return -EFAULT;
} else if (flags & F)
current->thread.TS_FPR(reg) = data.ll;
else
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alistair Popple <[email protected]>
commit bab9f954aaf352127725a9b7920226abdb65b604 upstream.
The nest MMU tlb flush needs to happen before the GPU translation
shootdown is launched to avoid the GPU refilling its tlb with stale
nmmu translations prior to the nmmu flush completing.
Fixes: 1ab66d1fbada ("powerpc/powernv: Introduce address translation services for Nvlink2")
Signed-off-by: Alistair Popple <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/platforms/powernv/npu-dma.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -546,6 +546,12 @@ static void mmio_invalidate(struct npu_c
unsigned long pid = npu_context->mm->context.id;
/*
+ * Unfortunately the nest mmu does not support flushing specific
+ * addresses so we have to flush the whole mm.
+ */
+ flush_tlb_mm(npu_context->mm);
+
+ /*
* Loop over all the NPUs this process is active on and launch
* an invalidate.
*/
@@ -576,12 +582,6 @@ static void mmio_invalidate(struct npu_c
}
}
- /*
- * Unfortunately the nest mmu does not support flushing specific
- * addresses so we have to flush the whole mm.
- */
- flush_tlb_mm(npu_context->mm);
-
mmio_invalidate_wait(mmio_atsd_reg, flush);
if (flush)
/* Wait for the flush to complete */
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: zhangyi (F) <[email protected]>
commit 95f1fda47c9d8738f858c3861add7bf0a36a7c0b upstream.
Quota does not get enabled for read-only mounts if filesystem
has quota feature, so that quotas cannot updated during orphan
cleanup, which will lead to quota inconsistency.
This patch turn on quotas during orphan cleanup for this case,
make sure quotas can be updated correctly.
Reported-by: Jan Kara <[email protected]>
Signed-off-by: zhangyi (F) <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ext4/super.c | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2404,6 +2404,7 @@ static void ext4_orphan_cleanup(struct s
unsigned int s_flags = sb->s_flags;
int ret, nr_orphans = 0, nr_truncates = 0;
#ifdef CONFIG_QUOTA
+ int quota_update = 0;
int i;
#endif
if (!es->s_last_orphan) {
@@ -2442,14 +2443,32 @@ static void ext4_orphan_cleanup(struct s
#ifdef CONFIG_QUOTA
/* Needed for iput() to work correctly and not trash data */
sb->s_flags |= MS_ACTIVE;
- /* Turn on journaled quotas so that they are updated correctly */
+
+ /*
+ * Turn on quotas which were not enabled for read-only mounts if
+ * filesystem has quota feature, so that they are updated correctly.
+ */
+ if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) {
+ int ret = ext4_enable_quotas(sb);
+
+ if (!ret)
+ quota_update = 1;
+ else
+ ext4_msg(sb, KERN_ERR,
+ "Cannot turn on quotas: error %d", ret);
+ }
+
+ /* Turn on journaled quotas used for old sytle */
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
if (EXT4_SB(sb)->s_qf_names[i]) {
int ret = ext4_quota_on_mount(sb, i);
- if (ret < 0)
+
+ if (!ret)
+ quota_update = 1;
+ else
ext4_msg(sb, KERN_ERR,
"Cannot turn on journaled "
- "quota: error %d", ret);
+ "quota: type %d: error %d", i, ret);
}
}
#endif
@@ -2510,10 +2529,12 @@ static void ext4_orphan_cleanup(struct s
ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
PLURAL(nr_truncates));
#ifdef CONFIG_QUOTA
- /* Turn off journaled quotas if they were enabled for orphan cleanup */
- for (i = 0; i < EXT4_MAXQUOTAS; i++) {
- if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
- dquot_quota_off(sb, i);
+ /* Turn off quotas if they were enabled for orphan cleanup */
+ if (quota_update) {
+ for (i = 0; i < EXT4_MAXQUOTAS; i++) {
+ if (sb_dqopt(sb)->files[i])
+ dquot_quota_off(sb, i);
+ }
}
#endif
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
@@ -5512,6 +5533,9 @@ static int ext4_enable_quotas(struct sup
DQUOT_USAGE_ENABLED |
(quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0));
if (err) {
+ for (type--; type >= 0; type--)
+ dquot_quota_off(sb, type);
+
ext4_warning(sb,
"Failed to enable quota tracking "
"(type=%d, err=%d). Please run "
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
commit 1bd8d6cd3e413d64e543ec3e69ff43e75a1cf1ea upstream.
In the ext4 implementations of SEEK_HOLE and SEEK_DATA, make sure we
return -ENXIO for negative offsets instead of banging around inside
the extent code and returning -EFSCORRUPTED.
Reported-by: Mateusz S <[email protected]>
Signed-off-by: Darrick J. Wong <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ext4/file.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -595,7 +595,7 @@ static loff_t ext4_seek_data(struct file
inode_lock(inode);
isize = i_size_read(inode);
- if (offset >= isize) {
+ if (offset < 0 || offset >= isize) {
inode_unlock(inode);
return -ENXIO;
}
@@ -658,7 +658,7 @@ static loff_t ext4_seek_hole(struct file
inode_lock(inode);
isize = i_size_read(inode);
- if (offset >= isize) {
+ if (offset < 0 || offset >= isize) {
inode_unlock(inode);
return -ENXIO;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
commit 39efc7cc7ccf82d1cd946580cdb70760f347305a upstream.
As the association status changes the driver needs to configure the
hardware. This is done based on information in the "sta" acquired by
ieee80211_find_sta(), which requires the caller to ensure that the "sta"
is valid while its being used; generally by entering an rcu read
section.
But the operations acting on the "sta" has to communicate with the
firmware and may therefor sleep, resulting in the following report:
[ 31.418190] BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:238
[ 31.425919] in_atomic(): 0, irqs_disabled(): 0, pid: 34, name:
kworker/u8:1
[ 31.434609] CPU: 0 PID: 34 Comm: kworker/u8:1 Tainted: G W
4.12.0-rc4-next-20170607+ #993
[ 31.441002] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC
(DT)
[ 31.450380] Workqueue: phy0 ieee80211_iface_work
[ 31.457226] Call trace:
[ 31.461830] [<ffffff8008088c58>] dump_backtrace+0x0/0x260
[ 31.464004] [<ffffff8008088f7c>] show_stack+0x14/0x20
[ 31.469557] [<ffffff8008392e70>] dump_stack+0x98/0xb8
[ 31.474592] [<ffffff80080e4330>] ___might_sleep+0xf0/0x118
[ 31.479626] [<ffffff80080e43a8>] __might_sleep+0x50/0x88
[ 31.485010] [<ffffff80088ff9a4>] mutex_lock+0x24/0x60
[ 31.490479] [<ffffff8008595c38>] wcn36xx_smd_set_link_st+0x30/0x130
[ 31.495428] [<ffffff8008591ed8>] wcn36xx_bss_info_changed+0x148/0x448
[ 31.501504] [<ffffff80088ab3c4>]
ieee80211_bss_info_change_notify+0xbc/0x118
[ 31.508102] [<ffffff80088f841c>] ieee80211_assoc_success+0x664/0x7f8
[ 31.515220] [<ffffff80088e13d4>]
ieee80211_rx_mgmt_assoc_resp+0x144/0x2d8
[ 31.521555] [<ffffff80088e1e20>]
ieee80211_sta_rx_queued_mgmt+0x190/0x698
[ 31.528239] [<ffffff80088bc44c>] ieee80211_iface_work+0x234/0x368
[ 31.535011] [<ffffff80080d81ac>] process_one_work+0x1cc/0x340
[ 31.541086] [<ffffff80080d8368>] worker_thread+0x48/0x430
[ 31.546814] [<ffffff80080de448>] kthread+0x108/0x138
[ 31.552195] [<ffffff8008082ec0>] ret_from_fork+0x10/0x50
In order to ensure that the "sta" remains alive (and consistent) for the
duration of bss_info_changed() mutual exclusion has to be ensured with
sta_remove().
This is done by introducing a mutex to cover firmware configuration
changes, which is made to also ensure mutual exclusion between other
operations changing the state or configuration of the firmware. With
this we can drop the rcu read lock.
Signed-off-by: Bjorn Andersson <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/ath/wcn36xx/main.c | 52 +++++++++++++++++++++++++++--
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 3 +
2 files changed, 53 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -372,6 +372,8 @@ static int wcn36xx_config(struct ieee802
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);
+ mutex_lock(&wcn->conf_mutex);
+
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
int ch = WCN36XX_HW_CHANNEL(wcn);
wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
@@ -382,6 +384,8 @@ static int wcn36xx_config(struct ieee802
}
}
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -396,6 +400,8 @@ static void wcn36xx_configure_filter(str
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n");
+ mutex_lock(&wcn->conf_mutex);
+
*total &= FIF_ALLMULTI;
fp = (void *)(unsigned long)multicast;
@@ -408,6 +414,8 @@ static void wcn36xx_configure_filter(str
else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc)
wcn36xx_smd_set_mc_list(wcn, vif, fp);
}
+
+ mutex_unlock(&wcn->conf_mutex);
kfree(fp);
}
@@ -471,6 +479,8 @@ static int wcn36xx_set_key(struct ieee80
key_conf->key,
key_conf->keylen);
+ mutex_lock(&wcn->conf_mutex);
+
switch (key_conf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40;
@@ -565,6 +575,8 @@ static int wcn36xx_set_key(struct ieee80
}
out:
+ mutex_unlock(&wcn->conf_mutex);
+
return ret;
}
@@ -725,6 +737,8 @@ static void wcn36xx_bss_info_changed(str
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n",
vif, changed);
+ mutex_lock(&wcn->conf_mutex);
+
if (changed & BSS_CHANGED_BEACON_INFO) {
wcn36xx_dbg(WCN36XX_DBG_MAC,
"mac bss changed dtim period %d\n",
@@ -787,7 +801,13 @@ static void wcn36xx_bss_info_changed(str
bss_conf->aid);
vif_priv->sta_assoc = true;
- rcu_read_lock();
+
+ /*
+ * Holding conf_mutex ensures mutal exclusion with
+ * wcn36xx_sta_remove() and as such ensures that sta
+ * won't be freed while we're operating on it. As such
+ * we do not need to hold the rcu_read_lock().
+ */
sta = ieee80211_find_sta(vif, bss_conf->bssid);
if (!sta) {
wcn36xx_err("sta %pM is not found\n",
@@ -811,7 +831,6 @@ static void wcn36xx_bss_info_changed(str
* place where AID is available.
*/
wcn36xx_smd_config_sta(wcn, vif, sta);
- rcu_read_unlock();
} else {
wcn36xx_dbg(WCN36XX_DBG_MAC,
"disassociated bss %pM vif %pM AID=%d\n",
@@ -873,6 +892,9 @@ static void wcn36xx_bss_info_changed(str
}
}
out:
+
+ mutex_unlock(&wcn->conf_mutex);
+
return;
}
@@ -882,7 +904,10 @@ static int wcn36xx_set_rts_threshold(str
struct wcn36xx *wcn = hw->priv;
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
+ mutex_lock(&wcn->conf_mutex);
wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value);
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -893,8 +918,12 @@ static void wcn36xx_remove_interface(str
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif);
+ mutex_lock(&wcn->conf_mutex);
+
list_del(&vif_priv->list);
wcn36xx_smd_delete_sta_self(wcn, vif->addr);
+
+ mutex_unlock(&wcn->conf_mutex);
}
static int wcn36xx_add_interface(struct ieee80211_hw *hw,
@@ -915,9 +944,13 @@ static int wcn36xx_add_interface(struct
return -EOPNOTSUPP;
}
+ mutex_lock(&wcn->conf_mutex);
+
list_add(&vif_priv->list, &wcn->vif_list);
wcn36xx_smd_add_sta_self(wcn, vif);
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -930,6 +963,8 @@ static int wcn36xx_sta_add(struct ieee80
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
vif, sta->addr);
+ mutex_lock(&wcn->conf_mutex);
+
spin_lock_init(&sta_priv->ampdu_lock);
sta_priv->vif = vif_priv;
/*
@@ -941,6 +976,9 @@ static int wcn36xx_sta_add(struct ieee80
sta_priv->aid = sta->aid;
wcn36xx_smd_config_sta(wcn, vif, sta);
}
+
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -954,8 +992,13 @@ static int wcn36xx_sta_remove(struct iee
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n",
vif, sta->addr, sta_priv->sta_index);
+ mutex_lock(&wcn->conf_mutex);
+
wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
sta_priv->vif = NULL;
+
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -999,6 +1042,8 @@ static int wcn36xx_ampdu_action(struct i
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
action, tid);
+ mutex_lock(&wcn->conf_mutex);
+
switch (action) {
case IEEE80211_AMPDU_RX_START:
sta_priv->tid = tid;
@@ -1038,6 +1083,8 @@ static int wcn36xx_ampdu_action(struct i
wcn36xx_err("Unknown AMPDU action\n");
}
+ mutex_unlock(&wcn->conf_mutex);
+
return 0;
}
@@ -1216,6 +1263,7 @@ static int wcn36xx_probe(struct platform
wcn = hw->priv;
wcn->hw = hw;
wcn->dev = &pdev->dev;
+ mutex_init(&wcn->conf_mutex);
mutex_init(&wcn->hal_mutex);
mutex_init(&wcn->scan_lock);
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -202,6 +202,9 @@ struct wcn36xx {
struct qcom_smem_state *tx_rings_empty_state;
unsigned tx_rings_empty_state_bit;
+ /* prevents concurrent FW reconfiguration */
+ struct mutex conf_mutex;
+
/*
* smd_buf must be protected with smd_mutex to garantee
* that all messages are sent one after another
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit ae11c0619973ffd73a496308d8a1cb5e1a353737 upstream.
Fix definition and usage of "maddf_flags" enumeration. Avoid duplicate
definition and apply more common capitalization.
This patch does not change any scenario. It just makes MADDF and
MSUBF emulation code more readable and easier to maintain, and
hopefully prevents future bugs as well.
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16889/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_maddf.c | 19 ++++++++-----------
arch/mips/math-emu/ieee754int.h | 4 ++++
arch/mips/math-emu/sp_maddf.c | 19 ++++++++-----------
3 files changed, 20 insertions(+), 22 deletions(-)
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -14,9 +14,6 @@
#include "ieee754dp.h"
-enum maddf_flags {
- maddf_negate_product = 1 << 0,
-};
static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
union ieee754dp y, enum maddf_flags flags)
@@ -85,8 +82,8 @@ static union ieee754dp _dp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
if ((zc == IEEE754_CLASS_INF) &&
- ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
- ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+ ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
+ ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
/*
* Cases of addition of infinities with opposite signs
* or subtraction of infinities with same signs.
@@ -99,9 +96,9 @@ static union ieee754dp _dp_maddf(union i
* same sign as product (x*y) (in case of MADDF.D instruction)
* or product -(x*y) (in MSUBF.D case). The result must be an
* infinity, and its sign is determined only by the value of
- * (flags & maddf_negate_product) and the signs of x and y.
+ * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
*/
- if (flags & maddf_negate_product)
+ if (flags & MADDF_NEGATE_PRODUCT)
return ieee754dp_inf(1 ^ (xs ^ ys));
else
return ieee754dp_inf(xs ^ ys);
@@ -115,9 +112,9 @@ static union ieee754dp _dp_maddf(union i
return ieee754dp_inf(zs);
if (zc == IEEE754_CLASS_ZERO) {
/* Handle cases +0 + (-0) and similar ones. */
- if ((!(flags & maddf_negate_product)
+ if ((!(flags & MADDF_NEGATE_PRODUCT)
&& (zs == (xs ^ ys))) ||
- ((flags & maddf_negate_product)
+ ((flags & MADDF_NEGATE_PRODUCT)
&& (zs != (xs ^ ys))))
/*
* Cases of addition of zeros of equal signs
@@ -167,7 +164,7 @@ static union ieee754dp _dp_maddf(union i
re = xe + ye;
rs = xs ^ ys;
- if (flags & maddf_negate_product)
+ if (flags & MADDF_NEGATE_PRODUCT)
rs ^= 1;
/* shunt to top of word */
@@ -291,5 +288,5 @@ union ieee754dp ieee754dp_maddf(union ie
union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
union ieee754dp y)
{
- return _dp_maddf(z, x, y, maddf_negate_product);
+ return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
}
--- a/arch/mips/math-emu/ieee754int.h
+++ b/arch/mips/math-emu/ieee754int.h
@@ -26,6 +26,10 @@
#define CLPAIR(x, y) ((x)*6+(y))
+enum maddf_flags {
+ MADDF_NEGATE_PRODUCT = 1 << 0,
+};
+
static inline void ieee754_clearcx(void)
{
ieee754_csr.cx = 0;
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -14,9 +14,6 @@
#include "ieee754sp.h"
-enum maddf_flags {
- maddf_negate_product = 1 << 0,
-};
static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
union ieee754sp y, enum maddf_flags flags)
@@ -86,8 +83,8 @@ static union ieee754sp _sp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
if ((zc == IEEE754_CLASS_INF) &&
- ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
- ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+ ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
+ ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
/*
* Cases of addition of infinities with opposite signs
* or subtraction of infinities with same signs.
@@ -100,9 +97,9 @@ static union ieee754sp _sp_maddf(union i
* same sign as product (x*y) (in case of MADDF.D instruction)
* or product -(x*y) (in MSUBF.D case). The result must be an
* infinity, and its sign is determined only by the value of
- * (flags & maddf_negate_product) and the signs of x and y.
+ * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
*/
- if (flags & maddf_negate_product)
+ if (flags & MADDF_NEGATE_PRODUCT)
return ieee754sp_inf(1 ^ (xs ^ ys));
else
return ieee754sp_inf(xs ^ ys);
@@ -116,9 +113,9 @@ static union ieee754sp _sp_maddf(union i
return ieee754sp_inf(zs);
if (zc == IEEE754_CLASS_ZERO) {
/* Handle cases +0 + (-0) and similar ones. */
- if ((!(flags & maddf_negate_product)
+ if ((!(flags & MADDF_NEGATE_PRODUCT)
&& (zs == (xs ^ ys))) ||
- ((flags & maddf_negate_product)
+ ((flags & MADDF_NEGATE_PRODUCT)
&& (zs != (xs ^ ys))))
/*
* Cases of addition of zeros of equal signs
@@ -170,7 +167,7 @@ static union ieee754sp _sp_maddf(union i
re = xe + ye;
rs = xs ^ ys;
- if (flags & maddf_negate_product)
+ if (flags & MADDF_NEGATE_PRODUCT)
rs ^= 1;
/* shunt to top of word */
@@ -287,5 +284,5 @@ union ieee754sp ieee754sp_maddf(union ie
union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
union ieee754sp y)
{
- return _sp_maddf(z, x, y, maddf_negate_product);
+ return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang, Jerry <[email protected]>
commit 2890decfd9969cac21067ca0c734fbccaf74d634 upstream.
v2: fix the SOS loading failure for PSP v3.1
Signed-off-by: Junwei Zhang <[email protected]>
Acked-by: Alex Deucher <[email protected]> (v1)
Acked-by: Huang Rui <[email protected]> (v1)
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +--
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 2 --
2 files changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -95,9 +95,8 @@ int psp_wait_for(struct psp_context *psp
int i;
struct amdgpu_device *adev = psp->adev;
- val = RREG32(reg_index);
-
for (i = 0; i < adev->usec_timeout; i++) {
+ val = RREG32(reg_index);
if (check_changed) {
if (val != reg_val)
return 0;
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -237,11 +237,9 @@ int psp_v3_1_bootloader_load_sos(struct
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
-#if 0
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
0, true);
-#endif
return ret;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cameron Gutman <[email protected]>
commit 122d6a347329818419b032c5a1776e6b3866d9b9 upstream.
We should only see devices with interrupt endpoints. Ignore any other
endpoints that we find, so we don't send try to send them interrupt URBs
and trigger a WARN down in the USB stack.
Reported-by: Andrey Konovalov <[email protected]>
Tested-by: Andrey Konovalov <[email protected]>
Signed-off-by: Cameron Gutman <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/input/joystick/xpad.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1764,10 +1764,12 @@ static int xpad_probe(struct usb_interfa
struct usb_endpoint_descriptor *ep =
&intf->cur_altsetting->endpoint[i].desc;
- if (usb_endpoint_dir_in(ep))
- ep_irq_in = ep;
- else
- ep_irq_out = ep;
+ if (usb_endpoint_xfer_int(ep)) {
+ if (usb_endpoint_dir_in(ep))
+ ep_irq_in = ep;
+ else
+ ep_irq_out = ep;
+ }
}
if (!ep_irq_in || !ep_irq_out) {
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul E. McKenney <[email protected]>
commit 35732cf9dd38b1efb0f2f22c91c61b51337d1ac3 upstream.
Tree RCU guarantees that every online CPU has a memory barrier between
any given grace period and any of that CPU's RCU read-side sections that
must be ordered against that grace period. Since RCU doesn't always
know where read-side critical sections are, the actual implementation
guarantees order against prior and subsequent non-idle non-offline code,
whether in an RCU read-side critical section or not. As a result, there
does not need to be a memory barrier at the end of synchronize_rcu()
and friends because the ordering internal to the grace period has
ordered every CPU's post-grace-period execution against each CPU's
pre-grace-period execution, again for all non-idle online CPUs.
In contrast, SRCU can have non-idle online CPUs that are completely
uninvolved in a given SRCU grace period, for example, a CPU that
never runs any SRCU read-side critical sections and took no part in
the grace-period processing. It is in theory possible for a given
synchronize_srcu()'s wakeup to be delivered to a CPU that was completely
uninvolved in the prior SRCU grace period, which could mean that the
code following that synchronize_srcu() would end up being unordered with
respect to both the grace period and any pre-existing SRCU read-side
critical sections.
This commit therefore adds an smp_mb() to the end of __synchronize_srcu(),
which prevents this scenario from occurring.
Reported-by: Lance Roy <[email protected]>
Signed-off-by: Paul E. McKenney <[email protected]>
Acked-by: Lance Roy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/rcu/srcutree.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -896,6 +896,15 @@ static void __synchronize_srcu(struct sr
__call_srcu(sp, &rcu.head, wakeme_after_rcu, do_norm);
wait_for_completion(&rcu.completion);
destroy_rcu_head_on_stack(&rcu.head);
+
+ /*
+ * Make sure that later code is ordered after the SRCU grace
+ * period. This pairs with the raw_spin_lock_irq_rcu_node()
+ * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed
+ * because the current CPU might have been totally uninvolved with
+ * (and thus unordered against) that grace period.
+ */
+ smp_mb();
}
/**
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Marciniszyn <[email protected]>
commit 5b0ef650bd0f820e922fcc42f1985d4621ae19cf upstream.
Section 9.7.7.2.5 of the 1.3 IBTA spec clearly says that receive
credits should never apply to RDMA write.
qib and hfi1 were doing that. The following situation will result
in a QP hang:
- A prior SEND or RDMA_WRITE with immmediate consumed the last
credit for a QP using RC receive buffer credits
- The prior op is acked so there are no more acks
- The peer ULP fails to post receive for some reason
- An RDMA write sees that the credits are exhausted and waits
- The peer ULP posts receive buffers
- The ULP posts a send or RDMA write that will be hung
The fix is to avoid the credit test for the RDMA write operation.
Reviewed-by: Kaike Wan <[email protected]>
Signed-off-by: Mike Marciniszyn <[email protected]>
Signed-off-by: Dennis Dalessandro <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/hw/hfi1/rc.c | 3 ++-
drivers/infiniband/hw/qib/qib_rc.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -425,7 +425,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp,
case IB_WR_RDMA_WRITE:
if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
qp->s_lsn++;
- /* FALLTHROUGH */
+ goto no_flow_control;
case IB_WR_RDMA_WRITE_WITH_IMM:
/* If no credit, return. */
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -433,6 +433,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp,
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
goto bail;
}
+no_flow_control:
put_ib_reth_vaddr(
wqe->rdma_wr.remote_addr,
&ohdr->u.rc.reth);
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -348,7 +348,7 @@ int qib_make_rc_req(struct rvt_qp *qp, u
case IB_WR_RDMA_WRITE:
if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
qp->s_lsn++;
- /* FALLTHROUGH */
+ goto no_flow_control;
case IB_WR_RDMA_WRITE_WITH_IMM:
/* If no credit, return. */
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -356,7 +356,7 @@ int qib_make_rc_req(struct rvt_qp *qp, u
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
goto bail;
}
-
+no_flow_control:
ohdr->u.rc.reth.vaddr =
cpu_to_be64(wqe->rdma_wr.remote_addr);
ohdr->u.rc.reth.rkey =
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit e840be6e7057757befc3581e1699e30fe7f0dd51 upstream.
Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any
NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following:
- if any of inputs is sNaN, return a sNaN using following rules: if
only one input is sNaN, return that one; if more than one input is
sNaN, order of precedence for return value is fd, fs, ft
- if no input is sNaN, but at least one of inputs is qNaN, return a
qNaN using following rules: if only one input is qNaN, return that
one; if more than one input is qNaN, order of precedence for
return value is fd, fs, ft
The previous code contained correct handling of some above cases, but
not all. Also, such handling was scattered into various cases of
"switch (CLPAIR(xc, yc))" statement, and elsewhere. With this patch,
this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is
significantly simplified.
A relevant example:
MADDF.S fd,fs,ft:
If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd
is going to contain qNaN3 (without this patch, it used to contain
qNaN1).
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16886/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_maddf.c | 66 ++++++++++++------------------------------
arch/mips/math-emu/sp_maddf.c | 66 +++++++++++++-----------------------------
2 files changed, 41 insertions(+), 91 deletions(-)
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -48,52 +48,34 @@ static union ieee754dp _dp_maddf(union i
ieee754_clearcx();
- switch (zc) {
- case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
+ /*
+ * Handle the cases when at least one of x, y or z is a NaN.
+ * Order of precedence is sNaN, qNaN and z, x, y.
+ */
+ if (zc == IEEE754_CLASS_SNAN)
return ieee754dp_nanxcpt(z);
- case IEEE754_CLASS_DNORM:
- DPDNORMZ;
- /* QNAN and ZERO cases are handled separately below */
- }
-
- switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
- return ieee754dp_nanxcpt(y);
-
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ if (xc == IEEE754_CLASS_SNAN)
return ieee754dp_nanxcpt(x);
-
- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ if (yc == IEEE754_CLASS_SNAN)
+ return ieee754dp_nanxcpt(y);
+ if (zc == IEEE754_CLASS_QNAN)
+ return z;
+ if (xc == IEEE754_CLASS_QNAN)
+ return x;
+ if (yc == IEEE754_CLASS_QNAN)
return y;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
- return x;
+ if (zc == IEEE754_CLASS_DNORM)
+ DPDNORMZ;
+ /* ZERO z cases are handled separately below */
+ switch (CLPAIR(xc, yc)) {
/*
* Infinity handling
*/
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754dp_indef();
@@ -102,8 +84,6 @@ static union ieee754dp _dp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
return ieee754dp_inf(xs ^ ys);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -120,25 +100,19 @@ static union ieee754dp _dp_maddf(union i
DPDNORMX;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754dp_inf(zs);
DPDNORMY;
break;
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754dp_inf(zs);
DPDNORMX;
break;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754dp_inf(zs);
/* fall through to real computations */
}
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -48,51 +48,35 @@ static union ieee754sp _sp_maddf(union i
ieee754_clearcx();
- switch (zc) {
- case IEEE754_CLASS_SNAN:
- ieee754_setcx(IEEE754_INVALID_OPERATION);
+ /*
+ * Handle the cases when at least one of x, y or z is a NaN.
+ * Order of precedence is sNaN, qNaN and z, x, y.
+ */
+ if (zc == IEEE754_CLASS_SNAN)
return ieee754sp_nanxcpt(z);
- case IEEE754_CLASS_DNORM:
- SPDNORMZ;
- /* QNAN and ZERO cases are handled separately below */
- }
-
- switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ if (xc == IEEE754_CLASS_SNAN)
+ return ieee754sp_nanxcpt(x);
+ if (yc == IEEE754_CLASS_SNAN)
return ieee754sp_nanxcpt(y);
+ if (zc == IEEE754_CLASS_QNAN)
+ return z;
+ if (xc == IEEE754_CLASS_QNAN)
+ return x;
+ if (yc == IEEE754_CLASS_QNAN)
+ return y;
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
- return ieee754sp_nanxcpt(x);
+ if (zc == IEEE754_CLASS_DNORM)
+ SPDNORMZ;
+ /* ZERO z cases are handled separately below */
- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
- return y;
+ switch (CLPAIR(xc, yc)) {
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
- return x;
/*
* Infinity handling
*/
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754sp_indef();
@@ -101,8 +85,6 @@ static union ieee754sp _sp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
return ieee754sp_inf(xs ^ ys);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -119,25 +101,19 @@ static union ieee754sp _sp_maddf(union i
SPDNORMX;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754sp_inf(zs);
SPDNORMY;
break;
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754sp_inf(zs);
SPDNORMX;
break;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
- if (zc == IEEE754_CLASS_QNAN)
- return z;
- else if (zc == IEEE754_CLASS_INF)
+ if (zc == IEEE754_CLASS_INF)
return ieee754sp_inf(zs);
/* fall through to real computations */
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 0c64fe6348687f0e1cea9a608eae9d351124a73a upstream.
Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is
infinity. The correct behavior in such cases is affected by the nature
of third input. Cases of addition of infinities with opposite signs
and subtraction of infinities with same signs may arise and must be
handles separately. Also, the value od flags argument (that determines
whether the instruction is MADDF or MSUBF) affects the outcome.
Relevant examples:
MADDF.S fd,fs,ft:
If fs contains +inf, ft contains +inf, and fd contains -inf, fd is
going to contain indef (without this patch, it used to contain
-inf).
MSUBF.S fd,fs,ft:
If fs contains +inf, ft contains 1.0, and fd contains +0.0, fd is
going to contain -inf (without this patch, it used to contain +inf).
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")
Signed-off-by: Douglas Leung <[email protected]>
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16887/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_maddf.c | 22 +++++++++++++++++++++-
arch/mips/math-emu/sp_maddf.c | 22 +++++++++++++++++++++-
2 files changed, 42 insertions(+), 2 deletions(-)
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -84,7 +84,27 @@ static union ieee754dp _dp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
- return ieee754dp_inf(xs ^ ys);
+ if ((zc == IEEE754_CLASS_INF) &&
+ ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+ ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+ /*
+ * Cases of addition of infinities with opposite signs
+ * or subtraction of infinities with same signs.
+ */
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754dp_indef();
+ }
+ /*
+ * z is here either not an infinity, or an infinity having the
+ * same sign as product (x*y) (in case of MADDF.D instruction)
+ * or product -(x*y) (in MSUBF.D case). The result must be an
+ * infinity, and its sign is determined only by the value of
+ * (flags & maddf_negate_product) and the signs of x and y.
+ */
+ if (flags & maddf_negate_product)
+ return ieee754dp_inf(1 ^ (xs ^ ys));
+ else
+ return ieee754dp_inf(xs ^ ys);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -85,7 +85,27 @@ static union ieee754sp _sp_maddf(union i
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
- return ieee754sp_inf(xs ^ ys);
+ if ((zc == IEEE754_CLASS_INF) &&
+ ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+ ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+ /*
+ * Cases of addition of infinities with opposite signs
+ * or subtraction of infinities with same signs.
+ */
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754sp_indef();
+ }
+ /*
+ * z is here either not an infinity, or an infinity having the
+ * same sign as product (x*y) (in case of MADDF.D instruction)
+ * or product -(x*y) (in MSUBF.D case). The result must be an
+ * infinity, and its sign is determined only by the value of
+ * (flags & maddf_negate_product) and the signs of x and y.
+ */
+ if (flags & maddf_negate_product)
+ return ieee754sp_inf(1 ^ (xs ^ ys));
+ else
+ return ieee754sp_inf(xs ^ ys);
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 304bfe473e70523e591fb1c9223289d355e0bdcb upstream.
Fix following special cases for MINA>.<D|S>:
- if one of the inputs is zero, and the other is subnormal, normal,
or infinity, the value of the former should be returned (that is,
a zero).
- if one of the inputs is infinity, and the other input is normal,
or subnormal, the value of the latter should be returned.
The previous implementation's logic for such cases was incorrect - it
appears as if it implements MAXA, and not MINA instruction.
A relevant example:
MINA.S fd,fs,ft:
If fs contains 100.0, and ft contains 0.0, fd is going to contain
0.0 (without this patch, it used to contain 100.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16885/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmin.c | 4 ++--
arch/mips/math-emu/sp_fmin.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -210,14 +210,14 @@ union ieee754dp ieee754dp_fmina(union ie
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
- return x;
+ return y;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
- return y;
+ return x;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
return ieee754dp_zero(xs | ys);
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -210,14 +210,14 @@ union ieee754sp ieee754sp_fmina(union ie
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
- return x;
+ return y;
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
- return y;
+ return x;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
return ieee754sp_zero(xs | ys);
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 1a41b3b441508ae63b1a9ec699ec94065739eb60 upstream.
Fix the value returned by <MAXA|MINA>.<D|S>, if the inputs are normal
fp numbers of the same absolute value, but opposite signs.
A relevant example:
MAXA.S fd,fs,ft:
If fs contains -3.0, and ft contains +3.0, fd is going to contain
+3.0 (without this patch, it used to contain -3.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16883/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmax.c | 8 ++++++--
arch/mips/math-emu/dp_fmin.c | 6 +++++-
arch/mips/math-emu/sp_fmax.c | 8 ++++++--
arch/mips/math-emu/sp_fmin.c | 6 +++++-
4 files changed, 22 insertions(+), 6 deletions(-)
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmaxa(union ie
return y;
/* Compare mantissa */
- if (xm <= ym)
+ if (xm < ym)
return y;
- return x;
+ else if (xm > ym)
+ return x;
+ else if (xs == 0)
+ return x;
+ return y;
}
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmina(union ie
return x;
/* Compare mantissa */
- if (xm <= ym)
+ if (xm < ym)
+ return x;
+ else if (xm > ym)
+ return y;
+ else if (xs == 1)
return x;
return y;
}
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmaxa(union ie
return y;
/* Compare mantissa */
- if (xm <= ym)
+ if (xm < ym)
return y;
- return x;
+ else if (xm > ym)
+ return x;
+ else if (xs == 0)
+ return x;
+ return y;
}
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmina(union ie
return x;
/* Compare mantissa */
- if (xm <= ym)
+ if (xm < ym)
+ return x;
+ else if (xm > ym)
+ return y;
+ else if (xs == 1)
return x;
return y;
}
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit e78bf0dc4789bdea1453595ae89e8db65918e22e upstream.
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S> fd,fs,ft, if both
inputs are quiet NaNs. The <MAX|MAXA|MIN|MINA>.<D|S> specifications
state that the returned value in such cases should be the quiet NaN
contained in register fs.
A relevant example:
MAX.S fd,fs,ft:
If fs contains qNaN1, and ft contains qNaN2, fd is going to contain
qNaN1 (without this patch, it used to contain qNaN2).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16880/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmax.c | 32 ++++++++++++++++++++++++++++----
arch/mips/math-emu/dp_fmin.c | 32 ++++++++++++++++++++++++++++----
arch/mips/math-emu/sp_fmax.c | 32 ++++++++++++++++++++++++++++----
arch/mips/math-emu/sp_fmin.c | 32 ++++++++++++++++++++++++++++----
4 files changed, 112 insertions(+), 16 deletions(-)
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union iee
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754dp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmaxa(union ie
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754dp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union iee
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754dp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmina(union ie
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754dp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union iee
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754sp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmaxa(union ie
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754sp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union iee
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754sp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmina(union ie
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
return ieee754sp_nanxcpt(x);
- /* numbers are preferred to NaNs */
+ /*
+ * Quiet NaN handling
+ */
+
+ /*
+ * The case of both inputs quiet NaNs
+ */
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ return x;
+
+ /*
+ * The cases of exactly one input quiet NaN (numbers
+ * are here preferred as returned values to NaNs)
+ */
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
return x;
- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit 15560a58bfd4ff82cdd16b2270d4ef9b06d2cc4d upstream.
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S>, if both inputs
are zeros. The right behavior in such cases is stated in instruction
reference manual and is as follows:
fs ft MAX MIN MAXA MINA
---------------------------------------------
0 0 0 0 0 0
0 -0 0 -0 0 -0
-0 0 0 -0 0 -0
-0 -0 -0 -0 -0 -0
Prior to this patch, some of the above cases were yielding correct
results. However, for the sake of code consistency, all such cases
are rewritten in this patch.
A relevant example:
MAX.S fd,fs,ft:
If fs contains +0.0, and ft contains -0.0, fd is going to contain
+0.0 (without this patch, it used to contain -0.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16881/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmax.c | 8 ++------
arch/mips/math-emu/dp_fmin.c | 8 ++------
arch/mips/math-emu/sp_fmax.c | 8 ++------
arch/mips/math-emu/sp_fmin.c | 8 ++------
4 files changed, 8 insertions(+), 24 deletions(-)
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union iee
return ys ? x : y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754dp_zero(1);
+ return ieee754dp_zero(xs & ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmaxa(union ie
return y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754dp_zero(1);
+ return ieee754dp_zero(xs & ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union iee
return ys ? y : x;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754dp_zero(1);
+ return ieee754dp_zero(xs | ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmina(union ie
return y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754dp_zero(1);
+ return ieee754dp_zero(xs | ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union iee
return ys ? x : y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754sp_zero(1);
+ return ieee754sp_zero(xs & ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmaxa(union ie
return y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754sp_zero(1);
+ return ieee754sp_zero(xs & ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union iee
return ys ? y : x;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754sp_zero(1);
+ return ieee754sp_zero(xs | ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmina(union ie
return y;
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
- if (xs == ys)
- return x;
- return ieee754sp_zero(1);
+ return ieee754sp_zero(xs | ys);
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandar Markovic <[email protected]>
commit aabf5cf02e22ebc4e541adf835910f388b6c3e65 upstream.
Fix the value returned by <MAX|MIN>.<D|S>, if both inputs are negative
normal fp numbers. The previous logic did not take into account that
if both inputs have the same sign, there should be separate treatment
of the cases when both inputs are negative and when both inputs are
positive.
A relevant example:
MAX.S fd,fs,ft:
If fs contains -5.0, and ft contains -7.0, fd is going to contain
-5.0 (without this patch, it used to contain -7.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <[email protected]>
Signed-off-by: Goran Ferenc <[email protected]>
Signed-off-by: Aleksandar Markovic <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: Bo Hu <[email protected]>
Cc: Douglas Leung <[email protected]>
Cc: Jin Qian <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Petar Jovanovic <[email protected]>
Cc: Raghu Gandham <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/16882/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/math-emu/dp_fmax.c | 32 ++++++++++++++++++++++++--------
arch/mips/math-emu/dp_fmin.c | 32 ++++++++++++++++++++++++--------
arch/mips/math-emu/sp_fmax.c | 32 ++++++++++++++++++++++++--------
arch/mips/math-emu/sp_fmin.c | 32 ++++++++++++++++++++++++--------
4 files changed, 96 insertions(+), 32 deletions(-)
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union iee
else if (xs < ys)
return x;
- /* Compare exponent */
- if (xe > ye)
- return x;
- else if (xe < ye)
- return y;
+ /* Signs of inputs are equal, let's compare exponents */
+ if (xs == 0) {
+ /* Inputs are both positive */
+ if (xe > ye)
+ return x;
+ else if (xe < ye)
+ return y;
+ } else {
+ /* Inputs are both negative */
+ if (xe > ye)
+ return y;
+ else if (xe < ye)
+ return x;
+ }
- /* Compare mantissa */
+ /* Signs and exponents of inputs are equal, let's compare mantissas */
+ if (xs == 0) {
+ /* Inputs are both positive, with equal signs and exponents */
+ if (xm <= ym)
+ return y;
+ return x;
+ }
+ /* Inputs are both negative, with equal signs and exponents */
if (xm <= ym)
- return y;
- return x;
+ return x;
+ return y;
}
union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union iee
else if (xs < ys)
return y;
- /* Compare exponent */
- if (xe > ye)
- return y;
- else if (xe < ye)
- return x;
+ /* Signs of inputs are the same, let's compare exponents */
+ if (xs == 0) {
+ /* Inputs are both positive */
+ if (xe > ye)
+ return y;
+ else if (xe < ye)
+ return x;
+ } else {
+ /* Inputs are both negative */
+ if (xe > ye)
+ return x;
+ else if (xe < ye)
+ return y;
+ }
- /* Compare mantissa */
+ /* Signs and exponents of inputs are equal, let's compare mantissas */
+ if (xs == 0) {
+ /* Inputs are both positive, with equal signs and exponents */
+ if (xm <= ym)
+ return x;
+ return y;
+ }
+ /* Inputs are both negative, with equal signs and exponents */
if (xm <= ym)
- return x;
- return y;
+ return y;
+ return x;
}
union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union iee
else if (xs < ys)
return x;
- /* Compare exponent */
- if (xe > ye)
- return x;
- else if (xe < ye)
- return y;
+ /* Signs of inputs are equal, let's compare exponents */
+ if (xs == 0) {
+ /* Inputs are both positive */
+ if (xe > ye)
+ return x;
+ else if (xe < ye)
+ return y;
+ } else {
+ /* Inputs are both negative */
+ if (xe > ye)
+ return y;
+ else if (xe < ye)
+ return x;
+ }
- /* Compare mantissa */
+ /* Signs and exponents of inputs are equal, let's compare mantissas */
+ if (xs == 0) {
+ /* Inputs are both positive, with equal signs and exponents */
+ if (xm <= ym)
+ return y;
+ return x;
+ }
+ /* Inputs are both negative, with equal signs and exponents */
if (xm <= ym)
- return y;
- return x;
+ return x;
+ return y;
}
union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union iee
else if (xs < ys)
return y;
- /* Compare exponent */
- if (xe > ye)
- return y;
- else if (xe < ye)
- return x;
+ /* Signs of inputs are the same, let's compare exponents */
+ if (xs == 0) {
+ /* Inputs are both positive */
+ if (xe > ye)
+ return y;
+ else if (xe < ye)
+ return x;
+ } else {
+ /* Inputs are both negative */
+ if (xe > ye)
+ return x;
+ else if (xe < ye)
+ return y;
+ }
- /* Compare mantissa */
+ /* Signs and exponents of inputs are equal, let's compare mantissas */
+ if (xs == 0) {
+ /* Inputs are both positive, with equal signs and exponents */
+ if (xm <= ym)
+ return x;
+ return y;
+ }
+ /* Inputs are both negative, with equal signs and exponents */
if (xm <= ym)
- return x;
- return y;
+ return y;
+ return x;
}
union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai-Heng Feng <[email protected]>
commit 697c5d8a36768b36729533fb44622b35d56d6ad0 upstream.
Similar to other Gigabyte laptops, the touchpad on P57 requires a
keyboard reset to detect Elantech touchpad correctly.
BugLink: https://bugs.launchpad.net/bugs/1594214
Signed-off-by: Kai-Heng Feng <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/input/serio/i8042-x86ia64io.h | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -840,6 +840,13 @@ static const struct dmi_system_id __init
},
},
{
+ /* Gigabyte P57 - Elantech touchpad */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
+ },
+ },
+ {
/* Schenker XMG C504 - Elantech touchpad */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit cee7413d84044a0c1919a7c70a2d761ae24390de upstream.
After commit 8b1bd11c1f8f ("pinctrl: samsung: Add the support the
multiple IORESOURCE_MEM for one pin-bank"), the S3C24xx (and probably
S3C64xx as well) fails:
Unable to handle kernel NULL pointer dereference at virtual address 000000a8
...
(s3c24xx_demux_eint4_7) from [<c004469c>] (__handle_domain_irq+0x6c/0xcc)
(__handle_domain_irq) from [<c0009444>] (s3c24xx_handle_irq+0x6c/0x12c)
(s3c24xx_handle_irq) from [<c000e5fc>] (__irq_svc+0x5c/0x78)
Mentioned commit moved the pointer to controller's base IO memory address
from each controller's driver data (samsung_pinctrl_drv_data) to per-bank
structure (samsung_pin_bank). The external interrupt demux
handlers (s3c24xx_demux_eint()) tried to get this base address from opaque
pointer stored under irq_chip data:
struct irq_data *irqd = irq_desc_get_irq_data(desc);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
...
pend = readl(bank->eint_base + EINTPEND_REG);
which is wrong because this is hardware irq and it bank was never set
for this irq_chip.
For S3C24xx and S3C64xx, this partially reverts mentioned commit by
bringing back the virt_base stored under each controller's driver data
(samsung_pinctrl_drv_data). This virt_base address will be now
duplicated:
- samsung_pinctrl_drv_data->virt_base: used on S3C24xx and S3C64xx,
- samsung_pin_bank->pctl_base: used on Exynos.
Fixes: 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank")
Cc: Sergio Prado <[email protected]>
Reported-by: Sergio Prado <[email protected]>
Signed-off-by: Krzysztof Kozlowski <[email protected]>
Tested-by: Lihua Yao <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 37 +++++++++++++++------------
drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 40 +++++++++++++-----------------
drivers/pinctrl/samsung/pinctrl-samsung.c | 6 ++++
drivers/pinctrl/samsung/pinctrl-samsung.h | 5 +++
4 files changed, 50 insertions(+), 38 deletions(-)
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(st
u32 val;
/* Make sure that pin is configured as interrupt */
- reg = bank->pctl_base + bank->pctl_offset;
+ reg = d->virt_base + bank->pctl_offset;
shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
@@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_
s3c24xx_eint_set_handler(data, type);
/* Set up interrupt trigger */
- reg = bank->eint_base + EINT_REG(index);
+ reg = d->virt_base + EINT_REG(index);
shift = EINT_OFFS(index);
val = readl(reg);
@@ -259,29 +259,32 @@ static void s3c2410_demux_eint0_3(struct
static void s3c2412_eint0_3_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long bitval = 1UL << data->hwirq;
- writel(bitval, bank->eint_base + EINTPEND_REG);
+ writel(bitval, d->virt_base + EINTPEND_REG);
}
static void s3c2412_eint0_3_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
- mask = readl(bank->eint_base + EINTMASK_REG);
+ mask = readl(d->virt_base + EINTMASK_REG);
mask |= (1UL << data->hwirq);
- writel(mask, bank->eint_base + EINTMASK_REG);
+ writel(mask, d->virt_base + EINTMASK_REG);
}
static void s3c2412_eint0_3_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
- mask = readl(bank->eint_base + EINTMASK_REG);
+ mask = readl(d->virt_base + EINTMASK_REG);
mask &= ~(1UL << data->hwirq);
- writel(mask, bank->eint_base + EINTMASK_REG);
+ writel(mask, d->virt_base + EINTMASK_REG);
}
static struct irq_chip s3c2412_eint0_3_chip = {
@@ -316,31 +319,34 @@ static void s3c2412_demux_eint0_3(struct
static void s3c24xx_eint_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
- writel(1UL << index, bank->eint_base + EINTPEND_REG);
+ writel(1UL << index, d->virt_base + EINTPEND_REG);
}
static void s3c24xx_eint_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
- mask = readl(bank->eint_base + EINTMASK_REG);
+ mask = readl(d->virt_base + EINTMASK_REG);
mask |= (1UL << index);
- writel(mask, bank->eint_base + EINTMASK_REG);
+ writel(mask, d->virt_base + EINTMASK_REG);
}
static void s3c24xx_eint_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
- mask = readl(bank->eint_base + EINTMASK_REG);
+ mask = readl(d->virt_base + EINTMASK_REG);
mask &= ~(1UL << index);
- writel(mask, bank->eint_base + EINTMASK_REG);
+ writel(mask, d->virt_base + EINTMASK_REG);
}
static struct irq_chip s3c24xx_eint_chip = {
@@ -356,14 +362,13 @@ static inline void s3c24xx_demux_eint(st
{
struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
- struct irq_data *irqd = irq_desc_get_irq_data(desc);
- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = data->drvdata;
unsigned int pend, mask;
chained_irq_enter(chip, desc);
- pend = readl(bank->eint_base + EINTPEND_REG);
- mask = readl(bank->eint_base + EINTMASK_REG);
+ pend = readl(d->virt_base + EINTPEND_REG);
+ mask = readl(d->virt_base + EINTMASK_REG);
pend &= ~mask;
pend &= range;
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(str
u32 val;
/* Make sure that pin is configured as interrupt */
- reg = bank->pctl_base + bank->pctl_offset;
+ reg = d->virt_base + bank->pctl_offset;
shift = pin;
if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
/* 4-bit bank type with 2 con regs */
@@ -308,8 +308,9 @@ static void s3c64xx_irq_set_function(str
static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
- void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset);
+ void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
u32 val;
val = readl(reg);
@@ -333,8 +334,9 @@ static void s3c64xx_gpio_irq_mask(struct
static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
- void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset);
+ void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
writel(1 << index, reg);
}
@@ -357,7 +359,7 @@ static int s3c64xx_gpio_irq_set_type(str
s3c64xx_irq_set_handler(irqd, type);
/* Set up interrupt trigger */
- reg = bank->eint_base + EINTCON_REG(bank->eint_offset);
+ reg = d->virt_base + EINTCON_REG(bank->eint_offset);
shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
@@ -409,8 +411,7 @@ static void s3c64xx_eint_gpio_irq(struct
{
struct irq_chip *chip = irq_desc_get_chip(desc);
struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc);
- struct irq_data *irqd = irq_desc_get_irq_data(desc);
- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
chained_irq_enter(chip, desc);
@@ -420,7 +421,7 @@ static void s3c64xx_eint_gpio_irq(struct
unsigned int pin;
unsigned int virq;
- svc = readl(bank->eint_base + SERVICE_REG);
+ svc = readl(drvdata->virt_base + SERVICE_REG);
group = SVC_GROUP(svc);
pin = svc & SVC_NUM_MASK;
@@ -515,15 +516,15 @@ static inline void s3c64xx_eint0_irq_set
{
struct s3c64xx_eint0_domain_data *ddata =
irq_data_get_irq_chip_data(irqd);
- struct samsung_pin_bank *bank = ddata->bank;
+ struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
u32 val;
- val = readl(bank->eint_base + EINT0MASK_REG);
+ val = readl(d->virt_base + EINT0MASK_REG);
if (mask)
val |= 1 << ddata->eints[irqd->hwirq];
else
val &= ~(1 << ddata->eints[irqd->hwirq]);
- writel(val, bank->eint_base + EINT0MASK_REG);
+ writel(val, d->virt_base + EINT0MASK_REG);
}
static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
@@ -540,10 +541,10 @@ static void s3c64xx_eint0_irq_ack(struct
{
struct s3c64xx_eint0_domain_data *ddata =
irq_data_get_irq_chip_data(irqd);
- struct samsung_pin_bank *bank = ddata->bank;
+ struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
writel(1 << ddata->eints[irqd->hwirq],
- bank->eint_base + EINT0PEND_REG);
+ d->virt_base + EINT0PEND_REG);
}
static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
@@ -551,7 +552,7 @@ static int s3c64xx_eint0_irq_set_type(st
struct s3c64xx_eint0_domain_data *ddata =
irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank *bank = ddata->bank;
- struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
void __iomem *reg;
int trigger;
u8 shift;
@@ -566,7 +567,7 @@ static int s3c64xx_eint0_irq_set_type(st
s3c64xx_irq_set_handler(irqd, type);
/* Set up interrupt trigger */
- reg = bank->eint_base + EINT0CON0_REG;
+ reg = d->virt_base + EINT0CON0_REG;
shift = ddata->eints[irqd->hwirq];
if (shift >= EINT_MAX_PER_REG) {
reg += 4;
@@ -598,19 +599,14 @@ static struct irq_chip s3c64xx_eint0_irq
static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
- struct irq_data *irqd = irq_desc_get_irq_data(desc);
- struct s3c64xx_eint0_domain_data *ddata =
- irq_data_get_irq_chip_data(irqd);
- struct samsung_pin_bank *bank = ddata->bank;
-
struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
-
+ struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
unsigned int pend, mask;
chained_irq_enter(chip, desc);
- pend = readl(bank->eint_base + EINT0PEND_REG);
- mask = readl(bank->eint_base + EINT0MASK_REG);
+ pend = readl(drvdata->virt_base + EINT0PEND_REG);
+ mask = readl(drvdata->virt_base + EINT0MASK_REG);
pend = pend & range & ~mask;
pend &= range;
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1013,6 +1013,12 @@ samsung_pinctrl_get_soc_data(struct sams
bank->eint_base = virt_base[0];
bank->pctl_base = virt_base[bdata->pctl_res_idx];
}
+ /*
+ * Legacy platforms should provide only one resource with IO memory.
+ * Store it as virt_base because legacy driver needs to access it
+ * through samsung_pinctrl_drv_data.
+ */
+ d->virt_base = virt_base[0];
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -247,6 +247,10 @@ struct samsung_pin_ctrl {
/**
* struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
* @node: global list node
+ * @virt_base: register base address of the controller; this will be equal
+ * to each bank samsung_pin_bank->pctl_base and used on legacy
+ * platforms (like S3C24XX or S3C64XX) which has to access the base
+ * through samsung_pinctrl_drv_data, not samsung_pin_bank).
* @dev: device instance representing the controller.
* @irq: interrpt number used by the controller to notify gpio interrupts.
* @ctrl: pin controller instance managed by the driver.
@@ -262,6 +266,7 @@ struct samsung_pin_ctrl {
*/
struct samsung_pinctrl_drv_data {
struct list_head node;
+ void __iomem *virt_base;
struct device *dev;
int irq;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 979990c6284814617d8f2179d197f72ff62b5d85 upstream.
kernelci.org reports a crazy stack usage for the VT code when CONFIG_KASAN
is enabled:
drivers/tty/vt/keyboard.c: In function 'kbd_keycode':
drivers/tty/vt/keyboard.c:1452:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
The problem is that tty_insert_flip_char() gets inlined many times into
kbd_keycode(), and also into other functions, and each copy requires 128
bytes for stack redzone to check for a possible out-of-bounds access on
the 'ch' and 'flags' arguments that are passed into
tty_insert_flip_string_flags as a variable-length string.
This introduces a new __tty_insert_flip_char() function for the slow
path, which receives the two arguments by value. This completely avoids
the problem and the stack usage goes back down to around 100 bytes.
Without KASAN, this is also slightly better, as we don't have to
spill the arguments to the stack but can simply pass 'ch' and 'flag'
in registers, saving a few bytes in .text for each call site.
This should be backported to linux-4.0 or later, which first introduced
the stack sanitizer in the kernel.
Fixes: c420f167db8c ("kasan: enable stack instrumentation")
Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_buffer.c | 24 ++++++++++++++++++++++++
include/linux/tty_flip.h | 3 ++-
2 files changed, 26 insertions(+), 1 deletion(-)
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -362,6 +362,30 @@ int tty_insert_flip_string_flags(struct
EXPORT_SYMBOL(tty_insert_flip_string_flags);
/**
+ * __tty_insert_flip_char - Add one character to the tty buffer
+ * @port: tty port
+ * @ch: character
+ * @flag: flag byte
+ *
+ * Queue a single byte to the tty buffering, with an optional flag.
+ * This is the slow path of tty_insert_flip_char.
+ */
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
+{
+ struct tty_buffer *tb = port->buf.tail;
+ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
+
+ if (!tty_buffer_request_room(port, 1))
+ return 0;
+
+ *flag_buf_ptr(tb, tb->used) = flag;
+ *char_buf_ptr(tb, tb->used++) = ch;
+
+ return 1;
+}
+EXPORT_SYMBOL(__tty_insert_flip_char);
+
+/**
* tty_schedule_flip - push characters to ldisc
* @port: tty port to push from
*
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struc
unsigned char **chars, size_t size);
extern void tty_flip_buffer_push(struct tty_port *port);
void tty_schedule_flip(struct tty_port *port);
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag);
static inline int tty_insert_flip_char(struct tty_port *port,
unsigned char ch, char flag)
@@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(s
*char_buf_ptr(tb, tb->used++) = ch;
return 1;
}
- return tty_insert_flip_string_flags(port, &ch, &flag, 1);
+ return __tty_insert_flip_char(port, ch, flag);
}
static inline int tty_insert_flip_string(struct tty_port *port,
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 065ea0a7afd64d6cf3464bdd1d8cd227527e2045 upstream.
While working on improving the fast path of tty_insert_flip_char(),
I noticed that by calling tty_buffer_request_room(), we needlessly
move to the separate flag buffer mode for the tty, even when all
characters use TTY_NORMAL as the flag.
This changes the code to call __tty_buffer_request_room() with the
correct flag, which will then allocate a regular buffer when it rounds
out of space but no special flags have been used. I'm guessing that
this is the behavior that Peter Hurley intended when he introduced
the compacted flip buffers.
Fixes: acc0f67f307f ("tty: Halve flip buffer GFP_ATOMIC memory consumption")
Cc: Peter Hurley <[email protected]>
Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_buffer.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -375,10 +375,11 @@ int __tty_insert_flip_char(struct tty_po
struct tty_buffer *tb = port->buf.tail;
int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
- if (!tty_buffer_request_room(port, 1))
+ if (!__tty_buffer_request_room(port, 1, flags))
return 0;
- *flag_buf_ptr(tb, tb->used) = flag;
+ if (~tb->flags & TTYB_NORMAL)
+ *flag_buf_ptr(tb, tb->used) = flag;
*char_buf_ptr(tb, tb->used++) = ch;
return 1;
4.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit b5accbb0dfae36d8d36cd882096943c98d5ede15 upstream.
When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
set, DIR1 is expected to have SGID bit set (and owning group equal to
the owning group of 'DIR0'). However when 'DIR0' also has some default
ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
'DIR1' to get cleared if user is not member of the owning group.
Fix the problem by creating __orangefs_set_acl() function that does not
call posix_acl_update_mode() and use it when inheriting ACLs. That
prevents SGID bit clearing and the mode has been properly set by
posix_acl_create() anyway.
Fixes: 073931017b49d9458aa351605b43a7e34598caef
CC: [email protected]
CC: Mike Marshall <[email protected]>
CC: [email protected]
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Mike Marshall <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/orangefs/acl.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
--- a/fs/orangefs/acl.c
+++ b/fs/orangefs/acl.c
@@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struc
return acl;
}
-int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
+ int type)
{
- struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
int error = 0;
void *value = NULL;
size_t size = 0;
@@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode
switch (type) {
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
- if (acl) {
- umode_t mode;
-
- error = posix_acl_update_mode(inode, &mode, &acl);
- if (error) {
- gossip_err("%s: posix_acl_update_mode err: %d\n",
- __func__,
- error);
- return error;
- }
-
- if (inode->i_mode != mode)
- SetModeFlag(orangefs_inode);
- inode->i_mode = mode;
- mark_inode_dirty_sync(inode);
- }
break;
case ACL_TYPE_DEFAULT:
name = XATTR_NAME_POSIX_ACL_DEFAULT;
@@ -132,6 +116,29 @@ out:
return error;
}
+int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+ int error;
+
+ if (type == ACL_TYPE_ACCESS && acl) {
+ umode_t mode;
+
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error) {
+ gossip_err("%s: posix_acl_update_mode err: %d\n",
+ __func__,
+ error);
+ return error;
+ }
+
+ if (inode->i_mode != mode)
+ SetModeFlag(ORANGEFS_I(inode));
+ inode->i_mode = mode;
+ mark_inode_dirty_sync(inode);
+ }
+ return __orangefs_set_acl(inode, acl, type);
+}
+
int orangefs_init_acl(struct inode *inode, struct inode *dir)
{
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
@@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inod
return error;
if (default_acl) {
- error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+ error = __orangefs_set_acl(inode, default_acl,
+ ACL_TYPE_DEFAULT);
posix_acl_release(default_acl);
}
if (acl) {
if (!error)
- error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
+ error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
posix_acl_release(acl);
}
On 09/24/2017 01:32 PM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.13.4 release.
> There are 109 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 Tue Sep 26 20:33:30 UTC 2017.
> Anything received after that time might be too late.
>
Build results:
total: 145 pass: 145 fail: 0
Qemu test results:
total: 123 pass: 123 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
On Sun, Sep 24, 2017 at 06:05:54PM -0700, Guenter Roeck wrote:
> On 09/24/2017 01:32 PM, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.13.4 release.
> > There are 109 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 Tue Sep 26 20:33:30 UTC 2017.
> > Anything received after that time might be too late.
> >
>
> Build results:
> total: 145 pass: 145 fail: 0
> Qemu test results:
> total: 123 pass: 123 fail: 0
>
> Details are available at http://kerneltests.org/builders.
Thanks for testing all of these and letting me know.
greg k-h
On 09/24/2017 02:32 PM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.13.4 release.
> There are 109 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 Tue Sep 26 20:33:30 UTC 2017.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.13.4-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.13.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
That's a good patch Greg... I have another ACL patch
that got pulled in 4.14 and there's some ACL patches
in the server part of Orangefs too... Reviewing Jan's
patch is what made me realize that Orangefs ACLs
were busted. Anywho... we're moving offices so it
will be a few days before I can try to get the other
patch submitted to stable...
-Mike
On Sun, Sep 24, 2017 at 4:32 PM, Greg Kroah-Hartman
<[email protected]> wrote:
> 4.13-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Jan Kara <[email protected]>
>
> commit b5accbb0dfae36d8d36cd882096943c98d5ede15 upstream.
>
> When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
> set, DIR1 is expected to have SGID bit set (and owning group equal to
> the owning group of 'DIR0'). However when 'DIR0' also has some default
> ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
> 'DIR1' to get cleared if user is not member of the owning group.
>
> Fix the problem by creating __orangefs_set_acl() function that does not
> call posix_acl_update_mode() and use it when inheriting ACLs. That
> prevents SGID bit clearing and the mode has been properly set by
> posix_acl_create() anyway.
>
> Fixes: 073931017b49d9458aa351605b43a7e34598caef
> CC: [email protected]
> CC: Mike Marshall <[email protected]>
> CC: [email protected]
> Signed-off-by: Jan Kara <[email protected]>
> Signed-off-by: Mike Marshall <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> ---
> fs/orangefs/acl.c | 48 ++++++++++++++++++++++++++++--------------------
> 1 file changed, 28 insertions(+), 20 deletions(-)
>
> --- a/fs/orangefs/acl.c
> +++ b/fs/orangefs/acl.c
> @@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struc
> return acl;
> }
>
> -int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
> +static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
> + int type)
> {
> - struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
> int error = 0;
> void *value = NULL;
> size_t size = 0;
> @@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode
> switch (type) {
> case ACL_TYPE_ACCESS:
> name = XATTR_NAME_POSIX_ACL_ACCESS;
> - if (acl) {
> - umode_t mode;
> -
> - error = posix_acl_update_mode(inode, &mode, &acl);
> - if (error) {
> - gossip_err("%s: posix_acl_update_mode err: %d\n",
> - __func__,
> - error);
> - return error;
> - }
> -
> - if (inode->i_mode != mode)
> - SetModeFlag(orangefs_inode);
> - inode->i_mode = mode;
> - mark_inode_dirty_sync(inode);
> - }
> break;
> case ACL_TYPE_DEFAULT:
> name = XATTR_NAME_POSIX_ACL_DEFAULT;
> @@ -132,6 +116,29 @@ out:
> return error;
> }
>
> +int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
> +{
> + int error;
> +
> + if (type == ACL_TYPE_ACCESS && acl) {
> + umode_t mode;
> +
> + error = posix_acl_update_mode(inode, &mode, &acl);
> + if (error) {
> + gossip_err("%s: posix_acl_update_mode err: %d\n",
> + __func__,
> + error);
> + return error;
> + }
> +
> + if (inode->i_mode != mode)
> + SetModeFlag(ORANGEFS_I(inode));
> + inode->i_mode = mode;
> + mark_inode_dirty_sync(inode);
> + }
> + return __orangefs_set_acl(inode, acl, type);
> +}
> +
> int orangefs_init_acl(struct inode *inode, struct inode *dir)
> {
> struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
> @@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inod
> return error;
>
> if (default_acl) {
> - error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
> + error = __orangefs_set_acl(inode, default_acl,
> + ACL_TYPE_DEFAULT);
> posix_acl_release(default_acl);
> }
>
> if (acl) {
> if (!error)
> - error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
> + error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
> posix_acl_release(acl);
> }
>
>
>
On Mon, Sep 25, 2017 at 05:13:55PM -0600, Shuah Khan wrote:
> On 09/24/2017 02:32 PM, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.13.4 release.
> > There are 109 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 Tue Sep 26 20:33:30 UTC 2017.
> > Anything received after that time might be too late.
> >
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.13.4-rc1.gz
> > or in the git tree and branch at:
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.13.y
> > and the diffstat can be found below.
> >
> > thanks,
> >
> > greg k-h
> >
>
> Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h
On Sun 2017-09-24 22:32:36, Greg Kroah-Hartman wrote:
> 4.13-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Daniel Drake <[email protected]>
>
> commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
>
> The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
> unresponsive after suspend/resume. The following error appears during
> resume:
>
> i2c_hid i2c-ELAN1300:00: failed to reset device.
>
> The problem here is that i2c_hid does not notice the interrupt being
> generated at this point, because the GPIO is no longer configured
> for interrupts.
>
> Fix this by saving pinctrl-amd pin registers during suspend and
> restoring them at resume time.
>
> Based on code from pinctrl-intel.
>
> Signed-off-by: Daniel Drake <[email protected]>
> Signed-off-by: Linus Walleij <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> --- a/drivers/pinctrl/pinctrl-amd.c
> +++ b/drivers/pinctrl/pinctrl-amd.c
> @@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
> .pin_config_group_set = amd_pinconf_group_set,
> };
>
> +#ifdef CONFIG_PM_SLEEP
> +static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
> +{
> + const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
> +
> + if (!pd)
> + return false;
> +
> + /*
> + * Only restore the pin if it is actually in use by the kernel (or
> + * by userspace).
> + */
> + if (pd->mux_owner || pd->gpio_owner ||
This code causes a compilation error in the current Linus' tree
(4.14-rc2+). I guess that the same problem will be also in
older trees.
IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD
is selected. The following patch helped here:
>From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001
From: Petr Mladek <[email protected]>
Date: Tue, 26 Sep 2017 15:51:28 +0200
Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over
suspend/resume") caused the following compilation errors:
drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
if (pd->mux_owner || pd->gpio_owner ||
^
drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
if (pd->mux_owner || pd->gpio_owner ||
We need to enable CONFIG_PINMUX for this driver as well.
Fixes: 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
Signed-off-by: Petr Mladek <[email protected]>
---
drivers/pinctrl/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1778cf4f81c7..82cd8b08d71f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -100,6 +100,7 @@ config PINCTRL_AMD
tristate "AMD GPIO pin control"
depends on GPIOLIB
select GPIOLIB_IRQCHIP
+ select PINMUX
select PINCONF
select GENERIC_PINCONF
help
--
1.8.5.6
On Tue, Sep 26, 2017 at 04:07:45PM +0200, Petr Mladek wrote:
> On Sun 2017-09-24 22:32:36, Greg Kroah-Hartman wrote:
> > 4.13-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Daniel Drake <[email protected]>
> >
> > commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
> >
> > The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
> > unresponsive after suspend/resume. The following error appears during
> > resume:
> >
> > i2c_hid i2c-ELAN1300:00: failed to reset device.
> >
> > The problem here is that i2c_hid does not notice the interrupt being
> > generated at this point, because the GPIO is no longer configured
> > for interrupts.
> >
> > Fix this by saving pinctrl-amd pin registers during suspend and
> > restoring them at resume time.
> >
> > Based on code from pinctrl-intel.
> >
> > Signed-off-by: Daniel Drake <[email protected]>
> > Signed-off-by: Linus Walleij <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> >
> > --- a/drivers/pinctrl/pinctrl-amd.c
> > +++ b/drivers/pinctrl/pinctrl-amd.c
> > @@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
> > .pin_config_group_set = amd_pinconf_group_set,
> > };
> >
> > +#ifdef CONFIG_PM_SLEEP
> > +static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
> > +{
> > + const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
> > +
> > + if (!pd)
> > + return false;
> > +
> > + /*
> > + * Only restore the pin if it is actually in use by the kernel (or
> > + * by userspace).
> > + */
> > + if (pd->mux_owner || pd->gpio_owner ||
>
> This code causes a compilation error in the current Linus' tree
> (4.14-rc2+). I guess that the same problem will be also in
> older trees.
>
> IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD
> is selected. The following patch helped here:
>
> >From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001
> From: Petr Mladek <[email protected]>
> Date: Tue, 26 Sep 2017 15:51:28 +0200
> Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over
> suspend/resume") caused the following compilation errors:
>
> drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
> drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
> if (pd->mux_owner || pd->gpio_owner ||
> ^
> drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
> if (pd->mux_owner || pd->gpio_owner ||
>
> We need to enable CONFIG_PINMUX for this driver as well.
>
> Fixes: 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
> Signed-off-by: Petr Mladek <[email protected]>
> ---
> drivers/pinctrl/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 1778cf4f81c7..82cd8b08d71f 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -100,6 +100,7 @@ config PINCTRL_AMD
> tristate "AMD GPIO pin control"
> depends on GPIOLIB
> select GPIOLIB_IRQCHIP
> + select PINMUX
> select PINCONF
> select GENERIC_PINCONF
> help
> --
> 1.8.5.6
What is the commit id for this patch in Linus's tree? I don't see it
there...
thanks,
greg k-h
On Wed 2017-09-27 10:39:26, Greg Kroah-Hartman wrote:
> On Tue, Sep 26, 2017 at 04:07:45PM +0200, Petr Mladek wrote:
> > On Sun 2017-09-24 22:32:36, Greg Kroah-Hartman wrote:
> > > 4.13-stable review patch. If anyone has any objections, please let me know.
> > >
> > > ------------------
> > >
> > > From: Daniel Drake <[email protected]>
> > >
> > > commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
> > >
> > > The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
> > > unresponsive after suspend/resume. The following error appears during
> > > resume:
> > >
> > > i2c_hid i2c-ELAN1300:00: failed to reset device.
> > >
> > > The problem here is that i2c_hid does not notice the interrupt being
> > > generated at this point, because the GPIO is no longer configured
> > > for interrupts.
> > >
> > > Fix this by saving pinctrl-amd pin registers during suspend and
> > > restoring them at resume time.
> > >
> > > Based on code from pinctrl-intel.
> > >
> > > Signed-off-by: Daniel Drake <[email protected]>
> > > Signed-off-by: Linus Walleij <[email protected]>
> > > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> > >
> > > --- a/drivers/pinctrl/pinctrl-amd.c
> > > +++ b/drivers/pinctrl/pinctrl-amd.c
> > > @@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
> > > .pin_config_group_set = amd_pinconf_group_set,
> > > };
> > >
> > > +#ifdef CONFIG_PM_SLEEP
> > > +static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
> > > +{
> > > + const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
> > > +
> > > + if (!pd)
> > > + return false;
> > > +
> > > + /*
> > > + * Only restore the pin if it is actually in use by the kernel (or
> > > + * by userspace).
> > > + */
> > > + if (pd->mux_owner || pd->gpio_owner ||
> >
> > This code causes a compilation error in the current Linus' tree
> > (4.14-rc2+). I guess that the same problem will be also in
> > older trees.
> >
> > IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD
> > is selected. The following patch helped here:
> >
> > >From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001
> > From: Petr Mladek <[email protected]>
> > Date: Tue, 26 Sep 2017 15:51:28 +0200
> > Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
> > MIME-Version: 1.0
> > Content-Type: text/plain; charset=UTF-8
> > Content-Transfer-Encoding: 8bit
> >
> > The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over
> > suspend/resume") caused the following compilation errors:
> >
> > drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
> > drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
> > if (pd->mux_owner || pd->gpio_owner ||
> > ^
> > drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
> > if (pd->mux_owner || pd->gpio_owner ||
> >
> > We need to enable CONFIG_PINMUX for this driver as well.
> >
> > Fixes: 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
> > Signed-off-by: Petr Mladek <[email protected]>
> > ---
> > drivers/pinctrl/Kconfig | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> > index 1778cf4f81c7..82cd8b08d71f 100644
> > --- a/drivers/pinctrl/Kconfig
> > +++ b/drivers/pinctrl/Kconfig
> > @@ -100,6 +100,7 @@ config PINCTRL_AMD
> > tristate "AMD GPIO pin control"
> > depends on GPIOLIB
> > select GPIOLIB_IRQCHIP
> > + select PINMUX
> > select PINCONF
> > select GENERIC_PINCONF
> > help
> > --
> > 1.8.5.6
>
> What is the commit id for this patch in Linus's tree? I don't see it
> there...
This extra patch has not been pushed to the Linus' tree yet.
It was only my proposal to fix the problem. I did not find
the original patch discussed on the kernel mailing list.
Therefore I sent this follow up fix as a reply to
the 4.13-stable review mail.
I hope that Linus Walleij would notice, review, and push it
into Linus' tree.
Best Regards,
Petr
On Wed, Sep 27, 2017 at 1:29 PM, Petr Mladek <[email protected]> wrote:
> On Wed 2017-09-27 10:39:26, Greg Kroah-Hartman wrote:
>> On Tue, Sep 26, 2017 at 04:07:45PM +0200, Petr Mladek wrote:
>> > On Sun 2017-09-24 22:32:36, Greg Kroah-Hartman wrote:
>> > > 4.13-stable review patch. If anyone has any objections, please let me know.
>> > >
>> > > ------------------
>> > >
>> > > From: Daniel Drake <[email protected]>
>> > >
>> > > commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
>> > >
>> > > The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
>> > > unresponsive after suspend/resume. The following error appears during
>> > > resume:
>> > >
>> > > i2c_hid i2c-ELAN1300:00: failed to reset device.
>> > >
>> > > The problem here is that i2c_hid does not notice the interrupt being
>> > > generated at this point, because the GPIO is no longer configured
>> > > for interrupts.
>> > >
>> > > Fix this by saving pinctrl-amd pin registers during suspend and
>> > > restoring them at resume time.
>> > >
>> > > Based on code from pinctrl-intel.
>> > >
>> > > Signed-off-by: Daniel Drake <[email protected]>
>> > > Signed-off-by: Linus Walleij <[email protected]>
>> > > Signed-off-by: Greg Kroah-Hartman <[email protected]>
>> > >
>> > > --- a/drivers/pinctrl/pinctrl-amd.c
>> > > +++ b/drivers/pinctrl/pinctrl-amd.c
>> > > @@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
>> > > .pin_config_group_set = amd_pinconf_group_set,
>> > > };
>> > >
>> > > +#ifdef CONFIG_PM_SLEEP
>> > > +static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
>> > > +{
>> > > + const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
>> > > +
>> > > + if (!pd)
>> > > + return false;
>> > > +
>> > > + /*
>> > > + * Only restore the pin if it is actually in use by the kernel (or
>> > > + * by userspace).
>> > > + */
>> > > + if (pd->mux_owner || pd->gpio_owner ||
>> >
>> > This code causes a compilation error in the current Linus' tree
>> > (4.14-rc2+). I guess that the same problem will be also in
>> > older trees.
>> >
>> > IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD
>> > is selected. The following patch helped here:
>> >
>> > >From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001
>> > From: Petr Mladek <[email protected]>
>> > Date: Tue, 26 Sep 2017 15:51:28 +0200
>> > Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
>> > MIME-Version: 1.0
>> > Content-Type: text/plain; charset=UTF-8
>> > Content-Transfer-Encoding: 8bit
>> >
>> > The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over
>> > suspend/resume") caused the following compilation errors:
>> >
>> > drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
>> > drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
>> > if (pd->mux_owner || pd->gpio_owner ||
>> > ^
>> > drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
>> > if (pd->mux_owner || pd->gpio_owner ||
>> >
>> > We need to enable CONFIG_PINMUX for this driver as well.
>> >
>> > Fixes: 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
>> > Signed-off-by: Petr Mladek <[email protected]>
>> > ---
>> > drivers/pinctrl/Kconfig | 1 +
>> > 1 file changed, 1 insertion(+)
>> >
>> > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>> > index 1778cf4f81c7..82cd8b08d71f 100644
>> > --- a/drivers/pinctrl/Kconfig
>> > +++ b/drivers/pinctrl/Kconfig
>> > @@ -100,6 +100,7 @@ config PINCTRL_AMD
>> > tristate "AMD GPIO pin control"
>> > depends on GPIOLIB
>> > select GPIOLIB_IRQCHIP
>> > + select PINMUX
>> > select PINCONF
>> > select GENERIC_PINCONF
>> > help
>> > --
>> > 1.8.5.6
>>
>> What is the commit id for this patch in Linus's tree? I don't see it
>> there...
>
> This extra patch has not been pushed to the Linus' tree yet.
> It was only my proposal to fix the problem. I did not find
> the original patch discussed on the kernel mailing list.
> Therefore I sent this follow up fix as a reply to
> the 4.13-stable review mail.
>
> I hope that Linus Walleij would notice, review, and push it
> into Linus' tree.
I missed it. OK looking for it so I can apply it.
Yours,
Linus Walleij
On Tue, Sep 26, 2017 at 4:07 PM, Petr Mladek <[email protected]> wrote:
> IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD
> is selected. The following patch helped here:
Took the patch out of this mail, applied it to fixes and tagged it for
stable.
Will send it to Torvals ASAP.
Yours,
Linus Walleij