summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt1
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--Makefile4
-rw-r--r--arch/arc/Kconfig8
-rw-r--r--arch/arc/Makefile4
-rw-r--r--arch/arc/include/asm/bug.h3
-rw-r--r--arch/arc/include/asm/elf.h2
-rw-r--r--arch/arc/kernel/setup.c2
-rw-r--r--arch/arc/kernel/traps.c8
-rw-r--r--arch/arc/kernel/unwind.c9
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c2
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c3
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c3
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c2
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex_defconfig1
-rw-r--r--arch/arm64/configs/sdm660-perf_defconfig1
-rw-r--r--arch/arm64/configs/sdm660_defconfig1
-rw-r--r--arch/arm64/kernel/vdso.c10
-rw-r--r--arch/ia64/include/asm/bug.h6
-rw-r--r--arch/m68k/include/asm/bug.h3
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/include/asm/compiler.h35
-rw-r--r--arch/mips/include/uapi/asm/sgidefs.h8
-rw-r--r--arch/mips/kernel/uprobes.c3
-rw-r--r--arch/parisc/math-emu/cnv_float.h8
-rw-r--r--arch/s390/include/asm/facility.h21
-rw-r--r--arch/sparc/include/asm/bug.h6
-rw-r--r--arch/sparc/kernel/perf_event.c4
-rw-r--r--arch/um/os-Linux/file.c1
-rw-r--r--arch/um/os-Linux/signal.c2
-rw-r--r--arch/x86/kernel/cpu/bugs.c11
-rw-r--r--arch/x86/kernel/ptrace.c5
-rw-r--r--arch/x86/kernel/tls.c9
-rw-r--r--arch/x86/kvm/i8254.c5
-rw-r--r--arch/x86/kvm/x86.c15
-rw-r--r--arch/x86/um/stub_segv.c1
-rw-r--r--crypto/crypto_user.c3
-rw-r--r--drivers/char/diag/diag_dci.c126
-rw-r--r--drivers/dma/imx-sdma.c4
-rw-r--r--drivers/gpu/drm/Kconfig2
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/drm_edid.c15
-rw-r--r--drivers/gpu/drm/drm_edid_load.c17
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c14
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c24
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
-rw-r--r--drivers/gpu/msm/kgsl_drawobj.c43
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c34
-rw-r--r--drivers/input/keyboard/imx_keypad.c18
-rw-r--r--drivers/input/misc/uinput.c22
-rw-r--r--drivers/input/mouse/elantech.c2
-rw-r--r--drivers/md/dm-verity-target.c4
-rw-r--r--drivers/md/md.c36
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c105
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c48
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c64
-rw-r--r--drivers/media/platform/msm/vidc/hfi_response_handler.c185
-rw-r--r--drivers/mfd/omap-usb-tll.c4
-rw-r--r--drivers/misc/vmw_vmci/vmci_context.c80
-rw-r--r--drivers/misc/vmw_vmci/vmci_handle_array.c38
-rw-r--r--drivers/misc/vmw_vmci/vmci_handle_array.h29
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/can/flexcan.c2
-rw-r--r--drivers/net/can/spi/Kconfig5
-rw-r--r--drivers/net/can/spi/mcp251x.c25
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c28
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_ethtool.c4
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c6
-rw-r--r--drivers/net/ethernet/sis/sis900.c16
-rw-r--r--drivers/net/ppp/ppp_mppe.c1
-rw-r--r--drivers/net/team/team.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c39
-rw-r--r--drivers/net/wireless/cnss2/qmi.c4
-rw-r--r--drivers/net/wireless/cnss2/usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/fw.h12
-rw-r--r--drivers/net/wireless/mwifiex/ie.c45
-rw-r--r--drivers/net/wireless/mwifiex/scan.c31
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c4
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c2
-rw-r--r--drivers/parport/share.c2
-rw-r--r--drivers/s390/cio/qdio_setup.c2
-rw-r--r--drivers/s390/cio/qdio_thinint.c5
-rw-r--r--drivers/s390/net/qeth_l2_main.c2
-rw-r--r--drivers/scsi/hpsa.c7
-rw-r--r--drivers/scsi/hpsa_cmd.h1
-rw-r--r--drivers/scsi/ufs/ufshcd.c3
-rw-r--r--drivers/scsi/vmw_pvscsi.c6
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c2
-rw-r--r--drivers/soc/qcom/icnss.c109
-rw-r--r--drivers/spi/spi-bitbang.c2
-rw-r--r--drivers/staging/android/lowmemorykiller.c157
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c3
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c3
-rw-r--r--drivers/staging/rdma/hfi1/chip.c1
-rw-r--r--drivers/tty/rocket.c2
-rw-r--r--drivers/usb/chipidea/udc.c20
-rw-r--r--drivers/usb/gadget/function/f_ccid.c2
-rw-r--r--drivers/usb/gadget/function/u_ether.c6
-rw-r--r--drivers/usb/gadget/udc/fusb300_udc.c5
-rw-r--r--drivers/usb/gadget/udc/lpc32xx_udc.c3
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c34
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h6
-rw-r--r--drivers/usb/serial/option.c1
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c10
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.c10
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c16
-rw-r--r--fs/9p/acl.c2
-rw-r--r--fs/binfmt_flat.c24
-rw-r--r--fs/btrfs/dev-replace.c29
-rw-r--r--fs/btrfs/reada.c7
-rw-r--r--fs/btrfs/volumes.c2
-rw-r--r--fs/btrfs/volumes.h5
-rw-r--r--fs/cifs/smb2maperror.c2
-rw-r--r--fs/ext4/crypto_policy.c2
-rw-r--r--fs/overlayfs/dir.c9
-rw-r--r--fs/overlayfs/inode.c13
-rw-r--r--fs/udf/inode.c93
-rw-r--r--include/asm-generic/bug.h1
-rw-r--r--include/drm/drm_edid.h14
-rw-r--r--include/linux/compiler-gcc.h15
-rw-r--r--include/linux/compiler.h5
-rw-r--r--include/linux/diagchar.h9
-rw-r--r--include/linux/swiotlb.h3
-rw-r--r--include/linux/vmw_vmci_defs.h11
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--include/net/busy_poll.h2
-rw-r--r--include/soc/qcom/icnss.h4
-rw-r--r--kernel/cpu.c3
-rw-r--r--kernel/events/core.c2
-rw-r--r--kernel/ptrace.c4
-rw-r--r--kernel/trace/trace.c6
-rw-r--r--kernel/trace/trace.h18
-rw-r--r--kernel/trace/trace_kdb.c6
-rw-r--r--lib/mpi/mpi-pow.c6
-rw-r--r--mm/page_idle.c4
-rw-r--r--net/9p/protocol.c12
-rw-r--r--net/9p/trans_common.c1
-rw-r--r--net/9p/trans_rdma.c7
-rw-r--r--net/bluetooth/hci_conn.c10
-rw-r--r--net/bluetooth/l2cap_core.c33
-rw-r--r--net/can/af_can.c1
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/mac80211/mesh.c5
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/sctp/endpointola.c8
-rw-r--r--net/tipc/core.c12
-rw-r--r--net/tipc/netlink_compat.c18
-rw-r--r--net/wireless/core.c2
-rw-r--r--samples/bpf/bpf_load.c2
-rwxr-xr-xscripts/checkstack.pl2
-rw-r--r--security/apparmor/policy_unpack.c2
-rw-r--r--sound/core/seq/oss/seq_oss_ioctl.c2
-rw-r--r--sound/core/seq/oss/seq_oss_rw.c2
-rw-r--r--sound/firewire/amdtp-am824.c2
-rw-r--r--sound/soc/codecs/cs4265.c2
-rw-r--r--sound/soc/codecs/max98090.c16
-rw-r--r--sound/usb/mixer_quirks.c4
-rw-r--r--tools/perf/builtin-help.c2
-rw-r--r--tools/perf/ui/tui/helpline.c2
164 files changed, 1686 insertions, 558 deletions
diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt
index ee3723beb701..33b38716b77f 100644
--- a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt
+++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt
@@ -4,6 +4,7 @@ Required properties:
- compatible: Should be one of the following:
- "microchip,mcp2510" for MCP2510.
- "microchip,mcp2515" for MCP2515.
+ - "microchip,mcp25625" for MCP25625.
- reg: SPI chip select.
- clocks: The clock feeding the CAN controller.
- interrupt-parent: The parent interrupt controller.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 69b096e6ac45..f9500fb1498b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -948,7 +948,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
The filter can be disabled or changed to another
driver later using sysfs.
- drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
+ drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
Broken monitors, graphic adapters, KVMs and EDIDless
panels may send no or incorrect EDID data sets.
This parameter allows to specify an EDID data sets
diff --git a/Makefile b/Makefile
index e14b0f715e89..692a1dc4d42d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
-SUBLEVEL = 184
+SUBLEVEL = 186
EXTRAVERSION =
NAME = Blurry Fish Butt
@@ -648,6 +648,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
+KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
@@ -732,7 +733,6 @@ ifeq ($(cc-name),clang)
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
-KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
KBUILD_CFLAGS += $(call cc-disable-warning, duplicate-decl-specifier)
# Quiet clang warning: comparison of unsigned expression < 0 is always false
KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index e983f410135a..a5d8bef65911 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -278,14 +278,6 @@ config ARC_DCCM_BASE
default "0xA0000000"
depends on ARC_HAS_DCCM
-config ARC_HAS_HW_MPY
- bool "Use Hardware Multiplier (Normal or Faster XMAC)"
- default y
- help
- Influences how gcc generates code for MPY operations.
- If enabled, MPYxx insns are generated, provided by Standard/XMAC
- Multipler. Otherwise software multipy lib is used
-
choice
prompt "MMU Version"
default ARC_MMU_V3 if ARC_CPU_770
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index fffaff9c7b2c..8f8d53f08141 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -72,10 +72,6 @@ ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
ldflags-$(upto_gcc44) += -marclinux
-ifndef CONFIG_ARC_HAS_HW_MPY
- cflags-y += -mno-mpy
-endif
-
LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
# Modules with short calls might break for calls into builtin-kernel
diff --git a/arch/arc/include/asm/bug.h b/arch/arc/include/asm/bug.h
index ea022d47896c..21ec82466d62 100644
--- a/arch/arc/include/asm/bug.h
+++ b/arch/arc/include/asm/bug.h
@@ -23,7 +23,8 @@ void die(const char *str, struct pt_regs *regs, unsigned long address);
#define BUG() do { \
pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
- dump_stack(); \
+ barrier_before_unreachable(); \
+ __builtin_trap(); \
} while (0)
#define HAVE_ARCH_BUG
diff --git a/arch/arc/include/asm/elf.h b/arch/arc/include/asm/elf.h
index 51a99e25fe33..8ee9113b2f8b 100644
--- a/arch/arc/include/asm/elf.h
+++ b/arch/arc/include/asm/elf.h
@@ -55,7 +55,7 @@ extern int elf_check_arch(const struct elf32_hdr *);
* the loader. We need to make sure that it is out of the way of the program
* that it will "exec", and that there is sufficient room for the brk.
*/
-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+#define ELF_ET_DYN_BASE (2UL * TASK_SIZE / 3)
/*
* When the program starts, a1 contains a pointer to a function to be
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 05131805aa33..3013f3f82b95 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -232,8 +232,6 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt);
}
- n += scnprintf(buf + n, len - n, "%s",
- IS_USED_CFG(CONFIG_ARC_HAS_HW_MPY));
}
n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n",
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index c927aa84e652..2fb0cd39a31c 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -155,3 +155,11 @@ void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
insterror_is_error(address, regs);
}
+
+/*
+ * abort() call generated by older gcc for __builtin_trap()
+ */
+void abort(void)
+{
+ __asm__ __volatile__("trap_s 5\n");
+}
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 5eb707640e9c..60b41d018227 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -183,11 +183,6 @@ static void *__init unw_hdr_alloc_early(unsigned long sz)
MAX_DMA_ADDRESS);
}
-static void *unw_hdr_alloc(unsigned long sz)
-{
- return kmalloc(sz, GFP_KERNEL);
-}
-
static void init_unwind_table(struct unwind_table *table, const char *name,
const void *core_start, unsigned long core_size,
const void *init_start, unsigned long init_size,
@@ -368,6 +363,10 @@ ret_err:
}
#ifdef CONFIG_MODULES
+static void *unw_hdr_alloc(unsigned long sz)
+{
+ return kmalloc(sz, GFP_KERNEL);
+}
static struct unwind_table *last_table;
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 1ed545cc2b83..99356e23776d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1479,6 +1479,8 @@ static __init void da850_evm_init(void)
if (ret)
pr_warn("%s: dsp/rproc registration failed: %d\n",
__func__, ret);
+
+ regulator_has_full_constraints();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 78d325f3245a..4728d0974849 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -660,6 +660,9 @@ static struct platform_device da8xx_lcdc_device = {
.id = 0,
.num_resources = ARRAY_SIZE(da8xx_lcdc_resources),
.resource = da8xx_lcdc_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
};
int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index 7f5df8992008..1127e500bea3 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -14,6 +14,7 @@
#include "common.h"
#include "cpuidle.h"
+#include "hardware.h"
static int imx6sx_idle_finish(unsigned long val)
{
@@ -97,7 +98,7 @@ int __init imx6sx_cpuidle_init(void)
* except for power up sw2iso which need to be
* larger than LDO ramp up time.
*/
- imx_gpc_set_arm_power_up_timing(0xf, 1);
+ imx_gpc_set_arm_power_up_timing(cpu_is_imx6sx() ? 0xf : 0x2, 1);
imx_gpc_set_arm_power_down_timing(1, 1);
return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index 62680aad2126..b5ce9ca76336 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -430,7 +430,7 @@ static void omap3_prm_reconfigure_io_chain(void)
* registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
* No return value.
*/
-static void __init omap3xxx_prm_enable_io_wakeup(void)
+static void omap3xxx_prm_enable_io_wakeup(void)
{
if (prm_features & PRM_HAS_IO_WAKEUP)
omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 6e3cbeff1576..7349f53745e3 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -621,6 +621,7 @@ CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
+CONFIG_OVERLAY_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 51d31bc72348..de05a73d9c11 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -648,6 +648,7 @@ CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
+CONFIG_OVERLAY_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig
index 274519f7055a..15051088956d 100644
--- a/arch/arm64/configs/sdm660-perf_defconfig
+++ b/arch/arm64/configs/sdm660-perf_defconfig
@@ -627,6 +627,7 @@ CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
+CONFIG_OVERLAY_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig
index 8df86944dce9..2eceb3bb2a83 100644
--- a/arch/arm64/configs/sdm660_defconfig
+++ b/arch/arm64/configs/sdm660_defconfig
@@ -650,6 +650,7 @@ CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
+CONFIG_OVERLAY_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 46fa4de29fb1..a6f1df69c0c3 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -36,7 +36,7 @@
#include <asm/vdso.h>
#include <asm/vdso_datapage.h>
-extern char vdso_start, vdso_end;
+extern char vdso_start[], vdso_end[];
static unsigned long vdso_pages;
static struct page **vdso_pagelist;
@@ -116,14 +116,14 @@ static int __init vdso_init(void)
int i;
unsigned long pfn;
- if (memcmp(&vdso_start, "\177ELF", 4)) {
+ if (memcmp(vdso_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
- vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
- vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+ vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
@@ -136,7 +136,7 @@ static int __init vdso_init(void)
/* Grab the vDSO code pages. */
- pfn = sym_to_pfn(&vdso_start);
+ pfn = sym_to_pfn(vdso_start);
for (i = 0; i < vdso_pages; i++)
vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
diff --git a/arch/ia64/include/asm/bug.h b/arch/ia64/include/asm/bug.h
index 823616b5020b..19067821249f 100644
--- a/arch/ia64/include/asm/bug.h
+++ b/arch/ia64/include/asm/bug.h
@@ -3,7 +3,11 @@
#ifdef CONFIG_BUG
#define ia64_abort() __builtin_trap()
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ barrier_before_unreachable(); \
+ ia64_abort(); \
+} while (0)
/* should this BUG be made generic? */
#define HAVE_ARCH_BUG
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h
index ef9a2e47352f..21ddbf925e22 100644
--- a/arch/m68k/include/asm/bug.h
+++ b/arch/m68k/include/asm/bug.h
@@ -7,16 +7,19 @@
#ifndef CONFIG_SUN3
#define BUG() do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ barrier_before_unreachable(); \
__builtin_trap(); \
} while (0)
#else
#define BUG() do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ barrier_before_unreachable(); \
panic("BUG!"); \
} while (0)
#endif
#else
#define BUG() do { \
+ barrier_before_unreachable(); \
__builtin_trap(); \
} while (0)
#endif
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 62c54336ab4f..f561e36917d1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -13,6 +13,7 @@ config MIPS
select HAVE_OPROFILE
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
+ select HAVE_ARCH_COMPILER_H
select HAVE_ARCH_KGDB
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h
index e081a265f422..cc2eb1b06050 100644
--- a/arch/mips/include/asm/compiler.h
+++ b/arch/mips/include/asm/compiler.h
@@ -8,6 +8,41 @@
#ifndef _ASM_COMPILER_H
#define _ASM_COMPILER_H
+/*
+ * With GCC 4.5 onwards we can use __builtin_unreachable to indicate to the
+ * compiler that a particular code path will never be hit. This allows it to be
+ * optimised out of the generated binary.
+ *
+ * Unfortunately at least GCC 4.6.3 through 7.3.0 inclusive suffer from a bug
+ * that can lead to instructions from beyond an unreachable statement being
+ * incorrectly reordered into earlier delay slots if the unreachable statement
+ * is the only content of a case in a switch statement. This can lead to
+ * seemingly random behaviour, such as invalid memory accesses from incorrectly
+ * reordered loads or stores. See this potential GCC fix for details:
+ *
+ * https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00360.html
+ *
+ * It is unclear whether GCC 8 onwards suffer from the same issue - nothing
+ * relevant is mentioned in GCC 8 release notes and nothing obviously relevant
+ * stands out in GCC commit logs, but these newer GCC versions generate very
+ * different code for the testcase which doesn't exhibit the bug.
+ *
+ * GCC also handles stack allocation suboptimally when calling noreturn
+ * functions or calling __builtin_unreachable():
+ *
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
+ *
+ * We work around both of these issues by placing a volatile asm statement,
+ * which GCC is prevented from reordering past, prior to __builtin_unreachable
+ * calls.
+ *
+ * The .insn statement is required to ensure that any branches to the
+ * statement, which sadly must be kept due to the asm statement, are known to
+ * be branches to code and satisfy linker requirements for microMIPS kernels.
+ */
+#undef barrier_before_unreachable
+#define barrier_before_unreachable() asm volatile(".insn")
+
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define GCC_IMM_ASM() "n"
#define GCC_REG_ACCUM "$0"
diff --git a/arch/mips/include/uapi/asm/sgidefs.h b/arch/mips/include/uapi/asm/sgidefs.h
index 876442fcfb32..5be81f8fd479 100644
--- a/arch/mips/include/uapi/asm/sgidefs.h
+++ b/arch/mips/include/uapi/asm/sgidefs.h
@@ -11,14 +11,6 @@
#define __ASM_SGIDEFS_H
/*
- * Using a Linux compiler for building Linux seems logic but not to
- * everybody.
- */
-#ifndef __linux__
-#error Use a Linux compiler or give up.
-#endif
-
-/*
* Definitions for the ISA levels
*
* With the introduction of MIPS32 / MIPS64 instruction sets definitions
diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c
index 4e7b89f2e244..1363d705cc8c 100644
--- a/arch/mips/kernel/uprobes.c
+++ b/arch/mips/kernel/uprobes.c
@@ -164,9 +164,6 @@ int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs)
*/
aup->resume_epc = regs->cp0_epc + 4;
if (insn_has_delay_slot((union mips_instruction) aup->insn[0])) {
- unsigned long epc;
-
- epc = regs->cp0_epc;
__compute_return_epc_for_insn(regs,
(union mips_instruction) aup->insn[0]);
aup->resume_epc = regs->cp0_epc;
diff --git a/arch/parisc/math-emu/cnv_float.h b/arch/parisc/math-emu/cnv_float.h
index 933423fa5144..b0db61188a61 100644
--- a/arch/parisc/math-emu/cnv_float.h
+++ b/arch/parisc/math-emu/cnv_float.h
@@ -60,19 +60,19 @@
((exponent < (SGL_P - 1)) ? \
(Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
-#define Int_isinexact_to_sgl(int_value) (int_value << 33 - SGL_EXP_LENGTH)
+#define Int_isinexact_to_sgl(int_value) ((int_value << 33 - SGL_EXP_LENGTH) != 0)
#define Sgl_roundnearest_from_int(int_value,sgl_value) \
if (int_value & 1<<(SGL_EXP_LENGTH - 2)) /* round bit */ \
- if ((int_value << 34 - SGL_EXP_LENGTH) || Slow(sgl_value)) \
+ if (((int_value << 34 - SGL_EXP_LENGTH) != 0) || Slow(sgl_value)) \
Sall(sgl_value)++
#define Dint_isinexact_to_sgl(dint_valueA,dint_valueB) \
- ((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) || Dintp2(dint_valueB))
+ (((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) != 0) || Dintp2(dint_valueB))
#define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value) \
if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2)) \
- if ((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) || \
+ if (((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) != 0) || \
Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
#define Dint_isinexact_to_dbl(dint_value) \
diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h
index 155fcc7bcba6..cd62de502aee 100644
--- a/arch/s390/include/asm/facility.h
+++ b/arch/s390/include/asm/facility.h
@@ -51,6 +51,18 @@ static inline int test_facility(unsigned long nr)
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
}
+static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size)
+{
+ register unsigned long reg0 asm("0") = size - 1;
+
+ asm volatile(
+ ".insn s,0xb2b00000,0(%1)" /* stfle */
+ : "+d" (reg0)
+ : "a" (stfle_fac_list)
+ : "memory", "cc");
+ return reg0;
+}
+
/**
* stfle - Store facility list extended
* @stfle_fac_list: array where facility list can be stored
@@ -70,13 +82,8 @@ static inline void stfle(u64 *stfle_fac_list, int size)
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
if (S390_lowcore.stfl_fac_list & 0x01000000) {
/* More facility bits available with stfle */
- register unsigned long reg0 asm("0") = size - 1;
-
- asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
- : "+d" (reg0)
- : "a" (stfle_fac_list)
- : "memory", "cc");
- nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
+ nr = __stfle_asm(stfle_fac_list, size);
+ nr = min_t(unsigned long, (nr + 1) * 8, size * 8);
}
memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
preempt_enable();
diff --git a/arch/sparc/include/asm/bug.h b/arch/sparc/include/asm/bug.h
index eaa8f8d38125..fa85cac0285c 100644
--- a/arch/sparc/include/asm/bug.h
+++ b/arch/sparc/include/asm/bug.h
@@ -8,10 +8,14 @@
void do_BUG(const char *file, int line);
#define BUG() do { \
do_BUG(__FILE__, __LINE__); \
+ barrier_before_unreachable(); \
__builtin_trap(); \
} while (0)
#else
-#define BUG() __builtin_trap()
+#define BUG() do { \
+ barrier_before_unreachable(); \
+ __builtin_trap(); \
+} while (0)
#endif
#define HAVE_ARCH_BUG
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index a5d0c2f08110..815352d501f0 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -889,6 +889,10 @@ static int sparc_perf_event_set_period(struct perf_event *event,
s64 period = hwc->sample_period;
int ret = 0;
+ /* The period may have been changed by PERF_EVENT_IOC_PERIOD */
+ if (unlikely(period != hwc->last_period))
+ left = period - (hwc->last_period - left);
+
if (unlikely(left <= -period)) {
left = period;
local64_set(&hwc->period_left, left);
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 26e0164895e4..6e6f6d28d54b 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -12,6 +12,7 @@
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <sys/un.h>
#include <sys/types.h>
#include <os.h>
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 56648f4f8b41..5da50451d372 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -14,7 +14,9 @@
#include <as-layout.h>
#include <kern_util.h>
#include <os.h>
+#include <sys/ucontext.h>
#include <sysdep/mcontext.h>
+#include <um_malloc.h>
void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
[SIGTRAP] = relay_signal,
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 2017fa20611c..310e279be0d8 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -807,6 +807,16 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
}
/*
+ * If SSBD is controlled by the SPEC_CTRL MSR, then set the proper
+ * bit in the mask to allow guests to use the mitigation even in the
+ * case where the host does not enable it.
+ */
+ if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
+ static_cpu_has(X86_FEATURE_AMD_SSBD)) {
+ x86_spec_ctrl_mask |= SPEC_CTRL_SSBD;
+ }
+
+ /*
* We have three CPU feature flags that are in play here:
* - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible.
* - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass
@@ -823,7 +833,6 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
x86_amd_ssb_disable();
} else {
x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
- x86_spec_ctrl_mask |= SPEC_CTRL_SSBD;
wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
}
}
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 479a409ddac8..1ca929767a1b 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -23,6 +23,7 @@
#include <linux/rcupdate.h>
#include <linux/export.h>
#include <linux/context_tracking.h>
+#include <linux/nospec.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -697,9 +698,11 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
{
struct thread_struct *thread = &tsk->thread;
unsigned long val = 0;
+ int index = n;
if (n < HBP_NUM) {
- struct perf_event *bp = thread->ptrace_bps[n];
+ struct perf_event *bp = thread->ptrace_bps[index];
+ index = array_index_nospec(index, HBP_NUM);
if (bp)
val = bp->hw.info.address;
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
index 7fc5e843f247..9f03c7e07a2b 100644
--- a/arch/x86/kernel/tls.c
+++ b/arch/x86/kernel/tls.c
@@ -4,6 +4,7 @@
#include <linux/user.h>
#include <linux/regset.h>
#include <linux/syscalls.h>
+#include <linux/nospec.h>
#include <asm/uaccess.h>
#include <asm/desc.h>
@@ -177,6 +178,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
struct user_desc __user *u_info)
{
struct user_desc info;
+ int index;
if (idx == -1 && get_user(idx, &u_info->entry_number))
return -EFAULT;
@@ -184,8 +186,11 @@ int do_get_thread_area(struct task_struct *p, int idx,
if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
return -EINVAL;
- fill_user_desc(&info, idx,
- &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
+ index = idx - GDT_ENTRY_TLS_MIN;
+ index = array_index_nospec(index,
+ GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1);
+
+ fill_user_desc(&info, idx, &p->thread.tls_array[index]);
if (copy_to_user(u_info, &info, sizeof(info)))
return -EFAULT;
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index ab5318727579..ef56d70d1026 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -678,7 +678,6 @@ static const struct kvm_io_device_ops speaker_dev_ops = {
.write = speaker_ioport_write,
};
-/* Caller must hold slots_lock */
struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
{
struct kvm_pit *pit;
@@ -733,6 +732,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
pit->mask_notifier.func = pit_mask_notifer;
kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+ mutex_lock(&kvm->slots_lock);
kvm_iodevice_init(&pit->dev, &pit_dev_ops);
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, KVM_PIT_BASE_ADDRESS,
KVM_PIT_MEM_LENGTH, &pit->dev);
@@ -747,13 +747,14 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
if (ret < 0)
goto fail_unregister;
}
+ mutex_unlock(&kvm->slots_lock);
return pit;
fail_unregister:
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
-
fail:
+ mutex_unlock(&kvm->slots_lock);
kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
kvm_free_irq_source_id(kvm, pit->irq_source_id);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 516d8b1562c8..8613422660b6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1293,7 +1293,7 @@ static int set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
vcpu->arch.tsc_always_catchup = 1;
return 0;
} else {
- WARN(1, "user requested TSC rate below hardware speed\n");
+ pr_warn_ratelimited("user requested TSC rate below hardware speed\n");
return -1;
}
}
@@ -1303,8 +1303,8 @@ static int set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
user_tsc_khz, tsc_khz);
if (ratio == 0 || ratio >= kvm_max_tsc_scaling_ratio) {
- WARN_ONCE(1, "Invalid TSC scaling ratio - virtual-tsc-khz=%u\n",
- user_tsc_khz);
+ pr_warn_ratelimited("Invalid TSC scaling ratio - virtual-tsc-khz=%u\n",
+ user_tsc_khz);
return -1;
}
@@ -3867,7 +3867,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
sizeof(struct kvm_pit_config)))
goto out;
create_pit:
- mutex_lock(&kvm->slots_lock);
+ mutex_lock(&kvm->lock);
r = -EEXIST;
if (kvm->arch.vpit)
goto create_pit_unlock;
@@ -3876,7 +3876,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (kvm->arch.vpit)
r = 0;
create_pit_unlock:
- mutex_unlock(&kvm->slots_lock);
+ mutex_unlock(&kvm->lock);
break;
case KVM_GET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
@@ -6409,7 +6409,8 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
kvm_scan_ioapic_routes(vcpu, vcpu->arch.eoi_exit_bitmap);
else {
kvm_x86_ops->sync_pir_to_irr(vcpu);
- kvm_ioapic_scan_entry(vcpu, vcpu->arch.eoi_exit_bitmap);
+ if (ioapic_in_kernel(vcpu->kvm))
+ kvm_ioapic_scan_entry(vcpu, vcpu->arch.eoi_exit_bitmap);
}
kvm_x86_ops->load_eoi_exitmap(vcpu);
}
@@ -7798,7 +7799,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
slot = id_to_memslot(slots, id);
if (size) {
- if (WARN_ON(slot->npages))
+ if (slot->npages)
return -EEXIST;
/*
diff --git a/arch/x86/um/stub_segv.c b/arch/x86/um/stub_segv.c
index fd6825537b97..27361cbb7ca9 100644
--- a/arch/x86/um/stub_segv.c
+++ b/arch/x86/um/stub_segv.c
@@ -6,6 +6,7 @@
#include <sysdep/stub.h>
#include <sysdep/faultinfo.h>
#include <sysdep/mcontext.h>
+#include <sys/ucontext.h>
void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig, siginfo_t *info, void *p)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 7097a3395b25..b93c6db18ed3 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -54,6 +54,9 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
list_for_each_entry(q, &crypto_alg_list, cra_list) {
int match = 0;
+ if (crypto_is_larval(q))
+ continue;
+
if ((q->cra_flags ^ p->cru_type) & p->cru_mask)
continue;
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index d18768b0e9da..19fbd702c0e6 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -727,32 +727,47 @@ int diag_dci_query_event_mask(struct diag_dci_client_tbl *entry,
return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0;
}
-static int diag_dci_filter_commands(struct diag_pkt_header_t *header)
+static int diag_dci_filter_commands(struct diag_pkt_header_t *header,
+ int header_len)
{
if (!header)
return -ENOMEM;
- switch (header->cmd_code) {
- case 0x7d: /* Msg Mask Configuration */
- case 0x73: /* Log Mask Configuration */
- case 0x81: /* Event Mask Configuration */
- case 0x82: /* Event Mask Change */
- case 0x60: /* Event Mask Toggle */
- return 1;
- }
+ if (header_len <= 0)
+ return -EIO;
- if (header->cmd_code == 0x4b && header->subsys_id == 0x12) {
- switch (header->subsys_cmd_code) {
- case 0x60: /* Extended Event Mask Config */
- case 0x61: /* Extended Msg Mask Config */
- case 0x62: /* Extended Log Mask Config */
- case 0x20C: /* Set current Preset ID */
- case 0x20D: /* Get current Preset ID */
- case 0x218: /* HDLC Disabled Command */
+ if (header_len) {
+ switch (header->cmd_code) {
+ case 0x7d: /* Msg Mask Configuration */
+ case 0x73: /* Log Mask Configuration */
+ case 0x81: /* Event Mask Configuration */
+ case 0x82: /* Event Mask Change */
+ case 0x60: /* Event Mask Toggle */
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: command not supported: %d\n",
+ header->cmd_code);
return 1;
}
}
+ if (header_len >= (3*sizeof(uint8_t))) {
+ if (header->cmd_code == 0x4b && header->subsys_id == 0x12) {
+ switch (header->subsys_cmd_code) {
+ case 0x60: /* Extended Event Mask Config */
+ case 0x61: /* Extended Msg Mask Config */
+ case 0x62: /* Extended Log Mask Config */
+ case 0x20C: /* Set current Preset ID */
+ case 0x20D: /* Get current Preset ID */
+ case 0x218: /* HDLC Disabled Command */
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: command not supported %d %d %d\n",
+ header->cmd_code, header->subsys_id,
+ header->subsys_cmd_code);
+ return 1;
+ }
+ }
+ }
+
return 0;
}
@@ -1796,7 +1811,7 @@ int diag_dci_send_handshake_pkt(int index)
static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header,
unsigned char *req_buf, int req_len,
- int tag)
+ int tag, int pkt_header_len)
{
uint8_t cmd_code, subsys_id, i, goto_download = 0;
uint8_t header_len = sizeof(struct diag_dci_pkt_header_t);
@@ -1806,12 +1821,16 @@ static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header,
unsigned char *payload_ptr = driver->apps_dci_buf + header_len;
struct diag_dci_pkt_header_t dci_header;
- if (!pkt_header || !req_buf || req_len <= 0 || tag < 0)
+ if (!pkt_header || !req_buf || req_len <= 0 || tag < 0 ||
+ pkt_header_len <= 0)
return -EIO;
- cmd_code = pkt_header->cmd_code;
- subsys_id = pkt_header->subsys_id;
- ss_cmd_code = pkt_header->subsys_cmd_code;
+ if (pkt_header_len >= (sizeof(uint8_t)))
+ cmd_code = pkt_header->cmd_code;
+ if (pkt_header_len >= (2 * sizeof(uint8_t)))
+ subsys_id = pkt_header->subsys_id;
+ if (pkt_header_len >= (3 * sizeof(uint8_t)))
+ ss_cmd_code = pkt_header->subsys_cmd_code;
if (cmd_code == DIAG_CMD_DOWNLOAD) {
*payload_ptr = DIAG_CMD_DOWNLOAD;
@@ -1931,7 +1950,7 @@ fill_buffer:
static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
{
int ret = DIAG_DCI_TABLE_ERR;
- int common_cmd = 0;
+ int common_cmd = 0, header_len = 0;
struct diag_pkt_header_t *header = NULL;
unsigned char *temp = buf;
unsigned char *req_buf = NULL;
@@ -1947,8 +1966,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
if (!buf)
return -EIO;
- if (len < (sizeof(struct dci_pkt_req_t) +
- sizeof(struct diag_pkt_header_t)) ||
+ if (len < sizeof(struct dci_pkt_req_t) ||
len > DCI_REQ_BUF_SIZE) {
pr_err("diag: dci: Invalid length %d len in %s", len, __func__);
return -EIO;
@@ -1959,13 +1977,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
read_len += sizeof(struct dci_pkt_req_t);
req_len -= sizeof(struct dci_pkt_req_t);
req_buf = temp; /* Start of the Request */
- header = (struct diag_pkt_header_t *)temp;
- read_len += sizeof(struct diag_pkt_header_t);
- if (read_len >= DCI_REQ_BUF_SIZE) {
- pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__,
- read_len);
- return -EIO;
- }
mutex_lock(&driver->dci_mutex);
dci_entry = diag_dci_get_client_entry(req_hdr.client_id);
@@ -1976,11 +1987,40 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
return DIAG_DCI_NO_REG;
}
+ header = (void *)temp;
+ header_len = len - sizeof(struct dci_pkt_req_t);
+ if (header_len <= 0) {
+ mutex_unlock(&driver->dci_mutex);
+ return -EIO;
+ }
+ if (header_len >= sizeof(uint8_t)) {
+ header->cmd_code = (uint16_t)(*(uint8_t *)temp);
+ read_len += sizeof(uint8_t);
+ }
+ if (header_len >= (2 * sizeof(uint8_t))) {
+ temp += sizeof(uint8_t);
+ header->subsys_id = (uint16_t)(*(uint8_t *)temp);
+ read_len += sizeof(uint8_t);
+ }
+ if (header_len == (3 * sizeof(uint8_t))) {
+ temp += sizeof(uint8_t);
+ header->subsys_cmd_code = (uint16_t)(*(uint8_t *)temp);
+ read_len += sizeof(uint8_t);
+ } else if (header_len >=
+ (2 * sizeof(uint8_t)) + sizeof(uint16_t)) {
+ temp += sizeof(uint8_t);
+ header->subsys_cmd_code = (uint16_t)(*(uint16_t *)temp);
+ read_len += sizeof(uint16_t);
+ }
+ if (read_len > DCI_REQ_BUF_SIZE) {
+ pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__,
+ read_len);
+ mutex_unlock(&driver->dci_mutex);
+ return -EIO;
+ }
+
/* Check if the command is allowed on DCI */
- if (diag_dci_filter_commands(header)) {
- pr_debug("diag: command not supported %d %d %d",
- header->cmd_code, header->subsys_id,
- header->subsys_cmd_code);
+ if (diag_dci_filter_commands(header, header_len)) {
mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_SEND_DATA_FAIL;
}
@@ -2034,14 +2074,18 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
/* Check if it is a dedicated Apps command */
ret = diag_dci_process_apps_pkt(header, req_buf, req_len,
- req_entry->tag);
+ req_entry->tag, header_len);
if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0)
return ret;
- reg_entry.cmd_code = header->cmd_code;
- reg_entry.subsys_id = header->subsys_id;
- reg_entry.cmd_code_hi = header->subsys_cmd_code;
- reg_entry.cmd_code_lo = header->subsys_cmd_code;
+ if (header_len >= (sizeof(uint8_t)))
+ reg_entry.cmd_code = header->cmd_code;
+ if (header_len >= (2 * sizeof(uint8_t)))
+ reg_entry.subsys_id = header->subsys_id;
+ if (header_len >= (3 * sizeof(uint8_t))) {
+ reg_entry.cmd_code_hi = header->subsys_cmd_code;
+ reg_entry.cmd_code_lo = header->subsys_cmd_code;
+ }
mutex_lock(&driver->cmd_reg_mutex);
temp_entry = diag_cmd_search(&reg_entry, ALL_PROC);
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 48d4dddf4941..4054747af0cb 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -614,7 +614,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
spin_lock_irqsave(&sdma->channel_0_lock, flags);
bd0->mode.command = C0_SETPM;
- bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+ bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
bd0->mode.count = size / 2;
bd0->buffer_addr = buf_phys;
bd0->ext_buffer_addr = address;
@@ -883,7 +883,7 @@ static int sdma_load_context(struct sdma_channel *sdmac)
context->gReg[7] = sdmac->watermark_level;
bd0->mode.command = C0_SETDM;
- bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+ bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
bd0->mode.count = sizeof(*context) / 4;
bd0->buffer_addr = sdma->context_phys;
bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel;
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 021d8391abea..65d6e1db8db8 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -63,7 +63,7 @@ config DRM_FBDEV_EMULATION
config DRM_LOAD_EDID_FIRMWARE
bool "Allow to specify an EDID data set instead of probing for it"
- depends on DRM_KMS_HELPER
+ depends on DRM
help
Say Y here, if you want to use EDID data to be loaded from the
/lib/firmware directory or one of the provided built-in
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index ea0d5ea57213..d4e3cf4356d7 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -20,12 +20,12 @@ drm-$(CONFIG_PCI) += ati_pcigart.o
drm-$(CONFIG_DRM_PANEL) += drm_panel.o
drm-$(CONFIG_OF) += drm_of.o
drm-$(CONFIG_AGP) += drm_agpsupport.o
+drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm-y += $(drm-m)
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
-drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index fbd717324328..d3f3e33230f2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1501,6 +1501,10 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
* level, drivers must make all reasonable efforts to expose it as an I2C
* adapter and use drm_get_edid() instead of abusing this function.
*
+ * The EDID may be overridden using debugfs override_edid or firmare EDID
+ * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
+ * order. Having either of them bypasses actual EDID reads.
+ *
* Return: Pointer to valid EDID or NULL if we couldn't find any.
*/
struct edid *drm_do_get_edid(struct drm_connector *connector,
@@ -1511,6 +1515,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
int i, j = 0, valid_extensions = 0;
u8 *block, *new;
bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
+ struct edid *override = NULL;
+
+ if (connector->override_edid)
+ override = drm_edid_duplicate((const struct edid *)
+ connector->edid_blob_ptr->data);
+
+ if (!override)
+ override = drm_load_edid_firmware(connector);
+
+ if (!IS_ERR_OR_NULL(override))
+ return override;
if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
return NULL;
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 698b8c3b09d9..4a097a952917 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -261,15 +261,14 @@ out:
return edid;
}
-int drm_load_edid_firmware(struct drm_connector *connector)
+struct edid *drm_load_edid_firmware(struct drm_connector *connector)
{
const char *connector_name = connector->name;
char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
- int ret;
struct edid *edid;
if (edid_firmware[0] == '\0')
- return 0;
+ return ERR_PTR(-ENOENT);
/*
* If there are multiple edid files specified and separated
@@ -298,7 +297,7 @@ int drm_load_edid_firmware(struct drm_connector *connector)
if (!edidname) {
if (!fallback) {
kfree(fwstr);
- return 0;
+ return ERR_PTR(-ENOENT);
}
edidname = fallback;
}
@@ -310,13 +309,5 @@ int drm_load_edid_firmware(struct drm_connector *connector)
edid = edid_load(connector, edidname, connector_name);
kfree(fwstr);
- if (IS_ERR_OR_NULL(edid))
- return 0;
-
- drm_mode_connector_update_edid_property(connector, edid);
- ret = drm_add_edid_modes(connector, edid);
- drm_edid_to_eld(connector, edid);
- kfree(edid);
-
- return ret;
+ return edid;
}
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 1fe4b8e6596b..81dfc23e1c6a 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -199,19 +199,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
goto prune;
}
-#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
- count = drm_load_edid_firmware(connector);
- if (count == 0)
-#endif
- {
- if (connector->override_edid) {
- struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
-
- count = drm_add_edid_modes(connector, edid);
- drm_edid_to_eld(connector, edid);
- } else
- count = (*connector_funcs->get_modes)(connector);
- }
+ count = (*connector_funcs->get_modes)(connector);
if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 99f89841a74a..8467be8c3f0b 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2014 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -27,22 +27,26 @@ struct msm_commit {
uint32_t fence;
struct msm_fence_cb fence_cb;
uint32_t crtc_mask;
+ uint32_t plane_mask;
struct kthread_work commit_work;
};
/* block until specified crtcs are no longer pending update, and
* atomically mark them as pending update
*/
-static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
+static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask,
+ uint32_t plane_mask)
{
int ret;
spin_lock(&priv->pending_crtcs_event.lock);
ret = wait_event_interruptible_locked(priv->pending_crtcs_event,
- !(priv->pending_crtcs & crtc_mask));
+ !(priv->pending_crtcs & crtc_mask) &&
+ !(priv->pending_planes & plane_mask));
if (ret == 0) {
DBG("start: %08x", crtc_mask);
priv->pending_crtcs |= crtc_mask;
+ priv->pending_planes |= plane_mask;
}
spin_unlock(&priv->pending_crtcs_event.lock);
@@ -51,18 +55,21 @@ static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
/* clear specified crtcs (no longer pending update)
*/
-static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
+static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask,
+ uint32_t plane_mask)
{
spin_lock(&priv->pending_crtcs_event.lock);
DBG("end: %08x", crtc_mask);
priv->pending_crtcs &= ~crtc_mask;
+ priv->pending_planes &= ~plane_mask;
wake_up_all_locked(&priv->pending_crtcs_event);
spin_unlock(&priv->pending_crtcs_event.lock);
}
static void commit_destroy(struct msm_commit *commit)
{
- end_atomic(commit->dev->dev_private, commit->crtc_mask);
+ end_atomic(commit->dev->dev_private, commit->crtc_mask,
+ commit->plane_mask);
kfree(commit);
}
@@ -593,7 +600,7 @@ int msm_atomic_commit(struct drm_device *dev,
struct drm_crtc *crtc = state->crtcs[i];
if (!crtc)
continue;
- commit->crtc_mask |= (1 << drm_crtc_index(crtc));
+ commit->crtc_mask |= (1 << i);
}
/*
@@ -608,13 +615,16 @@ int msm_atomic_commit(struct drm_device *dev,
if ((plane->state->fb != new_state->fb) && new_state->fb)
commit_set_fence(commit, new_state->fb);
+
+ commit->plane_mask |= (1 << i);
}
/*
* Wait for pending updates on any of the same crtc's and then
* mark our set of crtc's as busy:
*/
- ret = start_atomic(dev->dev_private, commit->crtc_mask);
+ ret = start_atomic(dev->dev_private, commit->crtc_mask,
+ commit->plane_mask);
if (ret) {
DRM_ERROR("start_atomic failed: %d\n", ret);
commit_destroy(commit);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 87649f7ec3dd..a9c28feb11ce 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -319,6 +319,7 @@ struct msm_drm_private {
/* crtcs pending async atomic updates: */
uint32_t pending_crtcs;
+ uint32_t pending_planes;
wait_queue_head_t pending_crtcs_event;
/* Registered address spaces.. currently this is fixed per # of
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index fba18231cb72..4e3788b4fed6 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017,2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -173,8 +173,11 @@ static void syncobj_timer(unsigned long data)
/*
* a generic function to retire a pending sync event and (possibly)
* kick the dispatcher
+ * Returns false if the event was already marked for cancellation in another
+ * thread. This function should return true if this thread is responsible for
+ * freeing up the memory, and the event will not be cancelled.
*/
-static void drawobj_sync_expire(struct kgsl_device *device,
+static bool drawobj_sync_expire(struct kgsl_device *device,
struct kgsl_drawobj_sync_event *event)
{
struct kgsl_drawobj_sync *syncobj = event->syncobj;
@@ -183,7 +186,7 @@ static void drawobj_sync_expire(struct kgsl_device *device,
* leave without doing anything useful
*/
if (!test_and_clear_bit(event->id, &syncobj->pending))
- return;
+ return false;
/*
* If no more pending events, delete the timer and schedule the command
@@ -196,6 +199,7 @@ static void drawobj_sync_expire(struct kgsl_device *device,
device->ftbl->drawctxt_sched(device,
event->syncobj->base.context);
}
+ return true;
}
/*
@@ -210,8 +214,13 @@ static void drawobj_sync_func(struct kgsl_device *device,
trace_syncpoint_timestamp_expire(event->syncobj,
event->context, event->timestamp);
- drawobj_sync_expire(device, event);
- kgsl_context_put(event->context);
+ /*
+ * Put down the context ref count only if
+ * this thread successfully clears the pending bit mask.
+ */
+ if (drawobj_sync_expire(device, event))
+ kgsl_context_put(event->context);
+
drawobj_put(&event->syncobj->base);
}
@@ -241,28 +250,25 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj)
static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
{
struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj);
- unsigned long pending, flags;
+ unsigned long flags;
unsigned int i;
/* Zap the canary timer */
del_timer_sync(&syncobj->timer);
/*
- * Copy off the pending list and clear all pending events - this will
- * render any subsequent asynchronous callback harmless
- */
- bitmap_copy(&pending, &syncobj->pending, KGSL_MAX_SYNCPOINTS);
- bitmap_zero(&syncobj->pending, KGSL_MAX_SYNCPOINTS);
-
- /*
* Clear all pending events - this will render any subsequent async
* callbacks harmless
*/
for (i = 0; i < syncobj->numsyncs; i++) {
struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i];
- /* Don't do anything if the event has already expired */
- if (!test_bit(i, &pending))
+ /*
+ * Don't do anything if the event has already expired.
+ * If this thread clears the pending bit mask then it is
+ * responsible for doing context put.
+ */
+ if (!test_and_clear_bit(i, &syncobj->pending))
continue;
switch (event->type) {
@@ -270,6 +276,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
kgsl_cancel_event(drawobj->device,
&event->context->events, event->timestamp,
drawobj_sync_func, event);
+ /*
+ * Do context put here to make sure the context is alive
+ * till this thread cancels kgsl event.
+ */
+ kgsl_context_put(event->context);
break;
case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
spin_lock_irqsave(&event->handle_lock, flags);
@@ -291,7 +302,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
* If we cancelled an event, there's a good chance that the context is
* on a dispatcher queue, so schedule to get it removed.
*/
- if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) &&
+ if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) &&
drawobj->device->ftbl->drawctxt_sched)
drawobj->device->ftbl->drawctxt_sched(drawobj->device,
drawobj->context);
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index c00bad02761a..0d75bc7b5065 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1028,14 +1028,15 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
const struct pmbus_driver_info *info,
const char *name,
int index, int page,
- const struct pmbus_sensor_attr *attr)
+ const struct pmbus_sensor_attr *attr,
+ bool paged)
{
struct pmbus_sensor *base;
int ret;
if (attr->label) {
ret = pmbus_add_label(data, name, index, attr->label,
- attr->paged ? page + 1 : 0);
+ paged ? page + 1 : 0);
if (ret)
return ret;
}
@@ -1067,6 +1068,30 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
return 0;
}
+static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info,
+ const struct pmbus_sensor_attr *attr)
+{
+ int p;
+
+ if (attr->paged)
+ return true;
+
+ /*
+ * Some attributes may be present on more than one page despite
+ * not being marked with the paged attribute. If that is the case,
+ * then treat the sensor as being paged and add the page suffix to the
+ * attribute name.
+ * We don't just add the paged attribute to all such attributes, in
+ * order to maintain the un-suffixed labels in the case where the
+ * attribute is only on page 0.
+ */
+ for (p = 1; p < info->pages; p++) {
+ if (info->func[p] & attr->func)
+ return true;
+ }
+ return false;
+}
+
static int pmbus_add_sensor_attrs(struct i2c_client *client,
struct pmbus_data *data,
const char *name,
@@ -1080,14 +1105,15 @@ static int pmbus_add_sensor_attrs(struct i2c_client *client,
index = 1;
for (i = 0; i < nattrs; i++) {
int page, pages;
+ bool paged = pmbus_sensor_is_paged(info, attrs);
- pages = attrs->paged ? info->pages : 1;
+ pages = paged ? info->pages : 1;
for (page = 0; page < pages; page++) {
if (!(info->func[page] & attrs->func))
continue;
ret = pmbus_add_sensor_attrs_one(client, data, info,
name, index, page,
- attrs);
+ attrs, paged);
if (ret)
return ret;
index++;
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 2165f3dd328b..842c0235471d 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -530,11 +530,12 @@ static int imx_keypad_probe(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused imx_kbd_suspend(struct device *dev)
+static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_keypad *kbd = platform_get_drvdata(pdev);
struct input_dev *input_dev = kbd->input_dev;
+ unsigned short reg_val = readw(kbd->mmio_base + KPSR);
/* imx kbd can wake up system even clock is disabled */
mutex_lock(&input_dev->mutex);
@@ -544,13 +545,20 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev)
mutex_unlock(&input_dev->mutex);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(&pdev->dev)) {
+ if (reg_val & KBD_STAT_KPKD)
+ reg_val |= KBD_STAT_KRIE;
+ if (reg_val & KBD_STAT_KPKR)
+ reg_val |= KBD_STAT_KDIE;
+ writew(reg_val, kbd->mmio_base + KPSR);
+
enable_irq_wake(kbd->irq);
+ }
return 0;
}
-static int __maybe_unused imx_kbd_resume(struct device *dev)
+static int __maybe_unused imx_kbd_noirq_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_keypad *kbd = platform_get_drvdata(pdev);
@@ -574,7 +582,9 @@ err_clk:
return ret;
}
-static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume);
+static const struct dev_pm_ops imx_kbd_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_kbd_noirq_suspend, imx_kbd_noirq_resume)
+};
static struct platform_driver imx_keypad_driver = {
.driver = {
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 2bb4c8633d3b..7cffff22a1ca 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -894,13 +894,31 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#ifdef CONFIG_COMPAT
-#define UI_SET_PHYS_COMPAT _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
+/*
+ * These IOCTLs change their size and thus their numbers between
+ * 32 and 64 bits.
+ */
+#define UI_SET_PHYS_COMPAT \
+ _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
+#define UI_BEGIN_FF_UPLOAD_COMPAT \
+ _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload_compat)
+#define UI_END_FF_UPLOAD_COMPAT \
+ _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload_compat)
static long uinput_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
- if (cmd == UI_SET_PHYS_COMPAT)
+ switch (cmd) {
+ case UI_SET_PHYS_COMPAT:
cmd = UI_SET_PHYS;
+ break;
+ case UI_BEGIN_FF_UPLOAD_COMPAT:
+ cmd = UI_BEGIN_FF_UPLOAD;
+ break;
+ case UI_END_FF_UPLOAD_COMPAT:
+ cmd = UI_END_FF_UPLOAD;
+ break;
+ }
return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
}
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 4c1e527f14a5..7b942ee364b6 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -1191,6 +1191,8 @@ static const char * const middle_button_pnp_ids[] = {
"LEN2132", /* ThinkPad P52 */
"LEN2133", /* ThinkPad P72 w/ NFC */
"LEN2134", /* ThinkPad P72 */
+ "LEN0407",
+ "LEN0408",
NULL
};
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 131077aabd08..ae6fd58d6349 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -220,8 +220,8 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
BUG();
}
- DMERR("%s: %s block %llu is corrupted", v->data_dev->name, type_str,
- block);
+ DMERR_LIMIT("%s: %s block %llu is corrupted", v->data_dev->name,
+ type_str, block);
if (v->corrupted_errs == DM_VERITY_MAX_CORRUPTED_ERRS)
DMERR("%s: reached maximum errors", v->data_dev->name);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 68ebab54883e..dd41ee2ee19d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7226,9 +7226,9 @@ static void status_unused(struct seq_file *seq)
static int status_resync(struct seq_file *seq, struct mddev *mddev)
{
sector_t max_sectors, resync, res;
- unsigned long dt, db;
- sector_t rt;
- int scale;
+ unsigned long dt, db = 0;
+ sector_t rt, curr_mark_cnt, resync_mark_cnt;
+ int scale, recovery_active;
unsigned int per_milli;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
@@ -7298,22 +7298,30 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
* db: blocks written from mark until now
* rt: remaining time
*
- * rt is a sector_t, so could be 32bit or 64bit.
- * So we divide before multiply in case it is 32bit and close
- * to the limit.
- * We scale the divisor (db) by 32 to avoid losing precision
- * near the end of resync when the number of remaining sectors
- * is close to 'db'.
- * We then divide rt by 32 after multiplying by db to compensate.
- * The '+1' avoids division by zero if db is very small.
+ * rt is a sector_t, which is always 64bit now. We are keeping
+ * the original algorithm, but it is not really necessary.
+ *
+ * Original algorithm:
+ * So we divide before multiply in case it is 32bit and close
+ * to the limit.
+ * We scale the divisor (db) by 32 to avoid losing precision
+ * near the end of resync when the number of remaining sectors
+ * is close to 'db'.
+ * We then divide rt by 32 after multiplying by db to compensate.
+ * The '+1' avoids division by zero if db is very small.
*/
dt = ((jiffies - mddev->resync_mark) / HZ);
if (!dt) dt++;
- db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
- - mddev->resync_mark_cnt;
+
+ curr_mark_cnt = mddev->curr_mark_cnt;
+ recovery_active = atomic_read(&mddev->recovery_active);
+ resync_mark_cnt = mddev->resync_mark_cnt;
+
+ if (curr_mark_cnt >= (recovery_active + resync_mark_cnt))
+ db = curr_mark_cnt - (recovery_active + resync_mark_cnt);
rt = max_sectors - resync; /* number of remaining sectors */
- sector_div(rt, db/32+1);
+ rt = div64_u64(rt, db/32+1);
rt *= dt;
rt >>= 5;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index e11c68861f39..1af55fe257af 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -20,6 +20,7 @@
#define HANDLE_TO_IDX(handle) (handle & 0xFF)
#define ISP_SOF_DEBUG_COUNT 0
+#define OTHER_VFE(vfe_id) (vfe_id == ISP_VFE0 ? ISP_VFE1 : ISP_VFE0)
static void msm_isp_reload_ping_pong_offset(
struct msm_vfe_axi_stream *stream_info);
@@ -615,12 +616,9 @@ static void msm_isp_update_framedrop_reg(struct msm_vfe_axi_stream *stream_info,
MSM_VFE_STREAM_STOP_PERIOD;
}
- if (stream_info->undelivered_request_cnt > 0 &&
- drop_reconfig != 1)
+ if (stream_info->undelivered_request_cnt > 0)
stream_info->current_framedrop_period =
MSM_VFE_STREAM_STOP_PERIOD;
- if (stream_info->controllable_output && drop_reconfig == 1)
- stream_info->current_framedrop_period = 1;
/*
* re-configure the period pattern, only if it's not already
* set to what we want
@@ -2050,6 +2048,8 @@ static int msm_isp_cfg_ping_pong_address(
if (!buf) {
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
+ if (stream_info->controllable_output)
+ return 1;
return 0;
}
@@ -2722,7 +2722,11 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
struct msm_isp_timestamp timestamp;
struct msm_vfe_frame_request_queue *queue_req;
unsigned long flags;
+ uint32_t pingpong_status;
int vfe_idx;
+ uint32_t pingpong_bit = 0;
+ uint32_t frame_id = 0;
+ struct timeval *time_stamp;
if (!reset_cmd) {
pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd);
@@ -2731,6 +2735,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
}
msm_isp_get_timestamp(&timestamp, vfe_dev);
+ time_stamp = &timestamp.buf_time;
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
stream_info = msm_isp_get_stream_common_data(
@@ -2753,6 +2758,28 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev,
/* set ping pong to scratch before flush */
spin_lock_irqsave(&stream_info->lock, flags);
+ frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+ if (stream_info->controllable_output &&
+ stream_info->undelivered_request_cnt > 0) {
+ pingpong_status = VFE_PING_FLAG;
+ pingpong_bit = (~(pingpong_status >>
+ stream_info->wm[0][0]) & 0x1);
+ if (stream_info->buf[pingpong_bit] != NULL) {
+ msm_isp_process_done_buf(vfe_dev, stream_info,
+ stream_info->buf[pingpong_bit],
+ time_stamp,
+ frame_id);
+ }
+ pingpong_status = VFE_PONG_FLAG;
+ pingpong_bit = (~(pingpong_status >>
+ stream_info->wm[0][0]) & 0x1);
+ if (stream_info->buf[pingpong_bit] != NULL) {
+ msm_isp_process_done_buf(vfe_dev, stream_info,
+ stream_info->buf[pingpong_bit],
+ time_stamp,
+ frame_id);
+ }
+ }
msm_isp_cfg_stream_scratch(stream_info,
VFE_PING_FLAG);
msm_isp_cfg_stream_scratch(stream_info,
@@ -3261,9 +3288,8 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl,
msm_isp_reset_framedrop(vfe_dev_ioctl, stream_info);
rc = msm_isp_init_stream_ping_pong_reg(stream_info);
if (rc < 0) {
- pr_err("%s: No buffer for stream%d\n", __func__,
- HANDLE_TO_IDX(
- stream_cfg_cmd->stream_handle[i]));
+ pr_err("%s: No buffer for stream%x\n", __func__,
+ stream_info->stream_id);
spin_unlock_irqrestore(&stream_info->lock, flags);
mutex_unlock(&vfe_dev_ioctl->buf_mgr->lock);
goto error;
@@ -3595,9 +3621,10 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
(stream_info->undelivered_request_cnt <=
MAX_BUFFERS_IN_HW)
) {
- pr_debug("%s:%d invalid time to request frame %d\n",
+ pr_debug("%s:%d invalid time to request frame %d try drop_reconfig\n",
__func__, __LINE__, frame_id);
vfe_dev->isp_page->drop_reconfig = 1;
+ return 0;
} else if ((vfe_dev->axi_data.src_info[frame_src].active) &&
((frame_id ==
vfe_dev->axi_data.src_info[frame_src].frame_id) ||
@@ -3605,10 +3632,11 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
(stream_info->undelivered_request_cnt <=
MAX_BUFFERS_IN_HW)) {
vfe_dev->isp_page->drop_reconfig = 1;
- pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d\n",
+ pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d try drop_reconfig\n",
__func__, vfe_dev->pdev->id, frame_id,
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
vfe_dev->axi_data.src_info[VFE_PIX_0].active);
+ return 0;
} else if ((vfe_dev->axi_data.src_info[frame_src].active && (frame_id !=
vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev->
axi_data.src_info[frame_src].sof_counter_step)) ||
@@ -3629,19 +3657,18 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
if ((frame_src == VFE_PIX_0) && !stream_info->undelivered_request_cnt &&
MSM_VFE_STREAM_STOP_PERIOD !=
stream_info->activated_framedrop_period) {
+ /* wm is reloaded if undelivered_request_cnt is zero.
+ * As per the hw behavior wm should be disabled or skip writing
+ * before reload happens other wise wm could start writing from
+ * middle of the frame and could result in image corruption.
+ * instead of dropping frame in this error scenario use
+ * drop_reconfig flag to process the request in next sof.
+ */
pr_debug("%s:%d vfe %d frame_id %d prev_pattern %x stream_id %x\n",
__func__, __LINE__, vfe_dev->pdev->id, frame_id,
stream_info->activated_framedrop_period,
stream_info->stream_id);
-
- rc = msm_isp_return_empty_buffer(vfe_dev, stream_info,
- user_stream_id, frame_id, buf_index, frame_src);
- if (rc < 0)
- pr_err("%s:%d failed: return_empty_buffer src %d\n",
- __func__, __LINE__, frame_src);
- stream_info->current_framedrop_period =
- MSM_VFE_STREAM_STOP_PERIOD;
- msm_isp_cfg_framedrop_reg(stream_info);
+ vfe_dev->isp_page->drop_reconfig = 1;
return 0;
}
@@ -3712,11 +3739,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
if (rc) {
spin_unlock_irqrestore(&stream_info->lock, flags);
stream_info->undelivered_request_cnt--;
- pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
- __func__, __LINE__);
- queue_req->cmd_used = 0;
- list_del(&queue_req->list);
- stream_info->request_q_cnt--;
+ queue_req = list_first_entry_or_null(
+ &stream_info->request_q,
+ struct msm_vfe_frame_request_queue, list);
+ if (queue_req) {
+ queue_req->cmd_used = 0;
+ list_del(&queue_req->list);
+ stream_info->request_q_cnt--;
+ }
+ pr_err_ratelimited("%s:%d fail to cfg HAL buffer stream %x\n",
+ __func__, __LINE__, stream_info->stream_id);
return rc;
}
@@ -3753,11 +3785,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
stream_info->undelivered_request_cnt--;
spin_unlock_irqrestore(&stream_info->lock,
flags);
+ queue_req = list_first_entry_or_null(
+ &stream_info->request_q,
+ struct msm_vfe_frame_request_queue, list);
+ if (queue_req) {
+ queue_req->cmd_used = 0;
+ list_del(&queue_req->list);
+ stream_info->request_q_cnt--;
+ }
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
__func__, __LINE__);
- queue_req->cmd_used = 0;
- list_del(&queue_req->list);
- stream_info->request_q_cnt--;
return rc;
}
} else {
@@ -4241,6 +4278,8 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
struct timeval *time_stamp;
uint32_t frame_id, buf_index = -1;
int vfe_idx;
+ struct vfe_device *temp_dev;
+ int other_vfe_id;
if (!ts) {
pr_err("%s: Error! Invalid argument\n", __func__);
@@ -4349,7 +4388,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
frame_id_diff = vfe_dev->irq_sof_id - frame_id;
if (stream_info->controllable_output && frame_id_diff > 1) {
+ pr_err_ratelimited("%s: scheduling problem do recovery irq_sof_id %d frame_id %d\n",
+ __func__, vfe_dev->irq_sof_id, frame_id);
/* scheduling problem need to do recovery */
+ stream_info->buf[pingpong_bit] = done_buf;
spin_unlock_irqrestore(&stream_info->lock, flags);
msm_isp_halt_send_error(vfe_dev,
ISP_EVENT_PING_PONG_MISMATCH);
@@ -4363,6 +4405,17 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
stream_info->bufq_handle[
VFE_BUF_QUEUE_DEFAULT] & 0xFF]++;
vfe_dev->error_info.framedrop_flag = 1;
+ if (vfe_dev->is_split) {
+ other_vfe_id = OTHER_VFE(vfe_dev->pdev->id);
+ temp_dev =
+ vfe_dev->common_data->dual_vfe_res->vfe_dev[
+ other_vfe_id];
+ temp_dev->error_info.stream_framedrop_count[
+ stream_info->bufq_handle[
+ VFE_BUF_QUEUE_DEFAULT] & 0xFF]++;
+ temp_dev->error_info.framedrop_flag = 1;
+ }
+
}
spin_unlock_irqrestore(&stream_info->lock, flags);
return;
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index d27f56a9ad65..7e4d9dfb6612 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1522,6 +1522,46 @@ long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
return rc;
}
+static void msm_jpeg_iommu_fault_handler (struct iommu_domain *domain,
+ struct device *dev, unsigned long iova, int flags, void *token)
+{
+ struct msm_jpeg_device *pgmn_dev;
+
+ if (token) {
+ pgmn_dev = token;
+ JPEG_PR_ERR("%s: core type %d addr 0x%lx\n",
+ __func__, pgmn_dev->core_type, iova);
+ JPEG_PR_ERR("%s: FE ion_fd %d y_addr 0x%x y_len %d\n",
+ __func__,
+ pgmn_dev->fe_pingpong_buf.buf[1].ion_fd,
+ pgmn_dev->fe_pingpong_buf.buf[1].y_buffer_addr,
+ pgmn_dev->fe_pingpong_buf.buf[1].y_len);
+ JPEG_PR_ERR("%s: FE cbcr_addr %x cbcr_len %d\n",
+ __func__,
+ pgmn_dev->fe_pingpong_buf.buf[1].cbcr_buffer_addr,
+ pgmn_dev->fe_pingpong_buf.buf[1].cbcr_len);
+ JPEG_PR_ERR("%s: FE pln2_addr %x pln2_len %d frame_len %d\n",
+ __func__,
+ pgmn_dev->fe_pingpong_buf.buf[1].pln2_addr,
+ pgmn_dev->fe_pingpong_buf.buf[1].pln2_len,
+ pgmn_dev->fe_pingpong_buf.buf[1].framedone_len);
+ JPEG_PR_ERR("%s: WE ion_fd %d y_addr 0x%x y_len %d\n",
+ __func__,
+ pgmn_dev->we_pingpong_buf.buf[0].ion_fd,
+ pgmn_dev->we_pingpong_buf.buf[0].y_buffer_addr,
+ pgmn_dev->we_pingpong_buf.buf[0].y_len);
+ JPEG_PR_ERR("%s: WE cbcr_addr %x cbcr_len %d\n",
+ __func__,
+ pgmn_dev->we_pingpong_buf.buf[0].cbcr_buffer_addr,
+ pgmn_dev->we_pingpong_buf.buf[0].cbcr_len);
+ JPEG_PR_ERR("%s: WE pln2_addr %x pln2_len %d frame_len %d\n",
+ __func__,
+ pgmn_dev->we_pingpong_buf.buf[0].pln2_addr,
+ pgmn_dev->we_pingpong_buf.buf[0].pln2_len,
+ pgmn_dev->we_pingpong_buf.buf[0].framedone_len);
+ }
+}
+
int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
{
int rc = 0;
@@ -1555,6 +1595,12 @@ int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
goto err_smmu;
}
+ cam_smmu_reg_client_page_fault_handler(
+ pgmn_dev->iommu_hdl,
+ msm_jpeg_iommu_fault_handler,
+ NULL,
+ pgmn_dev);
+
/* setup all the resources for the jpeg driver */
rc = msm_jpeg_platform_setup(pgmn_dev);
if (rc < 0) {
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 6339555bdf76..69155d60abb8 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1461,8 +1461,9 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
VBIF_CLIENT_CPP, cpp_vbif_error_handler);
if (cpp_dev->cpp_open_cnt == 1) {
- rc = cpp_init_hardware(cpp_dev);
+ rc = cpp_init_mem(cpp_dev);
if (rc < 0) {
+ pr_err("Error: init memory fail\n");
cpp_dev->cpp_open_cnt--;
cpp_dev->cpp_subscribe_list[i].active = 0;
cpp_dev->cpp_subscribe_list[i].vfh = NULL;
@@ -1470,16 +1471,14 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return rc;
}
- rc = cpp_init_mem(cpp_dev);
+ rc = cpp_init_hardware(cpp_dev);
if (rc < 0) {
- pr_err("Error: init memory fail\n");
cpp_dev->cpp_open_cnt--;
cpp_dev->cpp_subscribe_list[i].active = 0;
cpp_dev->cpp_subscribe_list[i].vfh = NULL;
mutex_unlock(&cpp_dev->mutex);
return rc;
}
-
cpp_dev->state = CPP_STATE_IDLE;
CPP_DBG("Invoking msm_ion_client_create()\n");
@@ -1499,6 +1498,8 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
uint32_t i;
int rc = -1;
+ int counter = 0;
+ u32 result = 0;
struct cpp_device *cpp_dev = NULL;
struct msm_device_queue *processing_q = NULL;
struct msm_device_queue *eventData_q = NULL;
@@ -1579,6 +1580,61 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x88));
pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C));
+
+ /* Update bandwidth usage to enable AXI/ABH clock,
+ * which will help to reset CPP AXI.Bandwidth will be
+ * made zero at cpp_release_hardware.
+ */
+ msm_cpp_update_bandwidth(cpp_dev, 0x1000, 0x1000);
+
+ /* mask IRQ status */
+ msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC);
+
+ /* clear IRQ status */
+ msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14);
+
+ /* MMSS_A_CPP_AXI_CMD = 0x16C, reset 0x1*/
+ msm_camera_io_w(0x1, cpp_dev->cpp_hw_base + 0x16C);
+
+ while (counter < MSM_CPP_POLL_RETRIES) {
+ result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
+ if (result & 0x2)
+ break;
+ /*
+ * Below usleep values are chosen based on experiments
+ * and this was the smallest number which works. This
+ * sleep is needed to leave enough time for hardware
+ * to update status register.
+ */
+ usleep_range(200, 250);
+ counter++;
+ }
+
+ pr_debug("CPP AXI done counter %d result 0x%x\n",
+ counter, result);
+
+ /* clear IRQ status */
+ msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14);
+ counter = 0;
+ /* MMSS_A_CPP_RST_CMD_0 = 0x8, firmware reset = 0x3DF77 */
+ msm_camera_io_w(0x3DF77, cpp_dev->cpp_hw_base + 0x8);
+
+ while (counter < MSM_CPP_POLL_RETRIES) {
+ result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
+ if (result & 0x1)
+ break;
+ /*
+ * Below usleep values are chosen based on experiments
+ * and this was the smallest number which works. This
+ * sleep is needed to leave enough time for hardware
+ * to update status register.
+ */
+ usleep_range(200, 250);
+ counter++;
+ }
+ pr_debug("CPP reset done counter %d result 0x%x\n",
+ counter, result);
+
msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
msm_cpp_clear_timer(cpp_dev);
cpp_release_hardware(cpp_dev);
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 00520dbbf70a..e3e4c97a5220 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -99,12 +99,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
return MSM_VIDC_BIT_DEPTH_UNSUPPORTED;
}
+static inline int validate_pkt_size(u32 rem_size, u32 msg_size)
+{
+ if (rem_size < msg_size) {
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, rem_size);
+ return false;
+ }
+ return true;
+}
+
static int hfi_process_sess_evt_seq_changed(u32 device_id,
struct hfi_msg_event_notify_packet *pkt,
struct msm_vidc_cb_info *info)
{
struct msm_vidc_cb_event event_notify = {0};
- int num_properties_changed;
+ u32 num_properties_changed, rem_size;
struct hfi_frame_size *frame_sz;
struct hfi_profile_level *profile_level;
struct hfi_bit_depth *pixel_depth;
@@ -114,11 +124,9 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
struct hfi_colour_space *colour_info;
- if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) {
- dprintk(VIDC_ERR,
- "hal_process_session_init_done: bad_pkt_size\n");
+ if (!validate_pkt_size(pkt->size,
+ sizeof(struct hfi_msg_event_notify_packet)))
return -E2BIG;
- }
event_notify.device_id = device_id;
event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -139,10 +147,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
if (num_properties_changed) {
data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
+ rem_size = pkt->size - sizeof(struct
+ hfi_msg_event_notify_packet) + sizeof(u32);
do {
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = (int) *((u32 *)data_ptr);
+ rem_size -= sizeof(u32);
switch (prop_id) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_frame_size)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
frame_sz =
(struct hfi_frame_size *) data_ptr;
@@ -152,8 +168,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
frame_sz->height, frame_sz->width);
data_ptr +=
sizeof(struct hfi_frame_size);
+ rem_size -= sizeof(struct hfi_frame_size);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_profile_level)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
profile_level =
(struct hfi_profile_level *) data_ptr;
@@ -162,8 +182,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
profile_level->level);
data_ptr +=
sizeof(struct hfi_profile_level);
+ rem_size -= sizeof(struct hfi_profile_level);
break;
case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_bit_depth)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pixel_depth = (struct hfi_bit_depth *) data_ptr;
/*
@@ -194,8 +218,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
event_notify.bit_depth, luma_bit_depth,
chroma_bit_depth);
data_ptr += sizeof(struct hfi_bit_depth);
+ rem_size -= sizeof(struct hfi_bit_depth);
break;
case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_pic_struct)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pic_struct = (struct hfi_pic_struct *) data_ptr;
event_notify.pic_struct =
@@ -205,8 +233,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
pic_struct->progressive_only);
data_ptr +=
sizeof(struct hfi_pic_struct);
+ rem_size -= sizeof(struct hfi_pic_struct);
break;
case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_colour_space)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
colour_info =
(struct hfi_colour_space *) data_ptr;
@@ -217,6 +249,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
colour_info->colour_space);
data_ptr +=
sizeof(struct hfi_colour_space);
+ rem_size -= sizeof(struct hfi_colour_space);
break;
default:
dprintk(VIDC_ERR,
@@ -574,7 +607,7 @@ static inline void copy_cap_prop(
}
static int hfi_fill_codec_info(u8 *data_ptr,
- struct vidc_hal_sys_init_done *sys_init_done) {
+ struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) {
u32 i;
u32 codecs = 0, codec_count = 0, size = 0;
struct msm_vidc_capability *capability;
@@ -584,6 +617,9 @@ static int hfi_fill_codec_info(u8 *data_ptr,
if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
struct hfi_codec_supported *prop;
+ if (!validate_pkt_size(rem_size - sizeof(u32),
+ sizeof(struct hfi_codec_supported)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
prop = (struct hfi_codec_supported *) data_ptr;
sys_init_done->dec_codec_supported =
@@ -591,6 +627,8 @@ static int hfi_fill_codec_info(u8 *data_ptr,
sys_init_done->enc_codec_supported =
prop->encoder_codec_supported;
size = sizeof(struct hfi_codec_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_codec_supported) + sizeof(u32);
} else {
dprintk(VIDC_WARN,
"%s: prop_id %#x, expected codec_supported property\n",
@@ -631,14 +669,22 @@ static int hfi_fill_codec_info(u8 *data_ptr,
}
sys_init_done->codec_count = codec_count;
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = *((u32 *)(orig_data_ptr + size));
if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
- struct hfi_max_sessions_supported *prop =
- (struct hfi_max_sessions_supported *)
+ struct hfi_max_sessions_supported *prop;
+
+ if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct
+ hfi_max_sessions_supported)))
+ return -E2BIG;
+ prop = (struct hfi_max_sessions_supported *)
(orig_data_ptr + size + sizeof(u32));
sys_init_done->max_sessions_supported = prop->max_sessions;
size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
dprintk(VIDC_DBG, "max_sessions_supported %d\n",
prop->max_sessions);
}
@@ -794,6 +840,21 @@ static enum vidc_status hfi_parse_init_done_properties(
enum vidc_status status = VIDC_ERR_NONE;
u32 prop_id, next_offset;
+#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\
+ if (pkt_size < property_size) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
+
+#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \
+ property_count) ({\
+ if (pkt_size/payload_size < property_count) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
+
while (status == VIDC_ERR_NONE && num_properties &&
rem_bytes >= sizeof(u32)) {
@@ -807,6 +868,10 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_codec_mask_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
codecs = prop->codecs;
domain = prop->video_domains;
next_offset += sizeof(struct hfi_codec_mask_supported);
@@ -819,11 +884,14 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_capability_supported_info *)
(data_ptr + next_offset);
- if ((rem_bytes - next_offset) < prop->num_capabilities *
- sizeof(struct hfi_capability_supported)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(u32),
+ sizeof(struct hfi_capability_supported),
+ prop->num_capabilities);
+
next_offset += sizeof(u32) +
prop->num_capabilities *
sizeof(struct hfi_capability_supported);
@@ -844,10 +912,10 @@ static enum vidc_status hfi_parse_init_done_properties(
char *fmt_ptr;
struct hfi_uncompressed_plane_info *plane_info;
- if ((rem_bytes - next_offset) < sizeof(*prop)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
num_format_entries = prop->format_entries;
next_offset = sizeof(*prop);
fmt_ptr = (char *)&prop->rg_format_info[0];
@@ -857,11 +925,10 @@ static enum vidc_status hfi_parse_init_done_properties(
plane_info =
(struct hfi_uncompressed_plane_info *) fmt_ptr;
- if ((rem_bytes - next_offset) <
- sizeof(*plane_info)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*plane_info));
+
bytes_to_skip = sizeof(*plane_info) -
sizeof(struct
hfi_uncompressed_plane_constraints) +
@@ -869,6 +936,10 @@ static enum vidc_status hfi_parse_init_done_properties(
sizeof(struct
hfi_uncompressed_plane_constraints);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ bytes_to_skip);
+
fmt_ptr += bytes_to_skip;
next_offset += bytes_to_skip;
num_format_entries--;
@@ -881,6 +952,15 @@ static enum vidc_status hfi_parse_init_done_properties(
struct hfi_properties_supported *prop =
(struct hfi_properties_supported *)
(data_ptr + next_offset);
+
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(*prop) +
+ sizeof(u32), sizeof(u32),
+ prop->num_properties);
+
next_offset += sizeof(*prop) - sizeof(u32)
+ prop->num_properties * sizeof(u32);
num_properties--;
@@ -897,8 +977,19 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_profile_level_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
ptr = (char *) &prop->rg_profile_level[0];
prof_count = prop->profile_count;
+
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset -
+ sizeof(u32),
+ sizeof(struct hfi_profile_level),
+ prop->profile_count);
+
next_offset += sizeof(u32);
if (prof_count > MAX_PROFILE_COUNT) {
@@ -925,6 +1016,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_interlace_format_supported));
next_offset +=
sizeof(struct hfi_interlace_format_supported);
num_properties--;
@@ -932,6 +1026,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_nal_stream_format_supported));
next_offset +=
sizeof(struct hfi_nal_stream_format_supported);
num_properties--;
@@ -939,18 +1036,27 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_intra_refresh));
next_offset +=
sizeof(struct hfi_intra_refresh);
num_properties--;
@@ -962,15 +1068,25 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_buffer_alloc_mode_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ next_offset +=
+ sizeof(struct hfi_buffer_alloc_mode_supported);
if (prop->num_entries >= 32) {
dprintk(VIDC_ERR,
"%s - num_entries: %d from f/w seems suspect\n",
__func__, prop->num_entries);
break;
}
+
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset +
+ sizeof(u32),
+ sizeof(u32),
+ prop->num_entries);
next_offset +=
- sizeof(struct hfi_buffer_alloc_mode_supported) -
- sizeof(u32) + prop->num_entries * sizeof(u32);
+ prop->num_entries * sizeof(u32) - sizeof(u32);
copy_alloc_mode_to_sessions(prop,
capabilities, num_sessions,
@@ -985,8 +1101,13 @@ static enum vidc_status hfi_parse_init_done_properties(
__func__, data_ptr, prop_id);
break;
}
- rem_bytes -= next_offset;
- data_ptr += next_offset;
+
+ if (rem_bytes > next_offset) {
+ rem_bytes -= next_offset;
+ data_ptr += next_offset;
+ } else {
+ rem_bytes = 0;
+ }
}
return status;
@@ -997,7 +1118,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
struct vidc_hal_sys_init_done *sys_init_done)
{
enum vidc_status status = VIDC_ERR_NONE;
- u32 rem_bytes, bytes_read, num_properties;
+ int bytes_read;
+ u32 rem_bytes, num_properties;
u8 *data_ptr;
u32 codecs = 0, domain = 0;
@@ -1006,6 +1128,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"hfi_msg_sys_init_done: Invalid input\n");
return VIDC_ERR_FAIL;
}
+ if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) {
+ dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n",
+ __func__, pkt->size);
+ return VIDC_ERR_FAIL;
+ }
rem_bytes = pkt->size - sizeof(struct
hfi_msg_sys_init_done_packet) + sizeof(u32);
@@ -1033,7 +1160,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"Venus didn't set any properties in SYS_INIT_DONE");
return status;
}
- bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
+ bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes);
+ if (bytes_read < 0)
+ return VIDC_ERR_FAIL;
data_ptr += bytes_read;
rem_bytes -= bytes_read;
num_properties--;
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index fe51e9709210..1093d8ad232b 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -129,12 +129,12 @@ static inline u32 usbtll_read(void __iomem *base, u32 reg)
return readl_relaxed(base + reg);
}
-static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
+static inline void usbtll_writeb(void __iomem *base, u32 reg, u8 val)
{
writeb_relaxed(val, base + reg);
}
-static inline u8 usbtll_readb(void __iomem *base, u8 reg)
+static inline u8 usbtll_readb(void __iomem *base, u32 reg)
{
return readb_relaxed(base + reg);
}
diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c
index f866a4baecb5..b9da2c6cc981 100644
--- a/drivers/misc/vmw_vmci/vmci_context.c
+++ b/drivers/misc/vmw_vmci/vmci_context.c
@@ -28,6 +28,9 @@
#include "vmci_driver.h"
#include "vmci_event.h"
+/* Use a wide upper bound for the maximum contexts. */
+#define VMCI_MAX_CONTEXTS 2000
+
/*
* List of current VMCI contexts. Contexts can be added by
* vmci_ctx_create() and removed via vmci_ctx_destroy().
@@ -124,19 +127,22 @@ struct vmci_ctx *vmci_ctx_create(u32 cid, u32 priv_flags,
/* Initialize host-specific VMCI context. */
init_waitqueue_head(&context->host_context.wait_queue);
- context->queue_pair_array = vmci_handle_arr_create(0);
+ context->queue_pair_array =
+ vmci_handle_arr_create(0, VMCI_MAX_GUEST_QP_COUNT);
if (!context->queue_pair_array) {
error = -ENOMEM;
goto err_free_ctx;
}
- context->doorbell_array = vmci_handle_arr_create(0);
+ context->doorbell_array =
+ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
if (!context->doorbell_array) {
error = -ENOMEM;
goto err_free_qp_array;
}
- context->pending_doorbell_array = vmci_handle_arr_create(0);
+ context->pending_doorbell_array =
+ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
if (!context->pending_doorbell_array) {
error = -ENOMEM;
goto err_free_db_array;
@@ -211,7 +217,7 @@ static int ctx_fire_notification(u32 context_id, u32 priv_flags)
* We create an array to hold the subscribers we find when
* scanning through all contexts.
*/
- subscriber_array = vmci_handle_arr_create(0);
+ subscriber_array = vmci_handle_arr_create(0, VMCI_MAX_CONTEXTS);
if (subscriber_array == NULL)
return VMCI_ERROR_NO_MEM;
@@ -630,20 +636,26 @@ int vmci_ctx_add_notification(u32 context_id, u32 remote_cid)
spin_lock(&context->lock);
- list_for_each_entry(n, &context->notifier_list, node) {
- if (vmci_handle_is_equal(n->handle, notifier->handle)) {
- exists = true;
- break;
+ if (context->n_notifiers < VMCI_MAX_CONTEXTS) {
+ list_for_each_entry(n, &context->notifier_list, node) {
+ if (vmci_handle_is_equal(n->handle, notifier->handle)) {
+ exists = true;
+ break;
+ }
}
- }
- if (exists) {
- kfree(notifier);
- result = VMCI_ERROR_ALREADY_EXISTS;
+ if (exists) {
+ kfree(notifier);
+ result = VMCI_ERROR_ALREADY_EXISTS;
+ } else {
+ list_add_tail_rcu(&notifier->node,
+ &context->notifier_list);
+ context->n_notifiers++;
+ result = VMCI_SUCCESS;
+ }
} else {
- list_add_tail_rcu(&notifier->node, &context->notifier_list);
- context->n_notifiers++;
- result = VMCI_SUCCESS;
+ kfree(notifier);
+ result = VMCI_ERROR_NO_MEM;
}
spin_unlock(&context->lock);
@@ -728,8 +740,7 @@ static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context,
u32 *buf_size, void **pbuf)
{
struct dbell_cpt_state *dbells;
- size_t n_doorbells;
- int i;
+ u32 i, n_doorbells;
n_doorbells = vmci_handle_arr_get_size(context->doorbell_array);
if (n_doorbells > 0) {
@@ -867,7 +878,8 @@ int vmci_ctx_rcv_notifications_get(u32 context_id,
spin_lock(&context->lock);
*db_handle_array = context->pending_doorbell_array;
- context->pending_doorbell_array = vmci_handle_arr_create(0);
+ context->pending_doorbell_array =
+ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
if (!context->pending_doorbell_array) {
context->pending_doorbell_array = *db_handle_array;
*db_handle_array = NULL;
@@ -949,12 +961,11 @@ int vmci_ctx_dbell_create(u32 context_id, struct vmci_handle handle)
return VMCI_ERROR_NOT_FOUND;
spin_lock(&context->lock);
- if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) {
- vmci_handle_arr_append_entry(&context->doorbell_array, handle);
- result = VMCI_SUCCESS;
- } else {
+ if (!vmci_handle_arr_has_entry(context->doorbell_array, handle))
+ result = vmci_handle_arr_append_entry(&context->doorbell_array,
+ handle);
+ else
result = VMCI_ERROR_DUPLICATE_ENTRY;
- }
spin_unlock(&context->lock);
vmci_ctx_put(context);
@@ -1090,15 +1101,16 @@ int vmci_ctx_notify_dbell(u32 src_cid,
if (!vmci_handle_arr_has_entry(
dst_context->pending_doorbell_array,
handle)) {
- vmci_handle_arr_append_entry(
+ result = vmci_handle_arr_append_entry(
&dst_context->pending_doorbell_array,
handle);
-
- ctx_signal_notify(dst_context);
- wake_up(&dst_context->host_context.wait_queue);
-
+ if (result == VMCI_SUCCESS) {
+ ctx_signal_notify(dst_context);
+ wake_up(&dst_context->host_context.wait_queue);
+ }
+ } else {
+ result = VMCI_SUCCESS;
}
- result = VMCI_SUCCESS;
}
spin_unlock(&dst_context->lock);
}
@@ -1125,13 +1137,11 @@ int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle)
if (context == NULL || vmci_handle_is_invalid(handle))
return VMCI_ERROR_INVALID_ARGS;
- if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) {
- vmci_handle_arr_append_entry(&context->queue_pair_array,
- handle);
- result = VMCI_SUCCESS;
- } else {
+ if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle))
+ result = vmci_handle_arr_append_entry(
+ &context->queue_pair_array, handle);
+ else
result = VMCI_ERROR_DUPLICATE_ENTRY;
- }
return result;
}
diff --git a/drivers/misc/vmw_vmci/vmci_handle_array.c b/drivers/misc/vmw_vmci/vmci_handle_array.c
index 344973a0fb0a..917e18a8af95 100644
--- a/drivers/misc/vmw_vmci/vmci_handle_array.c
+++ b/drivers/misc/vmw_vmci/vmci_handle_array.c
@@ -16,24 +16,29 @@
#include <linux/slab.h>
#include "vmci_handle_array.h"
-static size_t handle_arr_calc_size(size_t capacity)
+static size_t handle_arr_calc_size(u32 capacity)
{
- return sizeof(struct vmci_handle_arr) +
+ return VMCI_HANDLE_ARRAY_HEADER_SIZE +
capacity * sizeof(struct vmci_handle);
}
-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity)
+struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity)
{
struct vmci_handle_arr *array;
+ if (max_capacity == 0 || capacity > max_capacity)
+ return NULL;
+
if (capacity == 0)
- capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE;
+ capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY,
+ max_capacity);
array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC);
if (!array)
return NULL;
array->capacity = capacity;
+ array->max_capacity = max_capacity;
array->size = 0;
return array;
@@ -44,27 +49,34 @@ void vmci_handle_arr_destroy(struct vmci_handle_arr *array)
kfree(array);
}
-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
- struct vmci_handle handle)
+int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
+ struct vmci_handle handle)
{
struct vmci_handle_arr *array = *array_ptr;
if (unlikely(array->size >= array->capacity)) {
/* reallocate. */
struct vmci_handle_arr *new_array;
- size_t new_capacity = array->capacity * VMCI_ARR_CAP_MULT;
- size_t new_size = handle_arr_calc_size(new_capacity);
+ u32 capacity_bump = min(array->max_capacity - array->capacity,
+ array->capacity);
+ size_t new_size = handle_arr_calc_size(array->capacity +
+ capacity_bump);
+
+ if (array->size >= array->max_capacity)
+ return VMCI_ERROR_NO_MEM;
new_array = krealloc(array, new_size, GFP_ATOMIC);
if (!new_array)
- return;
+ return VMCI_ERROR_NO_MEM;
- new_array->capacity = new_capacity;
+ new_array->capacity += capacity_bump;
*array_ptr = array = new_array;
}
array->entries[array->size] = handle;
array->size++;
+
+ return VMCI_SUCCESS;
}
/*
@@ -74,7 +86,7 @@ struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array,
struct vmci_handle entry_handle)
{
struct vmci_handle handle = VMCI_INVALID_HANDLE;
- size_t i;
+ u32 i;
for (i = 0; i < array->size; i++) {
if (vmci_handle_is_equal(array->entries[i], entry_handle)) {
@@ -109,7 +121,7 @@ struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array)
* Handle at given index, VMCI_INVALID_HANDLE if invalid index.
*/
struct vmci_handle
-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index)
+vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index)
{
if (unlikely(index >= array->size))
return VMCI_INVALID_HANDLE;
@@ -120,7 +132,7 @@ vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index)
bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array,
struct vmci_handle entry_handle)
{
- size_t i;
+ u32 i;
for (i = 0; i < array->size; i++)
if (vmci_handle_is_equal(array->entries[i], entry_handle))
diff --git a/drivers/misc/vmw_vmci/vmci_handle_array.h b/drivers/misc/vmw_vmci/vmci_handle_array.h
index b5f3a7f98cf1..0fc58597820e 100644
--- a/drivers/misc/vmw_vmci/vmci_handle_array.h
+++ b/drivers/misc/vmw_vmci/vmci_handle_array.h
@@ -17,32 +17,41 @@
#define _VMCI_HANDLE_ARRAY_H_
#include <linux/vmw_vmci_defs.h>
+#include <linux/limits.h>
#include <linux/types.h>
-#define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4
-#define VMCI_ARR_CAP_MULT 2 /* Array capacity multiplier */
-
struct vmci_handle_arr {
- size_t capacity;
- size_t size;
+ u32 capacity;
+ u32 max_capacity;
+ u32 size;
+ u32 pad;
struct vmci_handle entries[];
};
-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity);
+#define VMCI_HANDLE_ARRAY_HEADER_SIZE \
+ offsetof(struct vmci_handle_arr, entries)
+/* Select a default capacity that results in a 64 byte sized array */
+#define VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY 6
+/* Make sure that the max array size can be expressed by a u32 */
+#define VMCI_HANDLE_ARRAY_MAX_CAPACITY \
+ ((U32_MAX - VMCI_HANDLE_ARRAY_HEADER_SIZE - 1) / \
+ sizeof(struct vmci_handle))
+
+struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity);
void vmci_handle_arr_destroy(struct vmci_handle_arr *array);
-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
- struct vmci_handle handle);
+int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
+ struct vmci_handle handle);
struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array,
struct vmci_handle
entry_handle);
struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array);
struct vmci_handle
-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index);
+vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index);
bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array,
struct vmci_handle entry_handle);
struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array);
-static inline size_t vmci_handle_arr_get_size(
+static inline u32 vmci_handle_arr_get_size(
const struct vmci_handle_arr *array)
{
return array->size;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fde7f5efc47d..0397afccf3a2 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4164,13 +4164,13 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->features |= NETIF_F_NETNS_LOCAL;
bond_dev->hw_features = BOND_VLAN_FEATURES |
- NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
bond_dev->features |= bond_dev->hw_features;
+ bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX;
}
/* Destroy a bonding device.
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 47f43bdecd51..baef09b9449f 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -171,7 +171,7 @@
#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
-#define FLEXCAN_TIMEOUT_US (50)
+#define FLEXCAN_TIMEOUT_US (250)
/* FLEXCAN hardware feature flags
*
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
index e6b3862230b9..618ec96b5adb 100644
--- a/drivers/net/can/spi/Kconfig
+++ b/drivers/net/can/spi/Kconfig
@@ -2,10 +2,11 @@ menu "CAN SPI interfaces"
depends on SPI
config CAN_MCP251X
- tristate "Microchip MCP251x SPI CAN controllers"
+ tristate "Microchip MCP251x and MCP25625 SPI CAN controllers"
depends on HAS_DMA
---help---
- Driver for the Microchip MCP251x SPI CAN controllers.
+ Driver for the Microchip MCP251x and MCP25625 SPI CAN
+ controllers.
config CAN_RH850
tristate "Renesas RH850 SPI CAN controller"
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 575790e8a75a..3bcbfcf0455a 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -1,5 +1,5 @@
/*
- * CAN bus driver for Microchip 251x CAN Controller with SPI Interface
+ * CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
*
* MCP2510 support and bug fixes by Christian Pellegrin
* <chripell@evolware.org>
@@ -41,7 +41,7 @@
* static struct spi_board_info spi_board_info[] = {
* {
* .modalias = "mcp2510",
- * // or "mcp2515" depending on your controller
+ * // "mcp2515" or "mcp25625" depending on your controller
* .platform_data = &mcp251x_info,
* .irq = IRQ_EINT13,
* .max_speed_hz = 2*1000*1000,
@@ -238,6 +238,7 @@ static const struct can_bittiming_const mcp251x_bittiming_const = {
enum mcp251x_model {
CAN_MCP251X_MCP2510 = 0x2510,
CAN_MCP251X_MCP2515 = 0x2515,
+ CAN_MCP251X_MCP25625 = 0x25625,
};
struct mcp251x_priv {
@@ -280,7 +281,6 @@ static inline int mcp251x_is_##_model(struct spi_device *spi) \
}
MCP251X_IS(2510);
-MCP251X_IS(2515);
static void mcp251x_clean(struct net_device *net)
{
@@ -640,7 +640,7 @@ static int mcp251x_hw_reset(struct spi_device *spi)
/* Wait for oscillator startup timer after reset */
mdelay(MCP251X_OST_DELAY_MS);
-
+
reg = mcp251x_read_reg(spi, CANSTAT);
if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
return -ENODEV;
@@ -821,9 +821,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
/* receive buffer 0 */
if (intf & CANINTF_RX0IF) {
mcp251x_hw_rx(spi, 0);
- /*
- * Free one buffer ASAP
- * (The MCP2515 does this automatically.)
+ /* Free one buffer ASAP
+ * (The MCP2515/25625 does this automatically.)
*/
if (mcp251x_is_2510(spi))
mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
@@ -832,7 +831,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
/* receive buffer 1 */
if (intf & CANINTF_RX1IF) {
mcp251x_hw_rx(spi, 1);
- /* the MCP2515 does this automatically */
+ /* The MCP2515/25625 does this automatically. */
if (mcp251x_is_2510(spi))
clear_intf |= CANINTF_RX1IF;
}
@@ -1006,6 +1005,10 @@ static const struct of_device_id mcp251x_of_match[] = {
.compatible = "microchip,mcp2515",
.data = (void *)CAN_MCP251X_MCP2515,
},
+ {
+ .compatible = "microchip,mcp25625",
+ .data = (void *)CAN_MCP251X_MCP25625,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, mcp251x_of_match);
@@ -1019,6 +1022,10 @@ static const struct spi_device_id mcp251x_id_table[] = {
.name = "mcp2515",
.driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
},
+ {
+ .name = "mcp25625",
+ .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP25625,
+ },
{ }
};
MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
@@ -1254,5 +1261,5 @@ module_spi_driver(mcp251x_can_driver);
MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
"Christian Pellegrin <chripell@evolware.org>");
-MODULE_DESCRIPTION("Microchip 251x CAN driver");
+MODULE_DESCRIPTION("Microchip 251x/25625 CAN driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index c56b61dce2d1..f4e83c86d643 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1559,7 +1559,8 @@ static int bnx2x_get_module_info(struct net_device *dev,
}
if (!sff8472_comp ||
- (diag_type & SFP_EEPROM_DIAG_ADDR_CHANGE_REQ)) {
+ (diag_type & SFP_EEPROM_DIAG_ADDR_CHANGE_REQ) ||
+ !(diag_type & SFP_EEPROM_DDM_IMPLEMENTED)) {
modinfo->type = ETH_MODULE_SFF_8079;
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
} else {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index b7d251108c19..7115f5025664 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -62,6 +62,7 @@
#define SFP_EEPROM_DIAG_TYPE_ADDR 0x5c
#define SFP_EEPROM_DIAG_TYPE_SIZE 1
#define SFP_EEPROM_DIAG_ADDR_CHANGE_REQ (1<<2)
+#define SFP_EEPROM_DDM_IMPLEMENTED (1<<6)
#define SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e
#define SFP_EEPROM_SFF_8472_COMP_SIZE 1
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 51bfe74be8d4..4e5646b3da09 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -868,7 +868,7 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
u64 *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
- int status;
+ int status, cnt;
u8 link_status = 0;
if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
@@ -879,6 +879,9 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
+ /* check link status before offline tests */
+ link_status = netif_carrier_ok(netdev);
+
if (test->flags & ETH_TEST_FL_OFFLINE) {
if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0)
test->flags |= ETH_TEST_FL_FAILED;
@@ -899,13 +902,26 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
test->flags |= ETH_TEST_FL_FAILED;
}
- status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
- if (status) {
- test->flags |= ETH_TEST_FL_FAILED;
- data[4] = -1;
- } else if (!link_status) {
+ /* link status was down prior to test */
+ if (!link_status) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = 1;
+ return;
+ }
+
+ for (cnt = 10; cnt; cnt--) {
+ status = be_cmd_link_status_query(adapter, NULL, &link_status,
+ 0);
+ if (status) {
+ test->flags |= ETH_TEST_FL_FAILED;
+ data[4] = -1;
+ break;
+ }
+
+ if (link_status)
+ break;
+
+ msleep_interruptible(500);
}
}
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 4b91eb70c683..a2f2db58b5ab 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -351,6 +351,7 @@ static int __lb_setup(struct net_device *ndev,
static int __lb_up(struct net_device *ndev,
enum hnae_loop loop_mode)
{
+#define NIC_LB_TEST_WAIT_PHY_LINK_TIME 300
struct hns_nic_priv *priv = netdev_priv(ndev);
struct hnae_handle *h = priv->ae_handle;
int speed, duplex;
@@ -389,6 +390,9 @@ static int __lb_up(struct net_device *ndev,
h->dev->ops->adjust_link(h, speed, duplex);
+ /* wait adjust link done and phy ready */
+ msleep(NIC_LB_TEST_WAIT_PHY_LINK_TIME);
+
return 0;
}
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 6b1cacd86c6e..7d64edeb1830 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -4171,7 +4171,7 @@ int e1000e_up(struct e1000_adapter *adapter)
e1000_configure_msix(adapter);
e1000_irq_enable(adapter);
- netif_start_queue(adapter->netdev);
+ /* Tx queue started by watchdog timer when link is up */
/* fire a link change interrupt to start the watchdog */
if (adapter->msix_entries)
@@ -4539,6 +4539,7 @@ static int e1000_open(struct net_device *netdev)
pm_runtime_get_sync(&pdev->dev);
netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
/* allocate transmit descriptors */
err = e1000e_setup_tx_resources(adapter->tx_ring);
@@ -4599,7 +4600,6 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
adapter->tx_hang_recheck = false;
- netif_start_queue(netdev);
hw->mac.get_link_status = true;
pm_runtime_put(&pdev->dev);
@@ -5226,6 +5226,7 @@ static void e1000_watchdog_task(struct work_struct *work)
if (phy->ops.cfg_on_link_up)
phy->ops.cfg_on_link_up(hw);
+ netif_wake_queue(netdev);
netif_carrier_on(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -5239,6 +5240,7 @@ static void e1000_watchdog_task(struct work_struct *work)
/* Link status message must follow this format */
pr_info("%s NIC Link is Down\n", adapter->netdev->name);
netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index fd812d2e5e1c..dff5b56738d3 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -1058,7 +1058,7 @@ sis900_open(struct net_device *net_dev)
sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
- sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
sw32(cr, RxENA | sr32(cr));
sw32(ier, IE);
@@ -1581,7 +1581,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
sw32(txdp, sis_priv->tx_ring_dma);
/* Enable all known interrupts by setting the interrupt mask. */
- sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
}
/**
@@ -1621,7 +1621,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
spin_unlock_irqrestore(&sis_priv->lock, flags);
return NETDEV_TX_OK;
}
- sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
+ sis_priv->tx_ring[entry].cmdsts = (OWN | INTR | skb->len);
sw32(cr, TxENA | sr32(cr));
sis_priv->cur_tx ++;
@@ -1677,7 +1677,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
do {
status = sr32(isr);
- if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
+ if ((status & (HIBERR|TxURN|TxERR|TxIDLE|TxDESC|RxORN|RxERR|RxOK)) == 0)
/* nothing intresting happened */
break;
handled = 1;
@@ -1687,7 +1687,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
/* Rx interrupt */
sis900_rx(net_dev);
- if (status & (TxURN | TxERR | TxIDLE))
+ if (status & (TxURN | TxERR | TxIDLE | TxDESC))
/* Tx interrupt */
sis900_finish_xmit(net_dev);
@@ -1899,8 +1899,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
if (tx_status & OWN) {
/* The packet is not transmitted yet (owned by hardware) !
- * Note: the interrupt is generated only when Tx Machine
- * is idle, so this is an almost impossible case */
+ * Note: this is an almost impossible condition
+ * in case of TxDESC ('descriptor interrupt') */
break;
}
@@ -2476,7 +2476,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
- sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
sw32(cr, RxENA | sr32(cr));
sw32(ier, IE);
diff --git a/drivers/net/ppp/ppp_mppe.c b/drivers/net/ppp/ppp_mppe.c
index 05005c660d4d..6376edd89ceb 100644
--- a/drivers/net/ppp/ppp_mppe.c
+++ b/drivers/net/ppp/ppp_mppe.c
@@ -62,6 +62,7 @@ MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_SOFTDEP("pre: arc4");
MODULE_VERSION("1.0.2");
static unsigned int
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 7b3ef6dc45a4..285d376f53ef 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2091,12 +2091,12 @@ static void team_setup(struct net_device *dev)
dev->features |= NETIF_F_NETNS_LOCAL;
dev->hw_features = TEAM_VLAN_FEATURES |
- NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
dev->features |= dev->hw_features;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_TX;
}
static int team_newlink(struct net *src_net, struct net_device *dev,
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 76842e6ca38e..b0f094f2f87f 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -128,6 +128,8 @@ static struct usb_device_id carl9170_usb_ids[] = {
};
MODULE_DEVICE_TABLE(usb, carl9170_usb_ids);
+static struct usb_driver carl9170_driver;
+
static void carl9170_usb_submit_data_urb(struct ar9170 *ar)
{
struct urb *urb;
@@ -968,32 +970,28 @@ err_out:
static void carl9170_usb_firmware_failed(struct ar9170 *ar)
{
- struct device *parent = ar->udev->dev.parent;
- struct usb_device *udev;
-
- /*
- * Store a copy of the usb_device pointer locally.
- * This is because device_release_driver initiates
- * carl9170_usb_disconnect, which in turn frees our
- * driver context (ar).
+ /* Store a copies of the usb_interface and usb_device pointer locally.
+ * This is because release_driver initiates carl9170_usb_disconnect,
+ * which in turn frees our driver context (ar).
*/
- udev = ar->udev;
+ struct usb_interface *intf = ar->intf;
+ struct usb_device *udev = ar->udev;
complete(&ar->fw_load_wait);
+ /* at this point 'ar' could be already freed. Don't use it anymore */
+ ar = NULL;
/* unbind anything failed */
- if (parent)
- device_lock(parent);
-
- device_release_driver(&udev->dev);
- if (parent)
- device_unlock(parent);
+ usb_lock_device(udev);
+ usb_driver_release_interface(&carl9170_driver, intf);
+ usb_unlock_device(udev);
- usb_put_dev(udev);
+ usb_put_intf(intf);
}
static void carl9170_usb_firmware_finish(struct ar9170 *ar)
{
+ struct usb_interface *intf = ar->intf;
int err;
err = carl9170_parse_firmware(ar);
@@ -1011,7 +1009,7 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar)
goto err_unrx;
complete(&ar->fw_load_wait);
- usb_put_dev(ar->udev);
+ usb_put_intf(intf);
return;
err_unrx:
@@ -1054,7 +1052,6 @@ static int carl9170_usb_probe(struct usb_interface *intf,
return PTR_ERR(ar);
udev = interface_to_usbdev(intf);
- usb_get_dev(udev);
ar->udev = udev;
ar->intf = intf;
ar->features = id->driver_info;
@@ -1096,15 +1093,14 @@ static int carl9170_usb_probe(struct usb_interface *intf,
atomic_set(&ar->rx_anch_urbs, 0);
atomic_set(&ar->rx_pool_urbs, 0);
- usb_get_dev(ar->udev);
+ usb_get_intf(intf);
carl9170_set_state(ar, CARL9170_STOPPED);
err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME,
&ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2);
if (err) {
- usb_put_dev(udev);
- usb_put_dev(udev);
+ usb_put_intf(intf);
carl9170_free(ar);
}
return err;
@@ -1133,7 +1129,6 @@ static void carl9170_usb_disconnect(struct usb_interface *intf)
carl9170_release_firmware(ar);
carl9170_free(ar);
- usb_put_dev(udev);
}
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c
index 7cc44634f031..7945f59439f7 100644
--- a/drivers/net/wireless/cnss2/qmi.c
+++ b/drivers/net/wireless/cnss2/qmi.c
@@ -284,7 +284,7 @@ static int cnss_qmi_initiate_cal_update_ind_hdlr(
void *msg, unsigned int msg_len)
{
struct msg_desc ind_desc;
- struct wlfw_initiate_cal_update_ind_msg_v01 ind_msg;
+ struct wlfw_initiate_cal_update_ind_msg_v01 ind_msg = {0};
struct cnss_cal_data *data;
int ret = 0;
@@ -324,7 +324,7 @@ static int cnss_qmi_initiate_cal_download_ind_hdlr(
void *msg, unsigned int msg_len)
{
struct msg_desc ind_desc;
- struct wlfw_initiate_cal_download_ind_msg_v01 ind_msg;
+ struct wlfw_initiate_cal_download_ind_msg_v01 ind_msg = {0};
struct cnss_cal_data *data;
int ret = 0;
diff --git a/drivers/net/wireless/cnss2/usb.c b/drivers/net/wireless/cnss2/usb.c
index 3d3932371b26..c647e0f8e9ba 100644
--- a/drivers/net/wireless/cnss2/usb.c
+++ b/drivers/net/wireless/cnss2/usb.c
@@ -52,6 +52,8 @@ int cnss_usb_dev_powerup(struct cnss_plat_data *plat_priv)
switch (plat_priv->device_id) {
case QCN7605_COMPOSITE_DEVICE_ID:
case QCN7605_STANDALONE_DEVICE_ID:
+ case QCN7605_VER20_STANDALONE_DEVICE_ID:
+ case QCN7605_VER20_COMPOSITE_DEVICE_ID:
ret = cnss_qcn7605_usb_powerup(plat_priv);
break;
default:
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1e1e81a0a8d4..9a5eb9ed8921 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1589,9 +1589,10 @@ struct mwifiex_ie_types_wmm_queue_status {
struct ieee_types_vendor_header {
u8 element_id;
u8 len;
- u8 oui[4]; /* 0~2: oui, 3: oui_type */
- u8 oui_subtype;
- u8 version;
+ struct {
+ u8 oui[3];
+ u8 oui_type;
+ } __packed oui;
} __packed;
struct ieee_types_wmm_parameter {
@@ -1605,6 +1606,9 @@ struct ieee_types_wmm_parameter {
* Version [1]
*/
struct ieee_types_vendor_header vend_hdr;
+ u8 oui_subtype;
+ u8 version;
+
u8 qos_info_bitmap;
u8 reserved;
struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
@@ -1622,6 +1626,8 @@ struct ieee_types_wmm_info {
* Version [1]
*/
struct ieee_types_vendor_header vend_hdr;
+ u8 oui_subtype;
+ u8 version;
u8 qos_info_bitmap;
} __packed;
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index abf52d25b981..de8435709735 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -328,6 +328,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
struct ieee80211_vendor_ie *vendorhdr;
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
int left_len, parsed_len = 0;
+ unsigned int token_len;
+ int err = 0;
if (!info->tail || !info->tail_len)
return 0;
@@ -343,6 +345,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
*/
while (left_len > sizeof(struct ieee_types_header)) {
hdr = (void *)(info->tail + parsed_len);
+ token_len = hdr->len + sizeof(struct ieee_types_header);
+ if (token_len > left_len) {
+ err = -EINVAL;
+ goto out;
+ }
+
switch (hdr->element_id) {
case WLAN_EID_SSID:
case WLAN_EID_SUPP_RATES:
@@ -356,13 +364,16 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
case WLAN_EID_VENDOR_SPECIFIC:
break;
default:
- memcpy(gen_ie->ie_buffer + ie_len, hdr,
- hdr->len + sizeof(struct ieee_types_header));
- ie_len += hdr->len + sizeof(struct ieee_types_header);
+ if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
+ err = -EINVAL;
+ goto out;
+ }
+ memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len);
+ ie_len += token_len;
break;
}
- left_len -= hdr->len + sizeof(struct ieee_types_header);
- parsed_len += hdr->len + sizeof(struct ieee_types_header);
+ left_len -= token_len;
+ parsed_len += token_len;
}
/* parse only WPA vendor IE from tail, WMM IE is configured by
@@ -372,15 +383,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
WLAN_OUI_TYPE_MICROSOFT_WPA,
info->tail, info->tail_len);
if (vendorhdr) {
- memcpy(gen_ie->ie_buffer + ie_len, vendorhdr,
- vendorhdr->len + sizeof(struct ieee_types_header));
- ie_len += vendorhdr->len + sizeof(struct ieee_types_header);
+ token_len = vendorhdr->len + sizeof(struct ieee_types_header);
+ if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
+ err = -EINVAL;
+ goto out;
+ }
+ memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len);
+ ie_len += token_len;
}
- if (!ie_len) {
- kfree(gen_ie);
- return 0;
- }
+ if (!ie_len)
+ goto out;
gen_ie->ie_index = cpu_to_le16(gen_idx);
gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
@@ -390,13 +403,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
NULL, NULL)) {
- kfree(gen_ie);
- return -1;
+ err = -EINVAL;
+ goto out;
}
priv->gen_idx = gen_idx;
+
+ out:
kfree(gen_ie);
- return 0;
+ return err;
}
/* This function parses different IEs-head & tail IEs, beacon IEs,
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index fb98f42cb5e7..673ca812bd4c 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1219,6 +1219,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
}
switch (element_id) {
case WLAN_EID_SSID:
+ if (element_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
bss_entry->ssid.ssid_len = element_len;
memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
element_len);
@@ -1228,6 +1230,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_SUPP_RATES:
+ if (element_len > MWIFIEX_SUPPORTED_RATES)
+ return -EINVAL;
memcpy(bss_entry->data_rates, current_ptr + 2,
element_len);
memcpy(bss_entry->supported_rates, current_ptr + 2,
@@ -1237,6 +1241,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_FH_PARAMS:
+ if (element_len + 2 < sizeof(*fh_param_set))
+ return -EINVAL;
fh_param_set =
(struct ieee_types_fh_param_set *) current_ptr;
memcpy(&bss_entry->phy_param_set.fh_param_set,
@@ -1245,6 +1251,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_DS_PARAMS:
+ if (element_len + 2 < sizeof(*ds_param_set))
+ return -EINVAL;
ds_param_set =
(struct ieee_types_ds_param_set *) current_ptr;
@@ -1256,6 +1264,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_CF_PARAMS:
+ if (element_len + 2 < sizeof(*cf_param_set))
+ return -EINVAL;
cf_param_set =
(struct ieee_types_cf_param_set *) current_ptr;
memcpy(&bss_entry->ss_param_set.cf_param_set,
@@ -1264,6 +1274,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_IBSS_PARAMS:
+ if (element_len + 2 < sizeof(*ibss_param_set))
+ return -EINVAL;
ibss_param_set =
(struct ieee_types_ibss_param_set *)
current_ptr;
@@ -1273,10 +1285,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_ERP_INFO:
+ if (!element_len)
+ return -EINVAL;
bss_entry->erp_flags = *(current_ptr + 2);
break;
case WLAN_EID_PWR_CONSTRAINT:
+ if (!element_len)
+ return -EINVAL;
bss_entry->local_constraint = *(current_ptr + 2);
bss_entry->sensed_11h = true;
break;
@@ -1319,15 +1335,22 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
vendor_ie = (struct ieee_types_vendor_specific *)
current_ptr;
- if (!memcmp
- (vendor_ie->vend_hdr.oui, wpa_oui,
- sizeof(wpa_oui))) {
+ /* 802.11 requires at least 3-byte OUI. */
+ if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui))
+ return -EINVAL;
+
+ /* Not long enough for a match? Skip it. */
+ if (element_len < sizeof(wpa_oui))
+ break;
+
+ if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui,
+ sizeof(wpa_oui))) {
bss_entry->bcn_wpa_ie =
(struct ieee_types_vendor_specific *)
current_ptr;
bss_entry->wpa_offset = (u16)
(current_ptr - bss_entry->beacon_buf);
- } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
+ } else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui,
sizeof(wmm_oui))) {
if (total_ie_len ==
sizeof(struct ieee_types_wmm_parameter) ||
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 6cfa2969b123..12eedb33db7b 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1305,7 +1305,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
/* Test to see if it is a WPA IE, if not, then it is a gen IE */
if (((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
- (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) ||
+ (!memcmp(&pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) ||
(pvendor_ie->element_id == WLAN_EID_RSN)) {
/* IE is a WPA/WPA2 IE so call set_wpa function */
@@ -1330,7 +1330,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
*/
pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
- (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
+ (!memcmp(&pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
priv->wps.session_enable = true;
mwifiex_dbg(priv->adapter, INFO,
"info: WPS Session Enabled.\n");
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index ed8b69d1d65c..7015dfab49cf 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -240,7 +240,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
mwifiex_dbg(priv->adapter, INFO,
"info: WMM Parameter IE: version=%d,\t"
"qos_info Parameter Set Count=%d, Reserved=%#x\n",
- wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap &
+ wmm_ie->version, wmm_ie->qos_info_bitmap &
IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK,
wmm_ie->reserved);
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index 754f21fd9768..f26af0214ab3 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -892,6 +892,7 @@ parport_register_dev_model(struct parport *port, const char *name,
par_dev->devmodel = true;
ret = device_register(&par_dev->dev);
if (ret) {
+ kfree(par_dev->state);
put_device(&par_dev->dev);
goto err_put_port;
}
@@ -909,6 +910,7 @@ parport_register_dev_model(struct parport *port, const char *name,
spin_unlock(&port->physport->pardevice_lock);
pr_debug("%s: cannot grant exclusive access for device %s\n",
port->name, name);
+ kfree(par_dev->state);
device_unregister(&par_dev->dev);
goto err_put_port;
}
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 35286907c636..d0090c5c88e7 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -150,6 +150,7 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
return -ENOMEM;
}
irq_ptr_qs[i] = q;
+ INIT_LIST_HEAD(&q->entry);
}
return 0;
}
@@ -178,6 +179,7 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
q->mask = 1 << (31 - i);
q->nr = i;
q->handler = handler;
+ INIT_LIST_HEAD(&q->entry);
}
static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 30e9fbbff051..debe69adfc70 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -80,7 +80,6 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
mutex_lock(&tiq_list_lock);
list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list);
mutex_unlock(&tiq_list_lock);
- xchg(irq_ptr->dsci, 1 << 7);
}
void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
@@ -88,14 +87,14 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
struct qdio_q *q;
q = irq_ptr->input_qs[0];
- /* if establish triggered an error */
- if (!q || !q->entry.prev || !q->entry.next)
+ if (!q)
return;
mutex_lock(&tiq_list_lock);
list_del_rcu(&q->entry);
mutex_unlock(&tiq_list_lock);
synchronize_rcu();
+ INIT_LIST_HEAD(&q->entry);
}
static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 34d3b7aff513..22045e7d78ac 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -2112,7 +2112,7 @@ static void qeth_bridgeport_an_set_cb(void *priv,
l2entry = (struct qdio_brinfo_entry_l2 *)entry;
code = IPA_ADDR_CHANGE_CODE_MACADDR;
- if (l2entry->addr_lnid.lnid)
+ if (l2entry->addr_lnid.lnid < VLAN_N_VID)
code |= IPA_ADDR_CHANGE_CODE_VLANID;
qeth_bridge_emit_host_event(card, anev_reg_unreg, code,
(struct net_if_token *)&l2entry->nit,
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 910b795fc5eb..e0952882e132 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4562,7 +4562,7 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
curr_sg->reserved[0] = 0;
curr_sg->reserved[1] = 0;
curr_sg->reserved[2] = 0;
- curr_sg->chain_indicator = 0x80;
+ curr_sg->chain_indicator = IOACCEL2_CHAIN;
curr_sg = h->ioaccel2_cmd_sg_list[c->cmdindex];
}
@@ -4579,6 +4579,11 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
curr_sg++;
}
+ /*
+ * Set the last s/g element bit
+ */
+ (curr_sg - 1)->chain_indicator = IOACCEL2_LAST_SG;
+
switch (cmd->sc_data_direction) {
case DMA_TO_DEVICE:
cp->direction &= ~IOACCEL2_DIRECTION_MASK;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 26488e2a7f02..7ffde12d57d4 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -513,6 +513,7 @@ struct ioaccel2_sg_element {
u8 reserved[3];
u8 chain_indicator;
#define IOACCEL2_CHAIN 0x80
+#define IOACCEL2_LAST_SG 0x40
};
/*
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2c1ee272f4f7..433e93f08956 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2380,7 +2380,8 @@ int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
memcpy(&query_res->upiu_res, &lrbp->ucd_rsp_ptr->qr, QUERY_OSF_SIZE);
/* Get the descriptor */
- if (lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) {
+ if (hba->dev_cmd.query.descriptor &&
+ lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) {
u8 *descp = (u8 *)lrbp->ucd_rsp_ptr +
GENERAL_UPIU_REQUEST_SIZE;
u16 resp_len;
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 23081ed8f1e3..3f2a5d6c437b 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -733,6 +733,7 @@ static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
struct pvscsi_adapter *adapter = shost_priv(host);
struct pvscsi_ctx *ctx;
unsigned long flags;
+ unsigned char op;
spin_lock_irqsave(&adapter->hw_lock, flags);
@@ -745,13 +746,14 @@ static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
}
cmd->scsi_done = done;
+ op = cmd->cmnd[0];
dev_dbg(&cmd->device->sdev_gendev,
- "queued cmd %p, ctx %p, op=%x\n", cmd, ctx, cmd->cmnd[0]);
+ "queued cmd %p, ctx %p, op=%x\n", cmd, ctx, op);
spin_unlock_irqrestore(&adapter->hw_lock, flags);
- pvscsi_kick_io(adapter, cmd->cmnd[0]);
+ pvscsi_kick_io(adapter, op);
return 0;
}
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index 7f7cc1527353..0577ae8fd4a4 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -940,6 +940,7 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx)
cmd_data = d_cmd->data;
kfree(d_cmd);
} else {
+ memset(&cmd, 0, sizeof(cmd));
fifo_read(einfo, &cmd, sizeof(cmd));
cmd_data = NULL;
}
@@ -1042,6 +1043,7 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx)
cmd_data)->size;
kfree(cmd_data);
} else {
+ memset(&intent, 0, sizeof(intent));
fifo_read(einfo, &intent,
sizeof(intent));
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 17bfb06a5651..714a4f16cd01 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -196,6 +196,8 @@ enum icnss_driver_event_type {
ICNSS_DRIVER_EVENT_REGISTER_DRIVER,
ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
+ ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
+ ICNSS_DRIVER_EVENT_IDLE_RESTART,
ICNSS_DRIVER_EVENT_MAX,
};
@@ -303,6 +305,7 @@ enum icnss_driver_state {
ICNSS_REJUVENATE,
ICNSS_BLOCK_SHUTDOWN,
ICNSS_PDR,
+ ICNSS_MODEM_CRASHED,
};
struct ce_irq_list {
@@ -636,6 +639,10 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type)
return "UNREGISTER_DRIVER";
case ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN:
return "PD_SERVICE_DOWN";
+ case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
+ return "IDLE_SHUTDOWN";
+ case ICNSS_DRIVER_EVENT_IDLE_RESTART:
+ return "IDLE_RESTART";
case ICNSS_DRIVER_EVENT_MAX:
return "EVENT_MAX";
}
@@ -2303,6 +2310,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv)
icnss_call_driver_shutdown(priv);
clear_bit(ICNSS_PDR, &priv->state);
+ clear_bit(ICNSS_MODEM_CRASHED, &priv->state);
clear_bit(ICNSS_REJUVENATE, &priv->state);
clear_bit(ICNSS_PD_RESTART, &priv->state);
priv->is_ssr = false;
@@ -2494,6 +2502,52 @@ out:
return ret;
}
+static int icnss_driver_event_idle_shutdown(void *data)
+{
+ int ret = 0;
+
+ if (!penv->ops || !penv->ops->idle_shutdown)
+ return 0;
+
+ if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) ||
+ test_bit(ICNSS_PDR, &penv->state) ||
+ test_bit(ICNSS_REJUVENATE, &penv->state)) {
+ icnss_pr_err("SSR/PDR is already in-progress during idle shutdown callback\n");
+ ret = -EBUSY;
+ } else {
+ icnss_pr_dbg("Calling driver idle shutdown, state: 0x%lx\n",
+ penv->state);
+ icnss_block_shutdown(true);
+ ret = penv->ops->idle_shutdown(&penv->pdev->dev);
+ icnss_block_shutdown(false);
+ }
+
+ return ret;
+}
+
+static int icnss_driver_event_idle_restart(void *data)
+{
+ int ret = 0;
+
+ if (!penv->ops || !penv->ops->idle_restart)
+ return 0;
+
+ if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) ||
+ test_bit(ICNSS_PDR, &penv->state) ||
+ test_bit(ICNSS_REJUVENATE, &penv->state)) {
+ icnss_pr_err("SSR/PDR is already in-progress during idle restart callback\n");
+ ret = -EBUSY;
+ } else {
+ icnss_pr_dbg("Calling driver idle restart, state: 0x%lx\n",
+ penv->state);
+ icnss_block_shutdown(true);
+ ret = penv->ops->idle_restart(&penv->pdev->dev);
+ icnss_block_shutdown(false);
+ }
+
+ return ret;
+}
+
static void icnss_driver_event_work(struct work_struct *work)
{
struct icnss_driver_event *event;
@@ -2535,6 +2589,12 @@ static void icnss_driver_event_work(struct work_struct *work)
ret = icnss_driver_event_pd_service_down(penv,
event->data);
break;
+ case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
+ ret = icnss_driver_event_idle_shutdown(event->data);
+ break;
+ case ICNSS_DRIVER_EVENT_IDLE_RESTART:
+ ret = icnss_driver_event_idle_restart(event->data);
+ break;
default:
icnss_pr_err("Invalid Event type: %d", event->type);
kfree(event);
@@ -2641,6 +2701,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
priv->is_ssr = true;
+ if (notif->crashed)
+ set_bit(ICNSS_MODEM_CRASHED, &priv->state);
+
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed &&
test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
if (!wait_for_completion_timeout(&priv->unblock_shutdown,
@@ -3597,6 +3660,48 @@ out:
}
EXPORT_SYMBOL(icnss_trigger_recovery);
+int icnss_idle_shutdown(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+
+ if (!priv) {
+ icnss_pr_err("Invalid drvdata: dev %pK", dev);
+ return -EINVAL;
+ }
+
+ if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) ||
+ test_bit(ICNSS_PDR, &priv->state) ||
+ test_bit(ICNSS_REJUVENATE, &penv->state)) {
+ icnss_pr_err("SSR/PDR is already in-progress during idle shutdown\n");
+ return -EBUSY;
+ }
+
+ return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
+ ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
+}
+EXPORT_SYMBOL(icnss_idle_shutdown);
+
+int icnss_idle_restart(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+
+ if (!priv) {
+ icnss_pr_err("Invalid drvdata: dev %pK", dev);
+ return -EINVAL;
+ }
+
+ if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) ||
+ test_bit(ICNSS_PDR, &priv->state) ||
+ test_bit(ICNSS_REJUVENATE, &penv->state)) {
+ icnss_pr_err("SSR/PDR is already in-progress during idle restart\n");
+ return -EBUSY;
+ }
+
+ return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_RESTART,
+ ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
+}
+EXPORT_SYMBOL(icnss_idle_restart);
+
static int icnss_smmu_init(struct icnss_priv *priv)
{
@@ -4053,6 +4158,10 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
continue;
case ICNSS_PDR:
seq_puts(s, "PDR TRIGGERED");
+ continue;
+ case ICNSS_MODEM_CRASHED:
+ seq_puts(s, "MODEM CRASHED");
+ continue;
}
seq_printf(s, "UNKNOWN-%d", i);
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 3aa9e6e3dac8..4ef54436b9d4 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -392,7 +392,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
if (ret)
spi_master_put(master);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(spi_bitbang_start);
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 9e12b2ce3272..c9e7b8b6e21c 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -49,6 +49,9 @@
#include <linux/cpuset.h>
#include <linux/vmpressure.h>
#include <linux/zcache.h>
+#include <linux/circ_buf.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
#define CREATE_TRACE_POINTS
#include <trace/events/almk.h>
@@ -87,6 +90,153 @@ static unsigned long lowmem_deathpending_timeout;
pr_info(x); \
} while (0)
+
+static DECLARE_WAIT_QUEUE_HEAD(event_wait);
+static DEFINE_SPINLOCK(lmk_event_lock);
+static struct circ_buf event_buffer;
+#define MAX_BUFFERED_EVENTS 8
+#define MAX_TASKNAME 128
+
+struct lmk_event {
+ char taskname[MAX_TASKNAME];
+ pid_t pid;
+ uid_t uid;
+ pid_t group_leader_pid;
+ unsigned long min_flt;
+ unsigned long maj_flt;
+ unsigned long rss_in_pages;
+ short oom_score_adj;
+ short min_score_adj;
+ unsigned long long start_time;
+ struct list_head list;
+};
+
+void handle_lmk_event(struct task_struct *selected, int selected_tasksize,
+ short min_score_adj)
+{
+ int head;
+ int tail;
+ struct lmk_event *events;
+ struct lmk_event *event;
+ int res;
+ char taskname[MAX_TASKNAME];
+
+ res = get_cmdline(selected, taskname, MAX_TASKNAME - 1);
+
+ /* No valid process name means this is definitely not associated with a
+ * userspace activity.
+ */
+
+ if (res <= 0 || res >= MAX_TASKNAME)
+ return;
+
+ taskname[res] = '\0';
+
+ spin_lock(&lmk_event_lock);
+
+ head = event_buffer.head;
+ tail = READ_ONCE(event_buffer.tail);
+
+ /* Do not continue to log if no space remains in the buffer. */
+ if (CIRC_SPACE(head, tail, MAX_BUFFERED_EVENTS) < 1) {
+ spin_unlock(&lmk_event_lock);
+ return;
+ }
+
+ events = (struct lmk_event *) event_buffer.buf;
+ event = &events[head];
+
+ memcpy(event->taskname, taskname, res + 1);
+
+ event->pid = selected->pid;
+ event->uid = from_kuid_munged(current_user_ns(), task_uid(selected));
+ if (selected->group_leader)
+ event->group_leader_pid = selected->group_leader->pid;
+ else
+ event->group_leader_pid = -1;
+ event->min_flt = selected->min_flt;
+ event->maj_flt = selected->maj_flt;
+ event->oom_score_adj = selected->signal->oom_score_adj;
+ event->start_time = nsec_to_clock_t(selected->real_start_time);
+ event->rss_in_pages = selected_tasksize;
+ event->min_score_adj = min_score_adj;
+
+ event_buffer.head = (head + 1) & (MAX_BUFFERED_EVENTS - 1);
+
+ spin_unlock(&lmk_event_lock);
+
+ wake_up_interruptible(&event_wait);
+}
+
+static int lmk_event_show(struct seq_file *s, void *unused)
+{
+ struct lmk_event *events = (struct lmk_event *) event_buffer.buf;
+ int head;
+ int tail;
+ struct lmk_event *event;
+
+ spin_lock(&lmk_event_lock);
+
+ head = event_buffer.head;
+ tail = event_buffer.tail;
+
+ if (head == tail) {
+ spin_unlock(&lmk_event_lock);
+ return -EAGAIN;
+ }
+
+ event = &events[tail];
+
+ seq_printf(s, "%lu %lu %lu %lu %lu %lu %hd %hd %llu\n%s\n",
+ (unsigned long) event->pid, (unsigned long) event->uid,
+ (unsigned long) event->group_leader_pid, event->min_flt,
+ event->maj_flt, event->rss_in_pages, event->oom_score_adj,
+ event->min_score_adj, event->start_time, event->taskname);
+
+ event_buffer.tail = (tail + 1) & (MAX_BUFFERED_EVENTS - 1);
+
+ spin_unlock(&lmk_event_lock);
+ return 0;
+}
+
+static unsigned int lmk_event_poll(struct file *file, poll_table *wait)
+{
+ int ret = 0;
+
+ poll_wait(file, &event_wait, wait);
+ spin_lock(&lmk_event_lock);
+ if (event_buffer.head != event_buffer.tail)
+ ret = POLLIN;
+ spin_unlock(&lmk_event_lock);
+ return ret;
+}
+
+static int lmk_event_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, lmk_event_show, inode->i_private);
+}
+
+static const struct file_operations event_file_ops = {
+ .open = lmk_event_open,
+ .poll = lmk_event_poll,
+ .read = seq_read
+};
+
+static void lmk_event_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ event_buffer.head = 0;
+ event_buffer.tail = 0;
+ event_buffer.buf = kmalloc(
+ sizeof(struct lmk_event) * MAX_BUFFERED_EVENTS, GFP_KERNEL);
+ if (!event_buffer.buf)
+ return;
+ entry = proc_create("lowmemorykiller", 0, NULL, &event_file_ops);
+ if (!entry)
+ pr_err("error creating kernel lmk event file\n");
+}
+
static unsigned long lowmem_count(struct shrinker *s,
struct shrink_control *sc)
{
@@ -572,6 +722,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
lowmem_deathpending_timeout = jiffies + HZ;
rem += selected_tasksize;
rcu_read_unlock();
+ get_task_struct(selected);
/* give the system time to free up the memory */
msleep_interruptible(20);
trace_almk_shrink(selected_tasksize, ret,
@@ -585,6 +736,11 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n",
sc->nr_to_scan, sc->gfp_mask, rem);
mutex_unlock(&scan_mutex);
+
+ if (selected) {
+ handle_lmk_event(selected, selected_tasksize, min_score_adj);
+ put_task_struct(selected);
+ }
return rem;
}
@@ -599,6 +755,7 @@ static int __init lowmem_init(void)
{
register_shrinker(&lowmem_shrinker);
vmpressure_notifier_register(&lmk_vmpr_nb);
+ lmk_event_init();
return 0;
}
device_initcall(lowmem_init);
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 4b39f6960c0a..bead4f645546 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -2324,7 +2324,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
devpriv->intr_running = false;
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- comedi_handle_events(dev, s_ao);
+ if (s_ao)
+ comedi_handle_events(dev, s_ao);
comedi_handle_events(dev, s_ai);
return IRQ_HANDLED;
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index b63472de761a..c62a1cc2b223 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -553,7 +553,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
}
#endif
comedi_handle_events(dev, s);
- comedi_handle_events(dev, s_ao);
+ if (s_ao)
+ comedi_handle_events(dev, s_ao);
return IRQ_RETVAL(handled);
}
diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c
index e48981994b10..e1531feb6c5d 100644
--- a/drivers/staging/rdma/hfi1/chip.c
+++ b/drivers/staging/rdma/hfi1/chip.c
@@ -5906,6 +5906,7 @@ void hfi1_quiet_serdes(struct hfi1_pportdata *ppd)
/* disable the port */
clear_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
+ cancel_work_sync(&ppd->freeze_work);
}
static inline int init_cpu_counters(struct hfi1_devdata *dd)
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c
index 2b8f2e0a4224..ec6d20f25e8b 100644
--- a/drivers/tty/rocket.c
+++ b/drivers/tty/rocket.c
@@ -279,7 +279,7 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1
module_param_array(pc104_4, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
-static int rp_init(void);
+static int __init rp_init(void);
static void rp_cleanup_module(void);
module_init(rp_init);
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index aff086ca97e4..6b06efcfd4b2 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1614,6 +1614,25 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
static int ci_udc_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver);
static int ci_udc_stop(struct usb_gadget *gadget);
+
+/* Match ISOC IN from the highest endpoint */
+static struct usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
+ struct usb_endpoint_descriptor *desc,
+ struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+ struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
+ struct usb_ep *ep;
+
+ if (usb_endpoint_xfer_isoc(desc) && usb_endpoint_dir_in(desc)) {
+ list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
+ if (ep->caps.dir_in && !ep->claimed)
+ return ep;
+ }
+ }
+
+ return NULL;
+}
+
/**
* Device operations part of the API to the USB controller hardware,
* which don't involve endpoints (or i/o)
@@ -1627,6 +1646,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
.vbus_draw = ci_udc_vbus_draw,
.udc_start = ci_udc_start,
.udc_stop = ci_udc_stop,
+ .match_ep = ci_udc_match_ep,
};
static int init_eps(struct ci_hdrc *ci)
diff --git a/drivers/usb/gadget/function/f_ccid.c b/drivers/usb/gadget/function/f_ccid.c
index 9a53cd328cc5..0b335575f245 100644
--- a/drivers/usb/gadget/function/f_ccid.c
+++ b/drivers/usb/gadget/function/f_ccid.c
@@ -855,9 +855,9 @@ static ssize_t ccid_bulk_write(struct file *fp, const char __user *buf,
&bulk_dev->tx_idle)))
ccid_request_free(req, ccid_dev->in);
r = -ENODEV;
+ goto done;
}
spin_unlock_irqrestore(&ccid_dev->lock, flags);
- goto done;
}
done:
pr_debug("ccid_bulk_write returning %d\n", r);
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index a5f20634ab0a..df9466103f1e 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -217,11 +217,12 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
out = dev->port_usb->out_ep;
else
out = NULL;
- spin_unlock_irqrestore(&dev->lock, flags);
if (!out)
+ {
+ spin_unlock_irqrestore(&dev->lock, flags);
return -ENOTCONN;
-
+ }
/* Padding up to RX_EXTRA handles minor disagreements with host.
* Normally we use the USB "terminate on short read" convention;
@@ -245,6 +246,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
if (dev->port_usb->is_fixed)
size = max_t(size_t, size, dev->port_usb->fixed_out_len);
+ spin_unlock_irqrestore(&dev->lock, flags);
DBG(dev, "%s: size: %zd\n", __func__, size);
skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c
index 948845c90e47..351012c498c5 100644
--- a/drivers/usb/gadget/udc/fusb300_udc.c
+++ b/drivers/usb/gadget/udc/fusb300_udc.c
@@ -1345,12 +1345,15 @@ static const struct usb_gadget_ops fusb300_gadget_ops = {
static int fusb300_remove(struct platform_device *pdev)
{
struct fusb300 *fusb300 = platform_get_drvdata(pdev);
+ int i;
usb_del_gadget_udc(&fusb300->gadget);
iounmap(fusb300->reg);
free_irq(platform_get_irq(pdev, 0), fusb300);
fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req);
+ for (i = 0; i < FUSB300_MAX_NUM_EP; i++)
+ kfree(fusb300->ep[i]);
kfree(fusb300);
return 0;
@@ -1494,6 +1497,8 @@ clean_up:
if (fusb300->ep0_req)
fusb300_free_request(&fusb300->ep[0]->ep,
fusb300->ep0_req);
+ for (i = 0; i < FUSB300_MAX_NUM_EP; i++)
+ kfree(fusb300->ep[i]);
kfree(fusb300);
}
if (reg)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 00b5006baf15..90d24f62bd81 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -964,8 +964,7 @@ static struct lpc32xx_usbd_dd_gad *udc_dd_alloc(struct lpc32xx_udc *udc)
dma_addr_t dma;
struct lpc32xx_usbd_dd_gad *dd;
- dd = (struct lpc32xx_usbd_dd_gad *) dma_pool_alloc(
- udc->dd_cache, (GFP_KERNEL | GFP_DMA), &dma);
+ dd = dma_pool_alloc(udc->dd_cache, GFP_ATOMIC | GFP_DMA, &dma);
if (dd)
dd->this_dma = dma;
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 6f37966ea54b..5e2aa4f85c81 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -819,9 +819,8 @@ static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
}
static void usbhsf_dma_complete(void *arg);
-static void xfer_work(struct work_struct *work)
+static void usbhsf_dma_xfer_preparing(struct usbhs_pkt *pkt)
{
- struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work);
struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_fifo *fifo;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
@@ -829,12 +828,10 @@ static void xfer_work(struct work_struct *work)
struct dma_chan *chan;
struct device *dev = usbhs_priv_to_dev(priv);
enum dma_transfer_direction dir;
- unsigned long flags;
- usbhs_lock(priv, flags);
fifo = usbhs_pipe_to_fifo(pipe);
if (!fifo)
- goto xfer_work_end;
+ return;
chan = usbhsf_dma_chan_get(fifo, pkt);
dir = usbhs_pipe_is_dir_in(pipe) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
@@ -843,7 +840,7 @@ static void xfer_work(struct work_struct *work)
pkt->trans, dir,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc)
- goto xfer_work_end;
+ return;
desc->callback = usbhsf_dma_complete;
desc->callback_param = pipe;
@@ -851,7 +848,7 @@ static void xfer_work(struct work_struct *work)
pkt->cookie = dmaengine_submit(desc);
if (pkt->cookie < 0) {
dev_err(dev, "Failed to submit dma descriptor\n");
- goto xfer_work_end;
+ return;
}
dev_dbg(dev, " %s %d (%d/ %d)\n",
@@ -862,8 +859,17 @@ static void xfer_work(struct work_struct *work)
dma_async_issue_pending(chan);
usbhsf_dma_start(pipe, fifo);
usbhs_pipe_enable(pipe);
+}
+
+static void xfer_work(struct work_struct *work)
+{
+ struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work);
+ struct usbhs_pipe *pipe = pkt->pipe;
+ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ unsigned long flags;
-xfer_work_end:
+ usbhs_lock(priv, flags);
+ usbhsf_dma_xfer_preparing(pkt);
usbhs_unlock(priv, flags);
}
@@ -916,8 +922,13 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
pkt->trans = len;
usbhsf_tx_irq_ctrl(pipe, 0);
- INIT_WORK(&pkt->work, xfer_work);
- schedule_work(&pkt->work);
+ /* FIXME: Workaound for usb dmac that driver can be used in atomic */
+ if (usbhs_get_dparam(priv, has_usb_dmac)) {
+ usbhsf_dma_xfer_preparing(pkt);
+ } else {
+ INIT_WORK(&pkt->work, xfer_work);
+ schedule_work(&pkt->work);
+ }
return 0;
@@ -1023,8 +1034,7 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt,
pkt->trans = pkt->length;
- INIT_WORK(&pkt->work, xfer_work);
- schedule_work(&pkt->work);
+ usbhsf_dma_xfer_preparing(pkt);
return 0;
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index af258bb632dd..7edcd5a8d175 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1024,6 +1024,7 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) },
/* EZPrototypes devices */
{ USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) },
+ { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 15d220eaf6e6..ed6b36674c15 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -1542,3 +1542,9 @@
#define CHETCO_SEASMART_DISPLAY_PID 0xA5AD /* SeaSmart NMEA2000 Display */
#define CHETCO_SEASMART_LITE_PID 0xA5AE /* SeaSmart Lite USB Adapter */
#define CHETCO_SEASMART_ANALOG_PID 0xA5AF /* SeaSmart Analog Adapter */
+
+/*
+ * Unjo AB
+ */
+#define UNJO_VID 0x22B7
+#define UNJO_ISODEBUG_V1_PID 0x150D
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 1effe74ec638..d7b31fdce94d 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1338,6 +1338,7 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0601, 0xff) }, /* GosunCn ZTE WeLink ME3630 (RNDIS mode) */
{ USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
.driver_info = RSVD(4) },
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 1b408e2838d6..f56e50d516cd 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -1,7 +1,7 @@
/*
* Core MDSS framebuffer driver.
*
- * Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
@@ -4662,6 +4662,7 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
struct mdp_destination_scaler_data __user *ds_data_user;
struct msm_fb_data_type *mfd;
struct mdss_overlay_private *mdp5_data = NULL;
+ struct mdss_data_type *mdata;
ret = copy_from_user(&commit, argp, sizeof(struct mdp_layer_commit));
if (ret) {
@@ -4764,6 +4765,13 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
ds_data_user = commit.commit_v1.dest_scaler;
if ((ds_data_user) &&
(commit.commit_v1.dest_scaler_cnt)) {
+ mdata = mfd_to_mdata(mfd);
+ if (!mdata || !mdata->scaler_off ||
+ !mdata->scaler_off->has_dest_scaler) {
+ pr_err("dest scaler not supported\n");
+ ret = -EPERM;
+ goto err;
+ }
ret = __mdss_fb_copy_destscaler_data(info, &commit);
if (ret) {
pr_err("copy dest scaler failed\n");
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c
index 1384c39d4c6f..8b8b4120d3fb 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_util.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -790,11 +790,13 @@ static void hdmi_ddc_trigger(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
if (mode == TRIGGER_READ && seg) {
DSS_REG_W_ND(io, HDMI_DDC_DATA, BIT(31) | (seg_addr << 8));
DSS_REG_W_ND(io, HDMI_DDC_DATA, seg_num << 8);
+ DSS_REG_W_ND(io, HDMI_DDC_DATA, (ddc_data->dev_addr << 8));
+ } else {
+ /* handle portion #1 */
+ DSS_REG_W_ND(io, HDMI_DDC_DATA,
+ BIT(31) | (ddc_data->dev_addr << 8));
}
- /* handle portion #1 */
- DSS_REG_W_ND(io, HDMI_DDC_DATA, BIT(31) | (ddc_data->dev_addr << 8));
-
/* handle portion #2 */
DSS_REG_W_ND(io, HDMI_DDC_DATA, ddc_data->offset << 8);
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index 43fc5eafb047..90a38b79e561 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -933,6 +933,7 @@ struct mdss_mdp_writeback_arg {
struct mdss_mdp_wfd;
struct mdss_overlay_private {
+ bool vsync_en;
ktime_t vsync_time;
ktime_t lineptr_time;
struct kernfs_node *vsync_event_sd;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 81218319d58b..daeed5d45072 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3307,12 +3307,14 @@ int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en)
goto end;
}
+ mdp5_data->vsync_en = en;
+
if (!ctl->panel_data->panel_info.cont_splash_enabled
&& (!mdss_mdp_ctl_is_power_on(ctl) ||
mdss_panel_is_power_on_ulp(ctl->power_state))) {
pr_debug("fb%d vsync pending first update en=%d, ctl power state:%d\n",
mfd->index, en, ctl->power_state);
- rc = -EPERM;
+ rc = 0;
goto end;
}
@@ -5759,6 +5761,15 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
}
panel_on:
+ if (mdp5_data->vsync_en) {
+ if ((ctl) && (ctl->ops.add_vsync_handler)) {
+ pr_info("reenabling vsync for fb%d\n", mfd->index);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
+ rc = ctl->ops.add_vsync_handler(ctl,
+ &ctl->vsync_handler);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
+ }
+ }
if (IS_ERR_VALUE(rc)) {
pr_err("Failed to turn on fb%d\n", mfd->index);
mdss_mdp_overlay_off(mfd);
@@ -6600,6 +6611,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
}
}
mfd->mdp_sync_pt_data.async_wait_fences = true;
+ mdp5_data->vsync_en = false;
pm_runtime_set_suspended(&mfd->pdev->dev);
pm_runtime_enable(&mfd->pdev->dev);
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index c30c6ceac2c4..d02ee4026e32 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -282,7 +282,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
switch (handler->flags) {
case ACL_TYPE_ACCESS:
if (acl) {
- struct iattr iattr;
+ struct iattr iattr = { 0 };
struct posix_acl *old_acl = acl;
retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f723cd3a455c..cc7bf84ef77c 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -808,9 +808,14 @@ err:
static int load_flat_shared_library(int id, struct lib_info *libs)
{
+ /*
+ * This is a fake bprm struct; only the members "buf", "file" and
+ * "filename" are actually used.
+ */
struct linux_binprm bprm;
int res;
char buf[16];
+ loff_t pos = 0;
memset(&bprm, 0, sizeof(bprm));
@@ -824,25 +829,10 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
if (IS_ERR(bprm.file))
return res;
- bprm.cred = prepare_exec_creds();
- res = -ENOMEM;
- if (!bprm.cred)
- goto out;
-
- /* We don't really care about recalculating credentials at this point
- * as we're past the point of no return and are dealing with shared
- * libraries.
- */
- bprm.cred_prepared = 1;
-
- res = prepare_binprm(&bprm);
-
- if (!IS_ERR_VALUE(res))
+ res = kernel_read(bprm.file, pos, bprm.buf, BINPRM_BUF_SIZE);
+ if (res >= 0)
res = load_flat_file(&bprm, libs, id, NULL);
- abort_creds(bprm.cred);
-
-out:
allow_write_access(bprm.file);
fput(bprm.file);
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 81e5bc62e8e3..1414a99b3ab4 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -495,18 +495,27 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
}
btrfs_wait_ordered_roots(root->fs_info, -1);
- trans = btrfs_start_transaction(root, 0);
- if (IS_ERR(trans)) {
- mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
- return PTR_ERR(trans);
+ while (1) {
+ trans = btrfs_start_transaction(root, 0);
+ if (IS_ERR(trans)) {
+ mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
+ return PTR_ERR(trans);
+ }
+ ret = btrfs_commit_transaction(trans, root);
+ WARN_ON(ret);
+ mutex_lock(&uuid_mutex);
+ /* keep away write_all_supers() during the finishing procedure */
+ mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
+ mutex_lock(&root->fs_info->chunk_mutex);
+ if (src_device->has_pending_chunks) {
+ mutex_unlock(&root->fs_info->chunk_mutex);
+ mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+ mutex_unlock(&uuid_mutex);
+ } else {
+ break;
+ }
}
- ret = btrfs_commit_transaction(trans, root);
- WARN_ON(ret);
- mutex_lock(&uuid_mutex);
- /* keep away write_all_supers() during the finishing procedure */
- mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
- mutex_lock(&root->fs_info->chunk_mutex);
btrfs_dev_replace_lock(dev_replace);
dev_replace->replace_state =
scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index 619f92963e27..f2af1f3d4aa8 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -762,16 +762,23 @@ static void __reada_start_machine(struct btrfs_fs_info *fs_info)
u64 total = 0;
int i;
+again:
do {
enqueued = 0;
+ mutex_lock(&fs_devices->device_list_mutex);
list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (atomic_read(&device->reada_in_flight) <
MAX_IN_FLIGHT)
enqueued += reada_start_machine_dev(fs_info,
device);
}
+ mutex_unlock(&fs_devices->device_list_mutex);
total += enqueued;
} while (enqueued && total < 10000);
+ if (fs_devices->seed) {
+ fs_devices = fs_devices->seed;
+ goto again;
+ }
if (enqueued == 0)
return;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index d1cca19b29d3..4eb7a6ba7e47 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4760,6 +4760,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
for (i = 0; i < map->num_stripes; i++) {
num_bytes = map->stripes[i].dev->bytes_used + stripe_size;
btrfs_device_set_bytes_used(map->stripes[i].dev, num_bytes);
+ map->stripes[i].dev->has_pending_chunks = true;
}
spin_lock(&extent_root->fs_info->free_chunk_lock);
@@ -7064,6 +7065,7 @@ void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
for (i = 0; i < map->num_stripes; i++) {
dev = map->stripes[i].dev;
dev->commit_bytes_used = dev->bytes_used;
+ dev->has_pending_chunks = false;
}
}
unlock_chunks(root);
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 3c651df420be..7feac2d9da56 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -62,6 +62,11 @@ struct btrfs_device {
spinlock_t io_lock ____cacheline_aligned;
int running_pending;
+ /* When true means this device has pending chunk alloc in
+ * current transaction. Protected by chunk_mutex.
+ */
+ bool has_pending_chunks;
+
/* regular prio bios */
struct btrfs_pending_bios pending_bios;
/* WRITE_SYNC bios */
diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c
index 7e93d5706bf6..4d0d4076de5a 100644
--- a/fs/cifs/smb2maperror.c
+++ b/fs/cifs/smb2maperror.c
@@ -455,7 +455,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
{STATUS_FILE_INVALID, -EIO, "STATUS_FILE_INVALID"},
{STATUS_ALLOTTED_SPACE_EXCEEDED, -EIO,
"STATUS_ALLOTTED_SPACE_EXCEEDED"},
- {STATUS_INSUFFICIENT_RESOURCES, -EREMOTEIO,
+ {STATUS_INSUFFICIENT_RESOURCES, -EAGAIN,
"STATUS_INSUFFICIENT_RESOURCES"},
{STATUS_DFS_EXIT_PATH_FOUND, -EIO, "STATUS_DFS_EXIT_PATH_FOUND"},
{STATUS_DEVICE_DATA_ERROR, -EIO, "STATUS_DEVICE_DATA_ERROR"},
diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
index e4f4fc4e56ab..77bd7bfb6329 100644
--- a/fs/ext4/crypto_policy.c
+++ b/fs/ext4/crypto_policy.c
@@ -111,6 +111,8 @@ int ext4_process_policy(const struct ext4_encryption_policy *policy,
if (!ext4_inode_has_encryption_context(inode)) {
if (!S_ISDIR(inode->i_mode))
return -EINVAL;
+ if (IS_DEADDIR(inode))
+ return -ENOENT;
if (!ext4_empty_dir(inode))
return -ENOTEMPTY;
return ext4_create_encryption_context_from_policy(inode,
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index d7d880f9495b..4cc40de38dff 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -415,8 +415,13 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
err = -ENOMEM;
override_cred = prepare_creds();
if (override_cred) {
- override_cred->fsuid = old_cred->fsuid;
- override_cred->fsgid = old_cred->fsgid;
+ const struct cred *our_cred;
+
+ our_cred = old_cred;
+ if (!our_cred)
+ our_cred = current_cred();
+ override_cred->fsuid = our_cred->fsuid;
+ override_cred->fsgid = our_cred->fsgid;
put_cred(override_creds(override_cred));
put_cred(override_cred);
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 985a4cdae06d..9aff8178aa8c 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/slab.h>
+#include <linux/cred.h>
#include <linux/xattr.h>
#include "overlayfs.h"
@@ -91,6 +92,7 @@ int ovl_permission(struct inode *inode, int mask)
struct ovl_entry *oe;
struct dentry *alias = NULL;
struct inode *realinode;
+ const struct cred *old_cred;
struct dentry *realdentry;
bool is_upper;
int err;
@@ -143,7 +145,18 @@ int ovl_permission(struct inode *inode, int mask)
goto out_dput;
}
+ /*
+ * Check overlay inode with the creds of task and underlying inode
+ * with creds of mounter
+ */
+ err = generic_permission(inode, mask);
+ if (err)
+ goto out_dput;
+
+ old_cred = ovl_override_creds(inode->i_sb);
err = __inode_permission(realinode, mask);
+ revert_creds(old_cred);
+
out_dput:
dput(alias);
return err;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 613193c6bb42..3876448ec0dc 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -479,13 +479,15 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block,
return NULL;
}
-/* Extend the file by 'blocks' blocks, return the number of extents added */
+/* Extend the file with new blocks totaling 'new_block_bytes',
+ * return the number of extents added
+ */
static int udf_do_extend_file(struct inode *inode,
struct extent_position *last_pos,
struct kernel_long_ad *last_ext,
- sector_t blocks)
+ loff_t new_block_bytes)
{
- sector_t add;
+ uint32_t add;
int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
struct super_block *sb = inode->i_sb;
struct kernel_lb_addr prealloc_loc = {};
@@ -495,7 +497,7 @@ static int udf_do_extend_file(struct inode *inode,
/* The previous extent is fake and we should not extend by anything
* - there's nothing to do... */
- if (!blocks && fake)
+ if (!new_block_bytes && fake)
return 0;
iinfo = UDF_I(inode);
@@ -526,13 +528,12 @@ static int udf_do_extend_file(struct inode *inode,
/* Can we merge with the previous extent? */
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
EXT_NOT_RECORDED_NOT_ALLOCATED) {
- add = ((1 << 30) - sb->s_blocksize -
- (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >>
- sb->s_blocksize_bits;
- if (add > blocks)
- add = blocks;
- blocks -= add;
- last_ext->extLength += add << sb->s_blocksize_bits;
+ add = (1 << 30) - sb->s_blocksize -
+ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ if (add > new_block_bytes)
+ add = new_block_bytes;
+ new_block_bytes -= add;
+ last_ext->extLength += add;
}
if (fake) {
@@ -544,28 +545,27 @@ static int udf_do_extend_file(struct inode *inode,
last_ext->extLength, 1);
/* Managed to do everything necessary? */
- if (!blocks)
+ if (!new_block_bytes)
goto out;
/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
last_ext->extLocation.logicalBlockNum = 0;
last_ext->extLocation.partitionReferenceNum = 0;
- add = (1 << (30-sb->s_blocksize_bits)) - 1;
- last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
- (add << sb->s_blocksize_bits);
+ add = (1 << 30) - sb->s_blocksize;
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | add;
/* Create enough extents to cover the whole hole */
- while (blocks > add) {
- blocks -= add;
+ while (new_block_bytes > add) {
+ new_block_bytes -= add;
err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1);
if (err)
return err;
count++;
}
- if (blocks) {
+ if (new_block_bytes) {
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
- (blocks << sb->s_blocksize_bits);
+ new_block_bytes;
err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1);
if (err)
@@ -596,6 +596,24 @@ out:
return count;
}
+/* Extend the final block of the file to final_block_len bytes */
+static void udf_do_extend_final_block(struct inode *inode,
+ struct extent_position *last_pos,
+ struct kernel_long_ad *last_ext,
+ uint32_t final_block_len)
+{
+ struct super_block *sb = inode->i_sb;
+ uint32_t added_bytes;
+
+ added_bytes = final_block_len -
+ (last_ext->extLength & (sb->s_blocksize - 1));
+ last_ext->extLength += added_bytes;
+ UDF_I(inode)->i_lenExtents += added_bytes;
+
+ udf_write_aext(inode, last_pos, &last_ext->extLocation,
+ last_ext->extLength, 1);
+}
+
static int udf_extend_file(struct inode *inode, loff_t newsize)
{
@@ -605,10 +623,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
int8_t etype;
struct super_block *sb = inode->i_sb;
sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
+ unsigned long partial_final_block;
int adsize;
struct udf_inode_info *iinfo = UDF_I(inode);
struct kernel_long_ad extent;
- int err;
+ int err = 0;
+ int within_final_block;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(struct short_ad);
@@ -618,18 +638,8 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
BUG();
etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+ within_final_block = (etype != -1);
- /* File has extent covering the new size (could happen when extending
- * inside a block)? */
- if (etype != -1)
- return 0;
- if (newsize & (sb->s_blocksize - 1))
- offset++;
- /* Extended file just to the boundary of the last file block? */
- if (offset == 0)
- return 0;
-
- /* Truncate is extending the file by 'offset' blocks */
if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
(epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
/* File has no extents at all or has empty last
@@ -643,7 +653,22 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
&extent.extLength, 0);
extent.extLength |= etype << 30;
}
- err = udf_do_extend_file(inode, &epos, &extent, offset);
+
+ partial_final_block = newsize & (sb->s_blocksize - 1);
+
+ /* File has extent covering the new size (could happen when extending
+ * inside a block)?
+ */
+ if (within_final_block) {
+ /* Extending file within the last file block */
+ udf_do_extend_final_block(inode, &epos, &extent,
+ partial_final_block);
+ } else {
+ loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
+ partial_final_block;
+ err = udf_do_extend_file(inode, &epos, &extent, add);
+ }
+
if (err < 0)
goto out;
err = 0;
@@ -748,6 +773,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
/* Are we beyond EOF? */
if (etype == -1) {
int ret;
+ loff_t hole_len;
isBeyondEOF = true;
if (count) {
if (c)
@@ -763,7 +789,8 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
startnum = (offset > 0);
}
/* Create extents for the hole between EOF and offset */
- ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
+ hole_len = (loff_t)offset << inode->i_blkbits;
+ ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len);
if (ret < 0) {
brelse(prev_epos.bh);
brelse(cur_epos.bh);
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 630dd2372238..09aa521a0085 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -47,6 +47,7 @@ struct bug_entry {
#ifndef HAVE_ARCH_BUG
#define BUG() do { \
printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+ barrier_before_unreachable(); \
panic("BUG!"); \
} while (0)
#endif
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index c0884e120041..0f64739300ff 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -24,6 +24,7 @@
#define __DRM_EDID_H__
#include <linux/types.h>
+#include <linux/hdmi.h>
#define EDID_LENGTH 128
#define DDC_ADDR 0x50
@@ -338,8 +339,6 @@ struct cea_sad {
struct drm_encoder;
struct drm_connector;
struct drm_display_mode;
-struct hdmi_avi_infoframe;
-struct hdmi_vendor_infoframe;
void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
@@ -347,7 +346,16 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
int drm_av_sync_delay(struct drm_connector *connector,
const struct drm_display_mode *mode);
struct drm_connector *drm_select_eld(struct drm_encoder *encoder);
-int drm_load_edid_firmware(struct drm_connector *connector);
+
+#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
+struct edid *drm_load_edid_firmware(struct drm_connector *connector);
+#else
+static inline struct edid *
+drm_load_edid_firmware(struct drm_connector *connector)
+{
+ return ERR_PTR(-ENOENT);
+}
+#endif
int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 143d40e8a1ea..af8b4a879934 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -207,6 +207,15 @@
#if GCC_VERSION >= 40500
/*
+ * calling noreturn functions, __builtin_unreachable() and __builtin_trap()
+ * confuse the stack allocation in gcc, leading to overly large stack
+ * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
+ *
+ * Adding an empty inline assembly before it works around the problem
+ */
+#define barrier_before_unreachable() asm volatile("")
+
+/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
* control elsewhere.
@@ -215,7 +224,11 @@
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
-#define unreachable() __builtin_unreachable()
+#define unreachable() \
+ do { \
+ barrier_before_unreachable(); \
+ __builtin_unreachable(); \
+ } while (0)
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 0db1fa621d8a..ed772311ec1f 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -175,6 +175,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define barrier_data(ptr) barrier()
#endif
+/* workaround for GCC PR82365 if needed */
+#ifndef barrier_before_unreachable
+# define barrier_before_unreachable() do { } while (0)
+#endif
+
/* Unreachable code */
#ifndef unreachable
# define unreachable() do { } while (1)
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 3ae123acbaaa..605f9731fe5d 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -145,7 +145,7 @@ the appropriate macros. */
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 26
-#define APPS_EVENT_LAST_ID 0xCA7
+#define APPS_EVENT_LAST_ID 0xCAA
#define MSG_SSID_0 0
#define MSG_SSID_0_LAST 130
@@ -180,7 +180,7 @@ the appropriate macros. */
#define MSG_SSID_15 8000
#define MSG_SSID_15_LAST 8000
#define MSG_SSID_16 8500
-#define MSG_SSID_16_LAST 8531
+#define MSG_SSID_16_LAST 8532
#define MSG_SSID_17 9000
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
@@ -770,7 +770,8 @@ static const uint32_t msg_bld_masks_16[] = {
MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR |
MSG_LVL_FATAL,
MSG_LVL_MED,
- MSG_LVL_MED
+ MSG_LVL_MED,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_17[] = {
@@ -910,7 +911,7 @@ static const uint32_t msg_bld_masks_25[] = {
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x1C94, /* EQUIP ID 1 */
+ 0x1C9A, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index e7a018eaf3a2..017fced60242 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -1,10 +1,13 @@
#ifndef __LINUX_SWIOTLB_H
#define __LINUX_SWIOTLB_H
+#include <linux/dma-direction.h>
+#include <linux/init.h>
#include <linux/types.h>
struct device;
struct dma_attrs;
+struct page;
struct scatterlist;
extern int swiotlb_force;
diff --git a/include/linux/vmw_vmci_defs.h b/include/linux/vmw_vmci_defs.h
index 65ac54c61c18..7023432013e8 100644
--- a/include/linux/vmw_vmci_defs.h
+++ b/include/linux/vmw_vmci_defs.h
@@ -75,9 +75,18 @@ enum {
/*
* A single VMCI device has an upper limit of 128MB on the amount of
- * memory that can be used for queue pairs.
+ * memory that can be used for queue pairs. Since each queue pair
+ * consists of at least two pages, the memory limit also dictates the
+ * number of queue pairs a guest can create.
*/
#define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024)
+#define VMCI_MAX_GUEST_QP_COUNT (VMCI_MAX_GUEST_QP_MEMORY / PAGE_SIZE / 2)
+
+/*
+ * There can be at most PAGE_SIZE doorbells since there is one doorbell
+ * per byte in the doorbell bitmap page.
+ */
+#define VMCI_MAX_GUEST_DOORBELL_COUNT PAGE_SIZE
/*
* Queues with pre-mapped data pages must be small, so that we don't pin
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 876688b5a356..7c0c83dfe86e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -174,6 +174,9 @@ struct adv_info {
#define HCI_MAX_SHORT_NAME_LENGTH 10
+/* Min encryption key size to match with SMP */
+#define HCI_MIN_ENC_KEY_SIZE 7
+
/* Default LE RPA expiry time, 15 minutes */
#define HCI_DEFAULT_RPA_TIMEOUT (15 * 60)
diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
index 1d67fb6b23a0..6d238506d49b 100644
--- a/include/net/busy_poll.h
+++ b/include/net/busy_poll.h
@@ -93,7 +93,7 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
goto out;
ops = napi->dev->netdev_ops;
- if (!ops->ndo_busy_poll)
+ if (!ops || !ops->ndo_busy_poll)
goto out;
do {
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 4de4cd5e89dc..716e28054e60 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -56,6 +56,8 @@ struct icnss_driver_ops {
int (*suspend_noirq)(struct device *dev);
int (*resume_noirq)(struct device *dev);
int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent);
+ int (*idle_shutdown)(struct device *dev);
+ int (*idle_restart)(struct device *dev);
};
@@ -159,4 +161,6 @@ extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int icnss_trigger_recovery(struct device *dev);
extern void icnss_block_shutdown(bool status);
extern bool icnss_is_pdr(void);
+extern int icnss_idle_restart(struct device *dev);
+extern int icnss_idle_shutdown(struct device *dev);
#endif /* _ICNSS_WLAN_H_ */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d484f2869861..98791b70277a 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -927,6 +927,9 @@ static int __init mitigations_parse_cmdline(char *arg)
cpu_mitigations = CPU_MITIGATIONS_OFF;
else if (!strcmp(arg, "auto"))
cpu_mitigations = CPU_MITIGATIONS_AUTO;
+ else
+ pr_crit("Unsupported mitigations=%s, system may still be vulnerable\n",
+ arg);
return 0;
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1973c48b0f63..bc33e20db315 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5194,7 +5194,7 @@ static void perf_sample_regs_user(struct perf_regs *regs_user,
if (user_mode(regs)) {
regs_user->abi = perf_reg_abi(current);
regs_user->regs = regs;
- } else if (current->mm) {
+ } else if (!(current->flags & PF_KTHREAD)) {
perf_get_regs_user(regs_user, regs, regs_user_copy);
} else {
regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 1aa33fe37aa8..da8c358930fb 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -45,9 +45,7 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent,
*/
static void ptrace_link(struct task_struct *child, struct task_struct *new_parent)
{
- rcu_read_lock();
- __ptrace_link(child, new_parent, __task_cred(new_parent));
- rcu_read_unlock();
+ __ptrace_link(child, new_parent, current_cred());
}
/**
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1a9e7a6c2134..6368792ab807 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7353,12 +7353,8 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
cnt++;
- /* reset all but tr, trace, and overruns */
- memset(&iter.seq, 0,
- sizeof(struct trace_iterator) -
- offsetof(struct trace_iterator, seq));
+ trace_iterator_reset(&iter);
iter.iter_flags |= TRACE_FILE_LAT_FMT;
- iter.pos = -1;
if (trace_find_next_entry_inc(&iter) != NULL) {
int ret;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index e1265f95457f..f62768288592 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1383,4 +1383,22 @@ static inline void trace_event_enum_update(struct trace_enum_map **map, int len)
extern struct trace_iterator *tracepoint_print_iter;
+/*
+ * Reset the state of the trace_iterator so that it can read consumed data.
+ * Normally, the trace_iterator is used for reading the data when it is not
+ * consumed, and must retain state.
+ */
+static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
+{
+ const size_t offset = offsetof(struct trace_iterator, seq);
+
+ /*
+ * Keep gcc from complaining about overwriting more than just one
+ * member in the structure.
+ */
+ memset((char *)iter + offset, 0, sizeof(struct trace_iterator) - offset);
+
+ iter->pos = -1;
+}
+
#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
index 896458285fdd..cf6337dc41f4 100644
--- a/kernel/trace/trace_kdb.c
+++ b/kernel/trace/trace_kdb.c
@@ -40,12 +40,8 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file)
kdb_printf("Dumping ftrace buffer:\n");
- /* reset all but tr, trace, and overruns */
- memset(&iter.seq, 0,
- sizeof(struct trace_iterator) -
- offsetof(struct trace_iterator, seq));
+ trace_iterator_reset(&iter);
iter.iter_flags |= TRACE_FILE_LAT_FMT;
- iter.pos = -1;
if (cpu_file == RING_BUFFER_ALL_CPUS) {
for_each_tracing_cpu(cpu) {
diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
index 468fb7cd1221..edf345b7f06b 100644
--- a/lib/mpi/mpi-pow.c
+++ b/lib/mpi/mpi-pow.c
@@ -37,6 +37,7 @@
int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
{
mpi_ptr_t mp_marker = NULL, bp_marker = NULL, ep_marker = NULL;
+ struct karatsuba_ctx karactx = {};
mpi_ptr_t xp_marker = NULL;
mpi_ptr_t tspace = NULL;
mpi_ptr_t rp, ep, mp, bp;
@@ -164,13 +165,11 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
int c;
mpi_limb_t e;
mpi_limb_t carry_limb;
- struct karatsuba_ctx karactx;
xp = xp_marker = mpi_alloc_limb_space(2 * (msize + 1));
if (!xp)
goto enomem;
- memset(&karactx, 0, sizeof karactx);
negative_result = (ep[0] & 1) && base->sign;
i = esize - 1;
@@ -295,8 +294,6 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
if (mod_shift_cnt)
mpihelp_rshift(rp, rp, rsize, mod_shift_cnt);
MPN_NORMALIZE(rp, rsize);
-
- mpihelp_release_karatsuba_ctx(&karactx);
}
if (negative_result && rsize) {
@@ -313,6 +310,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
leave:
rc = 0;
enomem:
+ mpihelp_release_karatsuba_ctx(&karactx);
if (assign_rp)
mpi_assign_limb_space(res, rp, size);
if (mp_marker)
diff --git a/mm/page_idle.c b/mm/page_idle.c
index d5dd79041484..fd75ae838f42 100644
--- a/mm/page_idle.c
+++ b/mm/page_idle.c
@@ -130,7 +130,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
end_pfn = pfn + count * BITS_PER_BYTE;
if (end_pfn > max_pfn)
- end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS);
+ end_pfn = max_pfn;
for (; pfn < end_pfn; pfn++) {
bit = pfn % BITMAP_CHUNK_BITS;
@@ -175,7 +175,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
end_pfn = pfn + count * BITS_PER_BYTE;
if (end_pfn > max_pfn)
- end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS);
+ end_pfn = max_pfn;
for (; pfn < end_pfn; pfn++) {
bit = pfn % BITMAP_CHUNK_BITS;
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 7f1b45c082c9..ed1e39ccaebf 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -622,13 +622,19 @@ int p9dirent_read(struct p9_client *clnt, char *buf, int len,
if (ret) {
p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
trace_9p_protocol_dump(clnt, &fake_pdu);
- goto out;
+ return ret;
}
- strcpy(dirent->d_name, nameptr);
+ ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
+ if (ret < 0) {
+ p9_debug(P9_DEBUG_ERROR,
+ "On the wire dirent name too long: %s\n",
+ nameptr);
+ kfree(nameptr);
+ return ret;
+ }
kfree(nameptr);
-out:
return fake_pdu.offset;
}
EXPORT_SYMBOL(p9dirent_read);
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c
index 38aa6345bdfa..9c0c894b56f8 100644
--- a/net/9p/trans_common.c
+++ b/net/9p/trans_common.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/module.h>
+#include "trans_common.h"
/**
* p9_release_req_pages - Release pages after the transaction.
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index f42550dd3560..83d2e7722ebf 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -255,8 +255,7 @@ p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
case RDMA_CM_EVENT_DISCONNECTED:
if (rdma)
rdma->state = P9_RDMA_CLOSED;
- if (c)
- c->status = Disconnected;
+ c->status = Disconnected;
break;
case RDMA_CM_EVENT_TIMEWAIT_EXIT:
@@ -476,7 +475,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
err = post_recv(client, rpl_context);
if (err) {
- p9_debug(P9_DEBUG_FCALL, "POST RECV failed\n");
+ p9_debug(P9_DEBUG_ERROR, "POST RECV failed: %d\n", err);
goto recv_error;
}
/* remove posted receive buffer from request structure */
@@ -544,7 +543,7 @@ dont_need_post_recv:
recv_error:
kfree(rpl_context);
spin_lock_irqsave(&rdma->req_lock, flags);
- if (rdma->state < P9_RDMA_CLOSING) {
+ if (err != -EINTR && rdma->state < P9_RDMA_CLOSING) {
rdma->state = P9_RDMA_CLOSING;
spin_unlock_irqrestore(&rdma->req_lock, flags);
rdma_disconnect(rdma->cm_id);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 1588d913c7a0..211c2599ab96 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1293,8 +1293,16 @@ auth:
return 0;
encrypt:
- if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) {
+ /* Ensure that the encryption key size has been read,
+ * otherwise stall the upper layer responses.
+ */
+ if (!conn->enc_key_size)
+ return 0;
+
+ /* Nothing else needed, all requirements are met */
return 1;
+ }
hci_conn_encrypt(conn);
return 0;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 86d7b9fb5543..ad00753adef7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1329,6 +1329,21 @@ static void l2cap_request_info(struct l2cap_conn *conn)
sizeof(req), &req);
}
+static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
+{
+ /* The minimum encryption key size needs to be enforced by the
+ * host stack before establishing any L2CAP connections. The
+ * specification in theory allows a minimum of 1, but to align
+ * BR/EDR and LE transports, a minimum of 7 is chosen.
+ *
+ * This check might also be called for unencrypted connections
+ * that have no key size requirements. Ensure that the link is
+ * actually encrypted before enforcing a key size.
+ */
+ return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
+ hcon->enc_key_size >= HCI_MIN_ENC_KEY_SIZE);
+}
+
static void l2cap_do_start(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = chan->conn;
@@ -1346,9 +1361,14 @@ static void l2cap_do_start(struct l2cap_chan *chan)
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
return;
- if (l2cap_chan_check_security(chan, true) &&
- __l2cap_no_conn_pending(chan))
+ if (!l2cap_chan_check_security(chan, true) ||
+ !__l2cap_no_conn_pending(chan))
+ return;
+
+ if (l2cap_check_enc_key_size(conn->hcon))
l2cap_start_connection(chan);
+ else
+ __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
}
static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
@@ -1427,7 +1447,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
continue;
}
- l2cap_start_connection(chan);
+ if (l2cap_check_enc_key_size(conn->hcon))
+ l2cap_start_connection(chan);
+ else
+ l2cap_chan_close(chan, ECONNREFUSED);
} else if (chan->state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
@@ -7433,7 +7456,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
}
if (chan->state == BT_CONNECT) {
- if (!status)
+ if (!status && l2cap_check_enc_key_size(hcon))
l2cap_start_connection(chan);
else
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
@@ -7442,7 +7465,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
struct l2cap_conn_rsp rsp;
__u16 res, stat;
- if (!status) {
+ if (!status && l2cap_check_enc_key_size(hcon)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
res = L2CAP_CR_PEND;
stat = L2CAP_CS_AUTHOR_PEND;
diff --git a/net/can/af_can.c b/net/can/af_can.c
index c866e761651a..b06ab2f05991 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -113,6 +113,7 @@ EXPORT_SYMBOL(can_ioctl);
static void can_sock_destruct(struct sock *sk)
{
skb_queue_purge(&sk->sk_receive_queue);
+ skb_queue_purge(&sk->sk_error_queue);
}
static const struct can_proto *can_get_proto(int protocol)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 69e1a11f4ca8..01f8d24f3af7 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -195,7 +195,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
}
sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
iph->saddr, iph->daddr,
- skb->dev->ifindex);
+ dif);
}
out:
read_unlock(&raw_v4_hashinfo.lock);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 1cbc7bd26de3..4bd8f3f056d8 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1138,7 +1138,8 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
ifmsh->chsw_ttl = 0;
/* Remove the CSA and MCSP elements from the beacon */
- tmp_csa_settings = rcu_dereference(ifmsh->csa);
+ tmp_csa_settings = rcu_dereference_protected(ifmsh->csa,
+ lockdep_is_held(&sdata->wdev.mtx));
RCU_INIT_POINTER(ifmsh->csa, NULL);
if (tmp_csa_settings)
kfree_rcu(tmp_csa_settings, rcu_head);
@@ -1160,6 +1161,8 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
struct mesh_csa_settings *tmp_csa_settings;
int ret = 0;
+ lockdep_assert_held(&sdata->wdev.mtx);
+
tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings),
GFP_ATOMIC);
if (!tmp_csa_settings)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a26f55f86129..6676b413d049 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3325,6 +3325,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
case NL80211_IFTYPE_STATION:
if (!bssid && !sdata->u.mgd.use_4addr)
return false;
+ if (ieee80211_is_robust_mgmt_frame(skb) && !rx->sta)
+ return false;
if (multicast)
return true;
return ether_addr_equal(sdata->vif.addr, hdr->addr1);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 9da76ba4d10f..3550f0784306 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -126,10 +126,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Initialize the bind addr area */
sctp_bind_addr_init(&ep->base.bind_addr, 0);
- /* Remember who we are attached to. */
- ep->base.sk = sk;
- sock_hold(ep->base.sk);
-
/* Create the lists of associations. */
INIT_LIST_HEAD(&ep->asocs);
@@ -165,6 +161,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep->auth_hmacs_list = auth_hmacs;
ep->auth_chunk_list = auth_chunks;
+ /* Remember who we are attached to. */
+ ep->base.sk = sk;
+ sock_hold(ep->base.sk);
+
return ep;
nomem_hmacs:
diff --git a/net/tipc/core.c b/net/tipc/core.c
index c306e9bc1621..35b376f58f21 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -129,7 +129,7 @@ static int __init tipc_init(void)
if (err)
goto out_sysctl;
- err = register_pernet_subsys(&tipc_net_ops);
+ err = register_pernet_device(&tipc_net_ops);
if (err)
goto out_pernet;
@@ -137,7 +137,7 @@ static int __init tipc_init(void)
if (err)
goto out_socket;
- err = register_pernet_subsys(&tipc_topsrv_net_ops);
+ err = register_pernet_device(&tipc_topsrv_net_ops);
if (err)
goto out_pernet_topsrv;
@@ -148,11 +148,11 @@ static int __init tipc_init(void)
pr_info("Started in single node mode\n");
return 0;
out_bearer:
- unregister_pernet_subsys(&tipc_topsrv_net_ops);
+ unregister_pernet_device(&tipc_topsrv_net_ops);
out_pernet_topsrv:
tipc_socket_stop();
out_socket:
- unregister_pernet_subsys(&tipc_net_ops);
+ unregister_pernet_device(&tipc_net_ops);
out_pernet:
tipc_unregister_sysctl();
out_sysctl:
@@ -167,9 +167,9 @@ out_netlink:
static void __exit tipc_exit(void)
{
tipc_bearer_cleanup();
- unregister_pernet_subsys(&tipc_topsrv_net_ops);
+ unregister_pernet_device(&tipc_topsrv_net_ops);
tipc_socket_stop();
- unregister_pernet_subsys(&tipc_net_ops);
+ unregister_pernet_device(&tipc_net_ops);
tipc_netlink_stop();
tipc_netlink_compat_stop();
tipc_unregister_sysctl();
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 8400211537a2..9a65664f749c 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -430,7 +430,11 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
if (!bearer)
return -EMSGSIZE;
- len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
+ len = TLV_GET_DATA_LEN(msg->req);
+ if (len <= 0)
+ return -EINVAL;
+
+ len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
@@ -505,7 +509,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
name = (char *)TLV_DATA(msg->req);
- len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
+ len = TLV_GET_DATA_LEN(msg->req);
+ if (len <= 0)
+ return -EINVAL;
+
+ len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
@@ -776,7 +784,11 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
if (!link)
return -EMSGSIZE;
- len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
+ len = TLV_GET_DATA_LEN(msg->req);
+ if (len <= 0)
+ return -EINVAL;
+
+ len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len))
return -EINVAL;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 27d5fadddf97..eafc34b27013 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -450,7 +450,7 @@ use_default_name:
&rdev->rfkill_ops, rdev);
if (!rdev->rfkill) {
- kfree(rdev);
+ wiphy_free(&rdev->wiphy);
return NULL;
}
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index da86a8e0a95a..e836b5ff2060 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -336,7 +336,7 @@ void read_trace_pipe(void)
static char buf[4096];
ssize_t sz;
- sz = read(trace_fd, buf, sizeof(buf));
+ sz = read(trace_fd, buf, sizeof(buf) - 1);
if (sz > 0) {
buf[sz] = 0;
puts(buf);
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 12a6940741fe..b8f616545277 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -45,7 +45,7 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
$x = "[0-9a-f]"; # hex character
$xs = "[0-9a-f ]"; # hex character or space
$funcre = qr/^$x* <(.*)>:$/;
- if ($arch eq 'aarch64') {
+ if ($arch =~ '^(aarch|arm)64$') {
#ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp, #-80]!
$re = qr/^.*stp.*sp, \#-([0-9]{1,8})\]\!/o;
} elsif ($arch eq 'arm') {
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index a689f10930b5..26db63168284 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -177,7 +177,7 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
char *tag = NULL;
size_t size = unpack_u16_chunk(e, &tag);
/* if a name is specified it must match. otherwise skip tag */
- if (name && (!size || strcmp(name, tag)))
+ if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
goto fail;
} else if (name) {
/* if a name is specified and there is no name tag fail */
diff --git a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c
index 5b8520177b0e..7d72e3d48ad5 100644
--- a/sound/core/seq/oss/seq_oss_ioctl.c
+++ b/sound/core/seq/oss/seq_oss_ioctl.c
@@ -62,7 +62,7 @@ static int snd_seq_oss_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
if (copy_from_user(ev, arg, 8))
return -EFAULT;
memset(&tmpev, 0, sizeof(tmpev));
- snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client);
+ snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.client, dp->addr.port);
tmpev.time.tick = 0;
if (! snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev)) {
snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
diff --git a/sound/core/seq/oss/seq_oss_rw.c b/sound/core/seq/oss/seq_oss_rw.c
index 6a7b6aceeca9..499f3e8f4949 100644
--- a/sound/core/seq/oss/seq_oss_rw.c
+++ b/sound/core/seq/oss/seq_oss_rw.c
@@ -174,7 +174,7 @@ insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
memset(&event, 0, sizeof(event));
/* set dummy -- to be sure */
event.type = SNDRV_SEQ_EVENT_NOTEOFF;
- snd_seq_oss_fill_addr(dp, &event, dp->addr.port, dp->addr.client);
+ snd_seq_oss_fill_addr(dp, &event, dp->addr.client, dp->addr.port);
if (snd_seq_oss_process_event(dp, rec, &event))
return 0; /* invalid event - no need to insert queue */
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c
index bebddc60fde8..99654e7eb2d4 100644
--- a/sound/firewire/amdtp-am824.c
+++ b/sound/firewire/amdtp-am824.c
@@ -388,7 +388,7 @@ static void read_midi_messages(struct amdtp_stream *s,
u8 *b;
for (f = 0; f < frames; f++) {
- port = (s->data_block_counter + f) % 8;
+ port = (8 - s->tx_first_dbc + s->data_block_counter + f) % 8;
b = (u8 *)&buffer[p->midi_position];
len = b[0] - 0x80;
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
index 93b02be3a90e..6edec2387861 100644
--- a/sound/soc/codecs/cs4265.c
+++ b/sound/soc/codecs/cs4265.c
@@ -60,7 +60,7 @@ static const struct reg_default cs4265_reg_defaults[] = {
static bool cs4265_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
- case CS4265_CHIP_ID ... CS4265_SPDIF_CTL2:
+ case CS4265_CHIP_ID ... CS4265_MAX_REGISTER:
return true;
default:
return false;
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 3e65dc74eb33..e7aef841f87d 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1924,6 +1924,21 @@ static int max98090_configure_dmic(struct max98090_priv *max98090,
return 0;
}
+static int max98090_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+ struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
+ unsigned int fmt = max98090->dai_fmt;
+
+ /* Remove 24-bit format support if it is not in right justified mode. */
+ if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_RIGHT_J) {
+ substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+ snd_pcm_hw_constraint_msbits(substream->runtime, 0, 16, 16);
+ }
+ return 0;
+}
+
static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -2331,6 +2346,7 @@ EXPORT_SYMBOL_GPL(max98090_mic_detect);
#define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
static const struct snd_soc_dai_ops max98090_dai_ops = {
+ .startup = max98090_dai_startup,
.set_sysclk = max98090_dai_set_sysclk,
.set_fmt = max98090_dai_set_fmt,
.set_tdm_slot = max98090_set_tdm_slot,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 5d2fc5f58bfe..f4fd9548c529 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -753,7 +753,7 @@ static int snd_ni_control_init_val(struct usb_mixer_interface *mixer,
return err;
}
- kctl->private_value |= (value << 24);
+ kctl->private_value |= ((unsigned int)value << 24);
return 0;
}
@@ -914,7 +914,7 @@ static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer,
if (err < 0)
return err;
- kctl->private_value |= value[0] << 24;
+ kctl->private_value |= (unsigned int)value[0] << 24;
return 0;
}
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index a7d588bf3cdd..ea5f73dd7581 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -179,7 +179,7 @@ static void add_man_viewer(const char *name)
while (*p)
p = &((*p)->next);
*p = zalloc(sizeof(**p) + len + 1);
- strncpy((*p)->name, name, len);
+ strcpy((*p)->name, name);
}
static int supported_man_viewer(const char *name, size_t len)
diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
index 88f5143a5981..3c97e27383a9 100644
--- a/tools/perf/ui/tui/helpline.c
+++ b/tools/perf/ui/tui/helpline.c
@@ -23,7 +23,7 @@ static void tui_helpline__push(const char *msg)
SLsmg_set_color(0);
SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols);
SLsmg_refresh();
- strncpy(ui_helpline__current, msg, sz)[sz - 1] = '\0';
+ strlcpy(ui_helpline__current, msg, sz);
}
static int tui_helpline__show(const char *format, va_list ap)