summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Garberi <dade.garberi@gmail.com>2019-07-20 23:27:51 +0200
committerDavide Garberi <dade.garberi@gmail.com>2019-07-20 23:29:04 +0200
commit6fba3d56fa329e7070587509046859fd7eb0294e (patch)
treebcece2f645ee67644fcb97742b7eb0b93596e950
parentf596df2038c423e9d2eaf6ddc55c02c7d5480531 (diff)
parent313e787f28bbdb3d49fc69a7b7c38e6f014a13e6 (diff)
Merge LA.UM.7.5.2.r1-03300-8x96.0 of https://source.codeaurora.org/quic/la/kernel/msm-4.4 into lineage-16.0
313e787f28bb Merge "power: qpnp-smbcharger: Change ordering of EXTCON_USB_SPEED" into kernel.lnx.4.4.r37-rel dfa5b807ec2c Merge changes I0ab244e6,I05a4aa96 into kernel.lnx.4.4.r37-rel c900b4827149 msm: ipa: Fix array out of bound and use after NULL check b562b057dd2a msm: ipa: Fix pointer checked for NULL may be used 216dfe7e7a14 usb: phy-msm-susb-qmp: Add checks to check clk_enabled 2c0a97a53f77 power: qpnp-smbcharger: Change ordering of EXTCON_USB_SPEED 56d12bfe26c3 Merge commit '09d42880fd9f4d04317f030021b85323b8f8b9b9' into HEAD 09d42880fd9f Merge "msm: camera_v2: isp: update the frame drop during error case" 19d79e95f10c Merge "msm:camera: add trace log support for VFE events" 3ae0451881ca Merge "msm: camera_v2: Remove sysfs bind/unbind files" 45b4ac208b7b msm:camera: add trace log support for VFE events 5974bd4025ea msm: camera_v2: Fix page fault issue in camera ISP ed8c0918eeb1 Merge "icnss: Reduce the shutdown timeout from 50sec to 15sec" 7e4d8780224c Merge "drm/msm/dsi-staging: Add range check in debugfs_dump_info_read" 978400398a92 icnss: Reduce the shutdown timeout from 50sec to 15sec 4e08c8cbacd4 msm: camera_v2: Remove sysfs bind/unbind files 79a8f215703e Merge "ASoC: sdm660_cdc: Set speaker amplifier enable bit" c0f636f83226 Merge "cnss2: Update board data file name format" bd48b0a101e8 Merge "msm: kgsl: Add missing check for snapshot IB dump" 2f5e49a21882 Merge "defconfig: msm: Disable EXT2 and EXT3 FS configs for MSM8998" 46ece1ae20ad Merge "sched/walt: Fix the memory leak of idle task load pointers" 78540133736a Merge "soc: qcom: smem: validate fields of shared structures" 196d97abd323 Merge "Merge android-4.4.183 (94fd428) into msm-4.4" fad4d2e83739 Merge "msm: kgsl: Change data type for GPU ib vote" 54d23a97a07e Merge "drivers: thermal: Use FCAP scm call instead of DMAX in LMH DCVSh" 1379d11803dd msm: kgsl: Add missing check for snapshot IB dump 2c8f4699fdd0 defconfig: msm: Disable EXT2 and EXT3 FS configs for MSM8998 fcc47ec62ae1 soc: qcom: smem: validate fields of shared structures 7151def9c713 ASoC: sdm660_cdc: Set speaker amplifier enable bit f395d5810f27 sched/walt: Fix the memory leak of idle task load pointers 03f0af3c211e drivers: thermal: Use FCAP scm call instead of DMAX in LMH DCVSh f6ee0c2bb45d drivers: thermal: Use FCAP scm call instead of DMAX in KTM cb7df67908b0 msm: kgsl: Change data type for GPU ib vote c94369b4c1fc cnss2: print firmware cap info in stats 9a1c2880320b Merge android-4.4.183 (94fd428) into msm-4.4 94fd42809f7d Merge 4.4.183 into android-4.4 308743255040 Linux 4.4.183 df7ba8162ca1 Abort file_remove_privs() for non-reg. files 8f6345a11caa coredump: fix race condition between mmget_not_zero()/get_task_mm() and core dumping 3692bc31c1ff Revert "crypto: crypto4xx - properly set IV after de- and encrypt" 39c7c903c63d scsi: libsas: delete sas port if expander discover failed a272035ea1bf scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() af8cd6101bf5 net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs b25c62cc16e0 KVM: PPC: Book3S: Use new mutex to synchronize access to rtas token list 7ef8d778cf3e ia64: fix build errors by exporting paddr_to_nid() 432030b25b86 configfs: Fix use-after-free when accessing sd->s_dentry d5a18c8609f3 i2c: dev: fix potential memory leak in i2cdev_ioctl_rdwr be1b9df5bba1 net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() 0bb6c295e463 gpio: fix gpio-adp5588 build errors dd961efe8dee perf/ring_buffer: Add ordering to rb->nest increment 8abd8a9a975e perf/ring_buffer: Fix exposing a temporarily decreased data_head 3e74b3f05abf x86/CPU/AMD: Don't force the CPB cap when running under a hypervisor f4678b7808e7 mISDN: make sure device name is NUL terminated e2f9c0f73454 sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg 753aa7556089 neigh: fix use-after-free read in pneigh_get_next 709d8771fab7 lapb: fixed leak of control-blocks. 1777c35e8d47 ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero 6f057abd08d1 be2net: Fix number of Rx queues used for flow hashing 7139a9f6246d ax25: fix inconsistent lock state in ax25_destroy_timer f1a5c6b083bc USB: serial: option: add Telit 0x1260 and 0x1261 compositions a67d65958e2a USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode b8ee804bba8f USB: serial: pl2303: add Allied Telesis VT-Kit3 f14747c88170 USB: usb-storage: Add new ID to ums-realtek 038c192699a9 USB: Fix chipmunk-like voice when using Logitech C270 for recording audio. 8f6b0e59d2a0 drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define() 6e0c7e73232f drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an invalid read ce391e4cdef8 KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION a1b9c6b4cba0 KVM: x86/pmu: do not mask the value that is written to fixed PMUs 7caddacf863f usbnet: ipheth: fix racing condition f80a35fcb9e9 scsi: bnx2fc: fix incorrect cast to u64 on shift operation da51a322f197 scsi: lpfc: add check for loss of ndlp when sending RRQ 3a2ff1088c2a Drivers: misc: fix out-of-bounds access in function param_set_kgdbts_var 1f8233ca3a48 ASoC: cs42xx8: Add regcache mask dirty 91f1fc1ae409 cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() 8b47af927e2e bcache: fix stack corruption by PRECEDING_KEY() a2aabf288bf7 i2c: acorn: fix i2c warning d774bd27b4f5 ptrace: restore smp_rmb() in __ptrace_may_access() 5aff00ee839a signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO 0b871fc866eb fs/ocfs2: fix race in ocfs2_dentry_attach_lock() c05fed507582 mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node be499b84c3bd libata: Extend quirks for the ST1000LM024 drives with NOLPM quirk d7a18814fff9 ALSA: seq: Cover unsubscribe_port() in list_mutex 4282a0b1db65 Revert "Bluetooth: Align minimum encryption key size for LE and BR/EDR connections" cd23996afa14 futex: Fix futex lock the wrong page 38fbd5c2d572 ARM: exynos: Fix undefined instruction during Exynos5422 resume 5767587907fd pwm: Fix deadlock warning when removing PWM device 113a78a0a537 ARM: dts: exynos: Always enable necessary APIO_1V8 and ABB_1V8 regulators on Arndale Octa 78184953a2ed pwm: tiehrpwm: Update shadow register for disabling PWMs d24e22cde8b3 dmaengine: idma64: Use actual device for DMA transfers 533171620cd5 gpio: gpio-omap: add check for off wake capable gpios 3b4652ba9d78 PCI: xilinx: Check for __get_free_pages() failure c869210e0ac6 video: imsttfb: fix potential NULL pointer dereferences 5c7fbc5f6a7d video: hgafb: fix potential NULL pointer dereference bea8fa863ce9 PCI: rcar: Fix a potential NULL pointer dereference 76208df36d7a PCI: rpadlpar: Fix leaked device_node references in add/remove paths 100468652e5a ARM: dts: imx6qdl: Specify IMX6QDL_CLK_IPG as "ipg" clock to SDMA 927d2be77e6c ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ipg" clock to SDMA 8aee025af280 ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ahb" clock to SDMA b49501f51371 clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 4270dc6a7a79 soc: mediatek: pwrap: Zero initialize rdata in pwrap_init_cipher 845676341c2d platform/chrome: cros_ec_proto: check for NULL transfer function c7155e51cf85 x86/PCI: Fix PCI IRQ routing table memory leak 198a54f07f51 nfsd: allow fh_want_write to be called twice e6779b264d69 fuse: retrieve: cap requested size to negotiated max_write 742cb74bf108 nvmem: core: fix read buffer in place 750c55e69cca ALSA: hda - Register irq handler after the chip initialization 09ad374f23ce iommu/vt-d: Set intel_iommu_gfx_mapped correctly 9e4ed17b9416 f2fs: fix to do sanity check on valid block count of segment 534ef922376e f2fs: fix to avoid panic in do_recover_data() 90a238a8a2d2 ntp: Allow TAI-UTC offset to be set to zero 25be7d51a012 drm/bridge: adv7511: Fix low refresh rate selection 8fdebdd06c4b perf/x86/intel: Allow PEBS multi-entry in watermark mode dee1ba919ca2 mfd: twl6040: Fix device init errors for ACCCTL register 4110c4188853 mfd: intel-lpss: Set the device in reset state when init 1bef19130b5b kernel/sys.c: prctl: fix false positive in validate_prctl_map() 937fa1624a1f mm/cma_debug.c: fix the break condition in cma_maxchunk_get() fceb0be41836 mm/cma.c: fix crash on CMA allocation if bitmap allocation fails 9c8d4d77e3aa hugetlbfs: on restore reserve error path retain subpool reservation d8129a5d7a9d ipc: prevent lockup on alloc_msg and free_msg 50c0db539937 sysctl: return -EINVAL if val violates minmax 8b9241b052a2 fs/fat/file.c: issue flush after the writeback of FAT 335e20ca9562 Merge "soc: qcom: glink_spi_xprt: Sanitize input for short cmd" abc2a59bfdb9 Merge "soc: qcom: hab: add error handling when dt item is missing" 9998d2e52dd4 mm: add /proc/pid/smaps_rollup a2165163680e Merge "msm: ais: sensor: actuator: fix out of bound read for bivcm region params" 7ec9476039c1 soc: qcom: hab: add error handling when dt item is missing 7967865bb4c4 msm: ais: sensor: actuator: fix out of bound read for bivcm region params 14f9c777669f Merge "Merge android-4.4.182 (9c4ab57) into msm-4.4" eee21eb4a635 ANDROID: kernel: cgroup: cpuset: Clear cpus_requested for empty buf f1adac4c222b ANDROID: kernel: cgroup: cpuset: Add missing allocation of cpus_requested in alloc_trial_cpuset 291c54b284a4 i2c: virtio: reallocate memory for each msg buffer ca64572d5459 Merge changes into msm-4.4 a32f2cd75906 Merge android-4.4.182 (9c4ab57) into msm-4.4 2ae4cde5790c Merge "i2c: refine the driver of i2c virtualization" 9c4ab5729952 Merge 4.4.182 into android-4.4 33790f2eda73 Linux 4.4.182 f938ae0ce5ef tcp: enforce tcp_min_snd_mss in tcp_mtu_probing() e757d052f3b8 tcp: add tcp_min_snd_mss sysctl ad472d3a9483 tcp: tcp_fragment() should apply sane memory limits 4657ee0fe05e tcp: limit payload size of sacked skbs 17c66e9e49a1 Merge "msm: vidc: add additional check to avoid out of bound access" 4e933027e684 Merge "Merge android-4.4.181 (bd858d7) into msm-4.4" be5afd934314 i2c: refine the driver of i2c virtualization f1057f82fa62 msm: vidc: add additional check to avoid out of bound access c176a066dfd3 diag: dci: Correct out of bounds check in processing dci pkt rsp cc47c2c325b9 Merge "msm: adsprpc: maintain local copy of rpra offloaded to DSP" 1f3eb68e71cd msm: adsprpc: maintain local copy of rpra offloaded to DSP a50f44266d21 Merge "diag: Prevent out-of-bound access while processing userspace data" c658076e45e0 Merge "ASoC: msm: Add support for AVS version check" f328b4d28d25 Merge "arm: dts: msm: Add avs-version dt property for 8996" 5dbfa1533af8 diag: Prevent out-of-bound access while processing userspace data eb0322ea9b07 arm: dts: msm: Add avs-version dt property for 8996 5ef154a26639 Merge android-4.4.181 (bd858d7) into msm-4.4 7caeb5cb7c4f soc: qcom: glink_spi_xprt: Sanitize input for short cmd 17fd8dbacb92 Merge "soc: qcom: hab: add missing variable declaration" 1cc130f95ec7 UPSTREAM: binder: check for overflow when alloc for security context 784672577648 BACKPORT: binder: fix race between munmap() and direct reclaim 849ecbea5548 soc: qcom: hab: add missing variable declaration bd858d730975 Merge 4.4.181 into android-4.4 0434b31d567e Merge "dwc3-msm: Fix dwc3_drd_state_string for undefined state" 411c38c969a7 Merge "usb: dwc3-msm: Ensure hardware is reset during role change" 8dce56fa0ccf Merge "usb: dwc3-msm: add enum for drd_states to remove otg_state usage" d7b7345c3a5d Linux 4.4.181 f1d7eebd9d67 ethtool: check the return value of get_regs_len 647f72b0d75c ipv4: Define __ipv4_neigh_lookup_noref when CONFIG_INET is disabled c9696a8f3e64 fuse: Add FOPEN_STREAM to use stream_open() 3bf0c459615a fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock 0f5fab865ae9 drm/gma500/cdv: Check vbt config bits when detecting lvds panels e087f7519114 genwqe: Prevent an integer overflow in the ioctl 59565e894518 MIPS: pistachio: Build uImage.gz by default 8061c23f5378 fuse: fallocate: fix return with locked inode cf30c1953467 parisc: Use implicit space register selection for loading the coherence index of I/O pdirs f0d1e74c8120 rcu: locking and unlocking need to always be at least barriers 44657dbba7c4 pktgen: do not sleep with the thread lock held. eded0b11c7a3 net: rds: fix memory leak in rds_ib_flush_mr_pool 54dd5e352cf7 net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query cc475966e5f7 neighbor: Call __ipv4_neigh_lookup_noref in neigh_xmit e5c6de6694ed ethtool: fix potential userspace buffer overflow 8795708bc939 media: uvcvideo: Fix uvc_alloc_entity() allocation alignment 2b13a9580ef9 usb: gadget: fix request length error for isoc transfer 8b15aae1baa2 net: cdc_ncm: GetNtbFormat endian fix 613b4bc1951d Revert "x86/build: Move _etext to actual end of .text" 6ad730b83178 userfaultfd: don't pin the user memory in userfaultfd_file_create() 4e06554db5e5 brcmfmac: add subtype check for event handling in data path 993b68aa3ef7 brcmfmac: add length checks in scheduled scan result handler 35bcfbad5d94 brcmfmac: fix incorrect event channel deduction 8c12de962667 brcmfmac: revise handling events in receive path 5f4688a15c24 brcmfmac: screening firmware event packet 6da841e9ae87 brcmfmac: Add length checks on firmware events c55a2cffa5ca bnx2x: disable GSO where gso_size is too big for hardware a33b6d4c8bc7 net: create skb_gso_validate_mac_len() c53c1a821d62 binder: replace "%p" with "%pK" 5280efe442b2 binder: Replace "%p" with "%pK" for stable 336c16621785 CIFS: cifs_read_allocate_pages: don't iterate through whole page array on ENOMEM 360f8fe46f74 kernel/signal.c: trace_signal_deliver when signal_group_exit 7a47d1873120 memcg: make it work on sparse non-0-node systems 5db0a9c3cc52 tty: max310x: Fix external crystal register setup e498745310d0 tty: serial: msm_serial: Fix XON/XOFF 986adddb9d8f drm/nouveau/i2c: Disable i2c bus access after ->fini() bf8f6b43c2e7 ALSA: hda/realtek - Set default power save node to 0 494447b90d6d Btrfs: fix race updating log root item during fsync af34de02a6a7 scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) e85d002556ea scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove 8282730a0afa media: smsusb: better handle optional alignment 0bce1ea89712 media: usb: siano: Fix false-positive "uninitialized variable" warning b1782be70e1e media: usb: siano: Fix general protection fault in smsusb d52c0ffb383f USB: rio500: fix memory leak in close after disconnect b92be99a0c8b USB: rio500: refuse more than one device at a time ee9d750e9ac8 USB: Add LPM quirk for Surface Dock GigE adapter 30e66d7d2fb9 USB: sisusbvga: fix oops in error path of sisusb_probe 018b7ea9ca24 USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor f5e1ec93b208 usb: xhci: avoid null pointer deref when bos field is NULL 017e6726a4fb xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() ec70e2c130d6 include/linux/bitops.h: sanitize rotate primitives fbbc4fe02a31 sparc64: Fix regression in non-hypervisor TLB flush xcall 5bce46edeb72 tipc: fix modprobe tipc failed after switch order of device registration -v2 416d252ba926 Revert "tipc: fix modprobe tipc failed after switch order of device registration" f1613a9e1bdc xen/pciback: Don't disable PCI_COMMAND on PCI device reset. 383687e15cd0 crypto: vmx - ghash: do nosimd fallback manually 61ba8e9f51b3 net: mvpp2: fix bad MVPP2_TXQ_SCHED_TOKEN_CNTR_REG queue value 1d33a3ebd945 bnxt_en: Fix aggregation buffer leak under OOM condition. 7d423301240b tipc: Avoid copying bytes beyond the supplied data 332bff9d9a08 usbnet: fix kernel crash after disconnect 16ffb5f7c335 net: stmmac: fix reset gpio free missing 4f9c73aa2930 net-gro: fix use-after-free read in napi_gro_frags() 5cbaa135a0e1 llc: fix skb leak in llc_build_and_send_ui_pkt() 36a7222071d1 ipv6: Consider sk_bound_dev_if when binding a raw socket to an address 9fbf1ac57c7a ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM 0984cb76d294 spi: Fix zero length xfer bug 854415f37aae spi: rspi: Fix sequencer reset during initialization c927451887c1 spi : spi-topcliff-pch: Fix to handle empty DMA buffers 445c07409179 scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices 3a5d11332896 media: saa7146: avoid high stack usage with clang 5a96cf10dc5c media: go7007: avoid clang frame overflow warning with KASAN 0e9f0805eeea media: m88ds3103: serialize reset messages in m88ds3103_set_frontend 9effa38946b6 scsi: qla4xxx: avoid freeing unallocated dma memory 95f0bb0a6c83 usb: core: Add PM runtime calls to usb_hcd_platform_shutdown 1909121a6192 rcutorture: Fix cleanup path for invalid torture_type strings 1081d04a0443 tty: ipwireless: fix missing checks for ioremap c05b2ed7bc1b virtio_console: initialize vtermno value for ports 348ec7b9a1c1 media: wl128x: prevent two potential buffer overflows 557ae685914b spi: tegra114: reset controller on probe 5e75d5e2cd0c cxgb3/l2t: Fix undefined behaviour dc2a8861fdb8 ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put 971e4a273242 ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put 5db3c5adf44a HID: core: move Usage Page concatenation to Main item cb7872f12835 chardev: add additional check for minor range overlap 5680f59f0f15 x86/ia32: Fix ia32_restore_sigcontext() AC leak 94032b2e05c9 arm64: cpu_ops: fix a leaked reference by adding missing of_node_put 04f45a555ec3 scsi: ufs: Avoid configuring regulator with undefined voltage range 60bcfed2ad60 scsi: ufs: Fix regulator load and icc-level configuration 0a597d2badef brcmfmac: fix race during disconnect when USB completion is in progress f95ab00ab455 brcmfmac: convert dev_init_lock mutex to completion db74ef82ca8b b43: shut up clang -Wuninitialized variable warning 951fbf92381a brcmfmac: fix missing checks for kmemdup 1d3ee4d7fc6a rtlwifi: fix a potential NULL pointer dereference 6d7b052d8466 iio: common: ssp_sensors: Initialize calculated_time in ssp_common_process_data e98ef6767e41 iio: hmc5843: fix potential NULL pointer dereferences a86d06179423 iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion 4400dcd69478 x86/build: Keep local relocations with ld.lld 75ffb58460e3 cpufreq: pmac32: fix possible object reference leak 3d041608fd4b cpufreq/pasemi: fix possible object reference leak 4d02f33a4f42 cpufreq: ppc_cbe: fix possible object reference leak 6be923556aad s390: cio: fix cio_irb declaration 65e3cb04a5a2 extcon: arizona: Disable mic detect if running when driver is removed db7eb206560c PM / core: Propagate dev->power.wakeup_path when no callbacks 066a286679b4 mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support 6a783be705ba mmc: sdhci-of-esdhc: add erratum eSDHC5 support 8b0e6af16ae6 mmc_spi: add a status check for spi_sync_locked a30e90a8eb3a scsi: libsas: Do discovery on empty PHY to update PHY info 915defac2a9a hwmon: (f71805f) Use request_muxed_region for Super-IO accesses 0eb8a476ffc5 hwmon: (pc87427) Use request_muxed_region for Super-IO accesses 79deb6abd1f5 hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses 92b4d16997c4 hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses e3e58378c678 hwmon: (vt1211) Use request_muxed_region for Super-IO accesses 488920af3bb3 RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure 2ff310e6dae2 i40e: don't allow changes to HW VLAN stripping on active port VLANs bc791e819503 x86/irq/64: Limit IST stack overflow check to #DB stack 3557f0857767 USB: core: Don't unbind interfaces following device reset failure 6f5e198878fb sched/core: Handle overflow in cpu_shares_write_u64 9812286a63a1 sched/core: Check quota and period overflow at usec to nsec conversion 9d4961a415ed powerpc/numa: improve control of topology updates 82077215ed25 media: pvrusb2: Prevent a buffer overflow ca865598abf1 media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable() a8e0739d465e audit: fix a memory leak bug ff3038fe657d media: ov2659: make S_FMT succeed even if requested format doesn't match 2d97a3abcf2f media: au0828: stop video streaming only when last user stops 115ccd9ca776 media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper 1433d7a0937b media: coda: clear error return value before picture run 5cadb7ae715f dmaengine: at_xdmac: remove BUG_ON macro in tasklet af8b5d7d9477 pinctrl: pistachio: fix leaked of_node references 74dd38a5a447 HID: logitech-hidpp: use RAP instead of FAP to get the protocol version 9bffc62051a9 mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions ae6b1f761180 x86/mm: Remove in_nmi() warning from 64-bit implementation of vmalloc_fault() b059848e119f smpboot: Place the __percpu annotation correctly 28d8827a09b0 x86/build: Move _etext to actual end of .text d3eb2caf6d41 bcache: avoid clang -Wunintialized warning 7bf3463abc95 bcache: add failure check to run_cache_set() for journal replay d4547049bb7f bcache: fix failure in journal relplay 5789884b98ab bcache: return error immediately in bch_journal_replay() 50d25ca802f5 net: cw1200: fix a NULL pointer dereference af2fb022b390 mwifiex: prevent an array overflow 4b24af093631 ASoC: fsl_sai: Update is_slave_mode with correct value c1045350a6c4 mac80211/cfg80211: update bss channel on channel switch a3c50ef9fd43 dmaengine: pl330: _stop: clear interrupt status 958848a1d97c w1: fix the resume command API e4163587c4ee rtc: 88pm860x: prevent use-after-free on device remove a898d150956b brcm80211: potential NULL dereference in brcmf_cfg80211_vndr_cmds_dcmd_handler() 5e1a879d9ab3 spi: pxa2xx: fix SCR (divisor) calculation 3d521a6fba45 ASoC: imx: fix fiq dependencies af283aba93bb powerpc/boot: Fix missing check of lseek() return value dba032038c95 mmc: core: Verify SD bus width 333e8303d6e0 cxgb4: Fix error path in cxgb4_init_module 6948c6bc17d6 gfs2: Fix lru_count going negative 635c71d11234 tools include: Adopt linux/bits.h ed2faf464d9b perf tools: No need to include bitops.h in util.h a1f254dc06f9 at76c50x-usb: Don't register led_trigger if usb_register_driver failed f5e4337e4a9c ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit e39af96f4dc1 media: vivid: use vfree() instead of kfree() for dev->bitmap_cap a04e71a0dbc6 media: cpia2: Fix use-after-free in cpia2_exit 28eeeb86046e fbdev: fix WARNING in __alloc_pages_nodemask bug bf8474c64846 hugetlb: use same fault hash key for shared and private mappings 6bc153907900 fbdev: fix divide error in fb_var_to_videomode 5c9a20390c01 btrfs: sysfs: don't leak memory when failing add fsid 0fa88718cdc5 Btrfs: fix race between ranged fsync and writeback of adjacent ranges 2f5ac0bd2ef7 gfs2: Fix sign extension bug in gfs2_update_stats 8aae5e98fec2 crypto: vmx - CTR: always increment IV as quadword 582bb52e4803 Revert "scsi: sd: Keep disk read-only when re-reading partition" bd020b331706 bio: fix improper use of smp_mb__before_atomic() 603212bdc59c KVM: x86: fix return value for reserved EFER 75d63b131b73 ext4: do not delete unlinked inode from orphan list on failed truncate 31943685dd49 fbdev: sm712fb: fix memory frequency by avoiding a switch/case fallthrough 7d64186e7910 btrfs: Honour FITRIM range constraints during free space trim 57e84e4c073d md/raid: raid5 preserve the writeback action after the parity check 9013f4870848 Revert "Don't jump to compute_result state from check_result state" 0c57364fa0f4 perf bench numa: Add define for RUSAGE_THREAD if not present 66ee750cfdd7 ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour fc0208b3428d power: supply: sysfs: prevent endless uevent loop with CONFIG_POWER_SUPPLY_DEBUG dd37fa44dffa KVM: arm/arm64: Ensure vcpu target is unset on reset failure fe4f461ba517 xfrm4: Fix uninitialized memory read in _decode_session4 cd0848733f25 vti4: ipip tunnel deregistration fixes. 8fd94b65d207 xfrm6_tunnel: Fix potential panic when unloading xfrm6_tunnel module 86040d722b29 xfrm: policy: Fix out-of-bound array accesses in __xfrm_policy_unlink daea41651d43 dm delay: fix a crash when invalid device is specified 566004721c90 PCI: Mark Atheros AR9462 to avoid bus reset 0dc2ad06ddad fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting 4673eae95b53 fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display c996722f7fff fbdev: sm712fb: fix support for 1024x768-16 mode ebfadb510e3c fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM c92bde52742c fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA 0d5cd17ce037 fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F ca5ce8db7f23 fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75 6c2fb5beecba fbdev: sm712fb: fix brightness control on reboot, don't set SR30 dbc86a927d66 perf intel-pt: Fix sample timestamp wrt non-taken branches eedc9a210f9f perf intel-pt: Fix improved sample timestamp f5da0aeca525 perf intel-pt: Fix instructions sampling rate a5b2e4b6ac21 memory: tegra: Fix integer overflow on tick value calculation 11988047b39a tracing: Fix partial reading of trace event's id file a7929c94860e ceph: flush dirty inodes before proceeding with remount 3c99cd905ba9 iommu/tegra-smmu: Fix invalid ASID bits on Tegra30/114 40857ab73988 fuse: honor RLIMIT_FSIZE in fuse_file_fallocate 73724958d129 fuse: fix writepages on 32bit 12060f4740ca clk: tegra: Fix PLLM programming on Tegra124+ when PMC overrides divider 4676a07add08 NFS4: Fix v4.0 client state corruption when mount e8623e7a8f4b media: ov6650: Fix sensor possibly not detected on probe dffc9e5ffae5 cifs: fix strcat buffer overflow and reduce raciness in smb21_set_oplock_level() b8ab0c4effb8 of: fix clang -Wunsequenced for be32_to_cpu() 2a98d346396a intel_th: msu: Fix single mode with IOMMU bc065776c31e md: add mddev->pers to avoid potential NULL pointer dereference ade291d2230a stm class: Fix channel free in stm output free path 65d14634b694 tipc: fix modprobe tipc failed after switch order of device registration ff69bb4be643 tipc: switch order of device registration to fix a crash 2ff783f3e05e ppp: deflate: Fix possible crash in deflate_init dd20e0c039fe net/mlx4_core: Change the error print to info print b2f72a431142 net: avoid weird emergency message 70064f7ea100 KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes 5e9bc16ff49f ALSA: hda/realtek - Fix for Lenovo B50-70 inverted internal microphone bug 98529ecd313b ext4: zero out the unused memory region in the extent tree block 9ff6372e5a6b fs/writeback.c: use rcu_barrier() to wait for inflight wb switches going into workqueue when umount bfce20eaf18e writeback: synchronize sync(2) against cgroup writeback membership switches cd042379c6ad crypto: arm/aes-neonbs - don't access already-freed walk.iv b70e97ae5d8e crypto: salsa20 - don't access already-freed walk.iv 6dc48d059646 crypto: chacha20poly1305 - set cra_name correctly b82055365307 crypto: gcm - fix incompatibility between "gcm" and "gcm_base" de087dd9f5c6 crypto: gcm - Fix error return code in crypto_gcm_create_common() 064d0c5a9ae6 ipmi:ssif: compare block number correctly for multi-part return messages bef039b2419e bcache: never set KEY_PTRS of journal key to 0 in journal_reclaim() 5651075a1ce3 bcache: fix a race between cache register and cacheset unregister 686e4352e3d8 Btrfs: do not start a transaction at iterate_extent_inodes() b268b6e501ed ext4: fix ext4_show_options for file systems w/o journal f3b9c26f191b ext4: actually request zeroing of inode table after grow e5100e7fa78e tty/vt: fix write/write race in ioctl(KDSKBSENT) handler 592a36c59f4c mfd: da9063: Fix OTP control register names to match datasheets for DA9063/63L e3a74fbc42ca ocfs2: fix ocfs2 read inode data panic in ocfs2_iget b614485b6b93 mm/mincore.c: make mincore() more conservative 80cc516ed783 ASoC: RT5677-SPI: Disable 16Bit SPI Transfers e6bf706cee3f ASoC: max98090: Fix restore of DAPM Muxes 2a8188c68e0a ALSA: hda/realtek - EAPD turn on later 1bbb08c8ab6a ALSA: hda/hdmi - Consider eld_valid when reporting jack event 2d8956305ae8 ALSA: usb-audio: Fix a memory leak bug b1c1888ad6c9 crypto: x86/crct10dif-pcl - fix use via crypto_shash_digest() 2ee7c2310cd0 crypto: crct10dif-generic - fix use via crypto_shash_digest() 2ee0dd38a0a0 crypto: vmx - fix copy-paste error in CTR mode f7dee0816e5d ARM: exynos: Fix a leaked reference by adding missing of_node_put ce814dc7e811 x86/speculation/mds: Improve CPU buffer clear documentation 4d68e2bf3834 x86/speculation/mds: Revert CPU buffer clear on double fault exit b1d850962510 ASoC: msm: Add support for AVS version check fbf98df8d02a cnss2: Update board data file name format 5e073ffd6668 drm/msm/dsi-staging: Add range check in debugfs_dump_info_read 9600b86489f9 dwc3-msm: Fix dwc3_drd_state_string for undefined state cc96e0915225 usb: dwc3-msm: Ensure hardware is reset during role change 02d74bda3466 usb: dwc3-msm: add enum for drd_states to remove otg_state usage e4e5a975f4ae Merge remote-tracking branch 'origin/upstream-f2fs-stable-linux-4.4.y' into android-4.4 2d812ba62ee4 f2fs: link f2fs quota ops for sysfile 6dc3fb0ba854 fs: sdcardfs: Add missing option to show_options * Excluded commits: 8be3b55c4cc7 msm: camera_v2: isp: update the frame drop during error case 28e17c1f6505 msm: camera_v2: isp: handle frame drop due to scheduling latency Change-Id: Ib67f22a311625da7dd130d2491ef9e035b1db54f Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
-rw-r--r--Documentation/ABI/testing/procfs-smaps_rollup31
-rw-r--r--Documentation/networking/ip-sysctl.txt8
-rw-r--r--Documentation/x86/mds.rst44
-rw-r--r--Makefile2
-rw-r--r--arch/arm/boot/dts/exynos5420-arndale-octa.dts2
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi2
-rw-r--r--arch/arm/configs/msmcortex_defconfig4
-rw-r--r--arch/arm/crypto/aesbs-glue.c4
-rw-r--r--arch/arm/kvm/arm.c11
-rw-r--r--arch/arm/mach-exynos/firmware.c1
-rw-r--r--arch/arm/mach-exynos/suspend.c21
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig4
-rw-r--r--arch/arm64/configs/msmcortex_defconfig4
-rw-r--r--arch/arm64/kernel/cpu_ops.c1
-rw-r--r--arch/ia64/mm/numa.c1
-rw-r--r--arch/mips/pistachio/Platform1
-rw-r--r--arch/powerpc/boot/addnote.c6
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/kvm/book3s.c1
-rw-r--r--arch/powerpc/kvm/book3s_rtas.c14
-rw-r--r--arch/powerpc/mm/numa.c18
-rw-r--r--arch/s390/kvm/kvm-s390.c35
-rw-r--r--arch/sparc/mm/ultra.S4
-rw-r--r--arch/x86/Makefile2
-rw-r--r--arch/x86/crypto/crct10dif-pclmul_glue.c13
-rw-r--r--arch/x86/ia32/ia32_signal.c29
-rw-r--r--arch/x86/kernel/cpu/amd.c7
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c2
-rw-r--r--arch/x86/kernel/irq_64.c19
-rw-r--r--arch/x86/kernel/traps.c8
-rw-r--r--arch/x86/kvm/pmu_intel.c13
-rw-r--r--arch/x86/kvm/x86.c31
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--arch/x86/pci/irq.c10
-rw-r--r--crypto/chacha20poly1305.c4
-rw-r--r--crypto/crct10dif_generic.c11
-rw-r--r--crypto/gcm.c36
-rw-r--r--crypto/salsa20_generic.c2
-rw-r--r--drivers/android/binder.c12
-rw-r--r--drivers/android/binder_alloc.c20
-rw-r--r--drivers/ata/libata-core.c9
-rw-r--r--drivers/base/power/main.c4
-rw-r--r--drivers/char/diag/diag_dci.c3
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c6
-rw-r--r--drivers/char/virtio_console.c3
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c11
-rw-r--r--drivers/clk/tegra/clk-pll.c4
-rw-r--r--drivers/cpufreq/pasemi-cpufreq.c1
-rw-r--r--drivers/cpufreq/pmac32-cpufreq.c2
-rw-r--r--drivers/cpufreq/ppc_cbe_cpufreq.c1
-rw-r--r--drivers/crypto/amcc/crypto4xx_alg.c3
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c9
-rw-r--r--drivers/crypto/vmx/aesp8-ppc.pl6
-rw-r--r--drivers/crypto/vmx/ghash.c218
-rw-r--r--drivers/dma/at_xdmac.c6
-rw-r--r--drivers/dma/idma64.c6
-rw-r--r--drivers/dma/idma64.h2
-rw-r--r--drivers/dma/pl330.c10
-rw-r--r--drivers/extcon/extcon-arizona.c10
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/gpio-omap.c25
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c3
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c3
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h1
-rw-r--r--drivers/gpu/drm/i2c/adv7511.c6
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_display.c5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c7
-rw-r--r--drivers/gpu/msm/adreno_snapshot.c15
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.c11
-rw-r--r--drivers/hid/hid-core.c36
-rw-r--r--drivers/hid/hid-logitech-hidpp.c17
-rw-r--r--drivers/hwmon/f71805f.c15
-rw-r--r--drivers/hwmon/pc87427.c14
-rw-r--r--drivers/hwmon/smsc47b397.c13
-rw-r--r--drivers/hwmon/smsc47m1.c28
-rw-r--r--drivers/hwmon/vt1211.c15
-rw-r--r--drivers/hwtracing/intel_th/msu.c35
-rw-r--r--drivers/hwtracing/stm/core.c2
-rw-r--r--drivers/i2c/busses/i2c-acorn.c1
-rw-r--r--drivers/i2c/busses/virtio-i2c.c118
-rw-r--r--drivers/i2c/i2c-dev.c1
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c16
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio.c2
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c2
-rw-r--r--drivers/infiniband/hw/mlx4/main.c3
-rw-r--r--drivers/iommu/intel-iommu.c7
-rw-r--r--drivers/iommu/tegra-smmu.c25
-rw-r--r--drivers/isdn/mISDN/socket.c5
-rw-r--r--drivers/md/bcache/alloc.c5
-rw-r--r--drivers/md/bcache/bset.c16
-rw-r--r--drivers/md/bcache/bset.h34
-rw-r--r--drivers/md/bcache/journal.c37
-rw-r--r--drivers/md/bcache/super.c19
-rw-r--r--drivers/md/dm-delay.c3
-rw-r--r--drivers/md/md.c6
-rw-r--r--drivers/md/raid5.c29
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c9
-rw-r--r--drivers/media/i2c/ov2659.c6
-rw-r--r--drivers/media/i2c/soc_camera/ov6650.c27
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c5
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c5
-rw-r--r--drivers/media/platform/coda/coda-bit.c3
-rw-r--r--drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c3
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c3
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h7
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c76
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c7
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c3
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c1
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c1
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c39
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h7
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c2
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c7
-rw-r--r--drivers/media/usb/au0828/au0828-video.c16
-rw-r--r--drivers/media/usb/cpia2/cpia2_v4l.c3
-rw-r--r--drivers/media/usb/go7007/go7007-fw.c4
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.h1
-rw-r--r--drivers/media/usb/siano/smsusb.c33
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c2
-rw-r--r--drivers/memory/tegra/mc.c2
-rw-r--r--drivers/mfd/intel-lpss.c3
-rw-r--r--drivers/mfd/twl6040.c13
-rw-r--r--drivers/misc/genwqe/card_dev.c2
-rw-r--r--drivers/misc/genwqe/card_utils.c4
-rw-r--r--drivers/misc/kgdbts.c4
-rw-r--r--drivers/mmc/core/sd.c8
-rw-r--r--drivers/mmc/host/mmc_spi.c4
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c5
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c18
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/l2t.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c15
-rw-r--r--drivers/net/ethernet/dec/tulip/de4x5.c1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c8
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c5
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c3
-rw-r--r--drivers/net/ppp/ppp_deflate.c20
-rw-r--r--drivers/net/usb/cdc_ncm.c4
-rw-r--r--drivers/net/usb/ipheth.c3
-rw-r--r--drivers/net/usb/usbnet.c6
-rw-r--r--drivers/net/wireless/at76c50x-usb.c4
-rw-r--r--drivers/net/wireless/b43/phy_lp.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bus.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c45
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h82
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.c5
-rw-r--r--drivers/net/wireless/cnss2/debug.c23
-rw-r--r--drivers/net/wireless/cnss2/qmi.c26
-rw-r--r--drivers/net/wireless/cw1200/main.c5
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c5
-rw-r--r--drivers/nvmem/core.c15
-rw-r--r--drivers/parisc/ccio-dma.c4
-rw-r--r--drivers/parisc/sba_iommu.c3
-rw-r--r--drivers/pci/host/pcie-rcar.c4
-rw-r--r--drivers/pci/host/pcie-xilinx.c12
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c4
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/pinctrl/pinctrl-pistachio.c2
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c11
-rw-r--r--drivers/platform/msm/ipa/ipa_rm_dependency_graph.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c19
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c19
-rw-r--r--drivers/power/power_supply_sysfs.c6
-rw-r--r--drivers/power/supply/qcom/qpnp-smbcharger.c4
-rw-r--r--drivers/pwm/core.c10
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c2
-rw-r--r--drivers/pwm/sysfs.c14
-rw-r--r--drivers/rtc/rtc-88pm860x.c2
-rw-r--r--drivers/s390/cio/cio.h2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c9
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c55
-rw-r--r--drivers/s390/scsi/zfcp_unit.c8
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_hwi.c2
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c4
-rw-r--r--drivers/scsi/libsas/sas_expander.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c11
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c2
-rw-r--r--drivers/scsi/sd.c3
-rw-r--r--drivers/scsi/ufs/ufshcd.c28
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c2
-rw-r--r--drivers/soc/qcom/glink_spi_xprt.c20
-rw-r--r--drivers/soc/qcom/hab/hab_ghs.c7
-rw-r--r--drivers/soc/qcom/hab/hab_msg.c1
-rw-r--r--drivers/soc/qcom/icnss.c6
-rw-r--r--drivers/soc/qcom/smem.c133
-rw-r--r--drivers/spi/spi-pxa2xx.c15
-rw-r--r--drivers/spi/spi-rspi.c9
-rw-r--r--drivers/spi/spi-tegra114.c32
-rw-r--r--drivers/spi/spi-topcliff-pch.c15
-rw-r--r--drivers/spi/spi.c2
-rw-r--r--drivers/ssb/bridge_pcmcia_80211.c9
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_i2c.c7
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_spi.c7
-rw-r--r--drivers/thermal/msm_lmh_dcvs.c33
-rw-r--r--drivers/thermal/msm_thermal.c58
-rw-r--r--drivers/tty/ipwireless/main.c8
-rw-r--r--drivers/tty/serial/8250/8250_dw.c4
-rw-r--r--drivers/tty/serial/max310x.c2
-rw-r--r--drivers/tty/serial/msm_serial.c5
-rw-r--r--drivers/tty/serial/sunhv.c2
-rw-r--r--drivers/tty/vt/keyboard.c33
-rw-r--r--drivers/usb/core/config.c4
-rw-r--r--drivers/usb/core/hcd.c3
-rw-r--r--drivers/usb/core/hub.c5
-rw-r--r--drivers/usb/core/quirks.c6
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c110
-rw-r--r--drivers/usb/host/xhci.c24
-rw-r--r--drivers/usb/misc/rio500.c41
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c15
-rw-r--r--drivers/usb/phy/phy-msm-ssusb-qmp.c20
-rw-r--r--drivers/usb/serial/option.c6
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h3
-rw-r--r--drivers/usb/storage/unusual_realtek.h5
-rw-r--r--drivers/video/fbdev/core/fbcmap.c2
-rw-r--r--drivers/video/fbdev/core/modedb.c3
-rw-r--r--drivers/video/fbdev/hgafb.c2
-rw-r--r--drivers/video/fbdev/imsttfb.c5
-rw-r--r--drivers/video/fbdev/sm712.h12
-rw-r--r--drivers/video/fbdev/sm712fb.c243
-rw-r--r--drivers/w1/w1_io.c3
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c2
-rw-r--r--drivers/xen/xenbus/xenbus_dev_frontend.c2
-rw-r--r--fs/btrfs/backref.c18
-rw-r--r--fs/btrfs/extent-tree.c25
-rw-r--r--fs/btrfs/file.c12
-rw-r--r--fs/btrfs/sysfs.c7
-rw-r--r--fs/btrfs/tree-log.c8
-rw-r--r--fs/ceph/super.c7
-rw-r--r--fs/char_dev.c6
-rw-r--r--fs/cifs/file.c4
-rw-r--r--fs/cifs/smb2ops.c14
-rw-r--r--fs/configfs/dir.c14
-rw-r--r--fs/ext4/extents.c17
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/ioctl.c2
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/f2fs/checkpoint.c6
-rw-r--r--fs/f2fs/super.c5
-rw-r--r--fs/fat/file.c11
-rw-r--r--fs/fs-writeback.c51
-rw-r--r--fs/fuse/dev.c2
-rw-r--r--fs/fuse/file.c13
-rw-r--r--fs/gfs2/glock.c22
-rw-r--r--fs/gfs2/lock_dlm.c9
-rw-r--r--fs/hugetlbfs/inode.c8
-rw-r--r--fs/inode.c9
-rw-r--r--fs/nfs/nfs4state.c4
-rw-r--r--fs/nfsd/vfs.h5
-rw-r--r--fs/ocfs2/dcache.c12
-rw-r--r--fs/ocfs2/export.c30
-rw-r--r--fs/open.c18
-rw-r--r--fs/proc/base.c2
-rw-r--r--fs/proc/internal.h3
-rw-r--r--fs/proc/task_mmu.c203
-rw-r--r--fs/read_write.c5
-rw-r--r--fs/sdcardfs/super.c2
-rw-r--r--fs/ufs/util.h2
-rw-r--r--fs/userfaultfd.c48
-rw-r--r--include/linux/backing-dev-defs.h1
-rw-r--r--include/linux/bio.h2
-rw-r--r--include/linux/bitops.h16
-rw-r--r--include/linux/cgroup.h10
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/hid.h1
-rw-r--r--include/linux/hugetlb.h4
-rw-r--r--include/linux/iio/adc/ad_sigma_delta.h1
-rw-r--r--include/linux/list_lru.h1
-rw-r--r--include/linux/mfd/da9063/registers.h6
-rw-r--r--include/linux/mm.h21
-rw-r--r--include/linux/of.h4
-rw-r--r--include/linux/pwm.h5
-rw-r--r--include/linux/rcupdate.h6
-rw-r--r--include/linux/sched.h9
-rw-r--r--include/linux/skbuff.h30
-rw-r--r--include/linux/smpboot.h2
-rw-r--r--include/linux/tcp.h3
-rw-r--r--include/linux/usb/gadget.h4
-rw-r--r--include/net/arp.h8
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/tcp.h2
-rw-r--r--include/trace/events/msm_cam.h30
-rw-r--r--include/uapi/linux/fuse.h2
-rw-r--r--include/uapi/linux/snmp.h1
-rw-r--r--include/uapi/linux/tipc_config.h10
-rw-r--r--ipc/mqueue.c10
-rw-r--r--ipc/msgutil.c6
-rw-r--r--kernel/auditfilter.c12
-rw-r--r--kernel/cpuset.c18
-rw-r--r--kernel/cred.c9
-rw-r--r--kernel/events/ring_buffer.c33
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/futex.c4
-rw-r--r--kernel/ptrace.c20
-rw-r--r--kernel/rcu/rcutorture.c5
-rw-r--r--kernel/sched/core.c20
-rw-r--r--kernel/sched/hmp.c5
-rw-r--r--kernel/sched/sched.h4
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/smpboot.c2
-rw-r--r--kernel/sys.c2
-rw-r--r--kernel/sysctl.c6
-rw-r--r--kernel/time/ntp.c2
-rw-r--r--kernel/trace/trace_events.c3
-rw-r--r--lib/strncpy_from_user.c5
-rw-r--r--lib/strnlen_user.c4
-rw-r--r--mm/backing-dev.c1
-rw-r--r--mm/cma.c4
-rw-r--r--mm/cma_debug.c2
-rw-r--r--mm/hugetlb.c40
-rw-r--r--mm/list_lru.c10
-rw-r--r--mm/mincore.c23
-rw-r--r--mm/mmap.c7
-rw-r--r--net/ax25/ax25_route.c2
-rw-r--r--net/bluetooth/hci_conn.c8
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/ethtool.c17
-rw-r--r--net/core/neighbour.c16
-rw-r--r--net/core/pktgen.c11
-rw-r--r--net/ipv4/ip_vti.c5
-rw-r--r--net/ipv4/proc.c1
-rw-r--r--net/ipv4/sysctl_net_ipv4.c11
-rw-r--r--net/ipv4/tcp.c1
-rw-r--r--net/ipv4/tcp_input.c28
-rw-r--r--net/ipv4/tcp_ipv4.c1
-rw-r--r--net/ipv4/tcp_output.c8
-rw-r--r--net/ipv4/tcp_timer.c1
-rw-r--r--net/ipv4/xfrm4_policy.c24
-rw-r--r--net/ipv6/ip6_flowlabel.c7
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/xfrm6_tunnel.c4
-rw-r--r--net/lapb/lapb_iface.c1
-rw-r--r--net/llc/llc_output.c2
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/rds/ib_rdma.c10
-rw-r--r--net/sched/sch_tbf.c10
-rw-r--r--net/tipc/core.c32
-rw-r--r--net/tipc/subscr.c14
-rw-r--r--net/tipc/subscr.h5
-rw-r--r--net/wireless/nl80211.c5
-rw-r--r--net/xfrm/xfrm_user.c2
-rw-r--r--scripts/coccinelle/api/stream_open.cocci363
-rw-r--r--sound/core/seq/seq_ports.c2
-rw-r--r--sound/pci/hda/hda_intel.c6
-rw-r--r--sound/pci/hda/patch_hdmi.c6
-rw-r--r--sound/pci/hda/patch_realtek.c7
-rw-r--r--sound/soc/codecs/cs42xx8.c1
-rw-r--r--sound/soc/codecs/max98090.c12
-rw-r--r--sound/soc/codecs/rt5677-spi.c35
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c6
-rw-r--r--sound/soc/davinci/davinci-mcasp.c2
-rw-r--r--sound/soc/fsl/Kconfig9
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c4
-rw-r--r--sound/soc/fsl/fsl_sai.c2
-rw-r--r--sound/soc/fsl/fsl_utils.c1
-rw-r--r--sound/usb/mixer.c2
-rw-r--r--tools/include/linux/bitops.h7
-rw-r--r--tools/include/linux/bits.h26
-rw-r--r--tools/perf/bench/numa.c4
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c31
-rw-r--r--tools/perf/util/string.c1
-rw-r--r--tools/perf/util/util.h1
387 files changed, 3787 insertions, 1470 deletions
diff --git a/Documentation/ABI/testing/procfs-smaps_rollup b/Documentation/ABI/testing/procfs-smaps_rollup
new file mode 100644
index 000000000000..0a54ed0d63c9
--- /dev/null
+++ b/Documentation/ABI/testing/procfs-smaps_rollup
@@ -0,0 +1,31 @@
+What: /proc/pid/smaps_rollup
+Date: August 2017
+Contact: Daniel Colascione <dancol@google.com>
+Description:
+ This file provides pre-summed memory information for a
+ process. The format is identical to /proc/pid/smaps,
+ except instead of an entry for each VMA in a process,
+ smaps_rollup has a single entry (tagged "[rollup]")
+ for which each field is the sum of the corresponding
+ fields from all the maps in /proc/pid/smaps.
+ For more details, see the procfs man page.
+
+ Typical output looks like this:
+
+ 00100000-ff709000 ---p 00000000 00:00 0 [rollup]
+ Rss: 884 kB
+ Pss: 385 kB
+ Shared_Clean: 696 kB
+ Shared_Dirty: 0 kB
+ Private_Clean: 120 kB
+ Private_Dirty: 68 kB
+ Referenced: 884 kB
+ Anonymous: 68 kB
+ LazyFree: 0 kB
+ AnonHugePages: 0 kB
+ ShmemPmdMapped: 0 kB
+ Shared_Hugetlb: 0 kB
+ Private_Hugetlb: 0 kB
+ Swap: 0 kB
+ SwapPss: 0 kB
+ Locked: 385 kB
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 71e28e4a047d..a7516e4c8ce8 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -220,6 +220,14 @@ tcp_base_mss - INTEGER
Path MTU discovery (MTU probing). If MTU probing is enabled,
this is the initial MSS used by the connection.
+tcp_min_snd_mss - INTEGER
+ TCP SYN and SYNACK messages usually advertise an ADVMSS option,
+ as described in RFC 1122 and RFC 6691.
+ If this ADVMSS option is smaller than tcp_min_snd_mss,
+ it is silently capped to tcp_min_snd_mss.
+
+ Default : 48 (at least 8 bytes of payload per segment)
+
tcp_congestion_control - STRING
Set the congestion control algorithm to be used for new
connections. The algorithm "reno" is always available, but
diff --git a/Documentation/x86/mds.rst b/Documentation/x86/mds.rst
index 534e9baa4e1d..5d4330be200f 100644
--- a/Documentation/x86/mds.rst
+++ b/Documentation/x86/mds.rst
@@ -142,45 +142,13 @@ Mitigation points
mds_user_clear.
The mitigation is invoked in prepare_exit_to_usermode() which covers
- most of the kernel to user space transitions. There are a few exceptions
- which are not invoking prepare_exit_to_usermode() on return to user
- space. These exceptions use the paranoid exit code.
+ all but one of the kernel to user space transitions. The exception
+ is when we return from a Non Maskable Interrupt (NMI), which is
+ handled directly in do_nmi().
- - Non Maskable Interrupt (NMI):
-
- Access to sensible data like keys, credentials in the NMI context is
- mostly theoretical: The CPU can do prefetching or execute a
- misspeculated code path and thereby fetching data which might end up
- leaking through a buffer.
-
- But for mounting other attacks the kernel stack address of the task is
- already valuable information. So in full mitigation mode, the NMI is
- mitigated on the return from do_nmi() to provide almost complete
- coverage.
-
- - Double fault (#DF):
-
- A double fault is usually fatal, but the ESPFIX workaround, which can
- be triggered from user space through modify_ldt(2) is a recoverable
- double fault. #DF uses the paranoid exit path, so explicit mitigation
- in the double fault handler is required.
-
- - Machine Check Exception (#MC):
-
- Another corner case is a #MC which hits between the CPU buffer clear
- invocation and the actual return to user. As this still is in kernel
- space it takes the paranoid exit path which does not clear the CPU
- buffers. So the #MC handler repopulates the buffers to some
- extent. Machine checks are not reliably controllable and the window is
- extremly small so mitigation would just tick a checkbox that this
- theoretical corner case is covered. To keep the amount of special
- cases small, ignore #MC.
-
- - Debug Exception (#DB):
-
- This takes the paranoid exit path only when the INT1 breakpoint is in
- kernel space. #DB on a user space address takes the regular exit path,
- so no extra mitigation required.
+ (The reason that NMI is special is that prepare_exit_to_usermode() can
+ enable IRQs. In NMI context, NMIs are blocked, and we don't want to
+ enable IRQs with NMIs blocked.)
2. C-State transition
diff --git a/Makefile b/Makefile
index 5524a77f1418..114f572e5649 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
-SUBLEVEL = 180
+SUBLEVEL = 183
EXTRAVERSION =
NAME = Blurry Fish Butt
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 4ecef6981d5c..b54c0b8a5b34 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -97,6 +97,7 @@
regulator-name = "PVDD_APIO_1V8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
+ regulator-always-on;
};
ldo3_reg: LDO3 {
@@ -135,6 +136,7 @@
regulator-name = "PVDD_ABB_1V8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
+ regulator-always-on;
};
ldo9_reg: LDO9 {
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e6af41c4bbc1..3992b8ea1c48 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -853,7 +853,7 @@
compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
reg = <0x020ec000 0x4000>;
interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6QDL_CLK_SDMA>,
+ clocks = <&clks IMX6QDL_CLK_IPG>,
<&clks IMX6QDL_CLK_SDMA>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index d8ba99f1d87b..ac820dfef977 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -657,7 +657,7 @@
reg = <0x020ec000 0x4000>;
interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_SDMA>,
- <&clks IMX6SL_CLK_SDMA>;
+ <&clks IMX6SL_CLK_AHB>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
/* imx6sl reuses imx6q sdma firmware */
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 6963dff815dc..5783eb8541ed 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -732,7 +732,7 @@
compatible = "fsl,imx6sx-sdma", "fsl,imx6q-sdma";
reg = <0x020ec000 0x4000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX6SX_CLK_SDMA>,
+ clocks = <&clks IMX6SX_CLK_IPG>,
<&clks IMX6SX_CLK_SDMA>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index f35c370c3e0f..21e74513f542 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -483,9 +483,7 @@ CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_MSM_TZ_LOG=y
CONFIG_SENSORS_SSC=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
index 648d5fac9cbf..3271c836e1a1 100644
--- a/arch/arm/crypto/aesbs-glue.c
+++ b/arch/arm/crypto/aesbs-glue.c
@@ -259,6 +259,8 @@ static int aesbs_xts_encrypt(struct blkcipher_desc *desc,
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+ if (err)
+ return err;
/* generate the initial tweak */
AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
@@ -283,6 +285,8 @@ static int aesbs_xts_decrypt(struct blkcipher_desc *desc,
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
+ if (err)
+ return err;
/* generate the initial tweak */
AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 4cddf20cdb82..5475e684a6b4 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -748,7 +748,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
const struct kvm_vcpu_init *init)
{
- unsigned int i;
+ unsigned int i, ret;
int phys_target = kvm_target_cpu();
if (init->target != phys_target)
@@ -783,9 +783,14 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
vcpu->arch.target = phys_target;
/* Now we know what it is, we can reset it. */
- return kvm_reset_vcpu(vcpu);
-}
+ ret = kvm_reset_vcpu(vcpu);
+ if (ret) {
+ vcpu->arch.target = -1;
+ bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
+ }
+ return ret;
+}
static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
struct kvm_vcpu_init *init)
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 111cfbf66fdb..7bfe2bd17400 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -207,6 +207,7 @@ void __init exynos_firmware_init(void)
return;
addr = of_get_address(nd, 0, NULL, NULL);
+ of_node_put(nd);
if (!addr) {
pr_err("%s: No address specified.\n", __func__);
return;
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index e8adb428dddb..013f4d55ede8 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -508,8 +508,27 @@ early_wakeup:
static void exynos5420_prepare_pm_resume(void)
{
+ unsigned int mpidr, cluster;
+
+ mpidr = read_cpuid_mpidr();
+ cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
WARN_ON(mcpm_cpu_powered_up());
+
+ if (IS_ENABLED(CONFIG_HW_PERF_EVENTS) && cluster != 0) {
+ /*
+ * When system is resumed on the LITTLE/KFC core (cluster 1),
+ * the DSCR is not properly updated until the power is turned
+ * on also for the cluster 0. Enable it for a while to
+ * propagate the SPNIDEN and SPIDEN signals from Secure JTAG
+ * block and avoid undefined instruction issue on CP14 reset.
+ */
+ pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN,
+ EXYNOS_COMMON_CONFIGURATION(0));
+ pmu_raw_writel(0,
+ EXYNOS_COMMON_CONFIGURATION(0));
+ }
}
static void exynos5420_pm_resume(void)
@@ -725,8 +744,10 @@ void __init exynos_pm_init(void)
if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+ of_node_put(np);
return;
}
+ of_node_put(np);
pm_data = (const struct exynos_pm_data *) match->data;
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 39b834cf859b..6ced770d9f88 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -608,9 +608,7 @@ CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_MSM_TZ_LOG=y
CONFIG_SENSORS_SSC=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_EXT4_FS_ENCRYPTION=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 0e306afd1cc6..14cdf2ffd61e 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -635,9 +635,7 @@ CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_MSM_TZ_LOG=y
CONFIG_SENSORS_SSC=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_EXT4_FS_ENCRYPTION=y
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index c7cfb8fe06f9..6342f1c61a09 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -84,6 +84,7 @@ static const char *__init cpu_read_enable_method(int cpu)
pr_err("%s: missing enable-method property\n",
dn->full_name);
}
+ of_node_put(dn);
} else {
enable_method = acpi_get_enable_method(cpu);
if (!enable_method) {
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
index aa19b7ac8222..476c7b4be378 100644
--- a/arch/ia64/mm/numa.c
+++ b/arch/ia64/mm/numa.c
@@ -49,6 +49,7 @@ paddr_to_nid(unsigned long paddr)
return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
}
+EXPORT_SYMBOL(paddr_to_nid);
#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA)
/*
diff --git a/arch/mips/pistachio/Platform b/arch/mips/pistachio/Platform
index d80cd612df1f..c3592b374ad2 100644
--- a/arch/mips/pistachio/Platform
+++ b/arch/mips/pistachio/Platform
@@ -6,3 +6,4 @@ cflags-$(CONFIG_MACH_PISTACHIO) += \
-I$(srctree)/arch/mips/include/asm/mach-pistachio
load-$(CONFIG_MACH_PISTACHIO) += 0xffffffff80400000
zload-$(CONFIG_MACH_PISTACHIO) += 0xffffffff81000000
+all-$(CONFIG_MACH_PISTACHIO) := uImage.gz
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c
index 9d9f6f334d3c..3da3e2b1b51b 100644
--- a/arch/powerpc/boot/addnote.c
+++ b/arch/powerpc/boot/addnote.c
@@ -223,7 +223,11 @@ main(int ac, char **av)
PUT_16(E_PHNUM, np + 2);
/* write back */
- lseek(fd, (long) 0, SEEK_SET);
+ i = lseek(fd, (long) 0, SEEK_SET);
+ if (i < 0) {
+ perror("lseek");
+ exit(1);
+ }
i = write(fd, buf, n);
if (i < 0) {
perror("write");
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a92d95aee42d..1883627eb12c 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -250,6 +250,7 @@ struct kvm_arch {
#ifdef CONFIG_PPC_BOOK3S_64
struct list_head spapr_tce_tables;
struct list_head rtas_tokens;
+ struct mutex rtas_token_lock;
DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
#endif
#ifdef CONFIG_KVM_MPIC
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 099c79d8c160..4aab1c9c83e1 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -809,6 +809,7 @@ int kvmppc_core_init_vm(struct kvm *kvm)
#ifdef CONFIG_PPC64
INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
INIT_LIST_HEAD(&kvm->arch.rtas_tokens);
+ mutex_init(&kvm->arch.rtas_token_lock);
#endif
return kvm->arch.kvm_ops->init_vm(kvm);
diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c
index ef27fbd5d9c5..b1b2273d1f6d 100644
--- a/arch/powerpc/kvm/book3s_rtas.c
+++ b/arch/powerpc/kvm/book3s_rtas.c
@@ -133,7 +133,7 @@ static int rtas_token_undefine(struct kvm *kvm, char *name)
{
struct rtas_token_definition *d, *tmp;
- lockdep_assert_held(&kvm->lock);
+ lockdep_assert_held(&kvm->arch.rtas_token_lock);
list_for_each_entry_safe(d, tmp, &kvm->arch.rtas_tokens, list) {
if (rtas_name_matches(d->handler->name, name)) {
@@ -154,7 +154,7 @@ static int rtas_token_define(struct kvm *kvm, char *name, u64 token)
bool found;
int i;
- lockdep_assert_held(&kvm->lock);
+ lockdep_assert_held(&kvm->arch.rtas_token_lock);
list_for_each_entry(d, &kvm->arch.rtas_tokens, list) {
if (d->token == token)
@@ -193,14 +193,14 @@ int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp)
if (copy_from_user(&args, argp, sizeof(args)))
return -EFAULT;
- mutex_lock(&kvm->lock);
+ mutex_lock(&kvm->arch.rtas_token_lock);
if (args.token)
rc = rtas_token_define(kvm, args.name, args.token);
else
rc = rtas_token_undefine(kvm, args.name);
- mutex_unlock(&kvm->lock);
+ mutex_unlock(&kvm->arch.rtas_token_lock);
return rc;
}
@@ -232,7 +232,7 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
orig_rets = args.rets;
args.rets = &args.args[be32_to_cpu(args.nargs)];
- mutex_lock(&vcpu->kvm->lock);
+ mutex_lock(&vcpu->kvm->arch.rtas_token_lock);
rc = -ENOENT;
list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) {
@@ -243,7 +243,7 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
}
}
- mutex_unlock(&vcpu->kvm->lock);
+ mutex_unlock(&vcpu->kvm->arch.rtas_token_lock);
if (rc == 0) {
args.rets = orig_rets;
@@ -269,8 +269,6 @@ void kvmppc_rtas_tokens_free(struct kvm *kvm)
{
struct rtas_token_definition *d, *tmp;
- lockdep_assert_held(&kvm->lock);
-
list_for_each_entry_safe(d, tmp, &kvm->arch.rtas_tokens, list) {
list_del(&d->list);
kfree(d);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bb3df222ae71..215bff2b8470 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1611,6 +1611,9 @@ int start_topology_update(void)
{
int rc = 0;
+ if (!topology_updates_enabled)
+ return 0;
+
if (firmware_has_feature(FW_FEATURE_PRRN)) {
if (!prrn_enabled) {
prrn_enabled = 1;
@@ -1640,6 +1643,9 @@ int stop_topology_update(void)
{
int rc = 0;
+ if (!topology_updates_enabled)
+ return 0;
+
if (prrn_enabled) {
prrn_enabled = 0;
#ifdef CONFIG_SMP
@@ -1685,11 +1691,13 @@ static ssize_t topology_write(struct file *file, const char __user *buf,
kbuf[read_len] = '\0';
- if (!strncmp(kbuf, "on", 2))
+ if (!strncmp(kbuf, "on", 2)) {
+ topology_updates_enabled = true;
start_topology_update();
- else if (!strncmp(kbuf, "off", 3))
+ } else if (!strncmp(kbuf, "off", 3)) {
stop_topology_update();
- else
+ topology_updates_enabled = false;
+ } else
return -EINVAL;
return count;
@@ -1704,9 +1712,7 @@ static const struct file_operations topology_ops = {
static int topology_update_init(void)
{
- /* Do not poll for changes if disabled at boot */
- if (topology_updates_enabled)
- start_topology_update();
+ start_topology_update();
if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops))
return -ENOMEM;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 5ddb1debba95..23911ecfbad6 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -2721,21 +2721,28 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
const struct kvm_memory_slot *new,
enum kvm_mr_change change)
{
- int rc;
-
- /* If the basics of the memslot do not change, we do not want
- * to update the gmap. Every update causes several unnecessary
- * segment translation exceptions. This is usually handled just
- * fine by the normal fault handler + gmap, but it will also
- * cause faults on the prefix page of running guest CPUs.
- */
- if (old->userspace_addr == mem->userspace_addr &&
- old->base_gfn * PAGE_SIZE == mem->guest_phys_addr &&
- old->npages * PAGE_SIZE == mem->memory_size)
- return;
+ int rc = 0;
- rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
- mem->guest_phys_addr, mem->memory_size);
+ switch (change) {
+ case KVM_MR_DELETE:
+ rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
+ old->npages * PAGE_SIZE);
+ break;
+ case KVM_MR_MOVE:
+ rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
+ old->npages * PAGE_SIZE);
+ if (rc)
+ break;
+ /* FALLTHROUGH */
+ case KVM_MR_CREATE:
+ rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
+ mem->guest_phys_addr, mem->memory_size);
+ break;
+ case KVM_MR_FLAGS_ONLY:
+ break;
+ default:
+ WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
+ }
if (rc)
pr_warn("failed to commit memory region\n");
return;
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S
index fcf4d27a38fb..e09f7b440b8c 100644
--- a/arch/sparc/mm/ultra.S
+++ b/arch/sparc/mm/ultra.S
@@ -586,7 +586,7 @@ xcall_flush_tlb_kernel_range: /* 44 insns */
sub %g7, %g1, %g3
srlx %g3, 18, %g2
brnz,pn %g2, 2f
- add %g2, 1, %g2
+ sethi %hi(PAGE_SIZE), %g2
sub %g3, %g2, %g3
or %g1, 0x20, %g1 ! Nucleus
1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
@@ -750,7 +750,7 @@ __cheetah_xcall_flush_tlb_kernel_range: /* 44 insns */
sub %g7, %g1, %g3
srlx %g3, 18, %g2
brnz,pn %g2, 2f
- add %g2, 1, %g2
+ sethi %hi(PAGE_SIZE), %g2
sub %g3, %g2, %g3
or %g1, 0x20, %g1 ! Nucleus
1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 568930248ad0..063de6441f8d 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -47,7 +47,7 @@ export REALMODE_CFLAGS
export BITS
ifdef CONFIG_X86_NEED_RELOCS
- LDFLAGS_vmlinux := --emit-relocs
+ LDFLAGS_vmlinux := --emit-relocs --discard-none
endif
#
diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c
index cd4df9322501..7bbfe7d35da7 100644
--- a/arch/x86/crypto/crct10dif-pclmul_glue.c
+++ b/arch/x86/crypto/crct10dif-pclmul_glue.c
@@ -76,15 +76,14 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
return 0;
}
-static int __chksum_finup(__u16 *crcp, const u8 *data, unsigned int len,
- u8 *out)
+static int __chksum_finup(__u16 crc, const u8 *data, unsigned int len, u8 *out)
{
if (irq_fpu_usable()) {
kernel_fpu_begin();
- *(__u16 *)out = crc_t10dif_pcl(*crcp, data, len);
+ *(__u16 *)out = crc_t10dif_pcl(crc, data, len);
kernel_fpu_end();
} else
- *(__u16 *)out = crc_t10dif_generic(*crcp, data, len);
+ *(__u16 *)out = crc_t10dif_generic(crc, data, len);
return 0;
}
@@ -93,15 +92,13 @@ static int chksum_finup(struct shash_desc *desc, const u8 *data,
{
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
- return __chksum_finup(&ctx->crc, data, len, out);
+ return __chksum_finup(ctx->crc, data, len, out);
}
static int chksum_digest(struct shash_desc *desc, const u8 *data,
unsigned int length, u8 *out)
{
- struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
- return __chksum_finup(&ctx->crc, data, length, out);
+ return __chksum_finup(0, data, length, out);
}
static struct shash_alg alg = {
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 0552884da18d..a7b9acd709db 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -60,9 +60,8 @@
} while (0)
#define RELOAD_SEG(seg) { \
- unsigned int pre = GET_SEG(seg); \
+ unsigned int pre = (seg) | 3; \
unsigned int cur = get_user_seg(seg); \
- pre |= 3; \
if (pre != cur) \
set_user_seg(seg, pre); \
}
@@ -71,6 +70,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
struct sigcontext_32 __user *sc)
{
unsigned int tmpflags, err = 0;
+ u16 gs, fs, es, ds;
void __user *buf;
u32 tmp;
@@ -78,16 +78,10 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
current->restart_block.fn = do_no_restart_syscall;
get_user_try {
- /*
- * Reload fs and gs if they have changed in the signal
- * handler. This does not handle long fs/gs base changes in
- * the handler, but does not clobber them at least in the
- * normal case.
- */
- RELOAD_SEG(gs);
- RELOAD_SEG(fs);
- RELOAD_SEG(ds);
- RELOAD_SEG(es);
+ gs = GET_SEG(gs);
+ fs = GET_SEG(fs);
+ ds = GET_SEG(ds);
+ es = GET_SEG(es);
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
COPY(dx); COPY(cx); COPY(ip); COPY(ax);
@@ -105,6 +99,17 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
buf = compat_ptr(tmp);
} get_user_catch(err);
+ /*
+ * Reload fs and gs if they have changed in the signal
+ * handler. This does not handle long fs/gs base changes in
+ * the handler, but does not clobber them at least in the
+ * normal case.
+ */
+ RELOAD_SEG(gs);
+ RELOAD_SEG(fs);
+ RELOAD_SEG(ds);
+ RELOAD_SEG(es);
+
err |= fpu__restore_sig(buf, 1);
force_iret();
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index e94e6f16172b..6f2483292de0 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -717,8 +717,11 @@ static void init_amd_zn(struct cpuinfo_x86 *c)
{
set_cpu_cap(c, X86_FEATURE_ZEN);
- /* Fix erratum 1076: CPB feature bit not being set in CPUID. */
- if (!cpu_has(c, X86_FEATURE_CPB))
+ /*
+ * Fix erratum 1076: CPB feature bit not being set in CPUID.
+ * Always set it, except when running under a hypervisor.
+ */
+ if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_CPB))
set_cpu_cap(c, X86_FEATURE_CPB);
}
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 325ed90511cf..3572434a73cb 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2513,7 +2513,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
return ret;
if (event->attr.precise_ip) {
- if (!(event->attr.freq || event->attr.wakeup_events)) {
+ if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) {
event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
if (!(event->attr.sample_type &
~intel_pmu_free_running_flags(event)))
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 206d0b90a3ab..e39d7197f9fb 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -25,9 +25,18 @@ int sysctl_panic_on_stackoverflow;
/*
* Probabilistic stack overflow check:
*
- * Only check the stack in process context, because everything else
- * runs on the big interrupt stacks. Checking reliably is too expensive,
- * so we just check from interrupts.
+ * Regular device interrupts can enter on the following stacks:
+ *
+ * - User stack
+ *
+ * - Kernel task stack
+ *
+ * - Interrupt stack if a device driver reenables interrupts
+ * which should only happen in really old drivers.
+ *
+ * - Debug IST stack
+ *
+ * All other contexts are invalid.
*/
static inline void stack_overflow_check(struct pt_regs *regs)
{
@@ -53,8 +62,8 @@ static inline void stack_overflow_check(struct pt_regs *regs)
return;
oist = this_cpu_ptr(&orig_ist);
- estack_top = (u64)oist->ist[0] - EXCEPTION_STKSZ + STACK_TOP_MARGIN;
- estack_bottom = (u64)oist->ist[N_EXCEPTION_STACKS - 1];
+ estack_bottom = (u64)oist->ist[DEBUG_STACK];
+ estack_top = estack_bottom - DEBUG_STKSZ + STACK_TOP_MARGIN;
if (regs->sp >= estack_top && regs->sp <= estack_bottom)
return;
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 6223929fc621..8c73bf1492b8 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -61,7 +61,6 @@
#include <asm/alternative.h>
#include <asm/fpu/xstate.h>
#include <asm/trace/mpx.h>
-#include <asm/nospec-branch.h>
#include <asm/mpx.h>
#include <asm/vm86.h>
@@ -338,13 +337,6 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
regs->ip = (unsigned long)general_protection;
regs->sp = (unsigned long)&normal_regs->orig_ax;
- /*
- * This situation can be triggered by userspace via
- * modify_ldt(2) and the return does not take the regular
- * user space exit, so a CPU buffer clear is required when
- * MDS mitigation is enabled.
- */
- mds_user_clear_cpu_buffers();
return;
}
#endif
diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c
index 23a7c7ba377a..8fc07ea23344 100644
--- a/arch/x86/kvm/pmu_intel.c
+++ b/arch/x86/kvm/pmu_intel.c
@@ -235,11 +235,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
}
break;
default:
- if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
- (pmc = get_fixed_pmc(pmu, msr))) {
- if (!msr_info->host_initiated)
- data = (s64)(s32)data;
- pmc->counter += data - pmc_read_counter(pmc);
+ if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
+ if (msr_info->host_initiated)
+ pmc->counter = data;
+ else
+ pmc->counter = (s32)data;
+ return 0;
+ } else if ((pmc = get_fixed_pmc(pmu, msr))) {
+ pmc->counter = data;
return 0;
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
if (data == pmc->eventsel)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d830a0d60ba4..516d8b1562c8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -990,11 +990,8 @@ static u32 emulated_msrs[] = {
static unsigned num_emulated_msrs;
-bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
+static bool __kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
{
- if (efer & efer_reserved_bits)
- return false;
-
if (efer & EFER_FFXSR) {
struct kvm_cpuid_entry2 *feat;
@@ -1012,19 +1009,33 @@ bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
}
return true;
+
+}
+bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
+{
+ if (efer & efer_reserved_bits)
+ return false;
+
+ return __kvm_valid_efer(vcpu, efer);
}
EXPORT_SYMBOL_GPL(kvm_valid_efer);
-static int set_efer(struct kvm_vcpu *vcpu, u64 efer)
+static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
u64 old_efer = vcpu->arch.efer;
+ u64 efer = msr_info->data;
- if (!kvm_valid_efer(vcpu, efer))
+ if (efer & efer_reserved_bits)
return 1;
- if (is_paging(vcpu)
- && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME))
- return 1;
+ if (!msr_info->host_initiated) {
+ if (!__kvm_valid_efer(vcpu, efer))
+ return 1;
+
+ if (is_paging(vcpu) &&
+ (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME))
+ return 1;
+ }
efer &= ~EFER_LMA;
efer |= vcpu->arch.efer & EFER_LMA;
@@ -2055,7 +2066,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
break;
case MSR_EFER:
- return set_efer(vcpu, data);
+ return set_efer(vcpu, msr_info);
case MSR_K7_HWCR:
data &= ~(u64)0x40; /* ignore flush filter disable */
data &= ~(u64)0x100; /* ignore ignne emulation enable */
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index c4dffae5d939..462c5c30b9a2 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -373,8 +373,6 @@ static noinline int vmalloc_fault(unsigned long address)
if (!(address >= VMALLOC_START && address < VMALLOC_END))
return -1;
- WARN_ON_ONCE(in_nmi());
-
/*
* Copy kernel mappings over when needed. This can also
* happen within a race in page table update. In the later
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 9bd115484745..5f0e596b0519 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1117,6 +1117,8 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
void __init pcibios_irq_init(void)
{
+ struct irq_routing_table *rtable = NULL;
+
DBG(KERN_DEBUG "PCI: IRQ init\n");
if (raw_pci_ops == NULL)
@@ -1127,8 +1129,10 @@ void __init pcibios_irq_init(void)
pirq_table = pirq_find_routing_table();
#ifdef CONFIG_PCI_BIOS
- if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
+ if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) {
pirq_table = pcibios_get_irq_routing_table();
+ rtable = pirq_table;
+ }
#endif
if (pirq_table) {
pirq_peer_trick();
@@ -1143,8 +1147,10 @@ void __init pcibios_irq_init(void)
* If we're using the I/O APIC, avoid using the PCI IRQ
* routing table
*/
- if (io_apic_assign_pci_irqs)
+ if (io_apic_assign_pci_irqs) {
+ kfree(rtable);
pirq_table = NULL;
+ }
}
x86_init.pci.fixup_irqs();
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index 0214600ba071..6c4724222e3a 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -637,8 +637,8 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
- "%s(%s,%s)", name, chacha_name,
- poly_name) >= CRYPTO_MAX_ALG_NAME)
+ "%s(%s,%s)", name, chacha->cra_name,
+ poly->cra_name) >= CRYPTO_MAX_ALG_NAME)
goto out_drop_chacha;
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"%s(%s,%s)", name, chacha->cra_driver_name,
diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c
index c1229614c7e3..eed577714975 100644
--- a/crypto/crct10dif_generic.c
+++ b/crypto/crct10dif_generic.c
@@ -65,10 +65,9 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
return 0;
}
-static int __chksum_finup(__u16 *crcp, const u8 *data, unsigned int len,
- u8 *out)
+static int __chksum_finup(__u16 crc, const u8 *data, unsigned int len, u8 *out)
{
- *(__u16 *)out = crc_t10dif_generic(*crcp, data, len);
+ *(__u16 *)out = crc_t10dif_generic(crc, data, len);
return 0;
}
@@ -77,15 +76,13 @@ static int chksum_finup(struct shash_desc *desc, const u8 *data,
{
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
- return __chksum_finup(&ctx->crc, data, len, out);
+ return __chksum_finup(ctx->crc, data, len, out);
}
static int chksum_digest(struct shash_desc *desc, const u8 *data,
unsigned int length, u8 *out)
{
- struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
- return __chksum_finup(&ctx->crc, data, length, out);
+ return __chksum_finup(0, data, length, out);
}
static struct shash_alg alg = {
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 0a12c09d7cb2..9d3bffc0238f 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -616,7 +616,6 @@ static void crypto_gcm_free(struct aead_instance *inst)
static int crypto_gcm_create_common(struct crypto_template *tmpl,
struct rtattr **tb,
- const char *full_name,
const char *ctr_name,
const char *ghash_name)
{
@@ -657,7 +656,8 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
goto err_free_inst;
err = -EINVAL;
- if (ghash->digestsize != 16)
+ if (strcmp(ghash->base.cra_name, "ghash") != 0 ||
+ ghash->digestsize != 16)
goto err_drop_ghash;
crypto_set_skcipher_spawn(&ctx->ctr, aead_crypto_instance(inst));
@@ -669,24 +669,24 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
ctr = crypto_skcipher_spawn_alg(&ctx->ctr);
- /* We only support 16-byte blocks. */
- if (ctr->cra_ablkcipher.ivsize != 16)
- goto out_put_ctr;
-
- /* Not a stream cipher? */
+ /* The skcipher algorithm must be CTR mode, using 16-byte blocks. */
err = -EINVAL;
- if (ctr->cra_blocksize != 1)
+ if (strncmp(ctr->cra_name, "ctr(", 4) != 0 ||
+ ctr->cra_ablkcipher.ivsize != 16 ||
+ ctr->cra_blocksize != 1)
goto out_put_ctr;
err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
+ "gcm(%s", ctr->cra_name + 4) >= CRYPTO_MAX_ALG_NAME)
+ goto out_put_ctr;
+
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"gcm_base(%s,%s)", ctr->cra_driver_name,
ghash_alg->cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
goto out_put_ctr;
- memcpy(inst->alg.base.cra_name, full_name, CRYPTO_MAX_ALG_NAME);
-
inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) &
CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = (ghash->base.cra_priority +
@@ -727,7 +727,6 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
{
const char *cipher_name;
char ctr_name[CRYPTO_MAX_ALG_NAME];
- char full_name[CRYPTO_MAX_ALG_NAME];
cipher_name = crypto_attr_alg_name(tb[1]);
if (IS_ERR(cipher_name))
@@ -737,12 +736,7 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
CRYPTO_MAX_ALG_NAME)
return -ENAMETOOLONG;
- if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >=
- CRYPTO_MAX_ALG_NAME)
- return -ENAMETOOLONG;
-
- return crypto_gcm_create_common(tmpl, tb, full_name,
- ctr_name, "ghash");
+ return crypto_gcm_create_common(tmpl, tb, ctr_name, "ghash");
}
static struct crypto_template crypto_gcm_tmpl = {
@@ -756,7 +750,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl,
{
const char *ctr_name;
const char *ghash_name;
- char full_name[CRYPTO_MAX_ALG_NAME];
ctr_name = crypto_attr_alg_name(tb[1]);
if (IS_ERR(ctr_name))
@@ -766,12 +759,7 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl,
if (IS_ERR(ghash_name))
return PTR_ERR(ghash_name);
- if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)",
- ctr_name, ghash_name) >= CRYPTO_MAX_ALG_NAME)
- return -ENAMETOOLONG;
-
- return crypto_gcm_create_common(tmpl, tb, full_name,
- ctr_name, ghash_name);
+ return crypto_gcm_create_common(tmpl, tb, ctr_name, ghash_name);
}
static struct crypto_template crypto_gcm_base_tmpl = {
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
index d7da0eea5622..319d9962552e 100644
--- a/crypto/salsa20_generic.c
+++ b/crypto/salsa20_generic.c
@@ -186,7 +186,7 @@ static int encrypt(struct blkcipher_desc *desc,
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt_block(desc, &walk, 64);
- salsa20_ivsetup(ctx, walk.iv);
+ salsa20_ivsetup(ctx, desc->info);
while (walk.nbytes >= 64) {
salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index bff9f44161c2..91fe6c39c804 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3130,6 +3130,7 @@ static void binder_transaction(struct binder_proc *proc,
if (target_node && target_node->txn_security_ctx) {
u32 secid;
+ size_t added_size;
security_task_getsecid(proc->tsk, &secid);
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
@@ -3139,7 +3140,15 @@ static void binder_transaction(struct binder_proc *proc,
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
- extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
+ added_size = ALIGN(secctx_sz, sizeof(u64));
+ extra_buffers_size += added_size;
+ if (extra_buffers_size < added_size) {
+ /* integer overflow of extra_buffers_size */
+ return_error = BR_FAILED_REPLY;
+ return_error_param = EINVAL;
+ return_error_line = __LINE__;
+ goto err_bad_extra_size;
+ }
}
trace_binder_transaction(reply, t, target_node);
@@ -3441,6 +3450,7 @@ err_copy_data_failed:
t->buffer->transaction = NULL;
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
err_binder_alloc_buf_failed:
+err_bad_extra_size:
if (secctx)
security_release_secctx(secctx, secctx_sz);
err_get_secctx_failed:
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index baecb4bf9d9b..c8614f3c70c4 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -924,15 +924,14 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
index = page - alloc->pages;
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
+
+ mm = alloc->vma_vm_mm;
+ /* Same as mmget_not_zero() in later kernel versions */
+ if (!atomic_inc_not_zero(&alloc->vma_vm_mm->mm_users))
+ goto err_mmget;
+ if (!down_write_trylock(&mm->mmap_sem))
+ goto err_down_write_mmap_sem_failed;
vma = alloc->vma;
- if (vma) {
- /* Same as mmget_not_zero() in later kernel versions */
- if (!atomic_inc_not_zero(&alloc->vma_vm_mm->mm_users))
- goto err_mmget;
- mm = alloc->vma_vm_mm;
- if (!down_write_trylock(&mm->mmap_sem))
- goto err_down_write_mmap_sem_failed;
- }
list_lru_isolate(lru, item);
spin_unlock(lock);
@@ -946,10 +945,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
PAGE_SIZE, NULL);
trace_binder_unmap_user_end(alloc, index);
-
- up_write(&mm->mmap_sem);
- mmput(mm);
}
+ up_write(&mm->mmap_sem);
+ mmput(mm);
trace_binder_unmap_kernel_start(alloc, index);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index d543172b20b3..a352f09baef6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4176,9 +4176,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ |
ATA_HORKAGE_FIRMWARE_WARN },
- /* drives which fail FPDMA_AA activation (some may freeze afterwards) */
- { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA },
- { "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA },
+ /* drives which fail FPDMA_AA activation (some may freeze afterwards)
+ the ST disks also have LPM issues */
+ { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA |
+ ATA_HORKAGE_NOLPM, },
+ { "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA |
+ ATA_HORKAGE_NOLPM, },
{ "VB0250EAVER", "HPG7", ATA_HORKAGE_BROKEN_FPDMA_AA },
/* Blacklist entries taken from Silicon Image 3124/3132
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 38857ab563f7..4192e46eda37 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1385,6 +1385,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (dev->power.syscore)
goto Complete;
+ /* Avoid direct_complete to let wakeup_path propagate. */
+ if (device_may_wakeup(dev) || dev->power.wakeup_path)
+ dev->power.direct_complete = false;
+
if (dev->power.direct_complete) {
if (pm_runtime_status_suspended(dev)) {
pm_runtime_disable(dev);
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 671ac2d7b6dc..db9162ef64c2 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1947,7 +1947,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) +
+ if (len < (sizeof(struct dci_pkt_req_t) +
sizeof(struct diag_pkt_header_t)) ||
len > DCI_REQ_BUF_SIZE) {
pr_err("diag: dci: Invalid length %d len in %s", len, __func__);
@@ -1960,7 +1960,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
req_len -= sizeof(struct dci_pkt_req_t);
req_buf = temp; /* Start of the Request */
header = (struct diag_pkt_header_t *)temp;
- temp += sizeof(struct diag_pkt_header_t);
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__,
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index b2da2382d544..67d23ed2d1a0 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -695,12 +695,16 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
/* End of read */
len = ssif_info->multi_len;
data = ssif_info->data;
- } else if (blocknum != ssif_info->multi_pos) {
+ } else if (blocknum + 1 != ssif_info->multi_pos) {
/*
* Out of sequence block, just abort. Block
* numbers start at zero for the second block,
* but multi_pos starts at one, so the +1.
*/
+ if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
+ dev_dbg(&ssif_info->client->dev,
+ "Received message out of sequence, expected %u, got %u\n",
+ ssif_info->multi_pos - 1, blocknum);
result = -EIO;
} else {
ssif_inc_stat(ssif_info, received_message_parts);
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 2aca689061e1..df9eab91c2d2 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -76,7 +76,7 @@ struct ports_driver_data {
/* All the console devices handled by this driver */
struct list_head consoles;
};
-static struct ports_driver_data pdrvdata;
+static struct ports_driver_data pdrvdata = { .next_vtermno = 1};
static DEFINE_SPINLOCK(pdrvdata_lock);
static DECLARE_COMPLETION(early_console_added);
@@ -1419,6 +1419,7 @@ static int add_port(struct ports_device *portdev, u32 id)
port->async_queue = NULL;
port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
+ port->cons.vtermno = 0;
port->host_connected = port->guest_connected = false;
port->stats = (struct port_stats) { 0 };
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 9040878e3e2b..a6cda84b67da 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -797,6 +797,9 @@ static const int rk3288_saved_cru_reg_ids[] = {
RK3288_CLKSEL_CON(10),
RK3288_CLKSEL_CON(33),
RK3288_CLKSEL_CON(37),
+
+ /* We turn aclk_dmac1 on for suspend; this will restore it */
+ RK3288_CLKGATE_CON(10),
};
static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
@@ -813,6 +816,14 @@ static int rk3288_clk_suspend(void)
}
/*
+ * Going into deep sleep (specifically setting PMU_CLR_DMA in
+ * RK3288_PMU_PWRMODE_CON1) appears to fail unless
+ * "aclk_dmac1" is on.
+ */
+ writel_relaxed(1 << (12 + 16),
+ rk3288_cru_base + RK3288_CLKGATE_CON(10));
+
+ /*
* Switch PLLs other than DPLL (for SDRAM) to slow mode to
* avoid crashes on resume. The Mask ROM on the system will
* put APLL, CPLL, and GPLL into slow mode at resume time
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index d6d4ecb88e94..311f6e62264f 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -492,8 +492,8 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
pll_override_writel(val, params->pmc_divp_reg, pll);
val = pll_override_readl(params->pmc_divnm_reg, pll);
- val &= ~(divm_mask(pll) << div_nmp->override_divm_shift) |
- ~(divn_mask(pll) << div_nmp->override_divn_shift);
+ val &= ~((divm_mask(pll) << div_nmp->override_divm_shift) |
+ (divn_mask(pll) << div_nmp->override_divn_shift));
val |= (cfg->m << div_nmp->override_divm_shift) |
(cfg->n << div_nmp->override_divn_shift);
pll_override_writel(val, params->pmc_divnm_reg, pll);
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
index 35dd4d7ffee0..58c933f48300 100644
--- a/drivers/cpufreq/pasemi-cpufreq.c
+++ b/drivers/cpufreq/pasemi-cpufreq.c
@@ -146,6 +146,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpu = of_get_cpu_node(policy->cpu, NULL);
+ of_node_put(cpu);
if (!cpu)
goto out;
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 1f49d97a70ea..14928e0dc326 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -549,6 +549,7 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
if (volt_gpio_np)
voltage_gpio = read_gpio(volt_gpio_np);
+ of_node_put(volt_gpio_np);
if (!voltage_gpio){
printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
return 1;
@@ -585,6 +586,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
if (volt_gpio_np)
voltage_gpio = read_gpio(volt_gpio_np);
+ of_node_put(volt_gpio_np);
pvr = mfspr(SPRN_PVR);
has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
index 5a4c5a639f61..2eaeebcc93af 100644
--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
@@ -86,6 +86,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (!cbe_get_cpu_pmd_regs(policy->cpu) ||
!cbe_get_cpu_mic_tm_regs(policy->cpu)) {
pr_info("invalid CBE regs pointers for cpufreq\n");
+ of_node_put(cpu);
return -EINVAL;
}
diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c
index e3b8bebfdd30..4afca3968773 100644
--- a/drivers/crypto/amcc/crypto4xx_alg.c
+++ b/drivers/crypto/amcc/crypto4xx_alg.c
@@ -138,8 +138,7 @@ static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher,
sa = (struct dynamic_sa_ctl *) ctx->sa_in;
ctx->hash_final = 0;
- set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, (cm == CRYPTO_MODE_CBC ?
- SA_SAVE_IV : SA_NOT_SAVE_IV),
+ set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
SA_NO_HEADER_PROC, SA_HASH_ALG_NULL,
SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO,
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 1e810f5f03fa..78d0722feacb 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -645,15 +645,6 @@ static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev,
addr = dma_map_page(dev->core_dev->device, sg_page(dst),
dst->offset, dst->length, DMA_FROM_DEVICE);
}
-
- if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) {
- struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-
- crypto4xx_memcpy_from_le32((u32 *)req->iv,
- pd_uinfo->sr_va->save_iv,
- crypto_skcipher_ivsize(skcipher));
- }
-
crypto4xx_ret_sg_desc(dev, pd_uinfo);
if (ablk_req->base.complete != NULL)
ablk_req->base.complete(&ablk_req->base, 0);
diff --git a/drivers/crypto/vmx/aesp8-ppc.pl b/drivers/crypto/vmx/aesp8-ppc.pl
index 228053921b3f..4277fdd037bb 100644
--- a/drivers/crypto/vmx/aesp8-ppc.pl
+++ b/drivers/crypto/vmx/aesp8-ppc.pl
@@ -1298,7 +1298,7 @@ Loop_ctr32_enc:
addi $idx,$idx,16
bdnz Loop_ctr32_enc
- vadduwm $ivec,$ivec,$one
+ vadduqm $ivec,$ivec,$one
vmr $dat,$inptail
lvx $inptail,0,$inp
addi $inp,$inp,16
@@ -1795,7 +1795,7 @@ Lctr32_enc8x_three:
stvx_u $out1,$x10,$out
stvx_u $out2,$x20,$out
addi $out,$out,0x30
- b Lcbc_dec8x_done
+ b Lctr32_enc8x_done
.align 5
Lctr32_enc8x_two:
@@ -1807,7 +1807,7 @@ Lctr32_enc8x_two:
stvx_u $out0,$x00,$out
stvx_u $out1,$x10,$out
addi $out,$out,0x20
- b Lcbc_dec8x_done
+ b Lctr32_enc8x_done
.align 5
Lctr32_enc8x_one:
diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c
index 84b9389bf1ed..d6b68cf7bba7 100644
--- a/drivers/crypto/vmx/ghash.c
+++ b/drivers/crypto/vmx/ghash.c
@@ -1,22 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* GHASH routines supporting VMX instructions on the Power 8
*
- * Copyright (C) 2015 International Business Machines Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Copyright (C) 2015, 2019 International Business Machines Inc.
*
* Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ *
+ * Extended by Daniel Axtens <dja@axtens.net> to replace the fallback
+ * mechanism. The new approach is based on arm64 code, which is:
+ * Copyright (C) 2014 - 2018 Linaro Ltd. <ard.biesheuvel@linaro.org>
*/
#include <linux/types.h>
@@ -39,71 +31,25 @@ void gcm_ghash_p8(u64 Xi[2], const u128 htable[16],
const u8 *in, size_t len);
struct p8_ghash_ctx {
+ /* key used by vector asm */
u128 htable[16];
- struct crypto_shash *fallback;
+ /* key used by software fallback */
+ be128 key;
};
struct p8_ghash_desc_ctx {
u64 shash[2];
u8 buffer[GHASH_DIGEST_SIZE];
int bytes;
- struct shash_desc fallback_desc;
};
-static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
-{
- const char *alg = "ghash-generic";
- struct crypto_shash *fallback;
- struct crypto_shash *shash_tfm = __crypto_shash_cast(tfm);
- struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm);
-
- fallback = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
- if (IS_ERR(fallback)) {
- printk(KERN_ERR
- "Failed to allocate transformation for '%s': %ld\n",
- alg, PTR_ERR(fallback));
- return PTR_ERR(fallback);
- }
-
- crypto_shash_set_flags(fallback,
- crypto_shash_get_flags((struct crypto_shash
- *) tfm));
-
- /* Check if the descsize defined in the algorithm is still enough. */
- if (shash_tfm->descsize < sizeof(struct p8_ghash_desc_ctx)
- + crypto_shash_descsize(fallback)) {
- printk(KERN_ERR
- "Desc size of the fallback implementation (%s) does not match the expected value: %lu vs %u\n",
- alg,
- shash_tfm->descsize - sizeof(struct p8_ghash_desc_ctx),
- crypto_shash_descsize(fallback));
- return -EINVAL;
- }
- ctx->fallback = fallback;
-
- return 0;
-}
-
-static void p8_ghash_exit_tfm(struct crypto_tfm *tfm)
-{
- struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm);
-
- if (ctx->fallback) {
- crypto_free_shash(ctx->fallback);
- ctx->fallback = NULL;
- }
-}
-
static int p8_ghash_init(struct shash_desc *desc)
{
- struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm));
struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
dctx->bytes = 0;
memset(dctx->shash, 0, GHASH_DIGEST_SIZE);
- dctx->fallback_desc.tfm = ctx->fallback;
- dctx->fallback_desc.flags = desc->flags;
- return crypto_shash_init(&dctx->fallback_desc);
+ return 0;
}
static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
@@ -122,7 +68,53 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
gcm_init_p8(ctx->htable, (const u64 *) key);
pagefault_enable();
preempt_enable();
- return crypto_shash_setkey(ctx->fallback, key, keylen);
+
+ memcpy(&ctx->key, key, GHASH_BLOCK_SIZE);
+
+ return 0;
+}
+
+static inline void __ghash_block(struct p8_ghash_ctx *ctx,
+ struct p8_ghash_desc_ctx *dctx)
+{
+ if (!IN_INTERRUPT) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_altivec();
+ enable_kernel_vsx();
+ enable_kernel_fp();
+ gcm_ghash_p8(dctx->shash, ctx->htable,
+ dctx->buffer, GHASH_DIGEST_SIZE);
+ pagefault_enable();
+ preempt_enable();
+ } else {
+ crypto_xor((u8 *)dctx->shash, dctx->buffer, GHASH_BLOCK_SIZE);
+ gf128mul_lle((be128 *)dctx->shash, &ctx->key);
+ }
+}
+
+static inline void __ghash_blocks(struct p8_ghash_ctx *ctx,
+ struct p8_ghash_desc_ctx *dctx,
+ const u8 *src, unsigned int srclen)
+{
+ if (!IN_INTERRUPT) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_altivec();
+ enable_kernel_vsx();
+ enable_kernel_fp();
+ gcm_ghash_p8(dctx->shash, ctx->htable,
+ src, srclen);
+ pagefault_enable();
+ preempt_enable();
+ } else {
+ while (srclen >= GHASH_BLOCK_SIZE) {
+ crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE);
+ gf128mul_lle((be128 *)dctx->shash, &ctx->key);
+ srclen -= GHASH_BLOCK_SIZE;
+ src += GHASH_BLOCK_SIZE;
+ }
+ }
}
static int p8_ghash_update(struct shash_desc *desc,
@@ -132,51 +124,33 @@ static int p8_ghash_update(struct shash_desc *desc,
struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm));
struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
- if (IN_INTERRUPT) {
- return crypto_shash_update(&dctx->fallback_desc, src,
- srclen);
- } else {
- if (dctx->bytes) {
- if (dctx->bytes + srclen < GHASH_DIGEST_SIZE) {
- memcpy(dctx->buffer + dctx->bytes, src,
- srclen);
- dctx->bytes += srclen;
- return 0;
- }
+ if (dctx->bytes) {
+ if (dctx->bytes + srclen < GHASH_DIGEST_SIZE) {
memcpy(dctx->buffer + dctx->bytes, src,
- GHASH_DIGEST_SIZE - dctx->bytes);
- preempt_disable();
- pagefault_disable();
- enable_kernel_altivec();
- enable_kernel_vsx();
- enable_kernel_fp();
- gcm_ghash_p8(dctx->shash, ctx->htable,
- dctx->buffer, GHASH_DIGEST_SIZE);
- pagefault_enable();
- preempt_enable();
- src += GHASH_DIGEST_SIZE - dctx->bytes;
- srclen -= GHASH_DIGEST_SIZE - dctx->bytes;
- dctx->bytes = 0;
- }
- len = srclen & ~(GHASH_DIGEST_SIZE - 1);
- if (len) {
- preempt_disable();
- pagefault_disable();
- enable_kernel_altivec();
- enable_kernel_vsx();
- enable_kernel_fp();
- gcm_ghash_p8(dctx->shash, ctx->htable, src, len);
- pagefault_enable();
- preempt_enable();
- src += len;
- srclen -= len;
- }
- if (srclen) {
- memcpy(dctx->buffer, src, srclen);
- dctx->bytes = srclen;
+ srclen);
+ dctx->bytes += srclen;
+ return 0;
}
- return 0;
+ memcpy(dctx->buffer + dctx->bytes, src,
+ GHASH_DIGEST_SIZE - dctx->bytes);
+
+ __ghash_block(ctx, dctx);
+
+ src += GHASH_DIGEST_SIZE - dctx->bytes;
+ srclen -= GHASH_DIGEST_SIZE - dctx->bytes;
+ dctx->bytes = 0;
+ }
+ len = srclen & ~(GHASH_DIGEST_SIZE - 1);
+ if (len) {
+ __ghash_blocks(ctx, dctx, src, len);
+ src += len;
+ srclen -= len;
}
+ if (srclen) {
+ memcpy(dctx->buffer, src, srclen);
+ dctx->bytes = srclen;
+ }
+ return 0;
}
static int p8_ghash_final(struct shash_desc *desc, u8 *out)
@@ -185,26 +159,14 @@ static int p8_ghash_final(struct shash_desc *desc, u8 *out)
struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm));
struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
- if (IN_INTERRUPT) {
- return crypto_shash_final(&dctx->fallback_desc, out);
- } else {
- if (dctx->bytes) {
- for (i = dctx->bytes; i < GHASH_DIGEST_SIZE; i++)
- dctx->buffer[i] = 0;
- preempt_disable();
- pagefault_disable();
- enable_kernel_altivec();
- enable_kernel_vsx();
- enable_kernel_fp();
- gcm_ghash_p8(dctx->shash, ctx->htable,
- dctx->buffer, GHASH_DIGEST_SIZE);
- pagefault_enable();
- preempt_enable();
- dctx->bytes = 0;
- }
- memcpy(out, dctx->shash, GHASH_DIGEST_SIZE);
- return 0;
+ if (dctx->bytes) {
+ for (i = dctx->bytes; i < GHASH_DIGEST_SIZE; i++)
+ dctx->buffer[i] = 0;
+ __ghash_block(ctx, dctx);
+ dctx->bytes = 0;
}
+ memcpy(out, dctx->shash, GHASH_DIGEST_SIZE);
+ return 0;
}
struct shash_alg p8_ghash_alg = {
@@ -219,11 +181,9 @@ struct shash_alg p8_ghash_alg = {
.cra_name = "ghash",
.cra_driver_name = "p8_ghash",
.cra_priority = 1000,
- .cra_flags = CRYPTO_ALG_TYPE_SHASH | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
.cra_blocksize = GHASH_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct p8_ghash_ctx),
.cra_module = THIS_MODULE,
- .cra_init = p8_ghash_init_tfm,
- .cra_exit = p8_ghash_exit_tfm,
},
};
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index af24c5bf32d6..8aa3ccf42e55 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1608,7 +1608,11 @@ static void at_xdmac_tasklet(unsigned long data)
struct at_xdmac_desc,
xfer_node);
dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc);
- BUG_ON(!desc->active_xfer);
+ if (!desc->active_xfer) {
+ dev_err(chan2dev(&atchan->chan), "Xfer not active: exiting");
+ spin_unlock_bh(&atchan->lock);
+ return;
+ }
txd = &desc->tx_dma_desc;
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
index 7d56b47e4fcf..25e25b64bc89 100644
--- a/drivers/dma/idma64.c
+++ b/drivers/dma/idma64.c
@@ -594,7 +594,7 @@ static int idma64_probe(struct idma64_chip *chip)
idma64->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
idma64->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
- idma64->dma.dev = chip->dev;
+ idma64->dma.dev = chip->sysdev;
ret = dma_async_device_register(&idma64->dma);
if (ret)
@@ -632,6 +632,7 @@ static int idma64_platform_probe(struct platform_device *pdev)
{
struct idma64_chip *chip;
struct device *dev = &pdev->dev;
+ struct device *sysdev = dev->parent;
struct resource *mem;
int ret;
@@ -648,11 +649,12 @@ static int idma64_platform_probe(struct platform_device *pdev)
if (IS_ERR(chip->regs))
return PTR_ERR(chip->regs);
- ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
if (ret)
return ret;
chip->dev = dev;
+ chip->sysdev = sysdev;
ret = idma64_probe(chip);
if (ret)
diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h
index f6aeff0af8a5..e40c69bd1fb5 100644
--- a/drivers/dma/idma64.h
+++ b/drivers/dma/idma64.h
@@ -215,12 +215,14 @@ static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
/**
* struct idma64_chip - representation of iDMA 64-bit controller hardware
* @dev: struct device of the DMA controller
+ * @sysdev: struct device of the physical device that does DMA
* @irq: irq line
* @regs: memory mapped I/O space
* @idma64: struct idma64 that is filed by idma64_probe()
*/
struct idma64_chip {
struct device *dev;
+ struct device *sysdev;
int irq;
void __iomem *regs;
struct idma64 *idma64;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 95619ee33112..799c182c3eac 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1006,6 +1006,7 @@ static void _stop(struct pl330_thread *thrd)
{
void __iomem *regs = thrd->dmac->base;
u8 insn[6] = {0, 0, 0, 0, 0, 0};
+ u32 inten = readl(regs + INTEN);
if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
@@ -1018,10 +1019,13 @@ static void _stop(struct pl330_thread *thrd)
_emit_KILL(0, insn);
- /* Stop generating interrupts for SEV */
- writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
-
_execute_DBGINSN(thrd, insn, is_manager(thrd));
+
+ /* clear the event */
+ if (inten & (1 << thrd->ev))
+ writel(1 << thrd->ev, regs + INTCLR);
+ /* Stop generating interrupts for SEV */
+ writel(inten & ~(1 << thrd->ev), regs + INTEN);
}
/* Start doing req 'idx' of thread 'thrd' */
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index e4890dd4fefd..38fb212e58ee 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -1616,6 +1616,16 @@ static int arizona_extcon_remove(struct platform_device *pdev)
struct arizona_extcon_info *info = platform_get_drvdata(pdev);
struct arizona *arizona = info->arizona;
int jack_irq_rise, jack_irq_fall;
+ bool change;
+
+ regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
+ ARIZONA_MICD_ENA, 0,
+ &change);
+
+ if (change) {
+ regulator_disable(info->micvdd);
+ pm_runtime_put(info->dev);
+ }
gpiod_put(info->micd_pol_gpio);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d4729fa59edb..1491dc41cf38 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -598,6 +598,7 @@ config GPIO_ADP5588
config GPIO_ADP5588_IRQ
bool "Interrupt controller support for ADP5588"
depends on GPIO_ADP5588=y
+ select GPIOLIB_IRQCHIP
help
Say yes here to enable the adp5588 to be used as an interrupt
controller. It requires the driver to be built in the kernel.
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 9943273ec981..c8c49b1d5f9f 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -292,6 +292,22 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset)
}
}
+/*
+ * Off mode wake-up capable GPIOs in bank(s) that are in the wakeup domain.
+ * See TRM section for GPIO for "Wake-Up Generation" for the list of GPIOs
+ * in wakeup domain. If bank->non_wakeup_gpios is not configured, assume none
+ * are capable waking up the system from off mode.
+ */
+static bool omap_gpio_is_off_wakeup_capable(struct gpio_bank *bank, u32 gpio_mask)
+{
+ u32 no_wake = bank->non_wakeup_gpios;
+
+ if (no_wake)
+ return !!(~no_wake & gpio_mask);
+
+ return false;
+}
+
static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
unsigned trigger)
{
@@ -323,13 +339,7 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
}
/* This part needs to be executed always for OMAP{34xx, 44xx} */
- if (!bank->regs->irqctrl) {
- /* On omap24xx proceed only when valid GPIO bit is set */
- if (bank->non_wakeup_gpios) {
- if (!(bank->non_wakeup_gpios & gpio_bit))
- goto exit;
- }
-
+ if (!bank->regs->irqctrl && !omap_gpio_is_off_wakeup_capable(bank, gpio)) {
/*
* Log the edge gpio and manually trigger the IRQ
* after resume if the input level changes
@@ -342,7 +352,6 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
bank->enabled_non_wakeup_gpios &= ~gpio_bit;
}
-exit:
bank->level_mask =
readl_relaxed(bank->base + bank->regs->leveldetect0) |
readl_relaxed(bank->base + bank->regs->leveldetect1);
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 211069b2b951..010fe3fc5ecf 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -620,6 +620,9 @@ void cdv_intel_lvds_init(struct drm_device *dev,
int pipe;
u8 pin;
+ if (!dev_priv->lvds_enabled_in_vbt)
+ return;
+
pin = GMBUS_PORT_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n");
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
index 63bde4e86c6a..e019ea271ffc 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -436,6 +436,9 @@ parse_driver_features(struct drm_psb_private *dev_priv,
if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
dev_priv->edp.support = 1;
+ dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0;
+ DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config);
+
/* This bit means to use 96Mhz for DPLL_A or not */
if (driver->primary_lfp_id)
dev_priv->dplla_96mhz = true;
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index e21726ecac32..4c7cc8a5edbd 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -536,6 +536,7 @@ struct drm_psb_private {
int lvds_ssc_freq;
bool is_lvds_on;
bool is_mipi_on;
+ bool lvds_enabled_in_vbt;
u32 mipi_ctrl_display;
unsigned int core_freq;
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index c7c243e9b808..4300e27ed113 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -781,11 +781,11 @@ static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
vsync_polarity = 1;
}
- if (mode->vrefresh <= 24000)
+ if (drm_mode_vrefresh(mode) <= 24)
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ;
- else if (mode->vrefresh <= 25000)
+ else if (drm_mode_vrefresh(mode) <= 25)
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ;
- else if (mode->vrefresh <= 30000)
+ else if (drm_mode_vrefresh(mode) <= 30)
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ;
else
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 742760cc791c..8e25260d21c0 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.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.
*
* 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
@@ -98,6 +98,9 @@ static ssize_t debugfs_dump_info_read(struct file *file,
"\tClock master = %s\n",
display->ctrl[display->clk_master_idx].ctrl->name);
+ if (len > count)
+ len = count;
+
if (copy_to_user(buff, buf, len)) {
kfree(buf);
return -EFAULT;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
index 6b6224dbd5bb..943eb2971c3e 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
@@ -37,6 +37,7 @@ struct nvkm_i2c_bus {
struct mutex mutex;
struct list_head head;
struct i2c_adapter i2c;
+ u8 enabled;
};
int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *);
@@ -56,6 +57,7 @@ struct nvkm_i2c_aux {
struct mutex mutex;
struct list_head head;
struct i2c_adapter i2c;
+ u8 enabled;
u32 intr;
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
index f0851d57df2f..f89692cb2bc7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
@@ -105,9 +105,15 @@ nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *aux)
{
struct nvkm_i2c_pad *pad = aux->pad;
int ret;
+
AUX_TRACE(aux, "acquire");
mutex_lock(&aux->mutex);
- ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX);
+
+ if (aux->enabled)
+ ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX);
+ else
+ ret = -EIO;
+
if (ret)
mutex_unlock(&aux->mutex);
return ret;
@@ -141,6 +147,24 @@ nvkm_i2c_aux_del(struct nvkm_i2c_aux **paux)
}
}
+void
+nvkm_i2c_aux_init(struct nvkm_i2c_aux *aux)
+{
+ AUX_TRACE(aux, "init");
+ mutex_lock(&aux->mutex);
+ aux->enabled = true;
+ mutex_unlock(&aux->mutex);
+}
+
+void
+nvkm_i2c_aux_fini(struct nvkm_i2c_aux *aux)
+{
+ AUX_TRACE(aux, "fini");
+ mutex_lock(&aux->mutex);
+ aux->enabled = false;
+ mutex_unlock(&aux->mutex);
+}
+
int
nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func,
struct nvkm_i2c_pad *pad, int id,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
index 35a892e4a4c3..04885c097a32 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
@@ -14,6 +14,8 @@ int nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
int id, struct nvkm_i2c_aux **);
void nvkm_i2c_aux_del(struct nvkm_i2c_aux **);
+void nvkm_i2c_aux_init(struct nvkm_i2c_aux *);
+void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *);
int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
u32 addr, u8 *data, u8 size);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
index 243a71ff0a0d..2acc5cbcb6fb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
@@ -160,8 +160,18 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_i2c *i2c = nvkm_i2c(subdev);
struct nvkm_i2c_pad *pad;
+ struct nvkm_i2c_bus *bus;
+ struct nvkm_i2c_aux *aux;
u32 mask;
+ list_for_each_entry(aux, &i2c->aux, head) {
+ nvkm_i2c_aux_fini(aux);
+ }
+
+ list_for_each_entry(bus, &i2c->bus, head) {
+ nvkm_i2c_bus_fini(bus);
+ }
+
if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) {
i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0);
i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask);
@@ -180,6 +190,7 @@ nvkm_i2c_init(struct nvkm_subdev *subdev)
struct nvkm_i2c *i2c = nvkm_i2c(subdev);
struct nvkm_i2c_bus *bus;
struct nvkm_i2c_pad *pad;
+ struct nvkm_i2c_aux *aux;
list_for_each_entry(pad, &i2c->pad, head) {
nvkm_i2c_pad_init(pad);
@@ -189,6 +200,10 @@ nvkm_i2c_init(struct nvkm_subdev *subdev)
nvkm_i2c_bus_init(bus);
}
+ list_for_each_entry(aux, &i2c->aux, head) {
+ nvkm_i2c_aux_init(aux);
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
index 807a2b67bd64..ed50cc3736b9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
@@ -110,6 +110,19 @@ nvkm_i2c_bus_init(struct nvkm_i2c_bus *bus)
BUS_TRACE(bus, "init");
if (bus->func->init)
bus->func->init(bus);
+
+ mutex_lock(&bus->mutex);
+ bus->enabled = true;
+ mutex_unlock(&bus->mutex);
+}
+
+void
+nvkm_i2c_bus_fini(struct nvkm_i2c_bus *bus)
+{
+ BUS_TRACE(bus, "fini");
+ mutex_lock(&bus->mutex);
+ bus->enabled = false;
+ mutex_unlock(&bus->mutex);
}
void
@@ -126,9 +139,15 @@ nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *bus)
{
struct nvkm_i2c_pad *pad = bus->pad;
int ret;
+
BUS_TRACE(bus, "acquire");
mutex_lock(&bus->mutex);
- ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C);
+
+ if (bus->enabled)
+ ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C);
+ else
+ ret = -EIO;
+
if (ret)
mutex_unlock(&bus->mutex);
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
index e1be14c23e54..2fdb1b8e7164 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
@@ -17,6 +17,7 @@ int nvkm_i2c_bus_new_(const struct nvkm_i2c_bus_func *, struct nvkm_i2c_pad *,
int id, struct nvkm_i2c_bus **);
void nvkm_i2c_bus_del(struct nvkm_i2c_bus **);
void nvkm_i2c_bus_init(struct nvkm_i2c_bus *);
+void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *);
int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index ad0dd566aded..8dba10135d53 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -2442,7 +2442,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,
cmd = container_of(header, typeof(*cmd), header);
- if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) {
+ if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX ||
+ cmd->body.type < SVGA3D_SHADERTYPE_MIN) {
DRM_ERROR("Illegal shader type %u.\n",
(unsigned) cmd->body.type);
return -EINVAL;
@@ -2681,6 +2682,10 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
if (view_type == vmw_view_max)
return -EINVAL;
cmd = container_of(header, typeof(*cmd), header);
+ if (unlikely(cmd->sid == SVGA3D_INVALID_ID)) {
+ DRM_ERROR("Invalid surface id.\n");
+ return -EINVAL;
+ }
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
user_surface_converter,
&cmd->sid, &srf_node);
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 6392ec1f069b..3cf601f3b5b8 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.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
@@ -70,6 +70,19 @@ void kgsl_snapshot_push_object(struct kgsl_process_private *process,
for (index = 0; index < objbufptr; index++) {
if (objbuf[index].gpuaddr == gpuaddr &&
objbuf[index].entry->priv == process) {
+ /*
+ * Check if newly requested size is within the
+ * allocated range or not, otherwise continue
+ * with previous size.
+ */
+ if (!kgsl_gpuaddr_in_memdesc(
+ &objbuf[index].entry->memdesc,
+ gpuaddr, dwords << 2)) {
+ KGSL_CORE_ERR(
+ "snapshot: IB 0x%016llx size is not within the memdesc range\n",
+ gpuaddr);
+ return;
+ }
objbuf[index].size = max_t(uint64_t,
objbuf[index].size,
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index b1b0b69d55ba..c916822036c1 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -61,7 +61,7 @@ static const char * const clocks[] = {
"iref_clk"
};
-static unsigned int ib_votes[KGSL_MAX_BUSLEVELS];
+static unsigned long ib_votes[KGSL_MAX_BUSLEVELS];
static int last_vote_buslevel;
static int max_vote_buslevel;
@@ -123,7 +123,7 @@ static void _record_pwrevent(struct kgsl_device *device,
/**
* kgsl_get_bw() - Return latest msm bus IB vote
*/
-static unsigned int kgsl_get_bw(void)
+static unsigned long kgsl_get_bw(void)
{
return ib_votes[last_vote_buslevel];
}
@@ -137,8 +137,9 @@ static unsigned int kgsl_get_bw(void)
static void _ab_buslevel_update(struct kgsl_pwrctrl *pwr,
unsigned long *ab)
{
- unsigned int ib = ib_votes[last_vote_buslevel];
- unsigned int max_bw = ib_votes[max_vote_buslevel];
+ unsigned long ib = ib_votes[last_vote_buslevel];
+ unsigned long max_bw = ib_votes[max_vote_buslevel];
+
if (!ab)
return;
if (ib == 0)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7f6c13740f4f..fd8cd41e6377 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -200,13 +200,14 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
* Add a usage to the temporary parser table.
*/
-static int hid_add_usage(struct hid_parser *parser, unsigned usage)
+static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size)
{
if (parser->local.usage_index >= HID_MAX_USAGES) {
hid_err(parser->device, "usage index exceeded\n");
return -1;
}
parser->local.usage[parser->local.usage_index] = usage;
+ parser->local.usage_size[parser->local.usage_index] = size;
parser->local.collection_index[parser->local.usage_index] =
parser->collection_stack_ptr ?
parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
@@ -463,10 +464,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
return 0;
}
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- return hid_add_usage(parser, data);
+ return hid_add_usage(parser, data, item->size);
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
@@ -475,9 +473,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
return 0;
}
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
parser->local.usage_minimum = data;
return 0;
@@ -488,9 +483,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
return 0;
}
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
count = data - parser->local.usage_minimum;
if (count + parser->local.usage_index >= HID_MAX_USAGES) {
/*
@@ -510,7 +502,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
}
for (n = parser->local.usage_minimum; n <= data; n++)
- if (hid_add_usage(parser, n)) {
+ if (hid_add_usage(parser, n, item->size)) {
dbg_hid("hid_add_usage failed\n");
return -1;
}
@@ -525,6 +517,22 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
}
/*
+ * Concatenate Usage Pages into Usages where relevant:
+ * As per specification, 6.2.2.8: "When the parser encounters a main item it
+ * concatenates the last declared Usage Page with a Usage to form a complete
+ * usage value."
+ */
+
+static void hid_concatenate_usage_page(struct hid_parser *parser)
+{
+ int i;
+
+ for (i = 0; i < parser->local.usage_index; i++)
+ if (parser->local.usage_size[i] <= 2)
+ parser->local.usage[i] += parser->global.usage_page << 16;
+}
+
+/*
* Process a main item.
*/
@@ -533,6 +541,8 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
__u32 data;
int ret;
+ hid_concatenate_usage_page(parser);
+
data = item_udata(item);
switch (item->tag) {
@@ -746,6 +756,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
__u32 data;
int i;
+ hid_concatenate_usage_page(parser);
+
data = item_udata(item);
switch (item->tag) {
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 5fd97860aec4..3666e5064d0d 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -414,13 +414,16 @@ static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
{
+ const u8 ping_byte = 0x5a;
+ u8 ping_data[3] = { 0, 0, ping_byte };
struct hidpp_report response;
int ret;
- ret = hidpp_send_fap_command_sync(hidpp,
+ ret = hidpp_send_rap_command_sync(hidpp,
+ REPORT_ID_HIDPP_SHORT,
HIDPP_PAGE_ROOT_IDX,
CMD_ROOT_GET_PROTOCOL_VERSION,
- NULL, 0, &response);
+ ping_data, sizeof(ping_data), &response);
if (ret == HIDPP_ERROR_INVALID_SUBID) {
hidpp->protocol_major = 1;
@@ -440,8 +443,14 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
if (ret)
return ret;
- hidpp->protocol_major = response.fap.params[0];
- hidpp->protocol_minor = response.fap.params[1];
+ if (response.rap.params[2] != ping_byte) {
+ hid_err(hidpp->hid_dev, "%s: ping mismatch 0x%02x != 0x%02x\n",
+ __func__, response.rap.params[2], ping_byte);
+ return -EPROTO;
+ }
+
+ hidpp->protocol_major = response.rap.params[0];
+ hidpp->protocol_minor = response.rap.params[1];
return ret;
}
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index facd05cda26d..e8c089886427 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -96,17 +96,23 @@ superio_select(int base, int ld)
outb(ld, base + 1);
}
-static inline void
+static inline int
superio_enter(int base)
{
+ if (!request_muxed_region(base, 2, DRVNAME))
+ return -EBUSY;
+
outb(0x87, base);
outb(0x87, base);
+
+ return 0;
}
static inline void
superio_exit(int base)
{
outb(0xaa, base);
+ release_region(base, 2);
}
/*
@@ -1561,7 +1567,7 @@ exit:
static int __init f71805f_find(int sioaddr, unsigned short *address,
struct f71805f_sio_data *sio_data)
{
- int err = -ENODEV;
+ int err;
u16 devid;
static const char * const names[] = {
@@ -1569,8 +1575,11 @@ static int __init f71805f_find(int sioaddr, unsigned short *address,
"F71872F/FG or F71806F/FG",
};
- superio_enter(sioaddr);
+ err = superio_enter(sioaddr);
+ if (err)
+ return err;
+ err = -ENODEV;
devid = superio_inw(sioaddr, SIO_REG_MANID);
if (devid != SIO_FINTEK_ID)
goto exit;
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index cb9fdd37bd0d..2b5b8c3de8fc 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -106,6 +106,13 @@ static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
#define LD_IN 1
#define LD_TEMP 1
+static inline int superio_enter(int sioaddr)
+{
+ if (!request_muxed_region(sioaddr, 2, DRVNAME))
+ return -EBUSY;
+ return 0;
+}
+
static inline void superio_outb(int sioaddr, int reg, int val)
{
outb(reg, sioaddr);
@@ -122,6 +129,7 @@ static inline void superio_exit(int sioaddr)
{
outb(0x02, sioaddr);
outb(0x02, sioaddr + 1);
+ release_region(sioaddr, 2);
}
/*
@@ -1220,7 +1228,11 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data)
{
u16 val;
u8 cfg, cfg_b;
- int i, err = 0;
+ int i, err;
+
+ err = superio_enter(sioaddr);
+ if (err)
+ return err;
/* Identify device */
val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 6bd200756560..cbdb5c4991ae 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -72,14 +72,19 @@ static inline void superio_select(int ld)
superio_outb(0x07, ld);
}
-static inline void superio_enter(void)
+static inline int superio_enter(void)
{
+ if (!request_muxed_region(REG, 2, DRVNAME))
+ return -EBUSY;
+
outb(0x55, REG);
+ return 0;
}
static inline void superio_exit(void)
{
outb(0xAA, REG);
+ release_region(REG, 2);
}
#define SUPERIO_REG_DEVID 0x20
@@ -300,8 +305,12 @@ static int __init smsc47b397_find(void)
u8 id, rev;
char *name;
unsigned short addr;
+ int err;
+
+ err = superio_enter();
+ if (err)
+ return err;
- superio_enter();
id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
switch (id) {
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 5d323186d2c1..d24df0c50bea 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -73,16 +73,21 @@ superio_inb(int reg)
/* logical device for fans is 0x0A */
#define superio_select() superio_outb(0x07, 0x0A)
-static inline void
+static inline int
superio_enter(void)
{
+ if (!request_muxed_region(REG, 2, DRVNAME))
+ return -EBUSY;
+
outb(0x55, REG);
+ return 0;
}
static inline void
superio_exit(void)
{
outb(0xAA, REG);
+ release_region(REG, 2);
}
#define SUPERIO_REG_ACT 0x30
@@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
{
u8 val;
unsigned short addr;
+ int err;
+
+ err = superio_enter();
+ if (err)
+ return err;
- superio_enter();
val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
/*
@@ -608,13 +617,14 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
{
if ((sio_data->activate & 0x01) == 0) {
- superio_enter();
- superio_select();
-
- pr_info("Disabling device\n");
- superio_outb(SUPERIO_REG_ACT, sio_data->activate);
-
- superio_exit();
+ if (!superio_enter()) {
+ superio_select();
+ pr_info("Disabling device\n");
+ superio_outb(SUPERIO_REG_ACT, sio_data->activate);
+ superio_exit();
+ } else {
+ pr_warn("Failed to disable device\n");
+ }
}
}
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 3a6bfa51cb94..95d5e8ec8b7f 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -226,15 +226,21 @@ static inline void superio_select(int sio_cip, int ldn)
outb(ldn, sio_cip + 1);
}
-static inline void superio_enter(int sio_cip)
+static inline int superio_enter(int sio_cip)
{
+ if (!request_muxed_region(sio_cip, 2, DRVNAME))
+ return -EBUSY;
+
outb(0x87, sio_cip);
outb(0x87, sio_cip);
+
+ return 0;
}
static inline void superio_exit(int sio_cip)
{
outb(0xaa, sio_cip);
+ release_region(sio_cip, 2);
}
/* ---------------------------------------------------------------------
@@ -1282,11 +1288,14 @@ EXIT:
static int __init vt1211_find(int sio_cip, unsigned short *address)
{
- int err = -ENODEV;
+ int err;
int devid;
- superio_enter(sio_cip);
+ err = superio_enter(sio_cip);
+ if (err)
+ return err;
+ err = -ENODEV;
devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
if (devid != SIO_VT1211_ID)
goto EXIT;
diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
index 9d9e47eb0842..7d5c53a1abe4 100644
--- a/drivers/hwtracing/intel_th/msu.c
+++ b/drivers/hwtracing/intel_th/msu.c
@@ -90,6 +90,7 @@ struct msc_iter {
* @reg_base: register window base address
* @thdev: intel_th_device pointer
* @win_list: list of windows in multiblock mode
+ * @single_sgt: single mode buffer
* @nr_pages: total number of pages allocated for this buffer
* @single_sz: amount of data in single mode
* @single_wrap: single mode wrap occurred
@@ -110,6 +111,7 @@ struct msc {
struct intel_th_device *thdev;
struct list_head win_list;
+ struct sg_table single_sgt;
unsigned long nr_pages;
unsigned long single_sz;
unsigned int single_wrap : 1;
@@ -610,22 +612,45 @@ static void intel_th_msc_deactivate(struct intel_th_device *thdev)
*/
static int msc_buffer_contig_alloc(struct msc *msc, unsigned long size)
{
+ unsigned long nr_pages = size >> PAGE_SHIFT;
unsigned int order = get_order(size);
struct page *page;
+ int ret;
if (!size)
return 0;
+ ret = sg_alloc_table(&msc->single_sgt, 1, GFP_KERNEL);
+ if (ret)
+ goto err_out;
+
+ ret = -ENOMEM;
page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
if (!page)
- return -ENOMEM;
+ goto err_free_sgt;
split_page(page, order);
- msc->nr_pages = size >> PAGE_SHIFT;
+ sg_set_buf(msc->single_sgt.sgl, page_address(page), size);
+
+ ret = dma_map_sg(msc_dev(msc)->parent->parent, msc->single_sgt.sgl, 1,
+ DMA_FROM_DEVICE);
+ if (ret < 0)
+ goto err_free_pages;
+
+ msc->nr_pages = nr_pages;
msc->base = page_address(page);
- msc->base_addr = page_to_phys(page);
+ msc->base_addr = sg_dma_address(msc->single_sgt.sgl);
return 0;
+
+err_free_pages:
+ __free_pages(page, order);
+
+err_free_sgt:
+ sg_free_table(&msc->single_sgt);
+
+err_out:
+ return ret;
}
/**
@@ -636,6 +661,10 @@ static void msc_buffer_contig_free(struct msc *msc)
{
unsigned long off;
+ dma_unmap_sg(msc_dev(msc)->parent->parent, msc->single_sgt.sgl,
+ 1, DMA_FROM_DEVICE);
+ sg_free_table(&msc->single_sgt);
+
for (off = 0; off < msc->nr_pages << PAGE_SHIFT; off += PAGE_SIZE) {
struct page *page = virt_to_page(msc->base + off);
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index b862b8e3f579..0f41fef8deac 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -225,8 +225,8 @@ stm_output_disclaim(struct stm_device *stm, struct stm_output *output)
bitmap_release_region(&master->chan_map[0], output->channel,
ilog2(output->nr_chans));
- output->nr_chans = 0;
master->nr_free += output->nr_chans;
+ output->nr_chans = 0;
}
/*
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
index 9d7be5af2bf2..6618db75fa25 100644
--- a/drivers/i2c/busses/i2c-acorn.c
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -83,6 +83,7 @@ static struct i2c_algo_bit_data ioc_data = {
static struct i2c_adapter ioc_ops = {
.nr = 0,
+ .name = "ioc",
.algo_data = &ioc_data,
};
diff --git a/drivers/i2c/busses/virtio-i2c.c b/drivers/i2c/busses/virtio-i2c.c
index 95c35541c295..674c38aae987 100644
--- a/drivers/i2c/busses/virtio-i2c.c
+++ b/drivers/i2c/busses/virtio-i2c.c
@@ -34,19 +34,6 @@
#define I2C_VIRTIO_WR 0x02
#define I2C_VIRTIO_RDWR 0x03
-/**
- * struct virtio_i2c - virtio i2c device
- * @adapter: i2c adapter
- * @vdev: the virtio device
- * @vq: i2c virtqueue
- */
-struct virtio_i2c {
- struct i2c_adapter adapter;
- struct virtio_device *vdev;
- struct virtqueue *vq;
- wait_queue_head_t inq;
-};
-
struct i2c_transfer_head {
u32 type; /* read or write from or to slave */
u32 addr; /* slave addr */
@@ -64,6 +51,21 @@ struct virtio_i2c_req {
struct i2c_transfer_end end;
};
+/**
+ * struct virtio_i2c - virtio i2c device
+ * @adapter: i2c adapter
+ * @vdev: the virtio device
+ * @i2c_req: description of the format of transfer data
+ * @vq: i2c virtqueue
+ */
+struct virtio_i2c {
+ struct i2c_adapter adapter;
+ struct virtio_device *vdev;
+ struct virtio_i2c_req i2c_req;
+ struct virtqueue *vq;
+ wait_queue_head_t inq;
+};
+
static int virti2c_transfer(struct virtio_i2c *vi2c,
struct virtio_i2c_req *i2c_req)
{
@@ -117,70 +119,62 @@ req_exit:
}
/* prepare the transfer req */
-static struct virtio_i2c_req *virti2c_transfer_prepare(struct i2c_msg *msg_1,
- struct i2c_msg *msg_2)
+static int virti2c_transfer_prepare(struct i2c_msg *msg_1,
+ struct i2c_msg *msg_2, struct virtio_i2c_req *i2c_req)
{
- char *ptr = NULL;
- int merge = 0;
- struct virtio_i2c_req *i2c_req;
+ if (IS_ERR_OR_NULL(msg_1) || !msg_1->len ||
+ IS_ERR_OR_NULL(msg_1->buf))
+ return -EINVAL;
- if (msg_1 == NULL)
- return NULL;
+ i2c_req->head.addr = msg_1->addr;
+ i2c_req->head.length = msg_1->len;
- if (msg_2)
- merge = 1;
+ if (IS_ERR_OR_NULL(msg_2)) {
+ i2c_req->buf = kzalloc(msg_1->len, GFP_KERNEL);
+ if (!i2c_req->buf)
+ return -ENOMEM;
- i2c_req = kzalloc(sizeof(struct virtio_i2c_req), GFP_KERNEL);
- if (i2c_req == NULL)
- return NULL;
+ if (msg_1->flags & I2C_M_RD) {
+ i2c_req->head.type = I2C_VIRTIO_RD;
+ } else {
+ i2c_req->head.type = I2C_VIRTIO_WR;
+ memcpy(i2c_req->buf, msg_1->buf, msg_1->len);
+ }
- if (merge)
- ptr = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL);
- else
- ptr = msg_1->buf;
- if (ptr == NULL)
- goto err_mem;
-
- /* prepare the head */
- i2c_req->head.type = merge ?
- I2C_VIRTIO_RDWR : ((msg_1->flags & I2C_M_RD) ?
- I2C_VIRTIO_RD : I2C_VIRTIO_WR);
- i2c_req->head.addr = msg_1->addr;
- i2c_req->head.length = msg_1->len;
- if (merge)
+ } else {
+ if (!msg_2->len || IS_ERR_OR_NULL(msg_2->buf))
+ return -EINVAL;
+
+ i2c_req->buf = kzalloc((msg_1->len + msg_2->len), GFP_KERNEL);
+ if (!i2c_req->buf)
+ return -ENOMEM;
+
+ i2c_req->head.type = I2C_VIRTIO_RDWR;
i2c_req->head.total_length = msg_1->len + msg_2->len;
- /* prepare the buf */
- if (merge)
- memcpy(ptr, msg_1->buf, msg_1->len);
- i2c_req->buf = ptr;
+ memcpy(i2c_req->buf, msg_1->buf, msg_1->len);
+ }
- return i2c_req;
-err_mem:
- kfree(i2c_req);
- i2c_req = NULL;
- return NULL;
+ return 0;
}
static void virti2c_transfer_end(struct virtio_i2c_req *req,
struct i2c_msg *msg)
{
- if (req->head.type == I2C_VIRTIO_RDWR) {
+ if (req->head.type == I2C_VIRTIO_RDWR)
memcpy(msg->buf, req->buf + req->head.length, msg->len);
- kfree(req->buf);
- req->buf = NULL;
- }
-
- kfree(req);
- req = NULL;
+ else if (req->head.type == I2C_VIRTIO_RD)
+ memcpy(msg->buf, req->buf, msg->len);
+ kfree(req->buf);
+ req->buf = NULL;
}
static int virtio_i2c_master_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
int i, ret;
- struct virtio_i2c_req *i2c_req;
struct virtio_i2c *vi2c = i2c_get_adapdata(adap);
+ struct virtio_i2c_req *i2c_req = &vi2c->i2c_req;
if (num < 1) {
dev_err(&vi2c->vdev->dev,
@@ -197,24 +191,22 @@ static int virtio_i2c_master_xfer(struct i2c_adapter *adap,
if (msgs[i].flags & I2C_M_RD) {
/* read the data from slave to master*/
- i2c_req = virti2c_transfer_prepare(&msgs[i], NULL);
+ ret = virti2c_transfer_prepare(&msgs[i], NULL, i2c_req);
} else if ((i + 1 < num) && (msgs[i + 1].flags & I2C_M_RD) &&
(msgs[i].addr == msgs[i + 1].addr)) {
/* write then read from same address*/
- i2c_req = virti2c_transfer_prepare(&msgs[i],
- &msgs[i+1]);
+ ret = virti2c_transfer_prepare(&msgs[i],
+ &msgs[i+1], i2c_req);
i += 1;
} else {
/* write the data to slave */
- i2c_req = virti2c_transfer_prepare(&msgs[i], NULL);
+ ret = virti2c_transfer_prepare(&msgs[i], NULL, i2c_req);
}
- if (i2c_req == NULL) {
- ret = -ENOMEM;
+ if (ret)
goto err;
- }
ret = virti2c_transfer(vi2c, i2c_req);
virti2c_transfer_end(i2c_req, &msgs[i]);
if (ret)
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 57e3790c87b1..e56b774e7cf9 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -295,6 +295,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
rdwr_pa[i].buf[0] < 1 ||
rdwr_pa[i].len < rdwr_pa[i].buf[0] +
I2C_SMBUS_BLOCK_MAX) {
+ i++;
res = -EINVAL;
break;
}
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index a1d072ecb717..30f200ad6b97 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -62,7 +62,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
struct spi_transfer t = {
.tx_buf = data,
.len = size + 1,
- .cs_change = sigma_delta->bus_locked,
+ .cs_change = sigma_delta->keep_cs_asserted,
};
struct spi_message m;
int ret;
@@ -217,6 +217,7 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
spi_bus_lock(sigma_delta->spi->master);
sigma_delta->bus_locked = true;
+ sigma_delta->keep_cs_asserted = true;
reinit_completion(&sigma_delta->completion);
ret = ad_sigma_delta_set_mode(sigma_delta, mode);
@@ -234,9 +235,10 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
ret = 0;
}
out:
+ sigma_delta->keep_cs_asserted = false;
+ ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
sigma_delta->bus_locked = false;
spi_bus_unlock(sigma_delta->spi->master);
- ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
return ret;
}
@@ -288,6 +290,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
spi_bus_lock(sigma_delta->spi->master);
sigma_delta->bus_locked = true;
+ sigma_delta->keep_cs_asserted = true;
reinit_completion(&sigma_delta->completion);
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
@@ -297,9 +300,6 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
ret = wait_for_completion_interruptible_timeout(
&sigma_delta->completion, HZ);
- sigma_delta->bus_locked = false;
- spi_bus_unlock(sigma_delta->spi->master);
-
if (ret == 0)
ret = -EIO;
if (ret < 0)
@@ -315,7 +315,10 @@ out:
sigma_delta->irq_dis = true;
}
+ sigma_delta->keep_cs_asserted = false;
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+ sigma_delta->bus_locked = false;
+ spi_bus_unlock(sigma_delta->spi->master);
mutex_unlock(&indio_dev->mlock);
if (ret)
@@ -352,6 +355,8 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
spi_bus_lock(sigma_delta->spi->master);
sigma_delta->bus_locked = true;
+ sigma_delta->keep_cs_asserted = true;
+
ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
if (ret)
goto err_unlock;
@@ -380,6 +385,7 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
sigma_delta->irq_dis = true;
}
+ sigma_delta->keep_cs_asserted = false;
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
sigma_delta->bus_locked = false;
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c
index a3ae165f8d9f..16180e6321bd 100644
--- a/drivers/iio/common/ssp_sensors/ssp_iio.c
+++ b/drivers/iio/common/ssp_sensors/ssp_iio.c
@@ -80,7 +80,7 @@ int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
unsigned int len, int64_t timestamp)
{
__le32 time;
- int64_t calculated_time;
+ int64_t calculated_time = 0;
struct ssp_sensor_data *spd = iio_priv(indio_dev);
if (indio_dev->scan_bytes == 0)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index c9cffced00ca..54fd4d81a3f1 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -360,6 +360,8 @@ static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)
skb_reset_transport_header(skb);
} else {
skb = alloc_skb(len, gfp);
+ if (!skb)
+ return NULL;
}
t4_set_arp_err_handler(skb, NULL, NULL);
return skb;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 67c4c73343d4..6968154a073e 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1042,6 +1042,8 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
* mlx4_ib_vma_close().
*/
down_write(&owning_mm->mmap_sem);
+ if (!mmget_still_valid(owning_mm))
+ goto skip_mm;
for (i = 0; i < HW_BAR_COUNT; i++) {
vma = context->hw_bar_info[i].vma;
if (!vma)
@@ -1061,6 +1063,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
context->hw_bar_info[i].vma->vm_ops = NULL;
}
+skip_mm:
up_write(&owning_mm->mmap_sem);
mmput(owning_mm);
put_task_struct(owning_process);
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 3e97c4b2ebed..b965561a4162 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3983,9 +3983,7 @@ static void __init init_no_remapping_devices(void)
/* This IOMMU has *only* gfx devices. Either bypass it or
set the gfx_mapped flag, as appropriate */
- if (dmar_map_gfx) {
- intel_iommu_gfx_mapped = 1;
- } else {
+ if (!dmar_map_gfx) {
drhd->ignored = 1;
for_each_active_dev_scope(drhd->devices,
drhd->devices_cnt, i, dev)
@@ -4694,6 +4692,9 @@ int __init intel_iommu_init(void)
goto out_free_reserved_range;
}
+ if (dmar_map_gfx)
+ intel_iommu_gfx_mapped = 1;
+
init_no_remapping_devices();
ret = init_dmars();
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 9305964250ac..c4eb293b1524 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -91,7 +91,6 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset)
#define SMMU_TLB_FLUSH_VA_MATCH_ALL (0 << 0)
#define SMMU_TLB_FLUSH_VA_MATCH_SECTION (2 << 0)
#define SMMU_TLB_FLUSH_VA_MATCH_GROUP (3 << 0)
-#define SMMU_TLB_FLUSH_ASID(x) (((x) & 0x7f) << 24)
#define SMMU_TLB_FLUSH_VA_SECTION(addr) ((((addr) & 0xffc00000) >> 12) | \
SMMU_TLB_FLUSH_VA_MATCH_SECTION)
#define SMMU_TLB_FLUSH_VA_GROUP(addr) ((((addr) & 0xffffc000) >> 12) | \
@@ -194,8 +193,12 @@ static inline void smmu_flush_tlb_asid(struct tegra_smmu *smmu,
{
u32 value;
- value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) |
- SMMU_TLB_FLUSH_VA_MATCH_ALL;
+ if (smmu->soc->num_asids == 4)
+ value = (asid & 0x3) << 29;
+ else
+ value = (asid & 0x7f) << 24;
+
+ value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_MATCH_ALL;
smmu_writel(smmu, value, SMMU_TLB_FLUSH);
}
@@ -205,8 +208,12 @@ static inline void smmu_flush_tlb_section(struct tegra_smmu *smmu,
{
u32 value;
- value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) |
- SMMU_TLB_FLUSH_VA_SECTION(iova);
+ if (smmu->soc->num_asids == 4)
+ value = (asid & 0x3) << 29;
+ else
+ value = (asid & 0x7f) << 24;
+
+ value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_SECTION(iova);
smmu_writel(smmu, value, SMMU_TLB_FLUSH);
}
@@ -216,8 +223,12 @@ static inline void smmu_flush_tlb_group(struct tegra_smmu *smmu,
{
u32 value;
- value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) |
- SMMU_TLB_FLUSH_VA_GROUP(iova);
+ if (smmu->soc->num_asids == 4)
+ value = (asid & 0x3) << 29;
+ else
+ value = (asid & 0x7f) << 24;
+
+ value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_GROUP(iova);
smmu_writel(smmu, value, SMMU_TLB_FLUSH);
}
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 0d29b5a6356d..8cbb75d09a1d 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -394,7 +394,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
memcpy(di.channelmap, dev->channelmap,
sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
- strcpy(di.name, dev_name(&dev->dev));
+ strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
err = -EFAULT;
} else
@@ -678,7 +678,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
memcpy(di.channelmap, dev->channelmap,
sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
- strcpy(di.name, dev_name(&dev->dev));
+ strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
err = -EFAULT;
} else
@@ -692,6 +692,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
+ dn.name[sizeof(dn.name) - 1] = '\0';
dev = get_mdevice(dn.id);
if (dev)
err = device_rename(&dev->dev, dn.name);
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 16c3390e5d9f..d82ae445c9ee 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -324,10 +324,11 @@ static int bch_allocator_thread(void *arg)
* possibly issue discards to them, then we add the bucket to
* the free list:
*/
- while (!fifo_empty(&ca->free_inc)) {
+ while (1) {
long bucket;
- fifo_pop(&ca->free_inc, bucket);
+ if (!fifo_pop(&ca->free_inc, bucket))
+ break;
if (ca->discard) {
mutex_unlock(&ca->set->bucket_lock);
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index 646fe85261c1..158eae17031c 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -823,12 +823,22 @@ unsigned bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
struct bset *i = bset_tree_last(b)->data;
struct bkey *m, *prev = NULL;
struct btree_iter iter;
+ struct bkey preceding_key_on_stack = ZERO_KEY;
+ struct bkey *preceding_key_p = &preceding_key_on_stack;
BUG_ON(b->ops->is_extents && !KEY_SIZE(k));
- m = bch_btree_iter_init(b, &iter, b->ops->is_extents
- ? PRECEDING_KEY(&START_KEY(k))
- : PRECEDING_KEY(k));
+ /*
+ * If k has preceding key, preceding_key_p will be set to address
+ * of k's preceding key; otherwise preceding_key_p will be set
+ * to NULL inside preceding_key().
+ */
+ if (b->ops->is_extents)
+ preceding_key(&START_KEY(k), &preceding_key_p);
+ else
+ preceding_key(k, &preceding_key_p);
+
+ m = bch_btree_iter_init(b, &iter, preceding_key_p);
if (b->ops->insert_fixup(b, k, &iter, replace_key))
return status;
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h
index ae964624efb2..b935839ab79c 100644
--- a/drivers/md/bcache/bset.h
+++ b/drivers/md/bcache/bset.h
@@ -417,20 +417,26 @@ static inline bool bch_cut_back(const struct bkey *where, struct bkey *k)
return __bch_cut_back(where, k);
}
-#define PRECEDING_KEY(_k) \
-({ \
- struct bkey *_ret = NULL; \
- \
- if (KEY_INODE(_k) || KEY_OFFSET(_k)) { \
- _ret = &KEY(KEY_INODE(_k), KEY_OFFSET(_k), 0); \
- \
- if (!_ret->low) \
- _ret->high--; \
- _ret->low--; \
- } \
- \
- _ret; \
-})
+/*
+ * Pointer '*preceding_key_p' points to a memory object to store preceding
+ * key of k. If the preceding key does not exist, set '*preceding_key_p' to
+ * NULL. So the caller of preceding_key() needs to take care of memory
+ * which '*preceding_key_p' pointed to before calling preceding_key().
+ * Currently the only caller of preceding_key() is bch_btree_insert_key(),
+ * and it points to an on-stack variable, so the memory release is handled
+ * by stackframe itself.
+ */
+static inline void preceding_key(struct bkey *k, struct bkey **preceding_key_p)
+{
+ if (KEY_INODE(k) || KEY_OFFSET(k)) {
+ (**preceding_key_p) = KEY(KEY_INODE(k), KEY_OFFSET(k), 0);
+ if (!(*preceding_key_p)->low)
+ (*preceding_key_p)->high--;
+ (*preceding_key_p)->low--;
+ } else {
+ (*preceding_key_p) = NULL;
+ }
+}
static inline bool bch_ptr_invalid(struct btree_keys *b, const struct bkey *k)
{
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 6ed066a0e7c0..6f9db98f2dfd 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -309,6 +309,18 @@ void bch_journal_mark(struct cache_set *c, struct list_head *list)
}
}
+bool is_discard_enabled(struct cache_set *s)
+{
+ struct cache *ca;
+ unsigned int i;
+
+ for_each_cache(ca, s, i)
+ if (ca->discard)
+ return true;
+
+ return false;
+}
+
int bch_journal_replay(struct cache_set *s, struct list_head *list)
{
int ret = 0, keys = 0, entries = 0;
@@ -322,9 +334,17 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list)
list_for_each_entry(i, list, list) {
BUG_ON(i->pin && atomic_read(i->pin) != 1);
- cache_set_err_on(n != i->j.seq, s,
-"bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)",
- n, i->j.seq - 1, start, end);
+ if (n != i->j.seq) {
+ if (n == start && is_discard_enabled(s))
+ pr_info("bcache: journal entries %llu-%llu may be discarded! (replaying %llu-%llu)",
+ n, i->j.seq - 1, start, end);
+ else {
+ pr_err("bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)",
+ n, i->j.seq - 1, start, end);
+ ret = -EIO;
+ goto err;
+ }
+ }
for (k = i->j.start;
k < bset_bkey_last(&i->j);
@@ -513,11 +533,11 @@ static void journal_reclaim(struct cache_set *c)
ca->sb.nr_this_dev);
}
- bkey_init(k);
- SET_KEY_PTRS(k, n);
-
- if (n)
+ if (n) {
+ bkey_init(k);
+ SET_KEY_PTRS(k, n);
c->journal.blocks_free = c->sb.bucket_size >> c->block_bits;
+ }
out:
if (!journal_full(&c->journal))
__closure_wake_up(&c->journal.wait);
@@ -641,6 +661,9 @@ static void journal_write_unlocked(struct closure *cl)
ca->journal.seq[ca->journal.cur_idx] = w->data->seq;
}
+ /* If KEY_PTRS(k) == 0, this jset gets lost in air */
+ BUG_ON(i == 0);
+
atomic_dec_bug(&fifo_back(&c->journal.pin));
bch_journal_next(&c->journal);
journal_reclaim(c);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 69356e9a3be5..bfbf5dd06ac5 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1355,6 +1355,7 @@ static void cache_set_free(struct closure *cl)
bch_btree_cache_free(c);
bch_journal_free(c);
+ mutex_lock(&bch_register_lock);
for_each_cache(ca, c, i)
if (ca) {
ca->set = NULL;
@@ -1377,7 +1378,6 @@ static void cache_set_free(struct closure *cl)
mempool_destroy(c->search);
kfree(c->devices);
- mutex_lock(&bch_register_lock);
list_del(&c->list);
mutex_unlock(&bch_register_lock);
@@ -1558,7 +1558,7 @@ err:
return NULL;
}
-static void run_cache_set(struct cache_set *c)
+static int run_cache_set(struct cache_set *c)
{
const char *err = "cannot allocate memory";
struct cached_dev *dc, *t;
@@ -1650,7 +1650,9 @@ static void run_cache_set(struct cache_set *c)
if (j->version < BCACHE_JSET_VERSION_UUID)
__uuid_write(c);
- bch_journal_replay(c, &journal);
+ err = "bcache: replay journal failed";
+ if (bch_journal_replay(c, &journal))
+ goto err;
} else {
pr_notice("invalidating existing data");
@@ -1718,11 +1720,13 @@ static void run_cache_set(struct cache_set *c)
flash_devs_run(c);
set_bit(CACHE_SET_RUNNING, &c->flags);
- return;
+ return 0;
err:
closure_sync(&cl);
/* XXX: test this, it's broken */
bch_cache_set_error(c, "%s", err);
+
+ return -EIO;
}
static bool can_attach_cache(struct cache *ca, struct cache_set *c)
@@ -1786,8 +1790,11 @@ found:
ca->set->cache[ca->sb.nr_this_dev] = ca;
c->cache_by_alloc[c->caches_loaded++] = ca;
- if (c->caches_loaded == c->sb.nr_in_set)
- run_cache_set(c);
+ if (c->caches_loaded == c->sb.nr_in_set) {
+ err = "failed to run cache set";
+ if (run_cache_set(c) < 0)
+ goto err;
+ }
return NULL;
err:
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index b4c356a21123..e789a4aae4e7 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -222,7 +222,8 @@ static void delay_dtr(struct dm_target *ti)
{
struct delay_c *dc = ti->private;
- destroy_workqueue(dc->kdelayd_wq);
+ if (dc->kdelayd_wq)
+ destroy_workqueue(dc->kdelayd_wq);
dm_put_device(ti, dc->dev_read);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e60d855b82e0..68ebab54883e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2690,8 +2690,10 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
err = 0;
}
} else if (cmd_match(buf, "re-add")) {
- if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1) &&
- rdev->saved_raid_disk >= 0) {
+ if (!rdev->mddev->pers)
+ err = -EINVAL;
+ else if (test_bit(Faulty, &rdev->flags) && (rdev->raid_disk == -1) &&
+ rdev->saved_raid_disk >= 0) {
/* clear_bit is performed _after_ all the devices
* have their local Faulty bit cleared. If any writes
* happen in the meantime in the local node, they
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 43e49105d97c..38e62418c6ff 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3861,7 +3861,7 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
/* now write out any block on a failed drive,
* or P or Q if they were recomputed
*/
- BUG_ON(s->uptodate < disks - 1); /* We don't need Q to recover */
+ dev = NULL;
if (s->failed == 2) {
dev = &sh->dev[s->failed_num[1]];
s->locked++;
@@ -3886,6 +3886,14 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
set_bit(R5_LOCKED, &dev->flags);
set_bit(R5_Wantwrite, &dev->flags);
}
+ if (WARN_ONCE(dev && !test_bit(R5_UPTODATE, &dev->flags),
+ "%s: disk%td not up to date\n",
+ mdname(conf->mddev),
+ dev - (struct r5dev *) &sh->dev)) {
+ clear_bit(R5_LOCKED, &dev->flags);
+ clear_bit(R5_Wantwrite, &dev->flags);
+ s->locked--;
+ }
clear_bit(STRIPE_DEGRADED, &sh->state);
set_bit(STRIPE_INSYNC, &sh->state);
@@ -3897,15 +3905,26 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
case check_state_check_result:
sh->check_state = check_state_idle;
- if (s->failed > 1)
- break;
/* handle a successful check operation, if parity is correct
* we are done. Otherwise update the mismatch count and repair
* parity if !MD_RECOVERY_CHECK
*/
if (sh->ops.zero_sum_result == 0) {
- /* Any parity checked was correct */
- set_bit(STRIPE_INSYNC, &sh->state);
+ /* both parities are correct */
+ if (!s->failed)
+ set_bit(STRIPE_INSYNC, &sh->state);
+ else {
+ /* in contrast to the raid5 case we can validate
+ * parity, but still have a failure to write
+ * back
+ */
+ sh->check_state = check_state_compute_result;
+ /* Returning at this point means that we may go
+ * off and bring p and/or q uptodate again so
+ * we make sure to check zero_sum_result again
+ * to verify if p or q need writeback
+ */
+ }
} else {
atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index d14d075ab1d6..9f0956e739a4 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -309,6 +309,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
u16 u16tmp, divide_ratio = 0;
u32 tuner_frequency, target_mclk;
s32 s32tmp;
+ static const struct reg_sequence reset_buf[] = {
+ {0x07, 0x80}, {0x07, 0x00}
+ };
dev_dbg(&client->dev,
"delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
@@ -321,11 +324,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
}
/* reset */
- ret = regmap_write(dev->regmap, 0x07, 0x80);
- if (ret)
- goto err;
-
- ret = regmap_write(dev->regmap, 0x07, 0x00);
+ ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2);
if (ret)
goto err;
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 49109f4f5bb4..fadec1d70582 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1117,8 +1117,10 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd,
if (ov2659_formats[index].code == mf->code)
break;
- if (index < 0)
- return -EINVAL;
+ if (index < 0) {
+ index = 0;
+ mf->code = ov2659_formats[index].code;
+ }
mf->colorspace = V4L2_COLORSPACE_SRGB;
mf->code = ov2659_formats[index].code;
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 1e4783b51a35..4e19f5e5d8cf 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -839,9 +839,18 @@ static int ov6650_video_probe(struct i2c_client *client)
u8 pidh, pidl, midh, midl;
int ret;
+ priv->clk = v4l2_clk_get(&client->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ dev_err(&client->dev, "v4l2_clk request err: %d\n", ret);
+ return ret;
+ }
+
ret = ov6650_s_power(&priv->subdev, 1);
if (ret < 0)
- return ret;
+ goto eclkput;
+
+ msleep(20);
/*
* check and show product ID and manufacturer ID
@@ -876,6 +885,11 @@ static int ov6650_video_probe(struct i2c_client *client)
done:
ov6650_s_power(&priv->subdev, 0);
+ if (!ret)
+ return 0;
+eclkput:
+ v4l2_clk_put(priv->clk);
+
return ret;
}
@@ -1033,18 +1047,9 @@ static int ov6650_probe(struct i2c_client *client,
priv->code = MEDIA_BUS_FMT_YUYV8_2X8;
priv->colorspace = V4L2_COLORSPACE_JPEG;
- priv->clk = v4l2_clk_get(&client->dev, NULL);
- if (IS_ERR(priv->clk)) {
- ret = PTR_ERR(priv->clk);
- goto eclkget;
- }
-
ret = ov6650_video_probe(client);
- if (ret) {
- v4l2_clk_put(priv->clk);
-eclkget:
+ if (ret)
v4l2_ctrl_handler_free(&priv->hdl);
- }
return ret;
}
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index 03cbcd2095c6..d4b3ce828285 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -270,9 +270,8 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
/* enable i2c-port pins */
saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
- hexium->i2c_adapter = (struct i2c_adapter) {
- .name = "hexium gemini",
- };
+ strscpy(hexium->i2c_adapter.name, "hexium gemini",
+ sizeof(hexium->i2c_adapter.name));
saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
DEB_S("cannot register i2c-device. skipping.\n");
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 15f0d66ff78a..214396b1ca73 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -232,9 +232,8 @@ static int hexium_probe(struct saa7146_dev *dev)
saa7146_write(dev, DD1_STREAM_B, 0x00000000);
saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
- hexium->i2c_adapter = (struct i2c_adapter) {
- .name = "hexium orion",
- };
+ strscpy(hexium->i2c_adapter.name, "hexium orion",
+ sizeof(hexium->i2c_adapter.name));
saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
DEB_S("cannot register i2c-device. skipping.\n");
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index d76511c1c1e3..a4639813cf35 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -1829,6 +1829,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
/* Clear decode success flag */
coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS);
+ /* Clear error return value */
+ coda_write(dev, 0, CODA_RET_DEC_PIC_ERR_MB);
+
trace_coda_dec_pic_run(ctx, meta);
coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
diff --git a/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
index 0ab5684ea816..9b67fb55a886 100644
--- a/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
@@ -768,9 +768,8 @@ static int32_t msm_actuator_bivcm_move_focus(
a_ctrl->curr_step_pos, dest_step_pos, curr_lens_pos);
while (a_ctrl->curr_step_pos != dest_step_pos) {
- if (a_ctrl->curr_region_index >= a_ctrl->region_size) {
+ if (a_ctrl->curr_region_index >= a_ctrl->region_size)
break;
- }
step_boundary =
a_ctrl->region_params[a_ctrl->curr_region_index].
step_bound[dir];
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
index 8e0a7443f98c..29ecf9168268 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -1471,6 +1471,7 @@ static struct platform_driver fd_driver = {
.name = MSM_FD_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = msm_fd_dt_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 05dbe24de4bd..c4e7e08a1d04 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -416,6 +416,12 @@ enum msm_isp_comp_irq_types {
#define MSM_VFE_REQUESTQ_SIZE 8
+struct msm_isp_pending_buf_info {
+ uint32_t is_buf_done_pending;
+ struct msm_isp_buffer *buf;
+ uint32_t frame_id;
+};
+
struct msm_vfe_axi_stream {
uint32_t frame_id;
enum msm_vfe_axi_state state;
@@ -472,6 +478,7 @@ struct msm_vfe_axi_stream {
uint32_t vfe_mask;
uint32_t composite_irq[MSM_ISP_COMP_IRQ_MAX];
int lpm_mode;
+ struct msm_isp_pending_buf_info pending_buf_info;
};
struct msm_vfe_axi_composite_info {
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 40ece2ffcf4b..de18bedc40cb 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
@@ -16,6 +16,7 @@
#include "msm_isp_stats_util.h"
#include "msm_isp_axi_util.h"
#include "msm_isp48.h"
+#include "trace/events/msm_cam.h"
#define HANDLE_TO_IDX(handle) (handle & 0xFF)
#define ISP_SOF_DEBUG_COUNT 0
@@ -27,6 +28,13 @@ static void __msm_isp_axi_stream_update(
struct msm_vfe_axi_stream *stream_info,
struct msm_isp_timestamp *ts);
+static int msm_isp_process_done_buf(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
+ struct timeval *time_stamp, uint32_t frame_id);
+static void msm_isp_free_pending_buffer(
+ struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info,
+ struct msm_isp_timestamp *ts);
static int msm_isp_update_stream_bandwidth(
struct msm_vfe_axi_stream *stream_info, int enable);
@@ -657,6 +665,10 @@ void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
case MSM_ISP_COMP_IRQ_REG_UPD:
stream_info->activated_framedrop_period =
stream_info->requested_framedrop_period;
+ /* Free Pending Buffers which are backed-up due to
+ * delay in RUP from userspace to Avoid pageFault
+ */
+ msm_isp_free_pending_buffer(vfe_dev, stream_info, ts);
__msm_isp_axi_stream_update(stream_info, ts);
break;
case MSM_ISP_COMP_IRQ_EPOCH:
@@ -1032,8 +1044,12 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
vfe_dev->isp_raw2_debug++;
}
- ISP_DBG("%s: vfe %d frame_src %d\n", __func__,
- vfe_dev->pdev->id, frame_src);
+ ISP_DBG("%s: vfe %d frame_src %d frameid %d\n", __func__,
+ vfe_dev->pdev->id, frame_src,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
+ trace_msm_cam_isp_status_dump("SOFNOTIFY:", vfe_dev->pdev->id,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
+ 0, 0);
/*
* Cannot support dual_cam and framedrop same time in union.
@@ -1518,6 +1534,40 @@ static void msm_isp_axi_stream_enable_cfg(
}
}
+static void msm_isp_free_pending_buffer(
+ struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info,
+ struct msm_isp_timestamp *ts)
+{
+ struct timeval *time_stamp;
+ struct msm_isp_buffer *done_buf = NULL;
+ uint32_t frame_id;
+ int rc;
+
+ if (!stream_info->controllable_output ||
+ !stream_info->pending_buf_info.is_buf_done_pending) {
+ return;
+ }
+
+ if (vfe_dev->vt_enable) {
+ msm_isp_get_avtimer_ts(ts);
+ time_stamp = &ts->vt_time;
+ } else {
+ time_stamp = &ts->buf_time;
+ }
+
+ done_buf = stream_info->pending_buf_info.buf;
+ frame_id = stream_info->pending_buf_info.frame_id;
+ if (done_buf) {
+ rc = msm_isp_process_done_buf(vfe_dev, stream_info,
+ done_buf, time_stamp, frame_id);
+ if (rc == 0) {
+ stream_info->pending_buf_info.buf = NULL;
+ stream_info->pending_buf_info.is_buf_done_pending = 0;
+ }
+ }
+}
+
static void __msm_isp_axi_stream_update(
struct msm_vfe_axi_stream *stream_info,
struct msm_isp_timestamp *ts)
@@ -3008,6 +3058,12 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev,
msm_isp_cfg_stream_scratch(stream_info, VFE_PING_FLAG);
msm_isp_cfg_stream_scratch(stream_info, VFE_PONG_FLAG);
stream_info->undelivered_request_cnt = 0;
+ if (stream_info->controllable_output &&
+ stream_info->pending_buf_info.is_buf_done_pending) {
+ msm_isp_free_pending_buffer(vfe_dev, stream_info,
+ &timestamp);
+ stream_info->pending_buf_info.is_buf_done_pending = 0;
+ }
for (k = 0; k < stream_info->num_isp; k++) {
vfe_dev = stream_info->vfe_dev[k];
if (stream_info->num_planes > 1)
@@ -4296,9 +4352,21 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
done_buf->is_drop_reconfig = 0;
spin_unlock_irqrestore(&stream_info->lock, flags);
} else {
+ /* If there is no regupdate from userspace then dont
+ * free buffer immediately, delegate it to RegUpdateAck
+ */
+ if (stream_info->controllable_output &&
+ !(vfe_dev->reg_update_requested &
+ BIT((uint32_t)VFE_PIX_0))) {
+ stream_info->pending_buf_info.is_buf_done_pending = 1;
+ stream_info->pending_buf_info.buf = done_buf;
+ stream_info->pending_buf_info.frame_id = frame_id;
+ }
spin_unlock_irqrestore(&stream_info->lock, flags);
- msm_isp_process_done_buf(vfe_dev, stream_info,
- done_buf, time_stamp, frame_id);
+ if (stream_info->pending_buf_info.is_buf_done_pending != 1) {
+ msm_isp_process_done_buf(vfe_dev, stream_info,
+ done_buf, time_stamp, frame_id);
+ }
}
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index b4149725ba69..42d8ad0fddc9 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -2090,6 +2090,10 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
} else {
atomic_add(1, &vfe_dev->irq_cnt);
}
+ atomic_add(1, &vfe_dev->irq_cnt);
+ trace_msm_cam_isp_status_dump("VFE_IRQ:", vfe_dev->pdev->id,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
+ irq_status0, irq_status1);
queue_cmd->vfeInterruptStatus0 = irq_status0;
queue_cmd->vfeInterruptStatus1 = irq_status1;
queue_cmd->vfe_pingpong_status = ping_pong_status;
@@ -2189,6 +2193,9 @@ void msm_isp_do_tasklet(unsigned long data)
atomic_sub(1, &vfe_dev->irq_cnt);
msm_isp_prepare_tasklet_debug_info(vfe_dev,
irq_status0, irq_status1, ts);
+ trace_msm_cam_isp_status_dump("VFE_TASKLET:", vfe_dev->pdev->id,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
+ irq_status0, irq_status1);
irq_ops = &vfe_dev->hw_info->vfe_ops.irq_ops;
irq_ops->process_reset_irq(vfe_dev,
irq_status0, irq_status1);
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
index 5ef08cbe9aee..0abb81e998f6 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.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
@@ -323,6 +323,7 @@ static struct platform_driver msm_jpeg_driver = {
.name = "msm_jpeg",
.owner = THIS_MODULE,
.of_match_table = msm_jpeg_dt_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 0d994a950acd..c847d5210735 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -1493,6 +1493,7 @@ static struct platform_driver jpegdma_driver = {
.name = MSM_JPEGDMA_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = msm_jpegdma_dt_match,
+ .suppress_bind_attrs = true,
},
};
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 5e4deace1454..876a6d75e7ce 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
@@ -4689,6 +4689,7 @@ static struct platform_driver cpp_driver = {
.name = MSM_CPP_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = msm_cpp_dt_match,
+ .suppress_bind_attrs = true,
},
};
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 18899373de8a..e5fad84020bf 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -39,6 +39,7 @@
#define FIRMWARE_SIZE 0X00A00000
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
#define QDSS_IOVA_START 0x80001000
+#define MIN_PAYLOAD_SIZE 3
static struct hal_device_data hal_ctxt;
@@ -3447,23 +3448,55 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
log_level = VIDC_ERR;
}
+#define SKIP_INVALID_PKT(pkt_size, payload_size, pkt_hdr_size) ({ \
+ if (pkt_size < pkt_hdr_size || \
+ payload_size < MIN_PAYLOAD_SIZE || \
+ payload_size > \
+ (pkt_size - pkt_hdr_size + sizeof(u8))) { \
+ dprintk(VIDC_ERR, \
+ "%s: invalid msg size - %d\n", \
+ __func__, pkt->msg_size); \
+ continue; \
+ } \
+ })
+
while (!__iface_dbgq_read(device, packet)) {
- struct hfi_msg_sys_coverage_packet *pkt =
- (struct hfi_msg_sys_coverage_packet *) packet;
+ struct hfi_packet_header *pkt =
+ (struct hfi_packet_header *) packet;
+
+ if (pkt->size < sizeof(struct hfi_packet_header)) {
+ dprintk(VIDC_ERR, "Invalid pkt size - %s\n",
+ __func__);
+ continue;
+ }
+
if (pkt->packet_type == HFI_MSG_SYS_COV) {
+ struct hfi_msg_sys_coverage_packet *pkt =
+ (struct hfi_msg_sys_coverage_packet *) packet;
int stm_size = 0;
+
+ SKIP_INVALID_PKT(pkt->size,
+ pkt->msg_size, sizeof(*pkt));
+
stm_size = stm_log_inv_ts(0, 0,
pkt->rg_msg_data, pkt->msg_size);
if (stm_size == 0)
dprintk(VIDC_ERR,
"In %s, stm_log returned size of 0\n",
__func__);
- } else {
+
+ } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) {
struct hfi_msg_sys_debug_packet *pkt =
(struct hfi_msg_sys_debug_packet *) packet;
+
+ SKIP_INVALID_PKT(pkt->size,
+ pkt->msg_size, sizeof(*pkt));
+
+ pkt->rg_msg_data[pkt->msg_size-1] = '\0';
dprintk(log_level, "%s", pkt->rg_msg_data);
}
}
+#undef SKIP_INVALID_PKT
if (local_packet)
kfree(packet);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 1218f0a86bc4..3709ad9fc658 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -976,6 +976,11 @@ struct vidc_hal_session_cmd_pkt {
u32 session_id;
};
+struct hfi_packet_header {
+ u32 size;
+ u32 packet_type;
+};
+
struct hfi_cmd_sys_init_packet {
u32 size;
u32 packet_type;
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index a84954f1be34..9eb0bc4a8d97 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -993,7 +993,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
rect_map_inside(&s->r, &dev->fmt_cap_rect);
if (dev->bitmap_cap && (compose->width != s->r.width ||
compose->height != s->r.height)) {
- kfree(dev->bitmap_cap);
+ vfree(dev->bitmap_cap);
dev->bitmap_cap = NULL;
}
*compose = s->r;
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index ebc73b034249..51639a3f7abe 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -494,7 +494,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
return -EIO;
}
/* Send response data to caller */
- if (response != NULL && response_len != NULL && evt_hdr->dlen) {
+ if (response != NULL && response_len != NULL && evt_hdr->dlen &&
+ evt_hdr->dlen <= payload_len) {
/* Skip header info and copy only response data */
skb_pull(skb, sizeof(struct fm_event_msg_hdr));
memcpy(response, skb->data, evt_hdr->dlen);
@@ -590,6 +591,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
return;
fm_evt_hdr = (void *)skb->data;
+ if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag))
+ return;
/* Skip header info and copy only response data */
skb_pull(skb, sizeof(struct fm_event_msg_hdr));
@@ -1315,7 +1318,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev)
static int fm_power_up(struct fmdev *fmdev, u8 mode)
{
u16 payload;
- __be16 asic_id, asic_ver;
+ __be16 asic_id = 0, asic_ver = 0;
int resp_len, ret;
u8 fw_name[50];
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 7b2fe1b56039..1df23c01ad37 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -711,6 +711,9 @@ static int au0828_analog_stream_enable(struct au0828_dev *d)
dprintk(1, "au0828_analog_stream_enable called\n");
+ if (test_bit(DEV_DISCONNECTED, &d->dev_state))
+ return -ENODEV;
+
iface = usb_ifnum_to_if(d->usbdev, 0);
if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
dprintk(1, "Changing intf#0 to alt 5\n");
@@ -799,9 +802,9 @@ int au0828_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
return rc;
}
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- v4l2_device_call_all(&dev->v4l2_dev, 0, video,
- s_stream, 1);
dev->vid_timeout_running = 1;
mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
} else if (vq->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
@@ -821,10 +824,11 @@ static void au0828_stop_streaming(struct vb2_queue *vq)
dprintk(1, "au0828_stop_streaming called %d\n", dev->streaming_users);
- if (dev->streaming_users-- == 1)
+ if (dev->streaming_users-- == 1) {
au0828_uninit_isoc(dev);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+ }
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
dev->vid_timeout_running = 0;
del_timer_sync(&dev->vid_timeout);
@@ -853,8 +857,10 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq)
dprintk(1, "au0828_stop_vbi_streaming called %d\n",
dev->streaming_users);
- if (dev->streaming_users-- == 1)
+ if (dev->streaming_users-- == 1) {
au0828_uninit_isoc(dev);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+ }
spin_lock_irqsave(&dev->slock, flags);
if (dev->isoc_ctl.vbi_buf != NULL) {
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index d793c630f1dd..05e7edb213de 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -1248,8 +1248,7 @@ static int __init cpia2_init(void)
LOG("%s v%s\n",
ABOUT, CPIA_VERSION);
check_parameters();
- cpia2_usb_init();
- return 0;
+ return cpia2_usb_init();
}
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
index 60bf5f0644d1..a5efcd4f7b4f 100644
--- a/drivers/media/usb/go7007/go7007-fw.c
+++ b/drivers/media/usb/go7007/go7007-fw.c
@@ -1499,8 +1499,8 @@ static int modet_to_package(struct go7007 *go, __le16 *code, int space)
return cnt;
}
-static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
- int *framelen)
+static noinline_for_stack int do_special(struct go7007 *go, u16 type,
+ __le16 *code, int space, int *framelen)
{
switch (type) {
case SPECIAL_FRM_HEAD:
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 0533ef20decf..232b0fd3e478 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -670,6 +670,8 @@ static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
{
+ if (v < 0 || v > PVR2_CVAL_INPUT_MAX)
+ return 0;
return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
index a82a00dd7329..80869990ffbb 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
@@ -54,6 +54,7 @@
#define PVR2_CVAL_INPUT_COMPOSITE 2
#define PVR2_CVAL_INPUT_SVIDEO 3
#define PVR2_CVAL_INPUT_RADIO 4
+#define PVR2_CVAL_INPUT_MAX PVR2_CVAL_INPUT_RADIO
enum pvr2_config {
pvr2_config_empty, /* No configuration */
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index ec30a004f319..e8f7a1f56be5 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -391,6 +391,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
struct smsusb_device_t *dev;
void *mdev;
int i, rc;
+ int align = 0;
/* create device object */
dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
@@ -402,6 +403,24 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
dev->udev = interface_to_usbdev(intf);
dev->state = SMSUSB_DISCONNECTED;
+ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+ struct usb_endpoint_descriptor *desc =
+ &intf->cur_altsetting->endpoint[i].desc;
+
+ if (desc->bEndpointAddress & USB_DIR_IN) {
+ dev->in_ep = desc->bEndpointAddress;
+ align = usb_endpoint_maxp(desc) - sizeof(struct sms_msg_hdr);
+ } else {
+ dev->out_ep = desc->bEndpointAddress;
+ }
+ }
+
+ pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
+ if (!dev->in_ep || !dev->out_ep || align < 0) { /* Missing endpoints? */
+ smsusb_term_device(intf);
+ return -ENODEV;
+ }
+
params.device_type = sms_get_board(board_id)->type;
switch (params.device_type) {
@@ -416,24 +435,12 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
/* fall-thru */
default:
dev->buffer_size = USB2_BUFFER_SIZE;
- dev->response_alignment =
- le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
- sizeof(struct sms_msg_hdr);
+ dev->response_alignment = align;
params.flags |= SMS_DEVICE_FAMILY2;
break;
}
- for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
- if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
- dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
- else
- dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
- }
-
- pr_debug("in_ep = %02x, out_ep = %02x\n",
- dev->in_ep, dev->out_ep);
-
params.device = &dev->udev->dev;
params.buffer_size = dev->buffer_size;
params.num_buffers = MAX_BUFFERS;
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index f2e3fdf385cc..ebd1b882556d 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -868,7 +868,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
unsigned int size;
unsigned int i;
- extra_size = ALIGN(extra_size, sizeof(*entity->pads));
+ extra_size = roundup(extra_size, sizeof(*entity->pads));
num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
+ num_inputs;
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 6ab481ee8ece..8ac02b6c162f 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -72,7 +72,7 @@ static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
u32 value;
/* compute the number of MC clock cycles per tick */
- tick = mc->tick * clk_get_rate(mc->clk);
+ tick = (unsigned long long)mc->tick * clk_get_rate(mc->clk);
do_div(tick, NSEC_PER_SEC);
value = readl(mc->regs + MC_EMEM_ARB_CFG);
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index ac867489b5a9..498875193386 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -267,6 +267,9 @@ static void intel_lpss_init_dev(const struct intel_lpss *lpss)
{
u32 value = LPSS_PRIV_SSP_REG_DIS_DMA_FIN;
+ /* Set the device in reset state */
+ writel(0, lpss->priv + LPSS_PRIV_RESETS);
+
intel_lpss_deassert_reset(lpss);
intel_lpss_set_remap_addr(lpss);
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index 72aab60ae846..db8684430f02 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -316,8 +316,19 @@ int twl6040_power(struct twl6040 *twl6040, int on)
}
}
+ /*
+ * Register access can produce errors after power-up unless we
+ * wait at least 8ms based on measurements on duovero.
+ */
+ usleep_range(10000, 12000);
+
/* Sync with the HW */
- regcache_sync(twl6040->regmap);
+ ret = regcache_sync(twl6040->regmap);
+ if (ret) {
+ dev_err(twl6040->dev, "Failed to sync with the HW: %i\n",
+ ret);
+ goto out;
+ }
/* Default PLL configuration after power up */
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
index c0012ca4229e..74923ffb0df1 100644
--- a/drivers/misc/genwqe/card_dev.c
+++ b/drivers/misc/genwqe/card_dev.c
@@ -782,6 +782,8 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m)
if ((m->addr == 0x0) || (m->size == 0))
return -EINVAL;
+ if (m->size > ULONG_MAX - PAGE_SIZE - (m->addr & ~PAGE_MASK))
+ return -EINVAL;
map_addr = (m->addr & PAGE_MASK);
map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE);
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 0c15ba21fa54..d4c719683a8a 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -582,6 +582,10 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr,
/* determine space needed for page_list. */
data = (unsigned long)uaddr;
offs = offset_in_page(data);
+ if (size > ULONG_MAX - PAGE_SIZE - offs) {
+ m->size = 0; /* mark unused and not added */
+ return -EINVAL;
+ }
m->nr_pages = DIV_ROUND_UP(offs + size, PAGE_SIZE);
m->page_list = kcalloc(m->nr_pages,
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index 99635dd9dbac..bb3a76ad80da 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -1132,7 +1132,7 @@ static void kgdbts_put_char(u8 chr)
static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
{
- int len = strlen(kmessage);
+ size_t len = strlen(kmessage);
if (len >= MAX_CONFIG_LEN) {
printk(KERN_ERR "kgdbts: config string too long\n");
@@ -1152,7 +1152,7 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
strcpy(config, kmessage);
/* Chop out \n char as a result of echo */
- if (config[len - 1] == '\n')
+ if (len && config[len - 1] == '\n')
config[len - 1] = '\0';
/* Go and configure with the new params. */
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 9a7f9d27be1f..f1a4abf616be 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -224,6 +224,14 @@ static int mmc_decode_scr(struct mmc_card *card)
if (scr->sda_spec3)
scr->cmds = UNSTUFF_BITS(resp, 32, 2);
+
+ /* SD Spec says: any SD Card shall set at least bits 0 and 2 */
+ if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) ||
+ !(scr->bus_widths & SD_SCR_BUS_WIDTH_4)) {
+ pr_err("%s: invalid bus width\n", mmc_hostname(card->host));
+ return -EINVAL;
+ }
+
return 0;
}
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index e03ec74f3fb0..40a369c7005a 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -819,6 +819,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
}
status = spi_sync_locked(spi, &host->m);
+ if (status < 0) {
+ dev_dbg(&spi->dev, "read error %d\n", status);
+ return status;
+ }
if (host->dma_dev) {
dma_sync_single_for_cpu(host->dma_dev,
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ac66c61d9433..356b294c93c9 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -624,6 +624,11 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
if (esdhc->vendor_ver > VENDOR_V_22)
host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+ if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) {
+ host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST;
+ host->quirks2 |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+ }
+
if (of_device_is_compatible(np, "fsl,p5040-esdhc") ||
of_device_is_compatible(np, "fsl,p5020-esdhc") ||
of_device_is_compatible(np, "fsl,p4080-esdhc") ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 403fa8d98aa3..d450d8b3708c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12824,6 +12824,24 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
+ /*
+ * A skb with gso_size + header length > 9700 will cause a
+ * firmware panic. Drop GSO support.
+ *
+ * Eventually the upper layer should not pass these packets down.
+ *
+ * For speed, if the gso_size is <= 9000, assume there will
+ * not be 700 bytes of headers and pass it through. Only do a
+ * full (slow) validation if the gso_size is > 9000.
+ *
+ * (Due to the way SKB_BY_FRAGS works this will also do a full
+ * validation in that case.)
+ */
+ if (unlikely(skb_is_gso(skb) &&
+ (skb_shinfo(skb)->gso_size > 9000) &&
+ !skb_gso_validate_mac_len(skb, 9700)))
+ features &= ~NETIF_F_GSO_MASK;
+
features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features);
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d9ab970dcbe9..81282b811a6c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -1140,6 +1140,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
skb = bnxt_copy_skb(bnapi, data, len, dma_addr);
bnxt_reuse_rx_data(rxr, cons, data);
if (!skb) {
+ if (agg_bufs)
+ bnxt_reuse_rx_agg_bufs(bnapi, cp_cons, agg_bufs);
rc = -ENOMEM;
goto next_rx;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.h b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
index 8cffcdfd5678..38b5858c335a 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.h
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
@@ -75,8 +75,8 @@ struct l2t_data {
struct l2t_entry *rover; /* starting point for next allocation */
atomic_t nfree; /* number of free entries */
rwlock_t lock;
- struct l2t_entry l2tab[0];
struct rcu_head rcu_head; /* to handle rcu cleanup */
+ struct l2t_entry l2tab[];
};
typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a3e1498ca67c..3b96622de8ff 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5061,15 +5061,24 @@ static int __init cxgb4_init_module(void)
ret = pci_register_driver(&cxgb4_driver);
if (ret < 0)
- debugfs_remove(cxgb4_debugfs_root);
+ goto err_pci;
#if IS_ENABLED(CONFIG_IPV6)
if (!inet6addr_registered) {
- register_inet6addr_notifier(&cxgb4_inet6addr_notifier);
- inet6addr_registered = true;
+ ret = register_inet6addr_notifier(&cxgb4_inet6addr_notifier);
+ if (ret)
+ pci_unregister_driver(&cxgb4_driver);
+ else
+ inet6addr_registered = true;
}
#endif
+ if (ret == 0)
+ return ret;
+
+err_pci:
+ debugfs_remove(cxgb4_debugfs_root);
+
return ret;
}
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
index 3acde3b9b767..7799cf33cc6e 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -2106,7 +2106,6 @@ static struct eisa_driver de4x5_eisa_driver = {
.remove = de4x5_eisa_remove,
}
};
-MODULE_DEVICE_TABLE(eisa, de4x5_eisa_ids);
#endif
#ifdef CONFIG_PCI
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 734f655c99c1..51bfe74be8d4 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -1050,7 +1050,7 @@ static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
break;
case ETHTOOL_GRXRINGS:
- cmd->data = adapter->num_rx_qs - 1;
+ cmd->data = adapter->num_rx_qs;
break;
default:
return -EINVAL;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 06b38f50980c..22c43a776c6c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -2263,6 +2263,10 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi)
struct i40e_vsi_context ctxt;
i40e_status ret;
+ /* Don't modify stripping options if a port VLAN is active */
+ if (vsi->info.pvid)
+ return;
+
if ((vsi->info.valid_sections &
cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID)) &&
((vsi->info.port_vlan_flags & I40E_AQ_VSI_PVLAN_MODE_MASK) == 0))
@@ -2293,6 +2297,10 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi)
struct i40e_vsi_context ctxt;
i40e_status ret;
+ /* Don't modify stripping options if a port VLAN is active */
+ if (vsi->info.pvid)
+ return;
+
if ((vsi->info.valid_sections &
cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID)) &&
((vsi->info.port_vlan_flags & I40E_AQ_VSI_PVLAN_EMOD_MASK) ==
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 42305f3234ff..03f0d20aa08b 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -3940,7 +3940,7 @@ static inline void mvpp2_gmac_max_rx_size_set(struct mvpp2_port *port)
/* Set defaults to the MVPP2 port */
static void mvpp2_defaults_set(struct mvpp2_port *port)
{
- int tx_port_num, val, queue, ptxq, lrxq;
+ int tx_port_num, val, queue, lrxq;
/* Configure port to loopback if needed */
if (port->flags & MVPP2_F_LOOPBACK)
@@ -3960,11 +3960,9 @@ static void mvpp2_defaults_set(struct mvpp2_port *port)
mvpp2_write(port->priv, MVPP2_TXP_SCHED_CMD_1_REG, 0);
/* Close bandwidth for all queues */
- for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) {
- ptxq = mvpp2_txq_phys(port->id, queue);
+ for (queue = 0; queue < MVPP2_MAX_TXQ; queue++)
mvpp2_write(port->priv,
- MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(ptxq), 0);
- }
+ MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(queue), 0);
/* Set refill period to 1 usec, refill tokens
* and bucket size to maximum
@@ -4722,7 +4720,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,
txq->descs_phys = 0;
/* Set minimum bandwidth for disabled TXQs */
- mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);
+ mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->log_id), 0);
/* Set Tx descriptors queue starting address and size */
mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index bcfac000199e..fcd1e6b3950d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1906,6 +1906,8 @@ static int mlx4_en_set_tunable(struct net_device *dev,
return ret;
}
+#define MLX4_EEPROM_PAGE_LEN 256
+
static int mlx4_en_get_module_info(struct net_device *dev,
struct ethtool_modinfo *modinfo)
{
@@ -1940,7 +1942,7 @@ static int mlx4_en_get_module_info(struct net_device *dev,
break;
case MLX4_MODULE_ID_SFP:
modinfo->type = ETH_MODULE_SFF_8472;
- modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN;
break;
default:
return -ENOSYS;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 897d061e4f03..3bf63de3a725 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -1485,7 +1485,7 @@ int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
rule.port = port;
rule.qpn = qpn;
INIT_LIST_HEAD(&rule.list);
- mlx4_err(dev, "going promisc on %x\n", port);
+ mlx4_info(dev, "going promisc on %x\n", port);
return mlx4_flow_attach(dev, &rule, regid_p);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index c2b21313dba7..a9c4818448f9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -1398,11 +1398,6 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port,
size -= offset + size - I2C_PAGE_SIZE;
i2c_addr = I2C_ADDR_LOW;
- if (offset >= I2C_PAGE_SIZE) {
- /* Reset offset to high page */
- i2c_addr = I2C_ADDR_HIGH;
- offset -= I2C_PAGE_SIZE;
- }
cable_info = (struct mlx4_cable_info *)inmad->data;
cable_info->dev_mem_address = cpu_to_be16(offset);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index afaf79b8761f..2d9f4ed9a65e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1408,6 +1408,10 @@ static void sh_eth_dev_exit(struct net_device *ndev)
sh_eth_get_stats(ndev);
sh_eth_reset(ndev);
+ /* Set the RMII mode again if required */
+ if (mdp->cd->rmiimode)
+ sh_eth_write(ndev, 0x1, RMIIMODE);
+
/* Set MAC address again */
update_mac_address(ndev);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 90d95b3654f5..6bdde92869fb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -154,7 +154,8 @@ int stmmac_mdio_reset(struct mii_bus *bus)
of_property_read_u32_array(np,
"snps,reset-delays-us", data->delays, 3);
- if (gpio_request(data->reset_gpio, "mdio-reset"))
+ if (devm_gpio_request(priv->device, data->reset_gpio,
+ "mdio-reset"))
return 0;
}
diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c
index b5edc7f96a39..685e875f5164 100644
--- a/drivers/net/ppp/ppp_deflate.c
+++ b/drivers/net/ppp/ppp_deflate.c
@@ -610,12 +610,20 @@ static struct compressor ppp_deflate_draft = {
static int __init deflate_init(void)
{
- int answer = ppp_register_compressor(&ppp_deflate);
- if (answer == 0)
- printk(KERN_INFO
- "PPP Deflate Compression module registered\n");
- ppp_register_compressor(&ppp_deflate_draft);
- return answer;
+ int rc;
+
+ rc = ppp_register_compressor(&ppp_deflate);
+ if (rc)
+ return rc;
+
+ rc = ppp_register_compressor(&ppp_deflate_draft);
+ if (rc) {
+ ppp_unregister_compressor(&ppp_deflate);
+ return rc;
+ }
+
+ pr_info("PPP Deflate Compression module registered\n");
+ return 0;
}
static void __exit deflate_cleanup(void)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 36e1377fc954..1e921e5eddc7 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -727,7 +727,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
int err;
u8 iface_no;
struct usb_cdc_parsed_header hdr;
- u16 curr_ntb_format;
+ __le16 curr_ntb_format;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -841,7 +841,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
goto error2;
}
- if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) {
+ if (curr_ntb_format == cpu_to_le16(USB_CDC_NCM_NTB32_FORMAT)) {
dev_info(&intf->dev, "resetting NTB format to 16-bit");
err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
USB_TYPE_CLASS | USB_DIR_OUT
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 01f95d192d25..2b16a5fed9de 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -437,17 +437,18 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
dev);
dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ netif_stop_queue(net);
retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
if (retval) {
dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
__func__, retval);
dev->net->stats.tx_errors++;
dev_kfree_skb_any(skb);
+ netif_wake_queue(net);
} else {
dev->net->stats.tx_packets++;
dev->net->stats.tx_bytes += skb->len;
dev_consume_skb_any(skb);
- netif_stop_queue(net);
}
return NETDEV_TX_OK;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 932c759c7ecb..a3a66c481e91 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -501,6 +501,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
if (netif_running (dev->net) &&
netif_device_present (dev->net) &&
+ test_bit(EVENT_DEV_OPEN, &dev->flags) &&
!test_bit (EVENT_RX_HALT, &dev->flags) &&
!test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
@@ -1387,6 +1388,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
spin_unlock_irqrestore(&dev->txq.lock, flags);
goto drop;
}
+ if (netif_queue_stopped(net)) {
+ usb_autopm_put_interface_async(dev->intf);
+ spin_unlock_irqrestore(&dev->txq.lock, flags);
+ goto drop;
+ }
#ifdef CONFIG_PM
/* if this triggers the device is still a sleep */
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 6cf47b0414a0..4e9b71858f98 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -2582,8 +2582,8 @@ static int __init at76_mod_init(void)
if (result < 0)
printk(KERN_ERR DRIVER_NAME
": usb_register failed (status %d)\n", result);
-
- led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+ else
+ led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
return result;
}
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 6922cbb99a04..5a0699fb4b9a 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1834,7 +1834,7 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
{
struct b43_phy_lp *lpphy = dev->phy.lp;
- struct lpphy_tx_gains gains, oldgains;
+ struct lpphy_tx_gains oldgains;
int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
lpphy_read_tx_pctl_mode_from_hardware(dev);
@@ -1848,9 +1848,9 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0)
- lpphy_papd_cal(dev, gains, 0, 1, 30);
+ lpphy_papd_cal(dev, oldgains, 0, 1, 30);
else
- lpphy_papd_cal(dev, gains, 0, 1, 65);
+ lpphy_papd_cal(dev, oldgains, 0, 1, 65);
if (old_afe_ovr)
lpphy_set_tx_gains(dev, oldgains);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
index 230cad788ace..84b8b1eaa22c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
@@ -214,7 +214,9 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
int prec);
/* Receive frame for delivery to OS. Callee disposes of rxp. */
-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
+/* Receive async event packet from firmware. Callee disposes of rxp. */
+void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
/* Indication from bus module regarding presence/insertion of dongle. */
int brcmf_attach(struct device *dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index a355d3303579..4029fbf0ce36 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -3328,9 +3328,15 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
struct brcmf_pno_scanresults_le *pfn_result;
u32 result_count;
u32 status;
+ u32 datalen;
brcmf_dbg(SCAN, "Enter\n");
+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+ return 0;
+ }
+
if (e->event_code == BRCMF_E_PFN_NET_LOST) {
brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
return 0;
@@ -3349,6 +3355,14 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
if (result_count > 0) {
int i;
+ data += sizeof(struct brcmf_pno_scanresults_le);
+ netinfo_start = (struct brcmf_pno_net_info_le *)data;
+ datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
+ if (datalen < result_count * sizeof(*netinfo)) {
+ brcmf_err("insufficient event data\n");
+ goto out_err;
+ }
+
request = kzalloc(sizeof(*request), GFP_KERNEL);
ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
@@ -3358,9 +3372,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
}
request->wiphy = wiphy;
- data += sizeof(struct brcmf_pno_scanresults_le);
- netinfo_start = (struct brcmf_pno_net_info_le *)data;
-
for (i = 0; i < result_count; i++) {
netinfo = &netinfo_start[i];
if (!netinfo) {
@@ -3370,6 +3381,8 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
goto out_err;
}
+ if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
+ netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
netinfo->SSID, netinfo->channel);
memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
@@ -4836,6 +4849,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
conn_info->req_ie =
kmemdup(cfg->extra_buf, conn_info->req_ie_len,
GFP_KERNEL);
+ if (!conn_info->req_ie)
+ conn_info->req_ie_len = 0;
} else {
conn_info->req_ie_len = 0;
conn_info->req_ie = NULL;
@@ -4852,6 +4867,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
conn_info->resp_ie =
kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
GFP_KERNEL);
+ if (!conn_info->resp_ie)
+ conn_info->resp_ie_len = 0;
} else {
conn_info->resp_ie_len = 0;
conn_info->resp_ie = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index 82753e7c7e7c..3082391c3062 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -303,15 +303,9 @@ void brcmf_txflowblock(struct device *dev, bool state)
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{
- skb->dev = ifp->ndev;
- skb->protocol = eth_type_trans(skb, skb->dev);
-
if (skb->pkt_type == PACKET_MULTICAST)
ifp->stats.multicast++;
- /* Process special event packets */
- brcmf_fweh_process_skb(ifp->drvr, skb);
-
if (!(ifp->ndev->flags & IFF_UP)) {
brcmu_pkt_buf_free_skb(skb);
return;
@@ -526,7 +520,7 @@ netif_rx:
}
}
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
{
struct brcmf_if *ifp;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -546,11 +540,44 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
return;
}
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
+
rd = (struct brcmf_skb_reorder_data *)skb->cb;
- if (rd->reorder)
+ if (rd->reorder) {
brcmf_rxreorder_process_info(ifp, rd->reorder, skb);
- else
+ } else {
+ /* Process special event packets */
+ if (handle_event)
+ brcmf_fweh_process_skb(ifp->drvr, skb,
+ BCMILCP_SUBTYPE_VENDOR_LONG);
+
brcmf_netif_rx(ifp, skb);
+ }
+}
+
+void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
+{
+ struct brcmf_if *ifp;
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ int ret;
+
+ brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
+
+ /* process and remove protocol-specific header */
+ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
+
+ if (ret || !ifp || !ifp->ndev) {
+ if (ret != -ENODATA && ifp)
+ ifp->stats.rx_errors++;
+ brcmu_pkt_buf_free_skb(skb);
+ return;
+ }
+
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
+
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0);
+ brcmu_pkt_buf_free_skb(skb);
}
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index 3878b6f6cfce..f9aa37032c2d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -26,50 +26,6 @@
#include "fwil.h"
/**
- * struct brcm_ethhdr - broadcom specific ether header.
- *
- * @subtype: subtype for this packet.
- * @length: TODO: length of appended data.
- * @version: version indication.
- * @oui: OUI of this packet.
- * @usr_subtype: subtype for this OUI.
- */
-struct brcm_ethhdr {
- __be16 subtype;
- __be16 length;
- u8 version;
- u8 oui[3];
- __be16 usr_subtype;
-} __packed;
-
-struct brcmf_event_msg_be {
- __be16 version;
- __be16 flags;
- __be32 event_type;
- __be32 status;
- __be32 reason;
- __be32 auth_type;
- __be32 datalen;
- u8 addr[ETH_ALEN];
- char ifname[IFNAMSIZ];
- u8 ifidx;
- u8 bsscfgidx;
-} __packed;
-
-/**
- * struct brcmf_event - contents of broadcom event packet.
- *
- * @eth: standard ether header.
- * @hdr: broadcom specific ether header.
- * @msg: common part of the actual event message.
- */
-struct brcmf_event {
- struct ethhdr eth;
- struct brcm_ethhdr hdr;
- struct brcmf_event_msg_be msg;
-} __packed;
-
-/**
* struct brcmf_fweh_queue_item - event item on event queue.
*
* @q: list element for queuing.
@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item {
u8 ifidx;
u8 ifaddr[ETH_ALEN];
struct brcmf_event_msg_be emsg;
+ u32 datalen;
u8 data[0];
};
@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
min_t(u32, emsg.datalen, 64),
"event payload, len=%d\n", emsg.datalen);
+ if (emsg.datalen > event->datalen) {
+ brcmf_err("event invalid length header=%d, msg=%d\n",
+ event->datalen, emsg.datalen);
+ goto event_free;
+ }
/* special handling of interface event */
if (event->code == BRCMF_E_IF) {
@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
* dispatch the event to a registered handler (using worker).
*/
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
- struct brcmf_event *event_packet)
+ struct brcmf_event *event_packet,
+ u32 packet_len)
{
enum brcmf_fweh_event_code code;
struct brcmf_fweh_info *fweh = &drvr->fweh;
@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
if (code != BRCMF_E_IF && !fweh->evt_handler[code])
return;
+ if (datalen > BRCMF_DCMD_MAXLEN)
+ return;
+
if (in_interrupt())
alloc_flag = GFP_ATOMIC;
@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
/* use memcpy to get aligned event message */
memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
memcpy(event->data, data, datalen);
+ event->datalen = datalen;
memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
brcmf_fweh_queue_event(fweh, event);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index d9a942842382..b53db92341ce 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -27,7 +27,6 @@
struct brcmf_pub;
struct brcmf_if;
struct brcmf_cfg80211_info;
-struct brcmf_event;
/* list of firmware events */
#define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
@@ -180,11 +179,53 @@ enum brcmf_fweh_event_code {
/**
* definitions for event packet validation.
*/
-#define BRCMF_EVENT_OUI_OFFSET 19
-#define BRCM_OUI "\x00\x10\x18"
-#define DOT11_OUI_LEN 3
-#define BCMILCP_BCM_SUBTYPE_EVENT 1
+#define BRCM_OUI "\x00\x10\x18"
+#define BCMILCP_BCM_SUBTYPE_EVENT 1
+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769
+/**
+ * struct brcm_ethhdr - broadcom specific ether header.
+ *
+ * @subtype: subtype for this packet.
+ * @length: TODO: length of appended data.
+ * @version: version indication.
+ * @oui: OUI of this packet.
+ * @usr_subtype: subtype for this OUI.
+ */
+struct brcm_ethhdr {
+ __be16 subtype;
+ __be16 length;
+ u8 version;
+ u8 oui[3];
+ __be16 usr_subtype;
+} __packed;
+
+struct brcmf_event_msg_be {
+ __be16 version;
+ __be16 flags;
+ __be32 event_type;
+ __be32 status;
+ __be32 reason;
+ __be32 auth_type;
+ __be32 datalen;
+ u8 addr[ETH_ALEN];
+ char ifname[IFNAMSIZ];
+ u8 ifidx;
+ u8 bsscfgidx;
+} __packed;
+
+/**
+ * struct brcmf_event - contents of broadcom event packet.
+ *
+ * @eth: standard ether header.
+ * @hdr: broadcom specific ether header.
+ * @msg: common part of the actual event message.
+ */
+struct brcmf_event {
+ struct ethhdr eth;
+ struct brcm_ethhdr hdr;
+ struct brcmf_event_msg_be msg;
+} __packed;
/**
* struct brcmf_event_msg - firmware event message.
@@ -256,34 +297,43 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr,
enum brcmf_fweh_event_code code);
int brcmf_fweh_activate_events(struct brcmf_if *ifp);
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
- struct brcmf_event *event_packet);
+ struct brcmf_event *event_packet,
+ u32 packet_len);
void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
- struct sk_buff *skb)
+ struct sk_buff *skb, u16 stype)
{
struct brcmf_event *event_packet;
- u8 *data;
- u16 usr_stype;
+ u16 subtype, usr_stype;
/* only process events when protocol matches */
if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
return;
- /* check for BRCM oui match */
+ if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
+ return;
+
event_packet = (struct brcmf_event *)skb_mac_header(skb);
- data = (u8 *)event_packet;
- data += BRCMF_EVENT_OUI_OFFSET;
- if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
+
+ /* check subtype if needed */
+ if (unlikely(stype)) {
+ subtype = get_unaligned_be16(&event_packet->hdr.subtype);
+ if (subtype != stype)
+ return;
+ }
+
+ /* check for BRCM oui match */
+ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
+ sizeof(event_packet->hdr.oui)))
return;
/* final match on usr_subtype */
- data += DOT11_OUI_LEN;
- usr_stype = get_unaligned_be16(data);
+ usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
return;
- brcmf_fweh_process_event(drvr, event_packet);
+ brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
}
#endif /* FWEH_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 44e618f9d890..6f7138cea555 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
@@ -1076,28 +1077,13 @@ static void brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf *msgbuf)
}
-static void
-brcmf_msgbuf_rx_skb(struct brcmf_msgbuf *msgbuf, struct sk_buff *skb,
- u8 ifidx)
-{
- struct brcmf_if *ifp;
-
- ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
- if (!ifp || !ifp->ndev) {
- brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
- brcmu_pkt_buf_free_skb(skb);
- return;
- }
- brcmf_netif_rx(ifp, skb);
-}
-
-
static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
{
struct msgbuf_rx_event *event;
u32 idx;
u16 buflen;
struct sk_buff *skb;
+ struct brcmf_if *ifp;
event = (struct msgbuf_rx_event *)buf;
idx = le32_to_cpu(event->msg.request_id);
@@ -1117,7 +1103,19 @@ static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
skb_trim(skb, buflen);
- brcmf_msgbuf_rx_skb(msgbuf, skb, event->msg.ifidx);
+ ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
+ if (!ifp || !ifp->ndev) {
+ brcmf_err("Received pkt for invalid ifidx %d\n",
+ event->msg.ifidx);
+ goto exit;
+ }
+
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
+
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0);
+
+exit:
+ brcmu_pkt_buf_free_skb(skb);
}
@@ -1129,6 +1127,7 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
u16 data_offset;
u16 buflen;
u32 idx;
+ struct brcmf_if *ifp;
brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1);
@@ -1149,7 +1148,14 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
skb_trim(skb, buflen);
- brcmf_msgbuf_rx_skb(msgbuf, skb, rx_complete->msg.ifidx);
+ ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
+ if (!ifp || !ifp->ndev) {
+ brcmf_err("Received pkt for invalid ifidx %d\n",
+ rx_complete->msg.ifidx);
+ brcmu_pkt_buf_free_skb(skb);
+ return;
+ }
+ brcmf_netif_rx(ifp, skb);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 9673689a74d8..83e5632f7163 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -1365,6 +1365,11 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
u16 mgmt_type;
u8 action;
+ if (e->datalen < sizeof(*rxframe)) {
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+ return 0;
+ }
+
ch.chspec = be16_to_cpu(rxframe->chanspec);
cfg->d11inf.decchspec(&ch);
/* Check if wpa_supplicant has registered for this frame */
@@ -1862,6 +1867,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
e->reason);
+ if (e->datalen < sizeof(*rxframe)) {
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
+ return 0;
+ }
+
ch.chspec = be16_to_cpu(rxframe->chanspec);
cfg->d11inf.decchspec(&ch);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index b4d9b47584d6..b082b8859b17 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -1394,6 +1394,17 @@ static inline u8 brcmf_sdio_getdatoffset(u8 *swheader)
return (u8)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT);
}
+static inline bool brcmf_sdio_fromevntchan(u8 *swheader)
+{
+ u32 hdrvalue;
+ u8 ret;
+
+ hdrvalue = *(u32 *)swheader;
+ ret = (u8)((hdrvalue & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT);
+
+ return (ret == SDPCM_EVENT_CHANNEL);
+}
+
static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
struct brcmf_sdio_hdrinfo *rd,
enum brcmf_sdio_frmtype type)
@@ -1754,7 +1765,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- brcmf_rx_frame(bus->sdiodev->dev, pfirst);
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
+ brcmf_rx_event(bus->sdiodev->dev, pfirst);
+ else
+ brcmf_rx_frame(bus->sdiodev->dev, pfirst,
+ false);
bus->sdcnt.rxglompkts++;
}
@@ -2081,18 +2096,19 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
__skb_trim(pkt, rd->len);
skb_pull(pkt, rd->dat_offset);
+ if (pkt->len == 0)
+ brcmu_pkt_buf_free_skb(pkt);
+ else if (rd->channel == SDPCM_EVENT_CHANNEL)
+ brcmf_rx_event(bus->sdiodev->dev, pkt);
+ else
+ brcmf_rx_frame(bus->sdiodev->dev, pkt,
+ false);
+
/* prepare the descriptor for the next read */
rd->len = rd->len_nxtfrm << 4;
rd->len_nxtfrm = 0;
/* treat all packet as event if we don't know */
rd->channel = SDPCM_EVENT_CHANNEL;
-
- if (pkt->len == 0) {
- brcmu_pkt_buf_free_skb(pkt);
- continue;
- }
-
- brcmf_rx_frame(bus->sdiodev->dev, pkt);
}
rxcount = maxframes - rxleft;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 689e64d004bc..3002268e57f3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -144,7 +144,7 @@ struct brcmf_usbdev_info {
struct usb_device *usbdev;
struct device *dev;
- struct mutex dev_init_lock;
+ struct completion dev_init_done;
int ctl_in_pipe, ctl_out_pipe;
struct urb *ctl_urb; /* URB for control endpoint */
@@ -502,7 +502,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
skb_put(skb, urb->actual_length);
- brcmf_rx_frame(devinfo->dev, skb);
+ brcmf_rx_frame(devinfo->dev, skb, true);
brcmf_usb_rx_refill(devinfo, req);
} else {
brcmu_pkt_buf_free_skb(skb);
@@ -669,12 +669,18 @@ static int brcmf_usb_up(struct device *dev)
static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo)
{
+ int i;
+
if (devinfo->ctl_urb)
usb_kill_urb(devinfo->ctl_urb);
if (devinfo->bulk_urb)
usb_kill_urb(devinfo->bulk_urb);
- brcmf_usb_free_q(&devinfo->tx_postq, true);
- brcmf_usb_free_q(&devinfo->rx_postq, true);
+ if (devinfo->tx_reqs)
+ for (i = 0; i < devinfo->bus_pub.ntxq; i++)
+ usb_kill_urb(devinfo->tx_reqs[i].urb);
+ if (devinfo->rx_reqs)
+ for (i = 0; i < devinfo->bus_pub.nrxq; i++)
+ usb_kill_urb(devinfo->rx_reqs[i].urb);
}
static void brcmf_usb_down(struct device *dev)
@@ -1226,11 +1232,11 @@ static void brcmf_usb_probe_phase2(struct device *dev,
if (ret)
goto error;
- mutex_unlock(&devinfo->dev_init_lock);
+ complete(&devinfo->dev_init_done);
return;
error:
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
- mutex_unlock(&devinfo->dev_init_lock);
+ complete(&devinfo->dev_init_done);
device_release_driver(dev);
}
@@ -1268,7 +1274,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
if (ret)
goto fail;
/* we are done */
- mutex_unlock(&devinfo->dev_init_lock);
+ complete(&devinfo->dev_init_done);
return 0;
}
bus->chip = bus_pub->devid;
@@ -1322,11 +1328,10 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->usbdev = usb;
devinfo->dev = &usb->dev;
- /* Take an init lock, to protect for disconnect while still loading.
+ /* Init completion, to protect for disconnect while still loading.
* Necessary because of the asynchronous firmware load construction
*/
- mutex_init(&devinfo->dev_init_lock);
- mutex_lock(&devinfo->dev_init_lock);
+ init_completion(&devinfo->dev_init_done);
usb_set_intfdata(intf, devinfo);
@@ -1402,7 +1407,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0;
fail:
- mutex_unlock(&devinfo->dev_init_lock);
+ complete(&devinfo->dev_init_done);
kfree(devinfo);
usb_set_intfdata(intf, NULL);
return ret;
@@ -1417,7 +1422,7 @@ brcmf_usb_disconnect(struct usb_interface *intf)
devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
if (devinfo) {
- mutex_lock(&devinfo->dev_init_lock);
+ wait_for_completion(&devinfo->dev_init_done);
/* Make sure that devinfo still exists. Firmware probe routines
* may have released the device and cleared the intfdata.
*/
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
index 8eff2753abad..d493021f6031 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
@@ -35,9 +35,10 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
struct brcmf_if *ifp;
const struct brcmf_vndr_dcmd_hdr *cmdhdr = data;
struct sk_buff *reply;
- int ret, payload, ret_len;
+ unsigned int payload, ret_len;
void *dcmd_buf = NULL, *wr_pointer;
u16 msglen, maxmsglen = PAGE_SIZE - 0x100;
+ int ret;
if (len < sizeof(*cmdhdr)) {
brcmf_err("vendor command too short: %d\n", len);
@@ -65,7 +66,7 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
brcmf_err("oversize return buffer %d\n", ret_len);
ret_len = BRCMF_DCMD_MAXLEN;
}
- payload = max(ret_len, len) + 1;
+ payload = max_t(unsigned int, ret_len, len) + 1;
dcmd_buf = vzalloc(payload);
if (NULL == dcmd_buf)
return -ENOMEM;
diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c
index 577cbb4482b3..e4db712d1db7 100644
--- a/drivers/net/wireless/cnss2/debug.c
+++ b/drivers/net/wireless/cnss2/debug.c
@@ -114,12 +114,33 @@ static int cnss_stats_show_state(struct seq_file *s,
return 0;
}
+static int cnss_stats_show_capability(struct seq_file *s,
+ struct cnss_plat_data *plat_priv)
+{
+ if (test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
+ seq_puts(s, "\n<---------- FW Capability ----------->\n");
+ seq_printf(s, "Chip ID: 0x%x\n",
+ plat_priv->chip_info.chip_id);
+ seq_printf(s, "Chip family: 0x%x\n",
+ plat_priv->chip_info.chip_family);
+ seq_printf(s, "Board ID: 0x%x\n",
+ plat_priv->board_info.board_id);
+ seq_printf(s, "SOC Info: 0x%x\n",
+ plat_priv->soc_info.soc_id);
+ seq_printf(s, "Firmware Version: 0x%x\n",
+ plat_priv->fw_version_info.fw_version);
+ seq_printf(s, "Firmware Build Timestamp: %s\n",
+ plat_priv->fw_version_info.fw_build_timestamp);
+ }
+ return 0;
+}
+
static int cnss_stats_show(struct seq_file *s, void *data)
{
struct cnss_plat_data *plat_priv = s->private;
cnss_stats_show_state(s, plat_priv);
-
+ cnss_stats_show_capability(s, plat_priv);
return 0;
}
diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c
index d86213175495..7cc44634f031 100644
--- a/drivers/net/wireless/cnss2/qmi.c
+++ b/drivers/net/wireless/cnss2/qmi.c
@@ -22,9 +22,10 @@
#define WLFW_SERVICE_INS_ID_V01 1
#define WLFW_CLIENT_ID 0x4b4e454c
-#define MAX_BDF_FILE_NAME 11
-#define DEFAULT_BDF_FILE_NAME "bdwlan.elf"
-#define BDF_FILE_NAME_PREFIX "bdwlan.e"
+#define MAX_BDF_FILE_NAME 32
+#define BDF_FILE_NAME_PREFIX "bdwlan"
+#define DEFAULT_ELF_BDF_FILE_NAME "bdwlan.elf"
+#define ELF_BDF_FILE_NAME_PREFIX "bdwlan.e"
#define BIN_BDF_FILE_NAME_PREFIX "bdwlan.b"
#define DEFAULT_BIN_BDF_FILE_NAME "bdwlan.bin"
@@ -799,22 +800,33 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv)
plat_priv->device_id == QCN7605_VER20_COMPOSITE_DEVICE_ID)
bdf_type = CNSS_BDF_BIN;
- if (plat_priv->board_info.board_id == 0xFF)
+ if (plat_priv->board_info.board_id == 0xFF) {
if (bdf_type == CNSS_BDF_BIN)
snprintf(filename, sizeof(filename),
DEFAULT_BIN_BDF_FILE_NAME);
else
snprintf(filename, sizeof(filename),
- DEFAULT_BDF_FILE_NAME);
- else {
+ DEFAULT_ELF_BDF_FILE_NAME);
+ } else if (plat_priv->board_info.board_id < 0xFF) {
if (bdf_type == CNSS_BDF_BIN)
snprintf(filename, sizeof(filename),
BIN_BDF_FILE_NAME_PREFIX "%02x",
plat_priv->board_info.board_id);
else
snprintf(filename, sizeof(filename),
- BDF_FILE_NAME_PREFIX "%02x",
+ ELF_BDF_FILE_NAME_PREFIX "%02x",
plat_priv->board_info.board_id);
+ } else {
+ if (bdf_type == CNSS_BDF_BIN)
+ snprintf(filename, sizeof(filename),
+ BDF_FILE_NAME_PREFIX "%02x.b%02x",
+ plat_priv->board_info.board_id >> 8 & 0xFF,
+ plat_priv->board_info.board_id & 0xFF);
+ else
+ snprintf(filename, sizeof(filename),
+ BDF_FILE_NAME_PREFIX "%02x.e%02x",
+ plat_priv->board_info.board_id >> 8 & 0xFF,
+ plat_priv->board_info.board_id & 0xFF);
}
if (bdf_bypass) {
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index dc478cedbde0..84624c812a15 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -345,6 +345,11 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
mutex_init(&priv->wsm_cmd_mux);
mutex_init(&priv->conf_mutex);
priv->workqueue = create_singlethread_workqueue("cw1200_wq");
+ if (!priv->workqueue) {
+ ieee80211_free_hw(hw);
+ return NULL;
+ }
+
sema_init(&priv->scan.lock, 1);
INIT_WORK(&priv->scan.work, cw1200_scan_work);
INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 99c86f8dfa41..1c43ac750f17 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -533,5 +533,8 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
rate_index = (rx_rate > MWIFIEX_RATE_INDEX_OFDM0) ?
rx_rate - 1 : rx_rate;
+ if (rate_index >= MWIFIEX_MAX_AC_RX_RATES)
+ rate_index = MWIFIEX_MAX_AC_RX_RATES - 1;
+
return rate_index;
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 4ac928bf1f8e..7de18ed10db8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -466,6 +466,11 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
/* <2> work queue */
rtlpriv->works.hw = hw;
rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
+ if (unlikely(!rtlpriv->works.rtl_wq)) {
+ pr_err("Failed to allocate work queue\n");
+ return;
+ }
+
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 6fd4e5a5ef4a..931cc33e46f0 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -789,7 +789,7 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell,
void *buf)
{
u8 *p, *b;
- int i, bit_offset = cell->bit_offset;
+ int i, extra, bit_offset = cell->bit_offset;
p = b = buf;
if (bit_offset) {
@@ -804,11 +804,16 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell,
p = b;
*b++ >>= bit_offset;
}
-
- /* result fits in less bytes */
- if (cell->bytes != DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE))
- *p-- = 0;
+ } else {
+ /* point to the msb */
+ p += cell->bytes - 1;
}
+
+ /* result fits in less bytes */
+ extra = cell->bytes - DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE);
+ while (--extra >= 0)
+ *p-- = 0;
+
/* clear msb bits if any leftover in the last byte */
*p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0);
}
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 34f1d6b41fb9..cc3708ea8084 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -563,8 +563,6 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
/* We currently only support kernel addresses */
BUG_ON(sid != KERNEL_SPACE);
- mtsp(sid,1);
-
/*
** WORD 1 - low order word
** "hints" parm includes the VALID bit!
@@ -595,7 +593,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
** Grab virtual index [0:11]
** Deposit virt_idx bits into I/O PDIR word
*/
- asm volatile ("lci %%r0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+ asm volatile ("lci %%r0(%1), %0" : "=r" (ci) : "r" (vba));
asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci));
asm volatile ("depw %1,15,12,%0" : "+r" (pa) : "r" (ci));
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index d6326144ce01..f3b9746157f8 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -573,8 +573,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
pa = virt_to_phys(vba);
pa &= IOVP_MASK;
- mtsp(sid,1);
- asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+ asm("lci 0(%1), %0" : "=r" (ci) : "r" (vba));
pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */
pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 414c33686621..b18cf12731ee 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -737,6 +737,10 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
/* setup MSI data target */
msi->pages = __get_free_pages(GFP_KERNEL, 0);
+ if (!msi->pages) {
+ err = -ENOMEM;
+ goto err;
+ }
base = virt_to_phys((void *)msi->pages);
rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR);
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index 4cfa46360d12..6a2499f4d610 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -349,14 +349,19 @@ static const struct irq_domain_ops msi_domain_ops = {
* xilinx_pcie_enable_msi - Enable MSI support
* @port: PCIe port information
*/
-static void xilinx_pcie_enable_msi(struct xilinx_pcie_port *port)
+static int xilinx_pcie_enable_msi(struct xilinx_pcie_port *port)
{
phys_addr_t msg_addr;
port->msi_pages = __get_free_pages(GFP_KERNEL, 0);
+ if (!port->msi_pages)
+ return -ENOMEM;
+
msg_addr = virt_to_phys((void *)port->msi_pages);
pcie_write(port, 0x0, XILINX_PCIE_REG_MSIBASE1);
pcie_write(port, msg_addr, XILINX_PCIE_REG_MSIBASE2);
+
+ return 0;
}
/* INTx Functions */
@@ -555,6 +560,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
struct device *dev = port->dev;
struct device_node *node = dev->of_node;
struct device_node *pcie_intc_node;
+ int ret;
/* Setup INTx */
pcie_intc_node = of_get_next_child(node, NULL);
@@ -582,7 +588,9 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
return PTR_ERR(port->irq_domain);
}
- xilinx_pcie_enable_msi(port);
+ ret = xilinx_pcie_enable_msi(port);
+ if (ret)
+ return ret;
}
return 0;
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index f2fcbe944d94..aae295708ea7 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -55,6 +55,7 @@ static struct device_node *find_vio_slot_node(char *drc_name)
if ((rc == 0) && (!strcmp(drc_name, name)))
break;
}
+ of_node_put(parent);
return dn;
}
@@ -78,6 +79,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name,
return np;
}
+/* Returns a device_node with its reference count incremented */
static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
{
struct device_node *dn;
@@ -314,6 +316,7 @@ int dlpar_add_slot(char *drc_name)
rc = dlpar_add_phb(drc_name, dn);
break;
}
+ of_node_put(dn);
printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name);
exit:
@@ -447,6 +450,7 @@ int dlpar_remove_slot(char *drc_name)
rc = dlpar_remove_pci_slot(drc_name, dn);
break;
}
+ of_node_put(dn);
vm_unmap_aliases();
printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d85010ebac5a..36c6f3702167 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3141,6 +3141,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset);
static void quirk_no_pm_reset(struct pci_dev *dev)
{
diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c
index 98a459b1c095..86e8d989092c 100644
--- a/drivers/pinctrl/pinctrl-pistachio.c
+++ b/drivers/pinctrl/pinctrl-pistachio.c
@@ -1373,6 +1373,7 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
if (!of_find_property(child, "gpio-controller", NULL)) {
dev_err(pctl->dev,
"No gpio-controller property for bank %u\n", i);
+ of_node_put(child);
ret = -ENODEV;
goto err;
}
@@ -1380,6 +1381,7 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
irq = irq_of_parse_and_map(child, 0);
if (irq < 0) {
dev_err(pctl->dev, "No IRQ for bank %u: %d\n", i, irq);
+ of_node_put(child);
ret = irq;
goto err;
}
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index a0b8c8a8c323..5c285f2b3a65 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -66,6 +66,17 @@ static int send_command(struct cros_ec_device *ec_dev,
else
xfer_fxn = ec_dev->cmd_xfer;
+ if (!xfer_fxn) {
+ /*
+ * This error can happen if a communication error happened and
+ * the EC is trying to use protocol v2, on an underlying
+ * communication mechanism that does not support v2.
+ */
+ dev_err_once(ec_dev->dev,
+ "missing EC transfer API, cannot send command\n");
+ return -EIO;
+ }
+
ret = (*xfer_fxn)(ec_dev, msg);
if (msg->result == EC_RES_IN_PROGRESS) {
int i;
diff --git a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
index e10c75a473ce..f5c36fed5ede 100644
--- a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
+++ b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -88,7 +88,8 @@ int ipa_rm_dep_graph_get_resource(
goto bail;
}
resource_index = ipa_rm_dep_get_index(resource_name);
- if (resource_index == IPA_RM_INDEX_INVALID) {
+ if (resource_index == IPA_RM_INDEX_INVALID ||
+ resource_index >= IPA_RM_RESOURCE_MAX) {
result = -EINVAL;
goto bail;
}
@@ -120,7 +121,8 @@ int ipa_rm_dep_graph_add(struct ipa_rm_dep_graph *graph,
goto bail;
}
resource_index = ipa_rm_dep_get_index(resource->name);
- if (resource_index == IPA_RM_INDEX_INVALID) {
+ if (resource_index == IPA_RM_INDEX_INVALID ||
+ resource_index >= IPA_RM_RESOURCE_MAX) {
result = -EINVAL;
goto bail;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index fb39829e0d81..6236c9385d91 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -2887,6 +2887,15 @@ int rmnet_ipa_query_tethering_stats_modem(
struct ipa_get_data_stats_resp_msg_v01 *resp;
int pipe_len, rc;
+ if (data != NULL) {
+ /* prevent string buffer overflows */
+ data->upstreamIface[IFNAMSIZ-1] = '\0';
+ data->tetherIface[IFNAMSIZ-1] = '\0';
+ } else if (reset != false) {
+ /* Data can be NULL for reset stats, checking reset != False */
+ return -EINVAL;
+ }
+
req = kzalloc(sizeof(struct ipa_get_data_stats_req_msg_v01),
GFP_KERNEL);
if (!req) {
@@ -2910,7 +2919,13 @@ int rmnet_ipa_query_tethering_stats_modem(
IPAWANDBG("reset the pipe stats\n");
} else {
/* print tethered-client enum */
- IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
+ if (data == NULL) {
+ kfree(req);
+ kfree(resp);
+ return -EINVAL;
+ }
+ IPAWANDBG_LOW("Tethered-client enum(%d)\n",
+ data->ipa_client);
}
rc = ipa_qmi_get_data_stats(req, resp);
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index ac2841ae9e09..de486afc91c1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -3001,6 +3001,15 @@ static int rmnet_ipa3_query_tethering_stats_modem(
struct ipa_get_data_stats_resp_msg_v01 *resp;
int pipe_len, rc;
+ if (data != NULL) {
+ /* prevent string buffer overflows */
+ data->upstreamIface[IFNAMSIZ-1] = '\0';
+ data->tetherIface[IFNAMSIZ-1] = '\0';
+ } else if (reset != false) {
+ /* Data can be NULL for reset stats, checking reset != False */
+ return -EINVAL;
+ }
+
req = kzalloc(sizeof(struct ipa_get_data_stats_req_msg_v01),
GFP_KERNEL);
if (!req) {
@@ -3024,7 +3033,13 @@ static int rmnet_ipa3_query_tethering_stats_modem(
IPAWANDBG("reset the pipe stats\n");
} else {
/* print tethered-client enum */
- IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
+ if (data == NULL) {
+ kfree(req);
+ kfree(resp);
+ return -EINVAL;
+ }
+ IPAWANDBG_LOW("Tethered-client enum(%d)\n",
+ data->ipa_client);
}
rc = ipa3_qmi_get_data_stats(req, resp);
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 41dd7ddb5e40..36217ae57146 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -395,15 +395,11 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
char *prop_buf;
char *attrname;
- dev_dbg(dev, "uevent\n");
-
if (!psy || !psy->desc) {
dev_dbg(dev, "No power supply yet\n");
return ret;
}
- dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->desc->name);
-
ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->desc->name);
if (ret)
return ret;
@@ -439,8 +435,6 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
goto out;
}
- dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
-
ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
kfree(attrname);
if (ret)
diff --git a/drivers/power/supply/qcom/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c
index cd635bbc8fb8..e61a9c96d681 100644
--- a/drivers/power/supply/qcom/qpnp-smbcharger.c
+++ b/drivers/power/supply/qcom/qpnp-smbcharger.c
@@ -4856,10 +4856,10 @@ static void handle_usb_insertion(struct smbchg_chip *chip)
/* Only notify USB if it's not a charger */
if (usb_supply_type == POWER_SUPPLY_TYPE_USB ||
usb_supply_type == POWER_SUPPLY_TYPE_USB_CDP) {
- extcon_set_cable_state_(chip->extcon, EXTCON_USB,
- chip->usb_present);
extcon_set_cable_state_(chip->extcon, EXTCON_USB_SPEED,
chip->usb_present);
+ extcon_set_cable_state_(chip->extcon, EXTCON_USB,
+ chip->usb_present);
}
/* Notify the USB psy if OV condition is not present */
if (!chip->usb_ov_det) {
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index ec84ff8ad1b4..6911f9662300 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -284,10 +284,12 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
if (IS_ENABLED(CONFIG_OF))
of_pwmchip_add(chip);
- pwmchip_sysfs_export(chip);
-
out:
mutex_unlock(&pwm_lock);
+
+ if (!ret)
+ pwmchip_sysfs_export(chip);
+
return ret;
}
EXPORT_SYMBOL_GPL(pwmchip_add_with_polarity);
@@ -321,7 +323,7 @@ int pwmchip_remove(struct pwm_chip *chip)
unsigned int i;
int ret = 0;
- pwmchip_sysfs_unexport_children(chip);
+ pwmchip_sysfs_unexport(chip);
mutex_lock(&pwm_lock);
@@ -341,8 +343,6 @@ int pwmchip_remove(struct pwm_chip *chip)
free_pwms(chip);
- pwmchip_sysfs_unexport(chip);
-
out:
mutex_unlock(&pwm_lock);
return ret;
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index 062dff1c902d..ede17f89d57f 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -385,6 +385,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
}
/* Update shadow register first before modifying active register */
+ ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
+ AQSFRC_RLDCSF_ZRO);
ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
/*
* Changes to immediate action on Action Qualifier. This puts
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 375008e2be20..199370e41da9 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -340,19 +340,6 @@ void pwmchip_sysfs_export(struct pwm_chip *chip)
void pwmchip_sysfs_unexport(struct pwm_chip *chip)
{
struct device *parent;
-
- parent = class_find_device(&pwm_class, NULL, chip,
- pwmchip_sysfs_match);
- if (parent) {
- /* for class_find_device() */
- put_device(parent);
- device_unregister(parent);
- }
-}
-
-void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
-{
- struct device *parent;
unsigned int i;
parent = class_find_device(&pwm_class, NULL, chip,
@@ -368,6 +355,7 @@ void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
}
put_device(parent);
+ device_unregister(parent);
}
static int __init pwm_sysfs_init(void)
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 19e53b3b8e00..166faae3a59c 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -414,7 +414,7 @@ static int pm860x_rtc_remove(struct platform_device *pdev)
struct pm860x_rtc_info *info = platform_get_drvdata(pdev);
#ifdef VRTC_CALIBRATION
- flush_scheduled_work();
+ cancel_delayed_work_sync(&info->calib_work);
/* disable measurement */
pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0);
#endif /* VRTC_CALIBRATION */
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index a01376ae1749..fdb87520543f 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -102,7 +102,7 @@ struct subchannel {
struct schib_config config;
} __attribute__ ((aligned(8)));
-DECLARE_PER_CPU(struct irb, cio_irb);
+DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
#define to_subchannel(n) container_of(n, struct subchannel, dev)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index a39a74500e23..aeb93478482f 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -161,6 +161,7 @@ extern const struct attribute_group *zfcp_port_attr_groups[];
extern struct mutex zfcp_sysfs_port_units_mutex;
extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
extern struct device_attribute *zfcp_sysfs_shost_attrs[];
+bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port);
/* zfcp_unit.c */
extern int zfcp_unit_add(struct zfcp_port *, u64);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index bdb257eaa2e5..68146b398603 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -124,6 +124,15 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
zfcp_sdev->erp_action.port = port;
+ mutex_lock(&zfcp_sysfs_port_units_mutex);
+ if (zfcp_sysfs_port_is_removing(port)) {
+ /* port is already gone */
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+ put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
+ return -ENXIO;
+ }
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+
unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
if (unit)
put_device(&unit->dev);
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 96a0be13e841..5df597d1b978 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -237,6 +237,53 @@ static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
+static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port)
+{
+ lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
+ atomic_set(&port->units, -1);
+}
+
+bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port)
+{
+ lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
+ return atomic_read(&port->units) == -1;
+}
+
+static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port)
+{
+ struct zfcp_adapter *const adapter = port->adapter;
+ unsigned long flags;
+ struct scsi_device *sdev;
+ bool in_use = true;
+
+ mutex_lock(&zfcp_sysfs_port_units_mutex);
+ if (atomic_read(&port->units) > 0)
+ goto unlock_port_units_mutex; /* zfcp_unit(s) under port */
+
+ spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
+ __shost_for_each_device(sdev, adapter->scsi_host) {
+ const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
+
+ if (sdev->sdev_state == SDEV_DEL ||
+ sdev->sdev_state == SDEV_CANCEL)
+ continue;
+ if (zsdev->port != port)
+ continue;
+ /* alive scsi_device under port of interest */
+ goto unlock_host_lock;
+ }
+
+ /* port is about to be removed, so no more unit_add or slave_alloc */
+ zfcp_sysfs_port_set_removing(port);
+ in_use = false;
+
+unlock_host_lock:
+ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
+unlock_port_units_mutex:
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+ return in_use;
+}
+
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -259,15 +306,11 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
else
retval = 0;
- mutex_lock(&zfcp_sysfs_port_units_mutex);
- if (atomic_read(&port->units) > 0) {
+ if (zfcp_sysfs_port_in_use(port)) {
retval = -EBUSY;
- mutex_unlock(&zfcp_sysfs_port_units_mutex);
+ put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
goto out;
}
- /* port is about to be removed, so no more unit_add */
- atomic_set(&port->units, -1);
- mutex_unlock(&zfcp_sysfs_port_units_mutex);
write_lock_irq(&adapter->port_list_lock);
list_del(&port->list);
diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c
index 157d3d203ba1..f00693698abc 100644
--- a/drivers/s390/scsi/zfcp_unit.c
+++ b/drivers/s390/scsi/zfcp_unit.c
@@ -122,7 +122,7 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
int retval = 0;
mutex_lock(&zfcp_sysfs_port_units_mutex);
- if (atomic_read(&port->units) == -1) {
+ if (zfcp_sysfs_port_is_removing(port)) {
/* port is already gone */
retval = -ENODEV;
goto out;
@@ -166,8 +166,14 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
write_lock_irq(&port->unit_list_lock);
list_add_tail(&unit->list, &port->unit_list);
write_unlock_irq(&port->unit_list_lock);
+ /*
+ * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
+ * due to zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
+ */
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
zfcp_unit_scsi_scan(unit);
+ return retval;
out:
mutex_unlock(&zfcp_sysfs_port_units_mutex);
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 28c671b609b2..0c71b69b9f88 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -829,7 +829,7 @@ ret_err_rqe:
((u64)err_entry->data.err_warn_bitmap_hi << 32) |
(u64)err_entry->data.err_warn_bitmap_lo;
for (i = 0; i < BNX2FC_NUM_ERR_BITS; i++) {
- if (err_warn_bit_map & (u64) (1 << i)) {
+ if (err_warn_bit_map & ((u64)1 << i)) {
err_warn = i;
break;
}
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index f3bb7af4e984..5eaf14c15590 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -634,6 +634,10 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
if (ndev->flags & IFF_LOOPBACK) {
ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr);
+ if (!ndev) {
+ err = -ENETUNREACH;
+ goto rel_neigh;
+ }
mtu = ndev->mtu;
pr_info("rt dev %s, loopback -> %s, mtu %u.\n",
n->dev->name, ndev->name, mtu);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 1a6f65db615e..400eee9d7783 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -978,6 +978,8 @@ static struct domain_device *sas_ex_discover_expander(
list_del(&child->dev_list_node);
spin_unlock_irq(&parent->port->dev_list_lock);
sas_put_device(child);
+ sas_port_delete(phy->port);
+ phy->port = NULL;
return NULL;
}
list_add_tail(&child->siblings, &parent->ex_dev.children);
@@ -2027,6 +2029,11 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) {
phy->phy_state = PHY_EMPTY;
sas_unregister_devs_sas_addr(dev, phy_id, last);
+ /*
+ * Even though the PHY is empty, for convenience we discover
+ * the PHY to update the PHY info, like negotiated linkrate.
+ */
+ sas_ex_phy_discover(dev, phy_id);
return res;
} else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
dev_type_flutter(type, phy->attached_dev_type)) {
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 398c9a0a5ade..82a690924f5e 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6498,7 +6498,10 @@ int
lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
{
struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
- rrq->nlp_DID);
+ rrq->nlp_DID);
+ if (!ndlp)
+ return 1;
+
if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
return lpfc_issue_els_rrq(rrq->vport, ndlp,
rrq->nlp_DID, rrq);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 4131addfb872..a67950908db1 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -902,7 +902,11 @@ lpfc_linkdown(struct lpfc_hba *phba)
lpfc_linkdown_port(vports[i]);
}
lpfc_destroy_vport_work_array(phba, vports);
- /* Clean up any firmware default rpi's */
+
+ /* Clean up any SLI3 firmware default rpi's */
+ if (phba->sli_rev > LPFC_SLI_REV3)
+ goto skip_unreg_did;
+
mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mb) {
lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb);
@@ -914,6 +918,7 @@ lpfc_linkdown(struct lpfc_hba *phba)
}
}
+ skip_unreg_did:
/* Setup myDID for link up if we are in pt2pt mode */
if (phba->pport->fc_flag & FC_PT2PT) {
phba->pport->fc_myDID = 0;
@@ -4647,6 +4652,10 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport)
LPFC_MBOXQ_t *mbox;
int rc;
+ /* Unreg DID is an SLI3 operation. */
+ if (phba->sli_rev > LPFC_SLI_REV3)
+ return;
+
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mbox) {
lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index c158967b59d7..d220b4f691c7 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -5939,7 +5939,7 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
val = rd_nvram_byte(ha, sec_addr);
if (val & BIT_7)
ddb_index[1] = (val & 0x7f);
-
+ goto exit_boot_info;
} else if (is_qla80XX(ha)) {
buf = dma_alloc_coherent(&ha->pdev->dev, size,
&buf_dma, GFP_KERNEL);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 605092092049..bfd7e3840874 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2415,7 +2415,6 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
int res;
struct scsi_device *sdp = sdkp->device;
struct scsi_mode_data data;
- int disk_ro = get_disk_ro(sdkp->disk);
set_disk_ro(sdkp->disk, 0);
if (sdp->skip_ms_page_3f) {
@@ -2455,7 +2454,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
"Test WP failed, assume Write Enabled\n");
} else {
sdkp->write_prot = ((data.device_specific & 0x80) != 0);
- set_disk_ro(sdkp->disk, sdkp->write_prot || disk_ro);
+ set_disk_ro(sdkp->disk, sdkp->write_prot);
}
}
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index acc3bdd0ab4c..e5998c616865 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7166,19 +7166,19 @@ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba,
goto out;
}
- if (hba->vreg_info.vcc)
+ if (hba->vreg_info.vcc && hba->vreg_info.vcc->max_uA)
icc_level = ufshcd_get_max_icc_level(
hba->vreg_info.vcc->max_uA,
POWER_DESC_MAX_ACTV_ICC_LVLS - 1,
&desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]);
- if (hba->vreg_info.vccq)
+ if (hba->vreg_info.vccq && hba->vreg_info.vccq->max_uA)
icc_level = ufshcd_get_max_icc_level(
hba->vreg_info.vccq->max_uA,
icc_level,
&desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]);
- if (hba->vreg_info.vccq2)
+ if (hba->vreg_info.vccq2 && hba->vreg_info.vccq2->max_uA)
icc_level = ufshcd_get_max_icc_level(
hba->vreg_info.vccq2->max_uA,
icc_level,
@@ -7954,6 +7954,15 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
if (!vreg)
return 0;
+ /*
+ * "set_load" operation shall be required on those regulators
+ * which specifically configured current limitation. Otherwise
+ * zero max_uA may cause unexpected behavior when regulator is
+ * enabled or set as high power mode.
+ */
+ if (!vreg->max_uA)
+ return 0;
+
ret = regulator_set_load(vreg->reg, ua);
if (ret < 0) {
dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n",
@@ -8005,12 +8014,15 @@ static int ufshcd_config_vreg(struct device *dev,
if (ret)
goto out;
- min_uV = on ? vreg->min_uV : 0;
- ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
- if (ret) {
- dev_err(dev, "%s: %s set voltage failed, err=%d\n",
+ if (vreg->min_uV && vreg->max_uV) {
+ min_uV = on ? vreg->min_uV : 0;
+ ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
+ if (ret) {
+ dev_err(dev,
+ "%s: %s set voltage failed, err=%d\n",
__func__, name, ret);
- goto out;
+ goto out;
+ }
}
}
out:
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 105597a885cb..33b10dd7d87e 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -591,7 +591,7 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
static int pwrap_init_cipher(struct pmic_wrapper *wrp)
{
int ret;
- u32 rdata;
+ u32 rdata = 0;
pwrap_writel(wrp, 0x1, PWRAP_CIPHER_SWRST);
pwrap_writel(wrp, 0x0, PWRAP_CIPHER_SWRST);
diff --git a/drivers/soc/qcom/glink_spi_xprt.c b/drivers/soc/qcom/glink_spi_xprt.c
index ade731cf3251..818051e6e9cb 100644
--- a/drivers/soc/qcom/glink_spi_xprt.c
+++ b/drivers/soc/qcom/glink_spi_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 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
@@ -641,10 +641,13 @@ static int glink_spi_xprt_tx_cmd(struct edge_info *einfo, void *src,
* is read.
* @frag_size: Size of the data fragment to read.
* @size_remaining: Size of data left to be read in this packet.
+ * @rx_size: Max size of data that can be read in this packet
+ * from source.
*/
static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id,
uint32_t rcid, uint32_t intent_id, void *src,
- uint32_t frag_size, uint32_t size_remaining)
+ uint32_t frag_size, uint32_t size_remaining,
+ int rx_size)
{
struct glink_core_rx_intent *intent;
int rc = 0;
@@ -667,8 +670,14 @@ static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id,
return;
}
- if (cmd_id == TX_SHORT_DATA_CMD)
+ if (cmd_id == TX_SHORT_DATA_CMD) {
+ if (frag_size > rx_size) {
+ GLINK_ERR("%s: frag size:%d greater than rx size %d\n",
+ __func__, frag_size, rx_size);
+ return;
+ }
memcpy(intent->data + intent->write_offset, src, frag_size);
+ }
else
rc = glink_spi_xprt_rx_data(einfo, src,
intent->data + intent->write_offset, frag_size);
@@ -838,7 +847,8 @@ static void process_rx_cmd(struct edge_info *einfo,
process_rx_data(einfo, cmd->id, cmd->param1,
cmd->param2,
(void *)(uintptr_t)(rx_descp->addr),
- rx_descp->size, rx_descp->size_left);
+ rx_descp->size, rx_descp->size_left,
+ rx_size);
break;
case TX_SHORT_DATA_CMD:
@@ -849,7 +859,7 @@ static void process_rx_cmd(struct edge_info *einfo,
offset += sizeof(*rx_sd_descp);
process_rx_data(einfo, cmd->id, cmd->param1,
cmd->param2, (void *)rx_sd_descp->data,
- cmd->param3, cmd->param4);
+ cmd->param3, cmd->param4, rx_size);
break;
case READ_NOTIF_CMD:
diff --git a/drivers/soc/qcom/hab/hab_ghs.c b/drivers/soc/qcom/hab/hab_ghs.c
index 01f42b5f67ac..2c8fb14dad1f 100644
--- a/drivers/soc/qcom/hab/hab_ghs.c
+++ b/drivers/soc/qcom/hab/hab_ghs.c
@@ -169,6 +169,7 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
mmid_device->name,
mmid_device->id,
dt_name_idx);
+ of_node_put(gvh_dn);
ret = -ENOENT;
goto err;
}
@@ -176,9 +177,13 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
ret = of_property_read_string(gvh_dn,
ghs_vmm_plugin_info.dt_name[dt_name_idx],
&ep_path);
- if (ret)
+ if (ret) {
pr_err("failed to read endpoint str ret %d\n",
ret);
+ of_node_put(gvh_dn);
+ ret = -ENOENT;
+ goto err;
+ }
of_node_put(gvh_dn);
ep_dn = of_find_node_by_path(ep_path);
diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c
index dabffa0e856a..9f92074665df 100644
--- a/drivers/soc/qcom/hab/hab_msg.c
+++ b/drivers/soc/qcom/hab/hab_msg.c
@@ -206,6 +206,7 @@ int hab_msg_recv(struct physical_channel *pchan,
struct virtual_channel *vchan = NULL;
struct export_desc *exp_desc = NULL, exp_ack = {0};
struct timeval tv = {0};
+ unsigned long long rx_mpm_tv = 0;
/* get the local virtual channel if it isn't an open message */
if (payload_type != HAB_PAYLOAD_TYPE_INIT &&
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 999dcde8c5b0..9781aa258943 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -75,7 +75,7 @@ module_param(qmi_timeout, ulong, 0600);
#define ICNSS_MAX_PROBE_CNT 2
-#define PROBE_TIMEOUT 5000
+#define PROBE_TIMEOUT 15000
#define icnss_ipc_log_string(_x...) do { \
if (icnss_ipc_log_context) \
@@ -2644,8 +2644,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed &&
test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
if (!wait_for_completion_timeout(&priv->unblock_shutdown,
- PROBE_TIMEOUT))
- icnss_pr_err("wlan driver probe timeout\n");
+ msecs_to_jiffies(PROBE_TIMEOUT)))
+ icnss_pr_err("modem block shutdown timeout\n");
}
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) {
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 19019aa092e8..2c77f9051a26 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Sony Mobile Communications AB.
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -228,7 +228,7 @@ struct smem_region {
* struct qcom_smem - device data for the smem device
* @dev: device pointer
* @hwlock: reference to a hwspinlock
- * @partitions: list of pointers to partitions affecting the current
+ * @ptable_entries: list of pointers to partitions table entry of current
* processor/host
* @num_regions: number of @regions
* @regions: list of the memory regions defining the shared memory
@@ -238,12 +238,24 @@ struct qcom_smem {
struct hwspinlock *hwlock;
- struct smem_partition_header *partitions[SMEM_HOST_COUNT];
+ struct smem_ptable_entry *ptable_entries[SMEM_HOST_COUNT];
unsigned num_regions;
struct smem_region regions[0];
};
+/* Pointer to the one and only smem handle */
+static struct qcom_smem *__smem;
+
+/* Timeout (ms) for the trylock of remote spinlocks */
+#define HWSPINLOCK_TIMEOUT 1000
+
+static struct smem_partition_header *
+ptable_entry_to_phdr(struct smem_ptable_entry *entry)
+{
+ return __smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+}
+
static struct smem_private_entry *
phdr_to_last_private_entry(struct smem_partition_header *phdr)
{
@@ -283,32 +295,33 @@ static void *entry_to_item(struct smem_private_entry *e)
return p + sizeof(*e) + le16_to_cpu(e->padding_hdr);
}
-/* Pointer to the one and only smem handle */
-static struct qcom_smem *__smem;
-
-/* Timeout (ms) for the trylock of remote spinlocks */
-#define HWSPINLOCK_TIMEOUT 1000
-
static int qcom_smem_alloc_private(struct qcom_smem *smem,
- unsigned host,
+ struct smem_ptable_entry *entry,
unsigned item,
size_t size)
{
struct smem_partition_header *phdr;
struct smem_private_entry *hdr, *end;
+ struct smem_partition_header *phdr;
size_t alloc_size;
void *cached;
+ void *p_end;
+
+ phdr = ptable_entry_to_phdr(entry);
+ p_end = (void *)phdr + le32_to_cpu(entry->size);
- phdr = smem->partitions[host];
hdr = phdr_to_first_private_entry(phdr);
end = phdr_to_last_private_entry(phdr);
cached = phdr_to_first_cached_entry(phdr);
+ if (WARN_ON((void *)end > p_end || (void *)cached > p_end))
+ return -EINVAL;
+
while (hdr < end) {
if (hdr->canary != SMEM_PRIVATE_CANARY) {
dev_err(smem->dev,
- "Found invalid canary in host %d partition\n",
- host);
+ "Found invalid canary in host %d:%d partition\n",
+ phdr->host0, phdr->host1);
return -EINVAL;
}
@@ -317,6 +330,8 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
hdr = private_entry_next(hdr);
}
+ if (WARN_ON((void *)hdr > p_end))
+ return -EINVAL;
/* Check that we don't grow into the cached region */
alloc_size = sizeof(*hdr) + ALIGN(size, 8);
@@ -389,6 +404,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
*/
int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
{
+ struct smem_ptable_entry *entry;
unsigned long flags;
int ret;
@@ -407,10 +423,12 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
if (ret)
return ret;
- if (host < SMEM_HOST_COUNT && __smem->partitions[host])
- ret = qcom_smem_alloc_private(__smem, host, item, size);
- else
+ if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) {
+ entry = __smem->ptable_entries[host];
+ ret = qcom_smem_alloc_private(__smem, entry, item, size);
+ } else {
ret = qcom_smem_alloc_global(__smem, item, size);
+ }
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
@@ -422,9 +440,11 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
unsigned item,
size_t *size)
{
+ struct smem_global_entry *entry;
struct smem_header *header;
struct smem_region *area;
- struct smem_global_entry *entry;
+ u64 entry_offset;
+ u32 e_size;
u32 aux_base;
unsigned i;
@@ -442,9 +462,16 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
area = &smem->regions[i];
if (area->aux_base == aux_base || !aux_base) {
+ e_size = le32_to_cpu(entry->size);
+ entry_offset = le32_to_cpu(entry->offset);
+
+ if (WARN_ON(e_size + entry_offset > area->size))
+ return ERR_PTR(-EINVAL);
+
if (size != NULL)
- *size = le32_to_cpu(entry->size);
- return area->virt_base + le32_to_cpu(entry->offset);
+ *size = e_size;
+
+ return area->virt_base + entry_offset;
}
}
@@ -452,35 +479,58 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
}
static void *qcom_smem_get_private(struct qcom_smem *smem,
- unsigned host,
+ struct smem_ptable_entry *entry,
unsigned item,
size_t *size)
{
struct smem_partition_header *phdr;
struct smem_private_entry *e, *end;
+ void *item_ptr, *p_end;
+ u32 partition_size;
+ u32 padding_data;
+ u32 e_size;
+
+ phdr = ptable_entry_to_phdr(entry);
+ partition_size = le32_to_cpu(entry->size);
+ p_end = (void *)phdr + partition_size;
- phdr = smem->partitions[host];
e = phdr_to_first_private_entry(phdr);
end = phdr_to_last_private_entry(phdr);
+ if (WARN_ON((void *)end > p_end))
+ return ERR_PTR(-EINVAL);
+
while (e < end) {
if (e->canary != SMEM_PRIVATE_CANARY) {
dev_err(smem->dev,
- "Found invalid canary in host %d partition\n",
- host);
+ "Found invalid canary in host %d:%d partition\n",
+ phdr->host0, phdr->host1);
return ERR_PTR(-EINVAL);
}
if (le16_to_cpu(e->item) == item) {
- if (size != NULL)
- *size = le32_to_cpu(e->size) -
- le16_to_cpu(e->padding_data);
-
- return entry_to_item(e);
+ if (size != NULL) {
+ e_size = le32_to_cpu(e->size);
+ padding_data = le16_to_cpu(e->padding_data);
+
+ if (e_size < partition_size
+ && padding_data < e_size)
+ *size = e_size - padding_data;
+ else
+ return ERR_PTR(-EINVAL);
+ }
+
+ item_ptr = entry_to_item(e);
+ if (WARN_ON(item_ptr > p_end))
+ return ERR_PTR(-EINVAL);
+
+ return item_ptr;
}
e = private_entry_next(e);
}
+ if (WARN_ON((void *)e > p_end))
+ return ERR_PTR(-EINVAL);
return ERR_PTR(-ENOENT);
}
@@ -496,6 +546,7 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
*/
void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
{
+ struct smem_ptable_entry *entry;
unsigned long flags;
int ret;
void *ptr = ERR_PTR(-EPROBE_DEFER);
@@ -509,11 +560,12 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
if (ret)
return ERR_PTR(ret);
- if (host < SMEM_HOST_COUNT && __smem->partitions[host])
- ptr = qcom_smem_get_private(__smem, host, item, size);
- else
+ if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) {
+ entry = __smem->ptable_entries[host];
+ ptr = qcom_smem_get_private(__smem, entry, item, size);
+ } else {
ptr = qcom_smem_get_global(__smem, item, size);
-
+ }
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
return ptr;
@@ -531,19 +583,28 @@ EXPORT_SYMBOL(qcom_smem_get);
int qcom_smem_get_free_space(unsigned host)
{
struct smem_partition_header *phdr;
+ struct smem_ptable_entry *entry;
struct smem_header *header;
unsigned ret;
if (!__smem)
return -EPROBE_DEFER;
- if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
- phdr = __smem->partitions[host];
+ if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) {
+ entry = __smem->ptable_entries[host];
+ phdr = ptable_entry_to_phdr(entry);
+
ret = le32_to_cpu(phdr->offset_free_cached) -
le32_to_cpu(phdr->offset_free_uncached);
+
+ if (ret > le32_to_cpu(entry->size))
+ return -EINVAL;
} else {
header = __smem->regions[0].virt_base;
ret = le32_to_cpu(header->available);
+
+ if (ret > __smem->regions[0].size)
+ return -EINVAL;
}
return ret;
@@ -616,7 +677,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
return -EINVAL;
}
- if (smem->partitions[remote_host]) {
+ if (smem->ptable_entries[remote_host]) {
dev_err(smem->dev,
"Already found a partition for host %d\n",
remote_host);
@@ -658,7 +719,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
return -EINVAL;
}
- smem->partitions[remote_host] = header;
+ smem->ptable_entries[remote_host] = entry;
}
return 0;
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 3cac73e4c3e4..193aa3da5033 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -859,10 +859,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
rate = min_t(int, ssp_clk, rate);
+ /*
+ * Calculate the divisor for the SCR (Serial Clock Rate), avoiding
+ * that the SSP transmission rate can be greater than the device rate
+ */
if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
- return (ssp_clk / (2 * rate) - 1) & 0xff;
+ return (DIV_ROUND_UP(ssp_clk, 2 * rate) - 1) & 0xff;
else
- return (ssp_clk / rate - 1) & 0xfff;
+ return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff;
}
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
@@ -1367,12 +1371,7 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
{
- struct device *dev = param;
-
- if (dev != chan->device->dev->parent)
- return false;
-
- return true;
+ return param == chan->device->dev;
}
static struct pxa2xx_spi_master *
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 9882d93e7566..0556259377f7 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -279,7 +279,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
/* Sets parity, interrupt mask */
rspi_write8(rspi, 0x00, RSPI_SPCR2);
- /* Sets SPCMD */
+ /* Resets sequencer */
+ rspi_write8(rspi, 0, RSPI_SPSCR);
rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
@@ -313,7 +314,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
rspi_write8(rspi, 0x00, RSPI_SSLND);
rspi_write8(rspi, 0x00, RSPI_SPND);
- /* Sets SPCMD */
+ /* Resets sequencer */
+ rspi_write8(rspi, 0, RSPI_SPSCR);
rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
@@ -364,7 +366,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
/* Sets buffer to allow normal operation */
rspi_write8(rspi, 0x00, QSPI_SPBFCR);
- /* Sets SPCMD */
+ /* Resets sequencer */
+ rspi_write8(rspi, 0, RSPI_SPSCR);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
/* Enables SPI function in master mode */
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 73779cecc3bb..705f515863d4 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1067,27 +1067,19 @@ static int tegra_spi_probe(struct platform_device *pdev)
spi_irq = platform_get_irq(pdev, 0);
tspi->irq = spi_irq;
- ret = request_threaded_irq(tspi->irq, tegra_spi_isr,
- tegra_spi_isr_thread, IRQF_ONESHOT,
- dev_name(&pdev->dev), tspi);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
- tspi->irq);
- goto exit_free_master;
- }
tspi->clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(tspi->clk)) {
dev_err(&pdev->dev, "can not get clock\n");
ret = PTR_ERR(tspi->clk);
- goto exit_free_irq;
+ goto exit_free_master;
}
tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
- goto exit_free_irq;
+ goto exit_free_master;
}
tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
@@ -1095,7 +1087,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0)
- goto exit_free_irq;
+ goto exit_free_master;
ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0)
goto exit_rx_dma_free;
@@ -1117,18 +1109,32 @@ static int tegra_spi_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret);
goto exit_pm_disable;
}
+
+ reset_control_assert(tspi->rst);
+ udelay(2);
+ reset_control_deassert(tspi->rst);
tspi->def_command1_reg = SPI_M_S;
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
pm_runtime_put(&pdev->dev);
+ ret = request_threaded_irq(tspi->irq, tegra_spi_isr,
+ tegra_spi_isr_thread, IRQF_ONESHOT,
+ dev_name(&pdev->dev), tspi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
+ tspi->irq);
+ goto exit_pm_disable;
+ }
master->dev.of_node = pdev->dev.of_node;
ret = devm_spi_register_master(&pdev->dev, master);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to master err %d\n", ret);
- goto exit_pm_disable;
+ goto exit_free_irq;
}
return ret;
+exit_free_irq:
+ free_irq(spi_irq, tspi);
exit_pm_disable:
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
@@ -1136,8 +1142,6 @@ exit_pm_disable:
tegra_spi_deinit_dma_param(tspi, false);
exit_rx_dma_free:
tegra_spi_deinit_dma_param(tspi, true);
-exit_free_irq:
- free_irq(spi_irq, tspi);
exit_free_master:
spi_master_put(master);
return ret;
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 93dfcee0f987..9f30a4ab2004 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -1326,18 +1326,27 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
return;
}
-static void pch_alloc_dma_buf(struct pch_spi_board_data *board_dat,
+static int pch_alloc_dma_buf(struct pch_spi_board_data *board_dat,
struct pch_spi_data *data)
{
struct pch_spi_dma_ctrl *dma;
+ int ret;
dma = &data->dma;
+ ret = 0;
/* Get Consistent memory for Tx DMA */
dma->tx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev,
PCH_BUF_SIZE, &dma->tx_buf_dma, GFP_KERNEL);
+ if (!dma->tx_buf_virt)
+ ret = -ENOMEM;
+
/* Get Consistent memory for Rx DMA */
dma->rx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev,
PCH_BUF_SIZE, &dma->rx_buf_dma, GFP_KERNEL);
+ if (!dma->rx_buf_virt)
+ ret = -ENOMEM;
+
+ return ret;
}
static int pch_spi_pd_probe(struct platform_device *plat_dev)
@@ -1414,7 +1423,9 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
if (use_dma) {
dev_info(&plat_dev->dev, "Use DMA for data transfers\n");
- pch_alloc_dma_buf(board_dat, data);
+ ret = pch_alloc_dma_buf(board_dat, data);
+ if (ret)
+ goto err_spi_register_master;
}
ret = spi_register_master(master);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 63446500d49c..5c7fd1571a01 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -903,6 +903,8 @@ static int spi_map_msg(struct spi_master *master, struct spi_message *msg)
if (max_tx || max_rx) {
list_for_each_entry(xfer, &msg->transfers,
transfer_list) {
+ if (!xfer->len)
+ continue;
if (!xfer->tx_buf)
xfer->tx_buf = master->dummy_tx;
if (!xfer->rx_buf)
diff --git a/drivers/ssb/bridge_pcmcia_80211.c b/drivers/ssb/bridge_pcmcia_80211.c
index d70568ea02d5..2ff7d90e166a 100644
--- a/drivers/ssb/bridge_pcmcia_80211.c
+++ b/drivers/ssb/bridge_pcmcia_80211.c
@@ -113,16 +113,21 @@ static struct pcmcia_driver ssb_host_pcmcia_driver = {
.resume = ssb_host_pcmcia_resume,
};
+static int pcmcia_init_failed;
+
/*
* These are not module init/exit functions!
* The module_pcmcia_driver() helper cannot be used here.
*/
int ssb_host_pcmcia_init(void)
{
- return pcmcia_register_driver(&ssb_host_pcmcia_driver);
+ pcmcia_init_failed = pcmcia_register_driver(&ssb_host_pcmcia_driver);
+
+ return pcmcia_init_failed;
}
void ssb_host_pcmcia_exit(void)
{
- pcmcia_unregister_driver(&ssb_host_pcmcia_driver);
+ if (!pcmcia_init_failed)
+ pcmcia_unregister_driver(&ssb_host_pcmcia_driver);
}
diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
index 3e06ceb32059..676a8e329eeb 100644
--- a/drivers/staging/iio/magnetometer/hmc5843_i2c.c
+++ b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
@@ -59,8 +59,13 @@ static const struct regmap_config hmc5843_i2c_regmap_config = {
static int hmc5843_i2c_probe(struct i2c_client *cli,
const struct i2c_device_id *id)
{
+ struct regmap *regmap = devm_regmap_init_i2c(cli,
+ &hmc5843_i2c_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
return hmc5843_common_probe(&cli->dev,
- devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config),
+ regmap,
id->driver_data, id->name);
}
diff --git a/drivers/staging/iio/magnetometer/hmc5843_spi.c b/drivers/staging/iio/magnetometer/hmc5843_spi.c
index 8be198058ea2..fded442a3c1d 100644
--- a/drivers/staging/iio/magnetometer/hmc5843_spi.c
+++ b/drivers/staging/iio/magnetometer/hmc5843_spi.c
@@ -59,6 +59,7 @@ static const struct regmap_config hmc5843_spi_regmap_config = {
static int hmc5843_spi_probe(struct spi_device *spi)
{
int ret;
+ struct regmap *regmap;
const struct spi_device_id *id = spi_get_device_id(spi);
spi->mode = SPI_MODE_3;
@@ -68,8 +69,12 @@ static int hmc5843_spi_probe(struct spi_device *spi)
if (ret)
return ret;
+ regmap = devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
return hmc5843_common_probe(&spi->dev,
- devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config),
+ regmap,
id->driver_data, id->name);
}
diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c
index 215c37526081..7e141f15a544 100644
--- a/drivers/thermal/msm_lmh_dcvs.c
+++ b/drivers/thermal/msm_lmh_dcvs.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
@@ -54,7 +54,7 @@
#define MSM_LIMITS_CLUSTER_0 0x6370302D
#define MSM_LIMITS_CLUSTER_1 0x6370312D
-#define MSM_LIMITS_DOMAIN_MAX 0x444D4158
+#define MSM_LIMIT_FREQ_CAP 0x46434150
#define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000
#define MSM_LIMITS_ARM_THRESHOLD_VAL 65000
@@ -194,34 +194,40 @@ static irqreturn_t lmh_dcvs_handle_isr(int irq, void *data)
}
static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn,
- uint32_t setting, uint32_t val)
+ uint32_t setting, uint32_t val, uint32_t val1,
+ bool enable_val1)
{
int ret;
struct scm_desc desc_arg;
uint32_t *payload = NULL;
+ uint32_t payload_len;
- payload = kzalloc(sizeof(uint32_t) * 5, GFP_KERNEL);
+ payload_len = ((enable_val1) ? 6 : 5) * sizeof(uint32_t);
+ payload = kcalloc((enable_val1) ? 6 : 5, sizeof(uint32_t), GFP_KERNEL);
if (!payload)
return -ENOMEM;
payload[0] = fn; /* algorithm */
payload[1] = 0; /* unused sub-algorithm */
payload[2] = setting;
- payload[3] = 1; /* number of values */
+ payload[3] = enable_val1 ? 2 : 1; /* number of values */
payload[4] = val;
+ if (enable_val1)
+ payload[5] = val1;
desc_arg.args[0] = SCM_BUFFER_PHYS(payload);
- desc_arg.args[1] = sizeof(uint32_t) * 5;
+ desc_arg.args[1] = payload_len;
desc_arg.args[2] = MSM_LIMITS_NODE_DCVS;
desc_arg.args[3] = node_id;
desc_arg.args[4] = 0; /* version */
desc_arg.arginfo = SCM_ARGS(5, SCM_RO, SCM_VAL, SCM_VAL,
SCM_VAL, SCM_VAL);
- dmac_flush_range(payload, (void *)payload + 5 * (sizeof(uint32_t)));
+ dmac_flush_range(payload, (void *)payload + payload_len);
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_LMH, MSM_LIMITS_DCVSH), &desc_arg);
kfree(payload);
+
return ret;
}
@@ -265,7 +271,7 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
case LIMITS_TRIP_LO:
ret = msm_lmh_dcvs_write(hw->affinity,
MSM_LIMITS_SUB_FN_THERMAL,
- MSM_LIMITS_ARM_THRESHOLD, temp);
+ MSM_LIMITS_ARM_THRESHOLD, temp, 0, 0);
break;
case LIMITS_TRIP_HI:
/*
@@ -276,13 +282,13 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
return -EINVAL;
ret = msm_lmh_dcvs_write(hw->affinity,
MSM_LIMITS_SUB_FN_THERMAL,
- MSM_LIMITS_HI_THRESHOLD, temp);
+ MSM_LIMITS_HI_THRESHOLD, temp, 0, 0);
if (ret)
break;
ret = msm_lmh_dcvs_write(hw->affinity,
MSM_LIMITS_SUB_FN_THERMAL,
MSM_LIMITS_LOW_THRESHOLD, temp -
- MSM_LIMITS_LOW_THRESHOLD_OFFSET);
+ MSM_LIMITS_LOW_THRESHOLD_OFFSET, 0, 0);
break;
default:
return -EINVAL;
@@ -347,8 +353,9 @@ static int lmh_set_max_limit(int cpu, u32 freq)
if (!hw)
return -EINVAL;
- return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_GENERAL,
- MSM_LIMITS_DOMAIN_MAX, freq);
+ return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL,
+ MSM_LIMIT_FREQ_CAP, freq,
+ freq >= hw->max_freq ? 0 : 1, 1);
}
static int lmh_get_cur_limit(int cpu, unsigned long *freq)
@@ -457,7 +464,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev)
/* Enable the thermal algorithm early */
ret = msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL,
- MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
if (ret)
return ret;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index ee211e857fa7..34999be5bdd0 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.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
@@ -59,11 +59,11 @@
#define MSM_LIMITS_DCVSH 0x10
#define MSM_LIMITS_NODE_DCVS 0x44435653
+#define MSM_LIMITS_SUB_FN_THERMAL 0x54484D4C
#define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00
#define MSM_LIMITS_SUB_FN_CRNT 0x43524E54
#define MSM_LIMITS_SUB_FN_REL 0x52454C00
-#define MSM_LIMITS_DOMAIN_MAX 0x444D4158
-#define MSM_LIMITS_DOMAIN_MIN 0x444D494E
+#define MSM_LIMITS_FREQ_CAP 0x46434150
#define MSM_LIMITS_CLUSTER_0 0x6370302D
#define MSM_LIMITS_CLUSTER_1 0x6370312D
#define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C
@@ -1018,55 +1018,58 @@ static struct notifier_block msm_thermal_cpufreq_notifier = {
.notifier_call = msm_thermal_cpufreq_callback,
};
-static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn, uint32_t setting,
- uint32_t val)
+static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn,
+ uint32_t setting, uint32_t val, uint32_t val1,
+ bool enable_val1)
{
int ret;
struct scm_desc desc_arg;
uint32_t *payload = NULL;
+ uint32_t payload_len;
- payload = kzalloc(sizeof(uint32_t) * 5, GFP_KERNEL);
+ payload_len = ((enable_val1) ? 6 : 5) * sizeof(uint32_t);
+ payload = kcalloc((enable_val1) ? 6 : 5, sizeof(uint32_t), GFP_KERNEL);
if (!payload)
return -ENOMEM;
- payload[0] = fn;
+ payload[0] = fn; /* algorithm */
payload[1] = 0; /* unused sub-algorithm */
payload[2] = setting;
- payload[3] = 1; /* number of values */
+ payload[3] = enable_val1 ? 2 : 1; /* number of values */
payload[4] = val;
+ if (enable_val1)
+ payload[5] = val1;
desc_arg.args[0] = SCM_BUFFER_PHYS(payload);
- desc_arg.args[1] = sizeof(uint32_t) * 5;
+ desc_arg.args[1] = payload_len;
desc_arg.args[2] = MSM_LIMITS_NODE_DCVS;
desc_arg.args[3] = node_id;
desc_arg.args[4] = 0; /* version */
desc_arg.arginfo = SCM_ARGS(5, SCM_RO, SCM_VAL, SCM_VAL,
SCM_VAL, SCM_VAL);
- dmac_flush_range(payload, (void *)payload + 5 * (sizeof(uint32_t)));
+ dmac_flush_range(payload, (void *)payload + payload_len);
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_LMH, MSM_LIMITS_DCVSH), &desc_arg);
kfree(payload);
+
return ret;
}
static int msm_lmh_dcvs_update(int cpu)
{
uint32_t id = cpus[cpu].parent_ptr->cluster_id;
- uint32_t max_freq = cpus[cpu].limited_max_freq;
- uint32_t min_freq = cpus[cpu].limited_min_freq;
+ uint32_t max_freq = cpus[cpu].limited_max_freq, hw_max_freq = U32_MAX;
uint32_t affinity;
int ret;
/*
- * It is better to use max/min limits of cluster for given
+ * It is better to use max limits of cluster for given
* cpu if cluster mitigation is supported. It ensures that it
- * requests aggregated max/min limits of all cpus in that cluster.
+ * requests aggregated max limits of all cpus in that cluster.
*/
- if (core_ptr) {
+ if (core_ptr)
max_freq = cpus[cpu].parent_ptr->limited_max_freq;
- min_freq = cpus[cpu].parent_ptr->limited_min_freq;
- }
switch (id) {
case 0:
@@ -1080,13 +1083,14 @@ static int msm_lmh_dcvs_update(int cpu)
return -EINVAL;
};
- ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_GENERAL,
- MSM_LIMITS_DOMAIN_MAX, max_freq);
- if (ret)
- return ret;
+ if (cpus[cpu].parent_ptr->freq_table)
+ hw_max_freq =
+ cpus[cpu].parent_ptr->freq_table[
+ cpus[cpu].parent_ptr->freq_idx_high].frequency;
- ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_GENERAL,
- MSM_LIMITS_DOMAIN_MIN, min_freq);
+ ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_THERMAL,
+ MSM_LIMITS_FREQ_CAP, max_freq,
+ max_freq >= hw_max_freq ? 0 : 1, 1);
if (ret)
return ret;
/*
@@ -1729,23 +1733,23 @@ static int msm_thermal_lmh_dcvs_init(struct platform_device *pdev)
*/
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
MSM_LIMITS_SUB_FN_REL,
- MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
if (ret)
pr_err("Unable to enable REL algo for cluster0\n");
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1,
MSM_LIMITS_SUB_FN_REL,
- MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
if (ret)
pr_err("Unable to enable REL algo for cluster1\n");
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
MSM_LIMITS_SUB_FN_CRNT,
- MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
if (ret)
pr_err("Unable enable CRNT algo for cluster0\n");
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1,
MSM_LIMITS_SUB_FN_CRNT,
- MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
if (ret)
pr_err("Unable enable CRNT algo for cluster1\n");
diff --git a/drivers/tty/ipwireless/main.c b/drivers/tty/ipwireless/main.c
index 655c7948261c..2fa4f9123469 100644
--- a/drivers/tty/ipwireless/main.c
+++ b/drivers/tty/ipwireless/main.c
@@ -113,6 +113,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->common_memory = ioremap(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]));
+ if (!ipw->common_memory) {
+ ret = -ENOMEM;
+ goto exit1;
+ }
if (!request_mem_region(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]),
IPWIRELESS_PCCARD_NAME)) {
@@ -133,6 +137,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->attr_memory = ioremap(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]));
+ if (!ipw->attr_memory) {
+ ret = -ENOMEM;
+ goto exit3;
+ }
if (!request_mem_region(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]),
IPWIRELESS_PCCARD_NAME)) {
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index a30d68c4b689..039837db65fc 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -258,7 +258,7 @@ static bool dw8250_fallback_dma_filter(struct dma_chan *chan, void *param)
static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
{
- return param == chan->device->dev->parent;
+ return param == chan->device->dev;
}
static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
@@ -290,7 +290,7 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
data->uart_16550_compatible = true;
}
- /* Platforms with iDMA */
+ /* Platforms with iDMA 64-bit */
if (platform_get_resource_byname(to_platform_device(p->dev),
IORESOURCE_MEM, "lpss_priv")) {
p->set_termios = dw8250_set_termios;
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index be55fb6def89..0ac0c618954e 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -571,7 +571,7 @@ static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq,
}
/* Configure clock source */
- clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT;
+ clksrc = MAX310X_CLKSRC_EXTCLK_BIT | (xtal ? MAX310X_CLKSRC_CRYST_BIT : 0);
/* Configure PLL */
if (pllcfg) {
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index efaac5eb6592..eb66f7a68dc4 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -872,6 +872,7 @@ static void msm_handle_tx(struct uart_port *port)
struct circ_buf *xmit = &msm_port->uart.state->xmit;
struct msm_dma *dma = &msm_port->tx_dma;
unsigned int pio_count, dma_count, dma_min;
+ char buf[4] = { 0 };
void __iomem *tf;
int err = 0;
@@ -881,10 +882,12 @@ static void msm_handle_tx(struct uart_port *port)
else
tf = port->membase + UART_TF;
+ buf[0] = port->x_char;
+
if (msm_port->is_uartdm)
msm_reset_dm_count(port, 1);
- iowrite8_rep(tf, &port->x_char, 1);
+ iowrite32_rep(tf, buf, 1);
port->icount.tx++;
port->x_char = 0;
return;
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
index 59828d819145..5ad978acd90c 100644
--- a/drivers/tty/serial/sunhv.c
+++ b/drivers/tty/serial/sunhv.c
@@ -392,7 +392,7 @@ static struct uart_ops sunhv_pops = {
static struct uart_driver sunhv_reg = {
.owner = THIS_MODULE,
.driver_name = "sunhv",
- .dev_name = "ttyS",
+ .dev_name = "ttyHV",
.major = TTY_MAJOR,
};
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 988c564b61a8..fd92c842504d 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -121,6 +121,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals);
static struct input_handler kbd_handler;
static DEFINE_SPINLOCK(kbd_event_lock);
static DEFINE_SPINLOCK(led_lock);
+static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf' and friends */
static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static bool dead_key_next;
@@ -1969,11 +1970,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
char *p;
u_char *q;
u_char __user *up;
- int sz;
+ int sz, fnw_sz;
int delta;
char *first_free, *fj, *fnw;
int i, j, k;
int ret;
+ unsigned long flags;
if (!capable(CAP_SYS_TTY_CONFIG))
perm = 0;
@@ -2016,7 +2018,14 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
goto reterr;
}
+ fnw = NULL;
+ fnw_sz = 0;
+ /* race aginst other writers */
+ again:
+ spin_lock_irqsave(&func_buf_lock, flags);
q = func_table[i];
+
+ /* fj pointer to next entry after 'q' */
first_free = funcbufptr + (funcbufsize - funcbufleft);
for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
;
@@ -2024,10 +2033,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
fj = func_table[j];
else
fj = first_free;
-
+ /* buffer usage increase by new entry */
delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
+
if (delta <= funcbufleft) { /* it fits in current buf */
if (j < MAX_NR_FUNC) {
+ /* make enough space for new entry at 'fj' */
memmove(fj + delta, fj, first_free - fj);
for (k = j; k < MAX_NR_FUNC; k++)
if (func_table[k])
@@ -2040,20 +2051,28 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
sz = 256;
while (sz < funcbufsize - funcbufleft + delta)
sz <<= 1;
- fnw = kmalloc(sz, GFP_KERNEL);
- if(!fnw) {
- ret = -ENOMEM;
- goto reterr;
+ if (fnw_sz != sz) {
+ spin_unlock_irqrestore(&func_buf_lock, flags);
+ kfree(fnw);
+ fnw = kmalloc(sz, GFP_KERNEL);
+ fnw_sz = sz;
+ if (!fnw) {
+ ret = -ENOMEM;
+ goto reterr;
+ }
+ goto again;
}
if (!q)
func_table[i] = fj;
+ /* copy data before insertion point to new location */
if (fj > funcbufptr)
memmove(fnw, funcbufptr, fj - funcbufptr);
for (k = 0; k < j; k++)
if (func_table[k])
func_table[k] = fnw + (func_table[k] - funcbufptr);
+ /* copy data after insertion point to new location */
if (first_free > fj) {
memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
for (k = j; k < MAX_NR_FUNC; k++)
@@ -2066,7 +2085,9 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
funcbufleft = funcbufleft - delta + sz - funcbufsize;
funcbufsize = sz;
}
+ /* finally insert item itself */
strcpy(func_table[i], kbs->kb_string);
+ spin_unlock_irqrestore(&func_buf_lock, flags);
break;
}
ret = 0;
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index d551194a6ad6..421f1d3fbdb8 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -905,8 +905,8 @@ int usb_get_bos_descriptor(struct usb_device *dev)
/* Get BOS descriptor */
ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE);
- if (ret < USB_DT_BOS_SIZE) {
- dev_err(ddev, "unable to get BOS descriptor\n");
+ if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) {
+ dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n");
if (ret >= 0)
ret = -ENOMSG;
kfree(bos);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8d732e9f74fa..4740c307e02d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -3068,6 +3068,9 @@ usb_hcd_platform_shutdown(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
+ /* No need for pm_runtime_put(), we're shutting down */
+ pm_runtime_get_sync(&dev->dev);
+
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 9408bfef34f3..9d46cb7cb21d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5656,7 +5656,10 @@ int usb_reset_device(struct usb_device *udev)
cintf->needs_binding = 1;
}
}
- usb_unbind_and_rebind_marked_interfaces(udev);
+
+ /* If the reset failed, hub_wq will unbind drivers later */
+ if (ret == 0)
+ usb_unbind_and_rebind_marked_interfaces(udev);
}
usb_autosuspend_device(udev);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 733479ddf8a7..19e819aa2419 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -64,9 +64,15 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Microsoft LifeCam-VX700 v2.0 */
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */
+ { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
+
/* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
{ USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech HD Webcam C270 */
+ { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
+
/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index a2a692dc9195..0650f0b69de7 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -133,6 +133,34 @@ struct dwc3_msm_req_complete {
struct usb_request *req);
};
+enum dwc3_drd_state {
+ DRD_STATE_UNDEFINED = 0,
+
+ DRD_STATE_IDLE,
+ DRD_STATE_PERIPHERAL,
+ DRD_STATE_PERIPHERAL_SUSPEND,
+
+ DRD_STATE_HOST_IDLE,
+ DRD_STATE_HOST,
+};
+
+static const char *const state_names[] = {
+ [DRD_STATE_UNDEFINED] = "undefined",
+ [DRD_STATE_IDLE] = "idle",
+ [DRD_STATE_PERIPHERAL] = "peripheral",
+ [DRD_STATE_PERIPHERAL_SUSPEND] = "peripheral_suspend",
+ [DRD_STATE_HOST_IDLE] = "host_idle",
+ [DRD_STATE_HOST] = "host",
+};
+
+static const char *dwc3_drd_state_string(enum dwc3_drd_state state)
+{
+ if (state < 0 || state >= ARRAY_SIZE(state_names))
+ return "UNKNOWN";
+
+ return state_names[state];
+}
+
enum dwc3_id_state {
DWC3_ID_GROUND = 0,
DWC3_ID_FLOAT,
@@ -150,6 +178,7 @@ enum plug_orientation {
#define ID 0
#define B_SESS_VLD 1
#define B_SUSPEND 2
+#define WAIT_FOR_LPM 3
#define PM_QOS_SAMPLE_SEC 2
#define PM_QOS_THRESHOLD 400
@@ -196,7 +225,7 @@ struct dwc3_msm {
unsigned long inputs;
unsigned max_power;
bool charging_disabled;
- enum usb_otg_state otg_state;
+ enum dwc3_drd_state drd_state;
enum usb_chg_state chg_state;
struct work_struct bus_vote_w;
unsigned int bus_vote;
@@ -1939,7 +1968,7 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc)
atomic_set(&mdwc->in_p3, val == DWC3_LINK_STATE_U3);
dwc3_msm_write_reg_field(mdwc->base, PWR_EVNT_IRQ_MASK_REG,
PWR_EVNT_POWERDOWN_IN_P3_MASK, 1);
- if (mdwc->otg_state == OTG_STATE_A_HOST) {
+ if (mdwc->drd_state == DRD_STATE_HOST) {
dev_dbg(mdwc->dev, "%s: set the core in host mode\n",
__func__);
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
@@ -2061,7 +2090,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
}
if (!mdwc->vbus_active && dwc->is_drd &&
- mdwc->otg_state == OTG_STATE_B_PERIPHERAL) {
+ mdwc->drd_state == DRD_STATE_PERIPHERAL) {
/*
* In some cases, the pm_runtime_suspend may be called by
* usb_bam when there is pending lpm flag. However, if this is
@@ -2083,7 +2112,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
* then check controller state of L2 and break
* LPM sequence. Check this for device bus suspend case.
*/
- if ((dwc->is_drd && mdwc->otg_state == OTG_STATE_B_SUSPEND) &&
+ if ((dwc->is_drd && mdwc->drd_state == DRD_STATE_PERIPHERAL_SUSPEND) &&
(dwc->gadget.state != USB_STATE_CONFIGURED)) {
pr_err("%s(): Trying to go in LPM with state:%d\n",
__func__, dwc->gadget.state);
@@ -2197,7 +2226,13 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
dev_info(mdwc->dev, "DWC3 in low power mode\n");
dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm));
+
+ /* kick_sm if it is waiting for lpm sequence to finish */
+ if (test_and_clear_bit(WAIT_FOR_LPM, &mdwc->inputs))
+ schedule_delayed_work(&mdwc->sm_work, 0);
+
mutex_unlock(&mdwc->suspend_resume_mutex);
+
return 0;
}
@@ -3710,6 +3745,9 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
if (!mdwc->host_only_mode)
dwc3_post_host_reset_core_init(dwc);
+ /* wait for LPM, to ensure h/w is reset after stop_host */
+ set_bit(WAIT_FOR_LPM, &mdwc->inputs);
+
pm_runtime_mark_last_busy(mdwc->dev);
pm_runtime_put_sync_autosuspend(mdwc->dev);
dbg_event(0xFF, "StopHost psync",
@@ -3792,6 +3830,9 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
dwc3_override_vbus_status(mdwc, false);
dwc3_usb3_phy_suspend(dwc, false);
+
+ /* wait for LPM, to ensure h/w is reset after stop_peripheral */
+ set_bit(WAIT_FOR_LPM, &mdwc->inputs);
}
pm_runtime_put_sync(mdwc->dev);
@@ -3862,7 +3903,7 @@ set_prop:
*
* @w: Pointer to the dwc3 otg workqueue
*
- * NOTE: After any change in otg_state, we must reschdule the state machine.
+ * NOTE: After any change in drd_state, we must reschdule the state machine.
*/
static void dwc3_otg_sm_work(struct work_struct *w)
{
@@ -3881,13 +3922,13 @@ static void dwc3_otg_sm_work(struct work_struct *w)
return;
}
- state = usb_otg_state_string(mdwc->otg_state);
+ state = dwc3_drd_state_string(mdwc->drd_state);
dev_dbg(mdwc->dev, "%s state\n", state);
dbg_event(0xFF, state, 0);
/* Check OTG state */
- switch (mdwc->otg_state) {
- case OTG_STATE_UNDEFINED:
+ switch (mdwc->drd_state) {
+ case DRD_STATE_UNDEFINED:
/* put controller and phy in suspend if no cable connected */
if (test_bit(ID, &mdwc->inputs) &&
!test_bit(B_SESS_VLD, &mdwc->inputs)) {
@@ -3899,19 +3940,24 @@ static void dwc3_otg_sm_work(struct work_struct *w)
pm_runtime_put_sync(mdwc->dev);
dbg_event(0xFF, "Undef NoUSB",
atomic_read(&mdwc->dev->power.usage_count));
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
break;
}
dbg_event(0xFF, "Exit UNDEF", 0);
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
pm_runtime_set_suspended(mdwc->dev);
pm_runtime_enable(mdwc->dev);
/* fall-through */
- case OTG_STATE_B_IDLE:
+ case DRD_STATE_IDLE:
+ if (test_bit(WAIT_FOR_LPM, &mdwc->inputs)) {
+ dev_dbg(mdwc->dev, "still not in lpm, wait.\n");
+ break;
+ }
+
if (!test_bit(ID, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "!id\n");
- mdwc->otg_state = OTG_STATE_A_IDLE;
+ mdwc->drd_state = DRD_STATE_HOST_IDLE;
work = 1;
} else if (test_bit(B_SESS_VLD, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "b_sess_vld\n");
@@ -3922,7 +3968,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
msecs_to_jiffies(SDP_CONNETION_CHECK_TIME));
/*
* Increment pm usage count upon cable connect. Count
- * is decremented in OTG_STATE_B_PERIPHERAL state on
+ * is decremented in DRD_STATE_PERIPHERAL state on
* cable disconnect or in bus suspend.
*/
pm_runtime_get_sync(mdwc->dev);
@@ -3944,7 +3990,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
}
}
dwc3_otg_start_peripheral(mdwc, 1);
- mdwc->otg_state = OTG_STATE_B_PERIPHERAL;
+ mdwc->drd_state = DRD_STATE_PERIPHERAL;
work = 1;
break;
} else {
@@ -3954,17 +4000,17 @@ static void dwc3_otg_sm_work(struct work_struct *w)
}
break;
- case OTG_STATE_B_PERIPHERAL:
+ case DRD_STATE_PERIPHERAL:
if (!test_bit(B_SESS_VLD, &mdwc->inputs) ||
!test_bit(ID, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "!id || !bsv\n");
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
cancel_delayed_work_sync(&mdwc->sdp_check);
dwc3_otg_start_peripheral(mdwc, 0);
/*
* Decrement pm usage count upon cable disconnect
* which was incremented upon cable connect in
- * OTG_STATE_B_IDLE state
+ * DRD_STATE_IDLE state
*/
pm_runtime_put_sync(mdwc->dev);
dbg_event(0xFF, "!BSV psync",
@@ -3973,13 +4019,13 @@ static void dwc3_otg_sm_work(struct work_struct *w)
} else if (test_bit(B_SUSPEND, &mdwc->inputs) &&
test_bit(B_SESS_VLD, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "BPER bsv && susp\n");
- mdwc->otg_state = OTG_STATE_B_SUSPEND;
+ mdwc->drd_state = DRD_STATE_PERIPHERAL_SUSPEND;
/*
* Decrement pm usage count upon bus suspend.
* Count was incremented either upon cable
- * connect in OTG_STATE_B_IDLE or host
+ * connect in DRD_STATE_IDLE or host
* initiated resume after bus suspend in
- * OTG_STATE_B_SUSPEND state
+ * DRD_STATE_PERIPHERAL_SUSPEND state
*/
pm_runtime_mark_last_busy(mdwc->dev);
pm_runtime_put_autosuspend(mdwc->dev);
@@ -3988,20 +4034,20 @@ static void dwc3_otg_sm_work(struct work_struct *w)
}
break;
- case OTG_STATE_B_SUSPEND:
+ case DRD_STATE_PERIPHERAL_SUSPEND:
if (!test_bit(B_SESS_VLD, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "BSUSP: !bsv\n");
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
cancel_delayed_work_sync(&mdwc->sdp_check);
dwc3_otg_start_peripheral(mdwc, 0);
} else if (!test_bit(B_SUSPEND, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "BSUSP !susp\n");
- mdwc->otg_state = OTG_STATE_B_PERIPHERAL;
+ mdwc->drd_state = DRD_STATE_PERIPHERAL;
/*
* Increment pm usage count upon host
* initiated resume. Count was decremented
* upon bus suspend in
- * OTG_STATE_B_PERIPHERAL state.
+ * DRD_STATE_PERIPHERAL state.
*/
pm_runtime_get_sync(mdwc->dev);
dbg_event(0xFF, "!SUSP gsync",
@@ -4009,15 +4055,15 @@ static void dwc3_otg_sm_work(struct work_struct *w)
}
break;
- case OTG_STATE_A_IDLE:
+ case DRD_STATE_HOST_IDLE:
/* Switch to A-Device*/
if (test_bit(ID, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "id\n");
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
mdwc->vbus_retry_count = 0;
work = 1;
} else {
- mdwc->otg_state = OTG_STATE_A_HOST;
+ mdwc->drd_state = DRD_STATE_HOST;
ret = dwc3_otg_start_host(mdwc, 1);
if ((ret == -EPROBE_DEFER) &&
mdwc->vbus_retry_count < 3) {
@@ -4025,14 +4071,14 @@ static void dwc3_otg_sm_work(struct work_struct *w)
* Get regulator failed as regulator driver is
* not up yet. Will try to start host after 1sec
*/
- mdwc->otg_state = OTG_STATE_A_IDLE;
+ mdwc->drd_state = DRD_STATE_HOST_IDLE;
dev_dbg(mdwc->dev, "Unable to get vbus regulator. Retrying...\n");
delay = VBUS_REG_CHECK_DELAY;
work = 1;
mdwc->vbus_retry_count++;
} else if (ret) {
dev_err(mdwc->dev, "unable to start host\n");
- mdwc->otg_state = OTG_STATE_A_IDLE;
+ mdwc->drd_state = DRD_STATE_HOST_IDLE;
goto ret;
}
if (mdwc->no_wakeup_src_in_hostmode) {
@@ -4042,12 +4088,12 @@ static void dwc3_otg_sm_work(struct work_struct *w)
}
break;
- case OTG_STATE_A_HOST:
+ case DRD_STATE_HOST:
if (test_bit(ID, &mdwc->inputs) || mdwc->hc_died) {
dbg_event(0xFF, "id || hc_died", 0);
dev_dbg(mdwc->dev, "%s state id || hc_died\n", state);
dwc3_otg_start_host(mdwc, 0);
- mdwc->otg_state = OTG_STATE_B_IDLE;
+ mdwc->drd_state = DRD_STATE_IDLE;
mdwc->vbus_retry_count = 0;
mdwc->hc_died = false;
work = 1;
@@ -4200,7 +4246,7 @@ static int dwc3_msm_pm_restore(struct device *dev)
pm_runtime_enable(dev);
/* Restore PHY flags if hibernated in host mode */
- if (mdwc->otg_state == OTG_STATE_A_HOST) {
+ if (mdwc->drd_state == DRD_STATE_HOST) {
mdwc->hs_phy->flags |= PHY_HOST_MODE;
if (mdwc->ss_phy) {
mdwc->ss_phy->flags |= PHY_HOST_MODE;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0ccd5cec42ff..a283665e2ed5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -21,6 +21,7 @@
*/
#include <linux/pci.h>
+#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/log2.h>
#include <linux/module.h>
@@ -46,7 +47,6 @@ static unsigned int quirks;
module_param(quirks, uint, S_IRUGO);
MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
-/* TODO: copied from ehci-hcd.c - can this be refactored? */
/*
* xhci_handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
@@ -63,18 +63,16 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
{
u32 result;
+ int ret;
- do {
- result = readl(ptr);
- if (result == ~(u32)0) /* card removed */
- return -ENODEV;
- result &= mask;
- if (result == done)
- return 0;
- udelay(1);
- usec--;
- } while (usec > 0);
- return -ETIMEDOUT;
+ ret = readl_poll_timeout_atomic(ptr, result,
+ (result & mask) == done ||
+ result == U32_MAX,
+ 1, usec);
+ if (result == U32_MAX) /* card removed */
+ return -ENODEV;
+
+ return ret;
}
int xhci_handshake_check_state(struct xhci_hcd *xhci,
@@ -4239,7 +4237,6 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
pm_addr = port_array[port_num] + PORTPMSC;
pm_val = readl(pm_addr);
hlpm_addr = port_array[port_num] + PORTHLPMC;
- field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
enable ? "enable" : "disable", port_num + 1);
@@ -4251,6 +4248,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
* default one which works with mixed HIRD and BESL
* systems. See XHCI_DEFAULT_BESL definition in xhci.h
*/
+ field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
if ((field & USB_BESL_SUPPORT) &&
(field & USB_BESL_BASELINE_VALID))
hird = USB_GET_BESL_BASELINE(field);
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 13731d512624..6e761fabffca 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -103,9 +103,22 @@ static int close_rio(struct inode *inode, struct file *file)
{
struct rio_usb_data *rio = &rio_instance;
- rio->isopen = 0;
+ /* against disconnect() */
+ mutex_lock(&rio500_mutex);
+ mutex_lock(&(rio->lock));
- dev_info(&rio->rio_dev->dev, "Rio closed.\n");
+ rio->isopen = 0;
+ if (!rio->present) {
+ /* cleanup has been delayed */
+ kfree(rio->ibuf);
+ kfree(rio->obuf);
+ rio->ibuf = NULL;
+ rio->obuf = NULL;
+ } else {
+ dev_info(&rio->rio_dev->dev, "Rio closed.\n");
+ }
+ mutex_unlock(&(rio->lock));
+ mutex_unlock(&rio500_mutex);
return 0;
}
@@ -464,15 +477,23 @@ static int probe_rio(struct usb_interface *intf,
{
struct usb_device *dev = interface_to_usbdev(intf);
struct rio_usb_data *rio = &rio_instance;
- int retval;
+ int retval = 0;
- dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
+ mutex_lock(&rio500_mutex);
+ if (rio->present) {
+ dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
+ retval = -EBUSY;
+ goto bail_out;
+ } else {
+ dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
+ }
retval = usb_register_dev(intf, &usb_rio_class);
if (retval) {
dev_err(&dev->dev,
"Not able to get a minor for this device.\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto bail_out;
}
rio->rio_dev = dev;
@@ -481,7 +502,8 @@ static int probe_rio(struct usb_interface *intf,
dev_err(&dev->dev,
"probe_rio: Not enough memory for the output buffer\n");
usb_deregister_dev(intf, &usb_rio_class);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto bail_out;
}
dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
@@ -490,7 +512,8 @@ static int probe_rio(struct usb_interface *intf,
"probe_rio: Not enough memory for the input buffer\n");
usb_deregister_dev(intf, &usb_rio_class);
kfree(rio->obuf);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto bail_out;
}
dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
@@ -498,8 +521,10 @@ static int probe_rio(struct usb_interface *intf,
usb_set_intfdata (intf, rio);
rio->present = 1;
+bail_out:
+ mutex_unlock(&rio500_mutex);
- return 0;
+ return retval;
}
static void disconnect_rio(struct usb_interface *intf)
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 306d6852ebc7..b9d50020c684 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3103,6 +3103,13 @@ static int sisusb_probe(struct usb_interface *intf,
mutex_init(&(sisusb->lock));
+ sisusb->sisusb_dev = dev;
+ sisusb->vrambase = SISUSB_PCI_MEMBASE;
+ sisusb->mmiobase = SISUSB_PCI_MMIOBASE;
+ sisusb->mmiosize = SISUSB_PCI_MMIOSIZE;
+ sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
+ /* Everything else is zero */
+
/* Register device */
retval = usb_register_dev(intf, &usb_sisusb_class);
if (retval) {
@@ -3112,13 +3119,7 @@ static int sisusb_probe(struct usb_interface *intf,
goto error_1;
}
- sisusb->sisusb_dev = dev;
- sisusb->minor = intf->minor;
- sisusb->vrambase = SISUSB_PCI_MEMBASE;
- sisusb->mmiobase = SISUSB_PCI_MMIOBASE;
- sisusb->mmiosize = SISUSB_PCI_MMIOSIZE;
- sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
- /* Everything else is zero */
+ sisusb->minor = intf->minor;
/* Allocate buffers */
sisusb->ibufsize = SISUSB_IBUF_SIZE;
diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c
index d1b6f1df860d..8cfbb1c100fe 100644
--- a/drivers/usb/phy/phy-msm-ssusb-qmp.c
+++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-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
@@ -484,14 +484,16 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend)
/* Make sure above write completed with PHY */
wmb();
- clk_disable_unprepare(phy->cfg_ahb_clk);
- clk_disable_unprepare(phy->aux_clk);
- clk_disable_unprepare(phy->pipe_clk);
- if (phy->ref_clk)
- clk_disable_unprepare(phy->ref_clk);
- if (phy->ref_clk_src)
- clk_disable_unprepare(phy->ref_clk_src);
- phy->clk_enabled = false;
+ if (phy->clk_enabled) {
+ clk_disable_unprepare(phy->cfg_ahb_clk);
+ clk_disable_unprepare(phy->aux_clk);
+ clk_disable_unprepare(phy->pipe_clk);
+ if (phy->ref_clk)
+ clk_disable_unprepare(phy->ref_clk);
+ if (phy->ref_clk_src)
+ clk_disable_unprepare(phy->ref_clk_src);
+ phy->clk_enabled = false;
+ }
phy->in_suspend = true;
msm_ssphy_power_enable(phy, 0);
dev_dbg(uphy->dev, "QMP PHY is suspend\n");
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9f96dd274370..1effe74ec638 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1166,6 +1166,10 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+ { USB_DEVICE(TELIT_VENDOR_ID, 0x1260),
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+ { USB_DEVICE(TELIT_VENDOR_ID, 0x1261),
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1900), /* Telit LN940 (QMI) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */
@@ -1767,6 +1771,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
.driver_info = RSVD(5) | RSVD(6) },
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */
+ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */
+ .driver_info = RSVD(7) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
.driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D),
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 9706d214c409..8fd5e19846ef 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -101,6 +101,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
+ { USB_DEVICE(AT_VENDOR_ID, AT_VTKIT3_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index d84c3b3d477b..496cbccbf26c 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -159,3 +159,6 @@
#define SMART_VENDOR_ID 0x0b8c
#define SMART_PRODUCT_ID 0x2303
+/* Allied Telesis VT-Kit3 */
+#define AT_VENDOR_ID 0x0caa
+#define AT_VTKIT3_PRODUCT_ID 0x3001
diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h
index f5fc3271e19c..e2c5491a411b 100644
--- a/drivers/usb/storage/unusual_realtek.h
+++ b/drivers/usb/storage/unusual_realtek.h
@@ -28,6 +28,11 @@ UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999,
"USB Card Reader",
USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
+UNUSUAL_DEV(0x0bda, 0x0153, 0x0000, 0x9999,
+ "Realtek",
+ "USB Card Reader",
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
+
UNUSUAL_DEV(0x0bda, 0x0158, 0x0000, 0x9999,
"Realtek",
"USB Card Reader",
diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
index a04fa896361a..1f8b480b1a4d 100644
--- a/drivers/video/fbdev/core/fbcmap.c
+++ b/drivers/video/fbdev/core/fbcmap.c
@@ -94,6 +94,8 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
int size = len * sizeof(u16);
int ret = -ENOMEM;
+ flags |= __GFP_NOWARN;
+
if (cmap->len != len) {
fb_dealloc_cmap(cmap);
if (!len)
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index de119f11b78f..455a15f70172 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -933,6 +933,9 @@ void fb_var_to_videomode(struct fb_videomode *mode,
if (var->vmode & FB_VMODE_DOUBLE)
vtotal *= 2;
+ if (!htotal || !vtotal)
+ return;
+
hfreq = pixclock/htotal;
mode->refresh = hfreq/vtotal;
}
diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c
index 15d3ccff2965..4a397c7c1b56 100644
--- a/drivers/video/fbdev/hgafb.c
+++ b/drivers/video/fbdev/hgafb.c
@@ -285,6 +285,8 @@ static int hga_card_detect(void)
hga_vram_len = 0x08000;
hga_vram = ioremap(0xb0000, hga_vram_len);
+ if (!hga_vram)
+ goto error;
if (request_region(0x3b0, 12, "hgafb"))
release_io_ports = 1;
diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index 9b167f7ef6c6..4994a540f680 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -1517,6 +1517,11 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info->fix.smem_start = addr;
info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
0x400000 : 0x800000);
+ if (!info->screen_base) {
+ release_mem_region(addr, size);
+ framebuffer_release(info);
+ return -ENOMEM;
+ }
info->fix.mmio_start = addr + 0x800000;
par->dc_regs = ioremap(addr + 0x800000, 0x1000);
par->cmap_regs_phys = addr + 0x840000;
diff --git a/drivers/video/fbdev/sm712.h b/drivers/video/fbdev/sm712.h
index aad1cc4be34a..c7ebf03b8d53 100644
--- a/drivers/video/fbdev/sm712.h
+++ b/drivers/video/fbdev/sm712.h
@@ -15,14 +15,10 @@
#define FB_ACCEL_SMI_LYNX 88
-#define SCREEN_X_RES 1024
-#define SCREEN_Y_RES 600
-#define SCREEN_BPP 16
-
-/*Assume SM712 graphics chip has 4MB VRAM */
-#define SM712_VIDEOMEMORYSIZE 0x00400000
-/*Assume SM722 graphics chip has 8MB VRAM */
-#define SM722_VIDEOMEMORYSIZE 0x00800000
+#define SCREEN_X_RES 1024
+#define SCREEN_Y_RES_PC 768
+#define SCREEN_Y_RES_NETBOOK 600
+#define SCREEN_BPP 16
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 86ae1d4556fc..589ac7e75413 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -530,6 +530,65 @@ static const struct modeinit vgamode[] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
},
},
+ { /* 1024 x 768 16Bpp 60Hz */
+ 1024, 768, 16, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
{ /* mode#5: 1024 x 768 24Bpp 60Hz */
1024, 768, 24, 60,
/* Init_MISC */
@@ -827,67 +886,80 @@ static inline unsigned int chan_to_field(unsigned int chan,
static int smtc_blank(int blank_mode, struct fb_info *info)
{
+ struct smtcfb_info *sfb = info->par;
+
/* clear DPMS setting */
switch (blank_mode) {
case FB_BLANK_UNBLANK:
/* Screen On: HSync: On, VSync : On */
+
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ break;
+ case 0x720:
+ smtc_seqw(0x6a, 0x0d);
+ smtc_seqw(0x6b, 0x02);
+ break;
+ }
+
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
- smtc_seqw(0x6a, 0x16);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
break;
case FB_BLANK_NORMAL:
/* Screen Off: HSync: On, VSync : On Soft blank */
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
smtc_seqw(0x6a, 0x16);
smtc_seqw(0x6b, 0x02);
- smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
break;
case FB_BLANK_VSYNC_SUSPEND:
/* Screen On: HSync: On, VSync : Off */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
case FB_BLANK_HSYNC_SUSPEND:
/* Screen On: HSync: Off, VSync : On */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
case FB_BLANK_POWERDOWN:
/* Screen On: HSync: Off, VSync : Off */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
default:
return -EINVAL;
@@ -1144,8 +1216,10 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
/* init SEQ register SR30 - SR75 */
for (i = 0; i < SIZE_SR30_SR75; i++)
- if ((i + 0x30) != 0x62 && (i + 0x30) != 0x6a &&
- (i + 0x30) != 0x6b)
+ if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 &&
+ (i + 0x30) != 0x6a && (i + 0x30) != 0x6b &&
+ (i + 0x30) != 0x70 && (i + 0x30) != 0x71 &&
+ (i + 0x30) != 0x74 && (i + 0x30) != 0x75)
smtc_seqw(i + 0x30,
vgamode[j].init_sr30_sr75[i]);
@@ -1170,8 +1244,12 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]);
/* init CRTC register CR30 - CR4D */
- for (i = 0; i < SIZE_CR30_CR4D; i++)
+ for (i = 0; i < SIZE_CR30_CR4D; i++) {
+ if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F)
+ /* side-effect, don't write to CR3B-CR3F */
+ continue;
smtc_crtcw(i + 0x30, vgamode[j].init_cr30_cr4d[i]);
+ }
/* init CRTC register CR90 - CRA7 */
for (i = 0; i < SIZE_CR90_CRA7; i++)
@@ -1322,6 +1400,11 @@ static int smtc_map_smem(struct smtcfb_info *sfb,
{
sfb->fb->fix.smem_start = pci_resource_start(pdev, 0);
+ if (sfb->chip_id == 0x720)
+ /* on SM720, the framebuffer starts at the 1 MB offset */
+ sfb->fb->fix.smem_start += 0x00200000;
+
+ /* XXX: is it safe for SM720 on Big-Endian? */
if (sfb->fb->var.bits_per_pixel == 32)
sfb->fb->fix.smem_start += big_addr;
@@ -1359,12 +1442,82 @@ static inline void sm7xx_init_hw(void)
outb_p(0x11, 0x3c5);
}
+static u_long sm7xx_vram_probe(struct smtcfb_info *sfb)
+{
+ u8 vram;
+
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ /*
+ * Assume SM712 graphics chip has 4MB VRAM.
+ *
+ * FIXME: SM712 can have 2MB VRAM, which is used on earlier
+ * laptops, such as IBM Thinkpad 240X. This driver would
+ * probably crash on those machines. If anyone gets one of
+ * those and is willing to help, run "git blame" and send me
+ * an E-mail.
+ */
+ return 0x00400000;
+ case 0x720:
+ outb_p(0x76, 0x3c4);
+ vram = inb_p(0x3c5) >> 6;
+
+ if (vram == 0x00)
+ return 0x00800000; /* 8 MB */
+ else if (vram == 0x01)
+ return 0x01000000; /* 16 MB */
+ else if (vram == 0x02)
+ return 0x00400000; /* illegal, fallback to 4 MB */
+ else if (vram == 0x03)
+ return 0x00400000; /* 4 MB */
+ }
+ return 0; /* unknown hardware */
+}
+
+static void sm7xx_resolution_probe(struct smtcfb_info *sfb)
+{
+ /* get mode parameter from smtc_scr_info */
+ if (smtc_scr_info.lfb_width != 0) {
+ sfb->fb->var.xres = smtc_scr_info.lfb_width;
+ sfb->fb->var.yres = smtc_scr_info.lfb_height;
+ sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth;
+ goto final;
+ }
+
+ /*
+ * No parameter, default resolution is 1024x768-16.
+ *
+ * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x600
+ * panel, also see the comments about Thinkpad 240X above.
+ */
+ sfb->fb->var.xres = SCREEN_X_RES;
+ sfb->fb->var.yres = SCREEN_Y_RES_PC;
+ sfb->fb->var.bits_per_pixel = SCREEN_BPP;
+
+#ifdef CONFIG_MIPS
+ /*
+ * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original
+ * target platform of this driver, but nearly all old x86 laptops have
+ * 1024x768. Lighting 768 panels using 600's timings would partially
+ * garble the display, so we don't want that. But it's not possible to
+ * distinguish them reliably.
+ *
+ * So we change the default to 768, but keep 600 as-is on MIPS.
+ */
+ sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK;
+#endif
+
+final:
+ big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth);
+}
+
static int smtcfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct smtcfb_info *sfb;
struct fb_info *info;
- u_long smem_size = 0x00800000; /* default 8MB */
+ u_long smem_size;
int err;
unsigned long mmio_base;
@@ -1404,29 +1557,19 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
sm7xx_init_hw();
- /* get mode parameter from smtc_scr_info */
- if (smtc_scr_info.lfb_width != 0) {
- sfb->fb->var.xres = smtc_scr_info.lfb_width;
- sfb->fb->var.yres = smtc_scr_info.lfb_height;
- sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth;
- } else {
- /* default resolution 1024x600 16bit mode */
- sfb->fb->var.xres = SCREEN_X_RES;
- sfb->fb->var.yres = SCREEN_Y_RES;
- sfb->fb->var.bits_per_pixel = SCREEN_BPP;
- }
-
- big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth);
/* Map address and memory detection */
mmio_base = pci_resource_start(pdev, 0);
pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);
+ smem_size = sm7xx_vram_probe(sfb);
+ dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n",
+ smem_size / 1048576);
+
switch (sfb->chip_id) {
case 0x710:
case 0x712:
sfb->fb->fix.mmio_start = mmio_base + 0x00400000;
sfb->fb->fix.mmio_len = 0x00400000;
- smem_size = SM712_VIDEOMEMORYSIZE;
sfb->lfb = ioremap(mmio_base, mmio_addr);
if (!sfb->lfb) {
dev_err(&pdev->dev,
@@ -1458,8 +1601,7 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
case 0x720:
sfb->fb->fix.mmio_start = mmio_base;
sfb->fb->fix.mmio_len = 0x00200000;
- smem_size = SM722_VIDEOMEMORYSIZE;
- sfb->dp_regs = ioremap(mmio_base, 0x00a00000);
+ sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size);
sfb->lfb = sfb->dp_regs + 0x00200000;
sfb->mmio = (smtc_regbaseaddress =
sfb->dp_regs + 0x000c0000);
@@ -1476,6 +1618,9 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
goto failed_fb;
}
+ /* probe and decide resolution */
+ sm7xx_resolution_probe(sfb);
+
/* can support 32 bpp */
if (15 == sfb->fb->var.bits_per_pixel)
sfb->fb->var.bits_per_pixel = 16;
@@ -1486,7 +1631,11 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
if (err)
goto failed;
- smtcfb_setmode(sfb);
+ /*
+ * The screen would be temporarily garbled when sm712fb takes over
+ * vesafb or VGA text mode. Zero the framebuffer.
+ */
+ memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len);
err = register_framebuffer(info);
if (err < 0)
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 282092421cc9..1a9d9ec8db4d 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -437,8 +437,7 @@ int w1_reset_resume_command(struct w1_master *dev)
if (w1_reset_bus(dev))
return -1;
- /* This will make only the last matched slave perform a skip ROM. */
- w1_write_8(dev, W1_RESUME_CMD);
+ w1_write_8(dev, dev->slave_count > 1 ? W1_RESUME_CMD : W1_SKIP_ROM);
return 0;
}
EXPORT_SYMBOL_GPL(w1_reset_resume_command);
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index fb0221434f81..49c5f0e9600a 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -126,8 +126,6 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
if (pci_is_enabled(dev))
pci_disable_device(dev);
- pci_write_config_word(dev, PCI_COMMAND, 0);
-
dev->is_busmaster = 0;
} else {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 816a0e08ef10..d7591efa7775 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -536,7 +536,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
if (xen_store_evtchn == 0)
return -ENOENT;
- nonseekable_open(inode, filp);
+ stream_open(inode, filp);
u = kzalloc(sizeof(*u), GFP_KERNEL);
if (u == NULL)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index e2f659dc5745..81c5d07a2af1 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1685,13 +1685,19 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
extent_item_objectid);
if (!search_commit_root) {
- trans = btrfs_join_transaction(fs_info->extent_root);
- if (IS_ERR(trans))
- return PTR_ERR(trans);
+ trans = btrfs_attach_transaction(fs_info->extent_root);
+ if (IS_ERR(trans)) {
+ if (PTR_ERR(trans) != -ENOENT &&
+ PTR_ERR(trans) != -EROFS)
+ return PTR_ERR(trans);
+ trans = NULL;
+ }
+ }
+
+ if (trans)
btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
- } else {
+ else
down_read(&fs_info->commit_root_sem);
- }
ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
tree_mod_seq_elem.seq, &refs,
@@ -1721,7 +1727,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
free_leaf_list(refs);
out:
- if (!search_commit_root) {
+ if (trans) {
btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
btrfs_end_transaction(trans, fs_info->extent_root);
} else {
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 978bbfed5a2c..df2bb4b61a00 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10730,9 +10730,9 @@ int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
* transaction.
*/
static int btrfs_trim_free_extents(struct btrfs_device *device,
- u64 minlen, u64 *trimmed)
+ struct fstrim_range *range, u64 *trimmed)
{
- u64 start = 0, len = 0;
+ u64 start = range->start, len = 0;
int ret;
*trimmed = 0;
@@ -10768,8 +10768,8 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
atomic_inc(&trans->use_count);
spin_unlock(&fs_info->trans_lock);
- ret = find_free_dev_extent_start(trans, device, minlen, start,
- &start, &len);
+ ret = find_free_dev_extent_start(trans, device, range->minlen,
+ start, &start, &len);
if (trans)
btrfs_put_transaction(trans);
@@ -10781,6 +10781,16 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
break;
}
+ /* If we are out of the passed range break */
+ if (start > range->start + range->len - 1) {
+ mutex_unlock(&fs_info->chunk_mutex);
+ ret = 0;
+ break;
+ }
+
+ start = max(range->start, start);
+ len = min(range->len, len);
+
ret = btrfs_issue_discard(device->bdev, start, len, &bytes);
up_read(&fs_info->commit_root_sem);
mutex_unlock(&fs_info->chunk_mutex);
@@ -10791,6 +10801,10 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
start += len;
*trimmed += bytes;
+ /* We've trimmed enough */
+ if (*trimmed >= range->len)
+ break;
+
if (fatal_signal_pending(current)) {
ret = -ERESTARTSYS;
break;
@@ -10857,8 +10871,7 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
devices = &root->fs_info->fs_devices->devices;
list_for_each_entry(device, devices, dev_list) {
- ret = btrfs_trim_free_extents(device, range->minlen,
- &group_trimmed);
+ ret = btrfs_trim_free_extents(device, range, &group_trimmed);
if (ret)
break;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 052973620595..d056060529f8 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1901,6 +1901,18 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
u64 len;
/*
+ * If the inode needs a full sync, make sure we use a full range to
+ * avoid log tree corruption, due to hole detection racing with ordered
+ * extent completion for adjacent ranges, and assertion failures during
+ * hole detection.
+ */
+ if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags)) {
+ start = 0;
+ end = LLONG_MAX;
+ }
+
+ /*
* The range length can be represented by u64, we have to do the typecasts
* to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
*/
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index e0ac85949067..e6aaa15505c5 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -733,7 +733,12 @@ int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
fs_devs->fsid_kobj.kset = btrfs_kset;
error = kobject_init_and_add(&fs_devs->fsid_kobj,
&btrfs_ktype, parent, "%pU", fs_devs->fsid);
- return error;
+ if (error) {
+ kobject_put(&fs_devs->fsid_kobj);
+ return error;
+ }
+
+ return 0;
}
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c7190f322576..57a46093656a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2809,6 +2809,12 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
log->log_transid = root->log_transid;
root->log_start_pid = 0;
/*
+ * Update or create log root item under the root's log_mutex to prevent
+ * races with concurrent log syncs that can lead to failure to update
+ * log root item because it was not created yet.
+ */
+ ret = update_log_root(trans, log);
+ /*
* IO has been started, blocks of the log tree have WRITTEN flag set
* in their headers. new modifications of the log will be written to
* new positions. so it's safe to allow log writers to go in.
@@ -2827,8 +2833,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
mutex_unlock(&log_root_tree->log_mutex);
- ret = update_log_root(trans, log);
-
mutex_lock(&log_root_tree->log_mutex);
if (atomic_dec_and_test(&log_root_tree->log_writers)) {
/*
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index f446afada328..ab8a8c9c74f2 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -712,6 +712,12 @@ static void ceph_umount_begin(struct super_block *sb)
return;
}
+static int ceph_remount(struct super_block *sb, int *flags, char *data)
+{
+ sync_filesystem(sb);
+ return 0;
+}
+
static const struct super_operations ceph_super_ops = {
.alloc_inode = ceph_alloc_inode,
.destroy_inode = ceph_destroy_inode,
@@ -719,6 +725,7 @@ static const struct super_operations ceph_super_ops = {
.drop_inode = ceph_drop_inode,
.sync_fs = ceph_sync_fs,
.put_super = ceph_put_super,
+ .remount_fs = ceph_remount,
.show_options = ceph_show_options,
.statfs = ceph_statfs,
.umount_begin = ceph_umount_begin,
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 24b142569ca9..d0655ca89481 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -130,6 +130,12 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
ret = -EBUSY;
goto out;
}
+
+ if (new_min < old_min && new_max > old_max) {
+ ret = -EBUSY;
+ goto out;
+ }
+
}
cd->next = *cp;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 1904203566ae..5ec1662cfdd3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2829,7 +2829,9 @@ cifs_read_allocate_pages(struct cifs_readdata *rdata, unsigned int nr_pages)
}
if (rc) {
- for (i = 0; i < nr_pages; i++) {
+ unsigned int nr_page_failed = i;
+
+ for (i = 0; i < nr_page_failed; i++) {
put_page(rdata->pages[i]);
rdata->pages[i] = NULL;
}
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index eae3cdffaf7f..591c93de8c20 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1329,26 +1329,28 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
{
char message[5] = {0};
+ unsigned int new_oplock = 0;
oplock &= 0xFF;
if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
return;
- cinode->oplock = 0;
if (oplock & SMB2_LEASE_READ_CACHING_HE) {
- cinode->oplock |= CIFS_CACHE_READ_FLG;
+ new_oplock |= CIFS_CACHE_READ_FLG;
strcat(message, "R");
}
if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
- cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
+ new_oplock |= CIFS_CACHE_HANDLE_FLG;
strcat(message, "H");
}
if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
- cinode->oplock |= CIFS_CACHE_WRITE_FLG;
+ new_oplock |= CIFS_CACHE_WRITE_FLG;
strcat(message, "W");
}
- if (!cinode->oplock)
- strcat(message, "None");
+ if (!new_oplock)
+ strncpy(message, "None", sizeof(message));
+
+ cinode->oplock = new_oplock;
cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
&cinode->vfs_inode);
}
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index a7a1b218f308..8e709b641b55 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -58,15 +58,13 @@ static void configfs_d_iput(struct dentry * dentry,
if (sd) {
/* Coordinate with configfs_readdir */
spin_lock(&configfs_dirent_lock);
- /* Coordinate with configfs_attach_attr where will increase
- * sd->s_count and update sd->s_dentry to new allocated one.
- * Only set sd->dentry to null when this dentry is the only
- * sd owner.
- * If not do so, configfs_d_iput may run just after
- * configfs_attach_attr and set sd->s_dentry to null
- * even it's still in use.
+ /*
+ * Set sd->s_dentry to null only when this dentry is the one
+ * that is going to be killed. Otherwise configfs_d_iput may
+ * run just after configfs_attach_attr and set sd->s_dentry to
+ * NULL even it's still in use.
*/
- if (atomic_read(&sd->s_count) <= 2)
+ if (sd->s_dentry == dentry)
sd->s_dentry = NULL;
spin_unlock(&configfs_dirent_lock);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 4a0b3a521399..a88c1ed81411 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1049,6 +1049,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
__le32 border;
ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
int err = 0;
+ size_t ext_size = 0;
/* make decision: where to split? */
/* FIXME: now decision is simplest: at current extent */
@@ -1140,6 +1141,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
le16_add_cpu(&neh->eh_entries, m);
}
+ /* zero out unused area in the extent block */
+ ext_size = sizeof(struct ext4_extent_header) +
+ sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
+ memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
ext4_extent_block_csum_set(inode, neh);
set_buffer_uptodate(bh);
unlock_buffer(bh);
@@ -1219,6 +1224,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
sizeof(struct ext4_extent_idx) * m);
le16_add_cpu(&neh->eh_entries, m);
}
+ /* zero out unused area in the extent block */
+ ext_size = sizeof(struct ext4_extent_header) +
+ (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
+ memset(bh->b_data + ext_size, 0,
+ inode->i_sb->s_blocksize - ext_size);
ext4_extent_block_csum_set(inode, neh);
set_buffer_uptodate(bh);
unlock_buffer(bh);
@@ -1284,6 +1294,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
ext4_fsblk_t newblock, goal = 0;
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
int err = 0;
+ size_t ext_size = 0;
/* Try to prepend new index to old one */
if (ext_depth(inode))
@@ -1309,9 +1320,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
goto out;
}
+ ext_size = sizeof(EXT4_I(inode)->i_data);
/* move top-level index/leaf into new block */
- memmove(bh->b_data, EXT4_I(inode)->i_data,
- sizeof(EXT4_I(inode)->i_data));
+ memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
+ /* zero out unused area in the extent block */
+ memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
/* set size of new block */
neh = ext_block_hdr(bh);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 12ca9da02fdc..6691d42ede93 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5020,7 +5020,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
up_write(&EXT4_I(inode)->i_data_sem);
ext4_journal_stop(handle);
if (error) {
- if (orphan)
+ if (orphan && inode->i_nlink)
ext4_orphan_del(NULL, inode);
goto err_out;
}
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 49857101bb57..06ca0e647a97 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -577,7 +577,7 @@ group_add_out:
if (err == 0)
err = err2;
mnt_drop_write_file(filp);
- if (!err && (o_group > EXT4_SB(sb)->s_groups_count) &&
+ if (!err && (o_group < EXT4_SB(sb)->s_groups_count) &&
ext4_has_group_desc_csum(sb) &&
test_opt(sb, INIT_INODE_TABLE))
err = ext4_register_li_request(sb, o_group);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0ec3689a8990..9a652931eef8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3866,7 +3866,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"data=, fs mounted w/o journal");
goto failed_mount_wq;
}
- sbi->s_def_mount_opt &= EXT4_MOUNT_JOURNAL_CHECKSUM;
+ sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
clear_opt(sb, JOURNAL_CHECKSUM);
clear_opt(sb, DATA_FLAGS);
sbi->s_journal = NULL;
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index c31911203019..b3cd53acbcd4 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1329,10 +1329,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH))
__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
- /*
- * TODO: we count on fsck.f2fs to clear this flag until we figure out
- * missing cases which clear it incorrectly.
- */
+ else
+ __clear_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR))
__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ea83c4aa9b9d..ff908f108eca 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3173,10 +3173,7 @@ try_onemore:
#ifdef CONFIG_QUOTA
sb->dq_op = &f2fs_quota_operations;
- if (f2fs_sb_has_quota_ino(sbi))
- sb->s_qcop = &dquot_quotactl_sysfile_ops;
- else
- sb->s_qcop = &f2fs_quotactl_ops;
+ sb->s_qcop = &f2fs_quotactl_ops;
sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
if (f2fs_sb_has_quota_ino(sbi)) {
diff --git a/fs/fat/file.c b/fs/fat/file.c
index a08f1039909a..d3f655ae020b 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -156,12 +156,17 @@ static int fat_file_release(struct inode *inode, struct file *filp)
int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
{
struct inode *inode = filp->f_mapping->host;
- int res, err;
+ int err;
+
+ err = __generic_file_fsync(filp, start, end, datasync);
+ if (err)
+ return err;
- res = generic_file_fsync(filp, start, end, datasync);
err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
+ if (err)
+ return err;
- return res ? res : err;
+ return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
}
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 0fe11984db09..de1138e4b049 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -331,11 +331,22 @@ struct inode_switch_wbs_context {
struct work_struct work;
};
+static void bdi_down_write_wb_switch_rwsem(struct backing_dev_info *bdi)
+{
+ down_write(&bdi->wb_switch_rwsem);
+}
+
+static void bdi_up_write_wb_switch_rwsem(struct backing_dev_info *bdi)
+{
+ up_write(&bdi->wb_switch_rwsem);
+}
+
static void inode_switch_wbs_work_fn(struct work_struct *work)
{
struct inode_switch_wbs_context *isw =
container_of(work, struct inode_switch_wbs_context, work);
struct inode *inode = isw->inode;
+ struct backing_dev_info *bdi = inode_to_bdi(inode);
struct address_space *mapping = inode->i_mapping;
struct bdi_writeback *old_wb = inode->i_wb;
struct bdi_writeback *new_wb = isw->new_wb;
@@ -344,6 +355,12 @@ static void inode_switch_wbs_work_fn(struct work_struct *work)
void **slot;
/*
+ * If @inode switches cgwb membership while sync_inodes_sb() is
+ * being issued, sync_inodes_sb() might miss it. Synchronize.
+ */
+ down_read(&bdi->wb_switch_rwsem);
+
+ /*
* By the time control reaches here, RCU grace period has passed
* since I_WB_SWITCH assertion and all wb stat update transactions
* between unlocked_inode_to_wb_begin/end() are guaranteed to be
@@ -435,6 +452,8 @@ skip_switch:
spin_unlock(&new_wb->list_lock);
spin_unlock(&old_wb->list_lock);
+ up_read(&bdi->wb_switch_rwsem);
+
if (switched) {
wb_wakeup(new_wb);
wb_put(old_wb);
@@ -475,9 +494,18 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
if (inode->i_state & I_WB_SWITCH)
return;
+ /*
+ * Avoid starting new switches while sync_inodes_sb() is in
+ * progress. Otherwise, if the down_write protected issue path
+ * blocks heavily, we might end up starting a large number of
+ * switches which will block on the rwsem.
+ */
+ if (!down_read_trylock(&bdi->wb_switch_rwsem))
+ return;
+
isw = kzalloc(sizeof(*isw), GFP_ATOMIC);
if (!isw)
- return;
+ goto out_unlock;
/* find and pin the new wb */
rcu_read_lock();
@@ -502,8 +530,6 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
ihold(inode);
isw->inode = inode;
- atomic_inc(&isw_nr_in_flight);
-
/*
* In addition to synchronizing among switchers, I_WB_SWITCH tells
* the RCU protected stat update paths to grab the mapping's
@@ -511,12 +537,17 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
* Let's continue after I_WB_SWITCH is guaranteed to be visible.
*/
call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
- return;
+
+ atomic_inc(&isw_nr_in_flight);
+
+ goto out_unlock;
out_free:
if (isw->new_wb)
wb_put(isw->new_wb);
kfree(isw);
+out_unlock:
+ up_read(&bdi->wb_switch_rwsem);
}
/**
@@ -880,7 +911,11 @@ restart:
void cgroup_writeback_umount(void)
{
if (atomic_read(&isw_nr_in_flight)) {
- synchronize_rcu();
+ /*
+ * Use rcu_barrier() to wait for all pending callbacks to
+ * ensure that all in-flight wb switches are in the workqueue.
+ */
+ rcu_barrier();
flush_workqueue(isw_wq);
}
}
@@ -896,6 +931,9 @@ fs_initcall(cgroup_writeback_init);
#else /* CONFIG_CGROUP_WRITEBACK */
+static void bdi_down_write_wb_switch_rwsem(struct backing_dev_info *bdi) { }
+static void bdi_up_write_wb_switch_rwsem(struct backing_dev_info *bdi) { }
+
static struct bdi_writeback *
locked_inode_to_wb_and_lock_list(struct inode *inode)
__releases(&inode->i_lock)
@@ -2341,8 +2379,11 @@ void sync_inodes_sb(struct super_block *sb)
return;
WARN_ON(!rwsem_is_locked(&sb->s_umount));
+ /* protect against inode wb switch, see inode_switch_wbs_work_fn() */
+ bdi_down_write_wb_switch_rwsem(bdi);
bdi_split_work_to_wbs(bdi, &work, false);
wb_wait_for_completion(bdi, &done);
+ bdi_up_write_wb_switch_rwsem(bdi);
wait_sb_inodes(sb);
}
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 0fc9e87802b5..817e46537e3c 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1734,7 +1734,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
offset = outarg->offset & ~PAGE_CACHE_MASK;
file_size = i_size_read(inode);
- num = outarg->size;
+ num = min(outarg->size, fc->max_write);
if (outarg->offset > file_size)
num = 0;
else if (outarg->offset + num > file_size)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 690bbb22ed6b..56c9caa7b16a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -194,7 +194,9 @@ void fuse_finish_open(struct inode *inode, struct file *file)
file->f_op = &fuse_direct_io_file_operations;
if (!(ff->open_flags & FOPEN_KEEP_CACHE))
invalidate_inode_pages2(inode->i_mapping);
- if (ff->open_flags & FOPEN_NONSEEKABLE)
+ if (ff->open_flags & FOPEN_STREAM)
+ stream_open(inode, file);
+ else if (ff->open_flags & FOPEN_NONSEEKABLE)
nonseekable_open(inode, file);
if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
struct fuse_inode *fi = get_fuse_inode(inode);
@@ -1602,7 +1604,7 @@ __acquires(fc->lock)
{
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
- size_t crop = i_size_read(inode);
+ loff_t crop = i_size_read(inode);
struct fuse_req *req;
while (fi->writectr >= 0 && !list_empty(&fi->queued_writes)) {
@@ -3022,6 +3024,13 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
}
}
+ if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+ offset + length > i_size_read(inode)) {
+ err = inode_newsize_ok(inode, offset + length);
+ if (err)
+ goto out;
+ }
+
if (!(mode & FALLOC_FL_KEEP_SIZE))
set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 09a0cf5f3dd8..1eb737c466dd 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -136,22 +136,26 @@ static int demote_ok(const struct gfs2_glock *gl)
void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
{
+ if (!(gl->gl_ops->go_flags & GLOF_LRU))
+ return;
+
spin_lock(&lru_lock);
- if (!list_empty(&gl->gl_lru))
- list_del_init(&gl->gl_lru);
- else
+ list_del(&gl->gl_lru);
+ list_add_tail(&gl->gl_lru, &lru_list);
+
+ if (!test_bit(GLF_LRU, &gl->gl_flags)) {
+ set_bit(GLF_LRU, &gl->gl_flags);
atomic_inc(&lru_count);
+ }
- list_add_tail(&gl->gl_lru, &lru_list);
- set_bit(GLF_LRU, &gl->gl_flags);
spin_unlock(&lru_lock);
}
static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
{
spin_lock(&lru_lock);
- if (!list_empty(&gl->gl_lru)) {
+ if (test_bit(GLF_LRU, &gl->gl_flags)) {
list_del_init(&gl->gl_lru);
atomic_dec(&lru_count);
clear_bit(GLF_LRU, &gl->gl_flags);
@@ -1040,8 +1044,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
!test_bit(GLF_DEMOTE, &gl->gl_flags))
fast_path = 1;
}
- if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl) &&
- (glops->go_flags & GLOF_LRU))
+ if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl))
gfs2_glock_add_to_lru(gl);
trace_gfs2_glock_queue(gh, 0);
@@ -1341,6 +1344,7 @@ __acquires(&lru_lock)
if (!spin_trylock(&gl->gl_lockref.lock)) {
add_back_to_lru:
list_add(&gl->gl_lru, &lru_list);
+ set_bit(GLF_LRU, &gl->gl_flags);
atomic_inc(&lru_count);
continue;
}
@@ -1348,7 +1352,6 @@ add_back_to_lru:
spin_unlock(&gl->gl_lockref.lock);
goto add_back_to_lru;
}
- clear_bit(GLF_LRU, &gl->gl_flags);
gl->gl_lockref.count++;
if (demote_ok(gl))
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
@@ -1384,6 +1387,7 @@ static long gfs2_scan_glock_lru(int nr)
if (!test_bit(GLF_LOCK, &gl->gl_flags)) {
list_move(&gl->gl_lru, &dispose);
atomic_dec(&lru_count);
+ clear_bit(GLF_LRU, &gl->gl_flags);
freed++;
continue;
}
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 8b907c5cc913..3c3d037df824 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -32,9 +32,10 @@ extern struct workqueue_struct *gfs2_control_wq;
* @delta is the difference between the current rtt sample and the
* running average srtt. We add 1/8 of that to the srtt in order to
* update the current srtt estimate. The variance estimate is a bit
- * more complicated. We subtract the abs value of the @delta from
- * the current variance estimate and add 1/4 of that to the running
- * total.
+ * more complicated. We subtract the current variance estimate from
+ * the abs value of the @delta and add 1/4 of that to the running
+ * total. That's equivalent to 3/4 of the current variance
+ * estimate plus 1/4 of the abs of @delta.
*
* Note that the index points at the array entry containing the smoothed
* mean value, and the variance is always in the following entry
@@ -50,7 +51,7 @@ static inline void gfs2_update_stats(struct gfs2_lkstats *s, unsigned index,
s64 delta = sample - s->stats[index];
s->stats[index] += (delta >> 3);
index++;
- s->stats[index] += ((abs(delta) - s->stats[index]) >> 2);
+ s->stats[index] += (s64)(abs(delta) - s->stats[index]) >> 2;
}
/**
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 27c4e2ac39a9..937c6ee1786f 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -414,9 +414,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
if (next >= end)
break;
- hash = hugetlb_fault_mutex_hash(h, current->mm,
- &pseudo_vma,
- mapping, next, 0);
+ hash = hugetlb_fault_mutex_hash(h, mapping, next, 0);
mutex_lock(&hugetlb_fault_mutex_table[hash]);
lock_page(page);
@@ -569,7 +567,6 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
struct address_space *mapping = inode->i_mapping;
struct hstate *h = hstate_inode(inode);
struct vm_area_struct pseudo_vma;
- struct mm_struct *mm = current->mm;
loff_t hpage_size = huge_page_size(h);
unsigned long hpage_shift = huge_page_shift(h);
pgoff_t start, index, end;
@@ -633,8 +630,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
addr = index * hpage_size;
/* mutex taken here, fault path and hole punch */
- hash = hugetlb_fault_mutex_hash(h, mm, &pseudo_vma, mapping,
- index, addr);
+ hash = hugetlb_fault_mutex_hash(h, mapping, index, addr);
mutex_lock(&hugetlb_fault_mutex_table[hash]);
/* See if already present in mapping to avoid alloc/free */
diff --git a/fs/inode.c b/fs/inode.c
index 9f98d1d0769d..10015f17b8ea 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1745,8 +1745,13 @@ int file_remove_privs(struct file *file)
int kill;
int error = 0;
- /* Fast path for nothing security related */
- if (IS_NOSEC(inode))
+ /*
+ * Fast path for nothing security related.
+ * As well for non-regular files, e.g. blkdev inodes.
+ * For example, blkdev_write_iter() might get here
+ * trying to remove privs which it is not allowed to.
+ */
+ if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
return 0;
kill = dentry_needs_remove_privs(dentry);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 44f5cea49699..5be61affeefd 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -140,6 +140,10 @@ int nfs40_discover_server_trunking(struct nfs_client *clp,
/* Sustain the lease, even if it's empty. If the clientid4
* goes stale it's of no use for trunking discovery. */
nfs4_schedule_state_renewal(*result);
+
+ /* If the client state need to recover, do it. */
+ if (clp->cl_state)
+ nfs4_schedule_state_manager(clp);
}
out:
return status;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index fcfc48cbe136..128d6e216fd7 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -109,8 +109,11 @@ void nfsd_put_raparams(struct file *file, struct raparms *ra);
static inline int fh_want_write(struct svc_fh *fh)
{
- int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
+ int ret;
+ if (fh->fh_want_write)
+ return 0;
+ ret = mnt_want_write(fh->fh_export->ex_path.mnt);
if (!ret)
fh->fh_want_write = true;
return ret;
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 290373024d9d..e8ace3b54e9c 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -310,6 +310,18 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry,
out_attach:
spin_lock(&dentry_attach_lock);
+ if (unlikely(dentry->d_fsdata && !alias)) {
+ /* d_fsdata is set by a racing thread which is doing
+ * the same thing as this thread is doing. Leave the racing
+ * thread going ahead and we return here.
+ */
+ spin_unlock(&dentry_attach_lock);
+ iput(dl->dl_inode);
+ ocfs2_lock_res_free(&dl->dl_lockres);
+ kfree(dl);
+ return 0;
+ }
+
dentry->d_fsdata = dl;
dl->dl_count++;
spin_unlock(&dentry_attach_lock);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 3494e220b510..bed15dec3c16 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -148,16 +148,24 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
u64 blkno;
struct dentry *parent;
struct inode *dir = d_inode(child);
+ int set;
trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
(unsigned long long)OCFS2_I(dir)->ip_blkno);
+ status = ocfs2_nfs_sync_lock(OCFS2_SB(dir->i_sb), 1);
+ if (status < 0) {
+ mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
+ parent = ERR_PTR(status);
+ goto bail;
+ }
+
status = ocfs2_inode_lock(dir, NULL, 0);
if (status < 0) {
if (status != -ENOENT)
mlog_errno(status);
parent = ERR_PTR(status);
- goto bail;
+ goto unlock_nfs_sync;
}
status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
@@ -166,11 +174,31 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
goto bail_unlock;
}
+ status = ocfs2_test_inode_bit(OCFS2_SB(dir->i_sb), blkno, &set);
+ if (status < 0) {
+ if (status == -EINVAL) {
+ status = -ESTALE;
+ } else
+ mlog(ML_ERROR, "test inode bit failed %d\n", status);
+ parent = ERR_PTR(status);
+ goto bail_unlock;
+ }
+
+ trace_ocfs2_get_dentry_test_bit(status, set);
+ if (!set) {
+ status = -ESTALE;
+ parent = ERR_PTR(status);
+ goto bail_unlock;
+ }
+
parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
bail_unlock:
ocfs2_inode_unlock(dir, 0);
+unlock_nfs_sync:
+ ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
+
bail:
trace_ocfs2_get_parent_end(parent);
diff --git a/fs/open.c b/fs/open.c
index 1fd96c5d3895..e6a55dd45cba 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1165,3 +1165,21 @@ int nonseekable_open(struct inode *inode, struct file *filp)
}
EXPORT_SYMBOL(nonseekable_open);
+
+/*
+ * stream_open is used by subsystems that want stream-like file descriptors.
+ * Such file descriptors are not seekable and don't have notion of position
+ * (file.f_pos is always 0). Contrary to file descriptors of other regular
+ * files, .read() and .write() can run simultaneously.
+ *
+ * stream_open never fails and is marked to return int so that it could be
+ * directly used as file_operations.open .
+ */
+int stream_open(struct inode *inode, struct file *filp)
+{
+ filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS);
+ filp->f_mode |= FMODE_STREAM;
+ return 0;
+}
+
+EXPORT_SYMBOL(stream_open);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2ab31c134e62..1f29bf67e52e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3119,6 +3119,7 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_PROC_PAGE_MONITOR
REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
REG("smaps", S_IRUGO, proc_pid_smaps_operations),
+ REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
#ifdef CONFIG_SECURITY
@@ -3515,6 +3516,7 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_PROC_PAGE_MONITOR
REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
REG("smaps", S_IRUGO, proc_tid_smaps_operations),
+ REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
#ifdef CONFIG_SECURITY
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 1f01beda3bf3..2bfff313bf94 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -285,10 +285,12 @@ extern int proc_remount(struct super_block *, int *, char *);
/*
* task_[no]mmu.c
*/
+struct mem_size_stats;
struct proc_maps_private {
struct inode *inode;
struct task_struct *task;
struct mm_struct *mm;
+ struct mem_size_stats *rollup;
#ifdef CONFIG_MMU
struct vm_area_struct *tail_vma;
#endif
@@ -304,6 +306,7 @@ extern const struct file_operations proc_tid_maps_operations;
extern const struct file_operations proc_pid_numa_maps_operations;
extern const struct file_operations proc_tid_numa_maps_operations;
extern const struct file_operations proc_pid_smaps_operations;
+extern const struct file_operations proc_pid_smaps_rollup_operations;
extern const struct file_operations proc_tid_smaps_operations;
extern const struct file_operations proc_clear_refs_operations;
extern const struct file_operations proc_pagemap_operations;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 2df3b2358b0a..c3faa39c0ce1 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -290,6 +290,7 @@ static int proc_map_release(struct inode *inode, struct file *file)
if (priv->mm)
mmdrop(priv->mm);
+ kfree(priv->rollup);
return seq_release_private(inode, file);
}
@@ -316,6 +317,23 @@ static int is_stack(struct proc_maps_private *priv,
vma->vm_end >= vma->vm_mm->start_stack;
}
+static void show_vma_header_prefix(struct seq_file *m,
+ unsigned long start, unsigned long end,
+ vm_flags_t flags, unsigned long long pgoff,
+ dev_t dev, unsigned long ino)
+{
+ seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
+ seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
+ start,
+ end,
+ flags & VM_READ ? 'r' : '-',
+ flags & VM_WRITE ? 'w' : '-',
+ flags & VM_EXEC ? 'x' : '-',
+ flags & VM_MAYSHARE ? 's' : 'p',
+ pgoff,
+ MAJOR(dev), MINOR(dev), ino);
+}
+
static void
show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
{
@@ -339,17 +357,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
/* We don't show the stack guard page in /proc/maps */
start = vma->vm_start;
end = vma->vm_end;
-
- seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
- seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
- start,
- end,
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
- flags & VM_MAYSHARE ? 's' : 'p',
- pgoff,
- MAJOR(dev), MINOR(dev), ino);
+ show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino);
/*
* Print the dentry name for named mappings, and a
@@ -474,6 +482,7 @@ const struct file_operations proc_tid_maps_operations = {
#ifdef CONFIG_PROC_PAGE_MONITOR
struct mem_size_stats {
+ bool first;
unsigned long resident;
unsigned long shared_clean;
unsigned long shared_dirty;
@@ -485,7 +494,9 @@ struct mem_size_stats {
unsigned long swap;
unsigned long shared_hugetlb;
unsigned long private_hugetlb;
+ unsigned long first_vma_start;
u64 pss;
+ u64 pss_locked;
u64 swap_pss;
};
@@ -695,69 +706,105 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
static int show_smap(struct seq_file *m, void *v, int is_pid)
{
+ struct proc_maps_private *priv = m->private;
struct vm_area_struct *vma = v;
- struct mem_size_stats mss;
+ struct mem_size_stats mss_stack;
+ struct mem_size_stats *mss;
struct mm_walk smaps_walk = {
.pmd_entry = smaps_pte_range,
#ifdef CONFIG_HUGETLB_PAGE
.hugetlb_entry = smaps_hugetlb_range,
#endif
.mm = vma->vm_mm,
- .private = &mss,
};
+ int ret = 0;
+ bool rollup_mode;
+ bool last_vma;
+
+ if (priv->rollup) {
+ rollup_mode = true;
+ mss = priv->rollup;
+ if (mss->first) {
+ mss->first_vma_start = vma->vm_start;
+ mss->first = false;
+ }
+ last_vma = !m_next_vma(priv, vma);
+ } else {
+ rollup_mode = false;
+ memset(&mss_stack, 0, sizeof(mss_stack));
+ mss = &mss_stack;
+ }
+
+ smaps_walk.private = mss;
- memset(&mss, 0, sizeof mss);
/* mmap_sem is held in m_start */
walk_page_vma(vma, &smaps_walk);
+ if (vma->vm_flags & VM_LOCKED)
+ mss->pss_locked += mss->pss;
+
+ if (!rollup_mode) {
+ show_map_vma(m, vma, is_pid);
+ } else if (last_vma) {
+ show_vma_header_prefix(
+ m, mss->first_vma_start, vma->vm_end, 0, 0, 0, 0);
+ seq_pad(m, ' ');
+ seq_puts(m, "[rollup]\n");
+ } else {
+ ret = SEQ_SKIP;
+ }
- show_map_vma(m, vma, is_pid);
-
- if (vma_get_anon_name(vma)) {
+ if (!rollup_mode && vma_get_anon_name(vma)) {
seq_puts(m, "Name: ");
seq_print_vma_name(m, vma);
seq_putc(m, '\n');
}
- seq_printf(m,
- "Size: %8lu kB\n"
- "Rss: %8lu kB\n"
- "Pss: %8lu kB\n"
- "Shared_Clean: %8lu kB\n"
- "Shared_Dirty: %8lu kB\n"
- "Private_Clean: %8lu kB\n"
- "Private_Dirty: %8lu kB\n"
- "Referenced: %8lu kB\n"
- "Anonymous: %8lu kB\n"
- "AnonHugePages: %8lu kB\n"
- "Shared_Hugetlb: %8lu kB\n"
- "Private_Hugetlb: %7lu kB\n"
- "Swap: %8lu kB\n"
- "SwapPss: %8lu kB\n"
- "KernelPageSize: %8lu kB\n"
- "MMUPageSize: %8lu kB\n"
- "Locked: %8lu kB\n",
- (vma->vm_end - vma->vm_start) >> 10,
- mss.resident >> 10,
- (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
- mss.shared_clean >> 10,
- mss.shared_dirty >> 10,
- mss.private_clean >> 10,
- mss.private_dirty >> 10,
- mss.referenced >> 10,
- mss.anonymous >> 10,
- mss.anonymous_thp >> 10,
- mss.shared_hugetlb >> 10,
- mss.private_hugetlb >> 10,
- mss.swap >> 10,
- (unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)),
- vma_kernel_pagesize(vma) >> 10,
- vma_mmu_pagesize(vma) >> 10,
- (vma->vm_flags & VM_LOCKED) ?
- (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0);
-
- show_smap_vma_flags(m, vma);
+ if (!rollup_mode)
+ seq_printf(m,
+ "Size: %8lu kB\n"
+ "KernelPageSize: %8lu kB\n"
+ "MMUPageSize: %8lu kB\n",
+ (vma->vm_end - vma->vm_start) >> 10,
+ vma_kernel_pagesize(vma) >> 10,
+ vma_mmu_pagesize(vma) >> 10);
+
+
+ if (!rollup_mode || last_vma)
+ seq_printf(m,
+ "Rss: %8lu kB\n"
+ "Pss: %8lu kB\n"
+ "Shared_Clean: %8lu kB\n"
+ "Shared_Dirty: %8lu kB\n"
+ "Private_Clean: %8lu kB\n"
+ "Private_Dirty: %8lu kB\n"
+ "Referenced: %8lu kB\n"
+ "Anonymous: %8lu kB\n"
+ "AnonHugePages: %8lu kB\n"
+ "Shared_Hugetlb: %8lu kB\n"
+ "Private_Hugetlb: %7lu kB\n"
+ "Swap: %8lu kB\n"
+ "SwapPss: %8lu kB\n"
+ "Locked: %8lu kB\n",
+ mss->resident >> 10,
+ (unsigned long)(mss->pss >> (10 + PSS_SHIFT)),
+ mss->shared_clean >> 10,
+ mss->shared_dirty >> 10,
+ mss->private_clean >> 10,
+ mss->private_dirty >> 10,
+ mss->referenced >> 10,
+ mss->anonymous >> 10,
+ mss->anonymous_thp >> 10,
+ mss->shared_hugetlb >> 10,
+ mss->private_hugetlb >> 10,
+ mss->swap >> 10,
+ (unsigned long)(mss->swap_pss >> (10 + PSS_SHIFT)),
+ (unsigned long)(mss->pss >> (10 + PSS_SHIFT)));
+
+ if (!rollup_mode) {
+ show_smap_vma_flags(m, vma);
+ }
m_cache_vma(m, vma);
- return 0;
+ return ret;
}
static int show_pid_smap(struct seq_file *m, void *v)
@@ -789,6 +836,25 @@ static int pid_smaps_open(struct inode *inode, struct file *file)
return do_maps_open(inode, file, &proc_pid_smaps_op);
}
+static int pid_smaps_rollup_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct proc_maps_private *priv;
+ int ret = do_maps_open(inode, file, &proc_pid_smaps_op);
+
+ if (ret < 0)
+ return ret;
+ seq = file->private_data;
+ priv = seq->private;
+ priv->rollup = kzalloc(sizeof(*priv->rollup), GFP_KERNEL);
+ if (!priv->rollup) {
+ proc_map_release(inode, file);
+ return -ENOMEM;
+ }
+ priv->rollup->first = true;
+ return 0;
+}
+
static int tid_smaps_open(struct inode *inode, struct file *file)
{
return do_maps_open(inode, file, &proc_tid_smaps_op);
@@ -801,6 +867,13 @@ const struct file_operations proc_pid_smaps_operations = {
.release = proc_map_release,
};
+const struct file_operations proc_pid_smaps_rollup_operations = {
+ .open = pid_smaps_rollup_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = proc_map_release,
+};
+
const struct file_operations proc_tid_smaps_operations = {
.open = tid_smaps_open,
.read = seq_read,
@@ -1011,6 +1084,24 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
continue;
up_read(&mm->mmap_sem);
down_write(&mm->mmap_sem);
+ /*
+ * Avoid to modify vma->vm_flags
+ * without locked ops while the
+ * coredump reads the vm_flags.
+ */
+ if (!mmget_still_valid(mm)) {
+ /*
+ * Silently return "count"
+ * like if get_task_mm()
+ * failed. FIXME: should this
+ * function have returned
+ * -ESRCH if get_task_mm()
+ * failed like if
+ * get_proc_task() fails?
+ */
+ up_write(&mm->mmap_sem);
+ goto out_mm;
+ }
for (vma = mm->mmap; vma; vma = vma->vm_next) {
vma->vm_flags &= ~VM_SOFTDIRTY;
vma_set_page_prot(vma);
diff --git a/fs/read_write.c b/fs/read_write.c
index 16e554ba885d..7b175b9134ec 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -553,12 +553,13 @@ EXPORT_SYMBOL(vfs_write);
static inline loff_t file_pos_read(struct file *file)
{
- return file->f_pos;
+ return file->f_mode & FMODE_STREAM ? 0 : file->f_pos;
}
static inline void file_pos_write(struct file *file, loff_t pos)
{
- file->f_pos = pos;
+ if ((file->f_mode & FMODE_STREAM) == 0)
+ file->f_pos = pos;
}
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c
index 7693b0e8efef..45cfa73b285e 100644
--- a/fs/sdcardfs/super.c
+++ b/fs/sdcardfs/super.c
@@ -313,6 +313,8 @@ static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
if (opts->nocache)
seq_printf(m, ",nocache");
+ if (opts->unshared_obb)
+ seq_printf(m, ",unshared_obb");
return 0;
};
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 3f9463f8cf2f..f877d5cadd98 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -228,7 +228,7 @@ ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode)
case UFS_UID_44BSD:
return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid);
case UFS_UID_EFT:
- if (inode->ui_u1.oldids.ui_suid == 0xFFFF)
+ if (inode->ui_u1.oldids.ui_sgid == 0xFFFF)
return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
/* Fall through */
default:
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index e7cc0d860499..08cc09b999fd 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -137,7 +137,7 @@ static void userfaultfd_ctx_put(struct userfaultfd_ctx *ctx)
VM_BUG_ON(waitqueue_active(&ctx->fault_wqh));
VM_BUG_ON(spin_is_locked(&ctx->fd_wqh.lock));
VM_BUG_ON(waitqueue_active(&ctx->fd_wqh));
- mmput(ctx->mm);
+ mmdrop(ctx->mm);
kmem_cache_free(userfaultfd_ctx_cachep, ctx);
}
}
@@ -434,6 +434,9 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
ACCESS_ONCE(ctx->released) = true;
+ if (!mmget_not_zero(mm))
+ goto wakeup;
+
/*
* Flush page faults out of all CPUs. NOTE: all page faults
* must be retried without returning VM_FAULT_SIGBUS if
@@ -443,6 +446,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
* taking the mmap_sem for writing.
*/
down_write(&mm->mmap_sem);
+ if (!mmget_still_valid(mm))
+ goto skip_mm;
prev = NULL;
for (vma = mm->mmap; vma; vma = vma->vm_next) {
cond_resched();
@@ -466,8 +471,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
vma->vm_flags = new_flags;
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
}
+skip_mm:
up_write(&mm->mmap_sem);
-
+ mmput(mm);
+wakeup:
/*
* After no new page faults can wait on this fault_*wqh, flush
* the last page faults that may have been already waiting on
@@ -761,10 +768,14 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
start = uffdio_register.range.start;
end = start + uffdio_register.range.len;
+ ret = -ENOMEM;
+ if (!mmget_not_zero(mm))
+ goto out;
+
down_write(&mm->mmap_sem);
+ if (!mmget_still_valid(mm))
+ goto out_unlock;
vma = find_vma_prev(mm, start, &prev);
-
- ret = -ENOMEM;
if (!vma)
goto out_unlock;
@@ -879,6 +890,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
} while (vma && vma->vm_start < end);
out_unlock:
up_write(&mm->mmap_sem);
+ mmput(mm);
if (!ret) {
/*
* Now that we scanned all vmas we can already tell
@@ -917,10 +929,14 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
start = uffdio_unregister.start;
end = start + uffdio_unregister.len;
+ ret = -ENOMEM;
+ if (!mmget_not_zero(mm))
+ goto out;
+
down_write(&mm->mmap_sem);
+ if (!mmget_still_valid(mm))
+ goto out_unlock;
vma = find_vma_prev(mm, start, &prev);
-
- ret = -ENOMEM;
if (!vma)
goto out_unlock;
@@ -1015,6 +1031,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
} while (vma && vma->vm_start < end);
out_unlock:
up_write(&mm->mmap_sem);
+ mmput(mm);
out:
return ret;
}
@@ -1084,9 +1101,11 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
goto out;
if (uffdio_copy.mode & ~UFFDIO_COPY_MODE_DONTWAKE)
goto out;
-
- ret = mcopy_atomic(ctx->mm, uffdio_copy.dst, uffdio_copy.src,
- uffdio_copy.len);
+ if (mmget_not_zero(ctx->mm)) {
+ ret = mcopy_atomic(ctx->mm, uffdio_copy.dst, uffdio_copy.src,
+ uffdio_copy.len);
+ mmput(ctx->mm);
+ }
if (unlikely(put_user(ret, &user_uffdio_copy->copy)))
return -EFAULT;
if (ret < 0)
@@ -1127,8 +1146,11 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
if (uffdio_zeropage.mode & ~UFFDIO_ZEROPAGE_MODE_DONTWAKE)
goto out;
- ret = mfill_zeropage(ctx->mm, uffdio_zeropage.range.start,
- uffdio_zeropage.range.len);
+ if (mmget_not_zero(ctx->mm)) {
+ ret = mfill_zeropage(ctx->mm, uffdio_zeropage.range.start,
+ uffdio_zeropage.range.len);
+ mmput(ctx->mm);
+ }
if (unlikely(put_user(ret, &user_uffdio_zeropage->zeropage)))
return -EFAULT;
if (ret < 0)
@@ -1306,12 +1328,12 @@ static struct file *userfaultfd_file_create(int flags)
ctx->released = false;
ctx->mm = current->mm;
/* prevent the mm struct to be freed */
- atomic_inc(&ctx->mm->mm_users);
+ atomic_inc(&ctx->mm->mm_count);
file = anon_inode_getfile("[userfaultfd]", &userfaultfd_fops, ctx,
O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS));
if (IS_ERR(file)) {
- mmput(ctx->mm);
+ mmdrop(ctx->mm);
kmem_cache_free(userfaultfd_ctx_cachep, ctx);
}
out:
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h
index a6296c2ffd93..b90dff08edb0 100644
--- a/include/linux/backing-dev-defs.h
+++ b/include/linux/backing-dev-defs.h
@@ -160,6 +160,7 @@ struct backing_dev_info {
struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
struct rb_root cgwb_congested_tree; /* their congested states */
atomic_t usage_cnt; /* counts both cgwbs and cgwb_contested's */
+ struct rw_semaphore wb_switch_rwsem; /* no cgwb switch while syncing */
#else
struct bdi_writeback_congested *wb_congested;
#endif
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 42e4e3cbb001..0ffb9a397620 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -290,7 +290,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned int count)
{
if (count != 1) {
bio->bi_flags |= (1 << BIO_REFFED);
- smp_mb__before_atomic();
+ smp_mb();
}
atomic_set(&bio->__bi_cnt, count);
}
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index e76d03f44c80..83edade218fa 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -68,7 +68,7 @@ static __always_inline unsigned long hweight_long(unsigned long w)
*/
static inline __u64 rol64(__u64 word, unsigned int shift)
{
- return (word << shift) | (word >> (64 - shift));
+ return (word << (shift & 63)) | (word >> ((-shift) & 63));
}
/**
@@ -78,7 +78,7 @@ static inline __u64 rol64(__u64 word, unsigned int shift)
*/
static inline __u64 ror64(__u64 word, unsigned int shift)
{
- return (word >> shift) | (word << (64 - shift));
+ return (word >> (shift & 63)) | (word << ((-shift) & 63));
}
/**
@@ -88,7 +88,7 @@ static inline __u64 ror64(__u64 word, unsigned int shift)
*/
static inline __u32 rol32(__u32 word, unsigned int shift)
{
- return (word << shift) | (word >> ((-shift) & 31));
+ return (word << (shift & 31)) | (word >> ((-shift) & 31));
}
/**
@@ -98,7 +98,7 @@ static inline __u32 rol32(__u32 word, unsigned int shift)
*/
static inline __u32 ror32(__u32 word, unsigned int shift)
{
- return (word >> shift) | (word << (32 - shift));
+ return (word >> (shift & 31)) | (word << ((-shift) & 31));
}
/**
@@ -108,7 +108,7 @@ static inline __u32 ror32(__u32 word, unsigned int shift)
*/
static inline __u16 rol16(__u16 word, unsigned int shift)
{
- return (word << shift) | (word >> (16 - shift));
+ return (word << (shift & 15)) | (word >> ((-shift) & 15));
}
/**
@@ -118,7 +118,7 @@ static inline __u16 rol16(__u16 word, unsigned int shift)
*/
static inline __u16 ror16(__u16 word, unsigned int shift)
{
- return (word >> shift) | (word << (16 - shift));
+ return (word >> (shift & 15)) | (word << ((-shift) & 15));
}
/**
@@ -128,7 +128,7 @@ static inline __u16 ror16(__u16 word, unsigned int shift)
*/
static inline __u8 rol8(__u8 word, unsigned int shift)
{
- return (word << shift) | (word >> (8 - shift));
+ return (word << (shift & 7)) | (word >> ((-shift) & 7));
}
/**
@@ -138,7 +138,7 @@ static inline __u8 rol8(__u8 word, unsigned int shift)
*/
static inline __u8 ror8(__u8 word, unsigned int shift)
{
- return (word >> shift) | (word << (8 - shift));
+ return (word >> (shift & 7)) | (word << ((-shift) & 7));
}
/**
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 210ccc4ea44b..8607c937145f 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -453,7 +453,7 @@ static inline struct cgroup_subsys_state *task_css(struct task_struct *task,
*
* Find the css for the (@task, @subsys_id) combination, increment a
* reference on and return it. This function is guaranteed to return a
- * valid css.
+ * valid css. The returned css may already have been offlined.
*/
static inline struct cgroup_subsys_state *
task_get_css(struct task_struct *task, int subsys_id)
@@ -463,7 +463,13 @@ task_get_css(struct task_struct *task, int subsys_id)
rcu_read_lock();
while (true) {
css = task_css(task, subsys_id);
- if (likely(css_tryget_online(css)))
+ /*
+ * Can't use css_tryget_online() here. A task which has
+ * PF_EXITING set may stay associated with an offline css.
+ * If such task calls this function, css_tryget_online()
+ * will keep failing.
+ */
+ if (likely(css_tryget(css)))
break;
cpu_relax();
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8f4c3ec25662..fa88c73f40fb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -143,6 +143,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate);
/* Has write method(s) */
#define FMODE_CAN_WRITE ((__force fmode_t)0x40000)
+/* File is stream-like */
+#define FMODE_STREAM ((__force fmode_t)0x200000)
+
/* File was opened by fanotify and shouldn't generate fanotify events */
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
@@ -2771,6 +2774,7 @@ extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
int whence, loff_t size);
extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
+extern int stream_open(struct inode * inode, struct file * filp);
#ifdef CONFIG_BLOCK
typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d16de62231d3..5f1e901353ed 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -378,6 +378,7 @@ struct hid_global {
struct hid_local {
unsigned usage[HID_MAX_USAGES]; /* usage array */
+ u8 usage_size[HID_MAX_USAGES]; /* usage size array */
unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
unsigned usage_index;
unsigned usage_minimum;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index ac19fa4829aa..b71d142a93f3 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -91,9 +91,7 @@ void putback_active_hugepage(struct page *page);
void free_huge_page(struct page *page);
void hugetlb_fix_reserve_counts(struct inode *inode, bool restore_reserve);
extern struct mutex *hugetlb_fault_mutex_table;
-u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm,
- struct vm_area_struct *vma,
- struct address_space *mapping,
+u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping,
pgoff_t idx, unsigned long address);
pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud);
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h
index 6cc48ac55fd2..40b14736c73d 100644
--- a/include/linux/iio/adc/ad_sigma_delta.h
+++ b/include/linux/iio/adc/ad_sigma_delta.h
@@ -66,6 +66,7 @@ struct ad_sigma_delta {
bool irq_dis;
bool bus_locked;
+ bool keep_cs_asserted;
uint8_t comm;
diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h
index 743b34f56f2b..f9a8889e134a 100644
--- a/include/linux/list_lru.h
+++ b/include/linux/list_lru.h
@@ -51,6 +51,7 @@ struct list_lru {
struct list_lru_node *node;
#ifdef CONFIG_MEMCG_KMEM
struct list_head list;
+ bool memcg_aware;
#endif
};
diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
index 2e0ba6d5fbc3..f97173bef581 100644
--- a/include/linux/mfd/da9063/registers.h
+++ b/include/linux/mfd/da9063/registers.h
@@ -215,9 +215,9 @@
/* DA9063 Configuration registers */
/* OTP */
-#define DA9063_REG_OPT_COUNT 0x101
-#define DA9063_REG_OPT_ADDR 0x102
-#define DA9063_REG_OPT_DATA 0x103
+#define DA9063_REG_OTP_CONT 0x101
+#define DA9063_REG_OTP_ADDR 0x102
+#define DA9063_REG_OTP_DATA 0x103
/* Customer Trim and Configuration */
#define DA9063_REG_T_OFFSET 0x104
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 47c7bb494c74..ecdabf3597ae 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1115,6 +1115,27 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address,
void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
unsigned long start, unsigned long end);
+/*
+ * This has to be called after a get_task_mm()/mmget_not_zero()
+ * followed by taking the mmap_sem for writing before modifying the
+ * vmas or anything the coredump pretends not to change from under it.
+ *
+ * NOTE: find_extend_vma() called from GUP context is the only place
+ * that can modify the "mm" (notably the vm_start/end) under mmap_sem
+ * for reading and outside the context of the process, so it is also
+ * the only case that holds the mmap_sem for reading that must call
+ * this function. Generally if the mmap_sem is hold for reading
+ * there's no need of this check after get_task_mm()/mmget_not_zero().
+ *
+ * This function can be obsoleted and the check can be removed, after
+ * the coredump code will hold the mmap_sem for writing before
+ * invoking the ->core_dump methods.
+ */
+static inline bool mmget_still_valid(struct mm_struct *mm)
+{
+ return likely(!mm->core_state);
+}
+
/**
* mm_walk - callbacks for walk_page_range
* @pmd_entry: if set, called for each non-empty PMD (3rd-level) entry
diff --git a/include/linux/of.h b/include/linux/of.h
index d9371c9cd88a..2772f027f88f 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -199,8 +199,8 @@ extern struct device_node *of_find_all_nodes(struct device_node *prev);
static inline u64 of_read_number(const __be32 *cell, int size)
{
u64 r = 0;
- while (size--)
- r = (r << 32) | be32_to_cpu(*(cell++));
+ for (; size--; cell++)
+ r = (r << 32) | be32_to_cpu(*cell);
return r;
}
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index aa8736d5b2f3..cfc3ed46cad2 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -331,7 +331,6 @@ static inline void pwm_remove_table(struct pwm_lookup *table, size_t num)
#ifdef CONFIG_PWM_SYSFS
void pwmchip_sysfs_export(struct pwm_chip *chip);
void pwmchip_sysfs_unexport(struct pwm_chip *chip);
-void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
#else
static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
{
@@ -340,10 +339,6 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
{
}
-
-static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
-{
-}
#endif /* CONFIG_PWM_SYSFS */
#endif /* __LINUX_PWM_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index a0189ba67fde..addd03641e1a 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -297,14 +297,12 @@ void synchronize_rcu(void);
static inline void __rcu_read_lock(void)
{
- if (IS_ENABLED(CONFIG_PREEMPT_COUNT))
- preempt_disable();
+ preempt_disable();
}
static inline void __rcu_read_unlock(void)
{
- if (IS_ENABLED(CONFIG_PREEMPT_COUNT))
- preempt_enable();
+ preempt_enable();
}
static inline void synchronize_rcu(void)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4b0047a30b72..cb0e7af8b169 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -384,7 +384,7 @@ extern int lockdep_tasklist_lock_is_held(void);
extern void sched_init(void);
extern void sched_init_smp(void);
extern asmlinkage void schedule_tail(struct task_struct *prev);
-extern void init_idle(struct task_struct *idle, int cpu, bool hotplug);
+extern void init_idle(struct task_struct *idle, int cpu);
extern void init_idle_bootup_task(struct task_struct *idle);
extern cpumask_var_t cpu_isolated_map;
@@ -3026,12 +3026,17 @@ extern struct mm_struct * mm_alloc(void);
/* mmdrop drops the mm and the page tables */
extern void __mmdrop(struct mm_struct *);
-static inline void mmdrop(struct mm_struct * mm)
+static inline void mmdrop(struct mm_struct *mm)
{
if (unlikely(atomic_dec_and_test(&mm->mm_count)))
__mmdrop(mm);
}
+static inline bool mmget_not_zero(struct mm_struct *mm)
+{
+ return atomic_inc_not_zero(&mm->mm_users);
+}
+
/* mmput gets rid of the mappings and all user-space */
extern int mmput(struct mm_struct *);
/* same as above but performs the slow path from the async kontext. Can
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 502787c29ce9..a2f12d377d23 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3664,5 +3664,35 @@ static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
return hdr_len + skb_gso_transport_seglen(skb);
}
+/**
+ * skb_gso_mac_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_mac_seglen is used to determine the real size of the
+ * individual segments, including MAC/L2, Layer3 (IP, IPv6) and L4
+ * headers (TCP/UDP).
+ */
+static inline unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
+{
+ unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
+ return hdr_len + skb_gso_transport_seglen(skb);
+}
+
+/**
+ * skb_gso_validate_mac_len - Will a split GSO skb fit in a given length?
+ *
+ * @skb: GSO skb
+ * @len: length to validate against
+ *
+ * skb_gso_validate_mac_len validates if a given skb will fit a wanted
+ * length once split, including L2, L3 and L4 headers and the payload.
+ */
+static inline bool
+skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len)
+{
+ return skb_gso_mac_seglen(skb) <= len;
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h
index 12910cf19869..12a4b09f4d08 100644
--- a/include/linux/smpboot.h
+++ b/include/linux/smpboot.h
@@ -30,7 +30,7 @@ struct smpboot_thread_data;
* @thread_comm: The base name of the thread
*/
struct smp_hotplug_thread {
- struct task_struct __percpu **store;
+ struct task_struct * __percpu *store;
struct list_head list;
int (*thread_should_run)(unsigned int cpu);
void (*thread_fn)(unsigned int cpu);
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 747404dbe506..085da1707cea 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -419,4 +419,7 @@ static inline void tcp_saved_syn_free(struct tcp_sock *tp)
tp->saved_syn = NULL;
}
+int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount,
+ int shiftlen);
+
#endif /* _LINUX_TCP_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 2bf825f5b711..b661b6e3496b 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -778,7 +778,9 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
*/
static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
{
- return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize));
+ int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc) & 0x7ff;
+
+ return round_up(len, max_packet_size);
}
/**
diff --git a/include/net/arp.h b/include/net/arp.h
index 1b3f86981757..92d2f7d7d1cb 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -17,6 +17,7 @@ static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32
return val * hash_rnd[0];
}
+#ifdef CONFIG_INET
static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
{
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
@@ -24,6 +25,13 @@ static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev
return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev);
}
+#else
+static inline
+struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
+{
+ return NULL;
+}
+#endif
static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key)
{
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7c0c83dfe86e..876688b5a356 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -174,9 +174,6 @@ 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/netns/ipv4.h b/include/net/netns/ipv4.h
index c68926b4899c..61c38f87ea07 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -88,6 +88,7 @@ struct netns_ipv4 {
int sysctl_tcp_fwmark_accept;
int sysctl_tcp_mtu_probing;
int sysctl_tcp_base_mss;
+ int sysctl_tcp_min_snd_mss;
int sysctl_tcp_probe_threshold;
u32 sysctl_tcp_probe_interval;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index dd161b625cd7..b9b5bc27b844 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -54,6 +54,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
#define MAX_TCP_HEADER (128 + MAX_HEADER)
#define MAX_TCP_OPTION_SPACE 40
+#define TCP_MIN_SND_MSS 48
+#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)
/*
* Never offer a window over 32767 without using window scaling. Some
diff --git a/include/trace/events/msm_cam.h b/include/trace/events/msm_cam.h
index b52845407ef0..b0dc7eac8b7a 100644
--- a/include/trace/events/msm_cam.h
+++ b/include/trace/events/msm_cam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 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
@@ -131,6 +131,34 @@ TRACE_EVENT(msm_cam_ping_pong_debug_dump,
)
);
+TRACE_EVENT(msm_cam_isp_status_dump,
+ TP_PROTO(char *event, uint32_t vfe_id, uint32_t frame_id,
+ uint32_t irq_status0, uint32_t irq_status1),
+ TP_ARGS(event, vfe_id, frame_id, irq_status0,
+ irq_status1),
+ TP_STRUCT__entry(
+ __field(char *, event)
+ __field(unsigned int, vfe_id)
+ __field(unsigned int, frame_id)
+ __field(unsigned int, irq_status0)
+ __field(unsigned int, irq_status1)
+ ),
+ TP_fast_assign(
+ __entry->event = event;
+ __entry->vfe_id = vfe_id;
+ __entry->frame_id = frame_id;
+ __entry->irq_status0 = irq_status0;
+ __entry->irq_status1 = irq_status1;
+ ),
+ TP_printk("%s vfe %d, frame %d, irq_st0 %x, irq_st1 %x\n",
+ __entry->event,
+ __entry->vfe_id,
+ __entry->frame_id,
+ __entry->irq_status0,
+ __entry->irq_status1
+ )
+);
+
#endif /* _MSM_CAM_TRACE_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 8a702e7b3f71..5846f050e90f 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -205,10 +205,12 @@ struct fuse_file_lock {
* FOPEN_DIRECT_IO: bypass page cache for this open file
* FOPEN_KEEP_CACHE: don't invalidate the data cache on open
* FOPEN_NONSEEKABLE: the file is not seekable
+ * FOPEN_STREAM: the file is stream-like (no file position at all)
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#define FOPEN_NONSEEKABLE (1 << 2)
+#define FOPEN_STREAM (1 << 4)
/**
* INIT request/reply flags
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index 9de808ebce05..422183f396d5 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -281,6 +281,7 @@ enum
LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */
LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */
LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */
+ LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */
__LINUX_MIB_MAX
};
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 087b0ef82c07..bbebd258cf07 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -301,8 +301,10 @@ static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len)
tlv_ptr = (struct tlv_desc *)tlv;
tlv_ptr->tlv_type = htons(type);
tlv_ptr->tlv_len = htons(tlv_len);
- if (len && data)
- memcpy(TLV_DATA(tlv_ptr), data, tlv_len);
+ if (len && data) {
+ memcpy(TLV_DATA(tlv_ptr), data, len);
+ memset(TLV_DATA(tlv_ptr) + len, 0, TLV_SPACE(len) - tlv_len);
+ }
return TLV_SPACE(len);
}
@@ -399,8 +401,10 @@ static inline int TCM_SET(void *msg, __u16 cmd, __u16 flags,
tcm_hdr->tcm_len = htonl(msg_len);
tcm_hdr->tcm_type = htons(cmd);
tcm_hdr->tcm_flags = htons(flags);
- if (data_len && data)
+ if (data_len && data) {
memcpy(TCM_DATA(msg), data, data_len);
+ memset(TCM_DATA(msg) + data_len, 0, TCM_SPACE(data_len) - msg_len);
+ }
return TCM_SPACE(data_len);
}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 46436543ad28..598b8bf8d80c 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -373,7 +373,8 @@ static void mqueue_evict_inode(struct inode *inode)
struct user_struct *user;
unsigned long mq_bytes, mq_treesize;
struct ipc_namespace *ipc_ns;
- struct msg_msg *msg;
+ struct msg_msg *msg, *nmsg;
+ LIST_HEAD(tmp_msg);
clear_inode(inode);
@@ -384,10 +385,15 @@ static void mqueue_evict_inode(struct inode *inode)
info = MQUEUE_I(inode);
spin_lock(&info->lock);
while ((msg = msg_get(info)) != NULL)
- free_msg(msg);
+ list_add_tail(&msg->m_list, &tmp_msg);
kfree(info->node_cache);
spin_unlock(&info->lock);
+ list_for_each_entry_safe(msg, nmsg, &tmp_msg, m_list) {
+ list_del(&msg->m_list);
+ free_msg(msg);
+ }
+
/* Total amount of bytes accounted for the mqueue */
mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) +
min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) *
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index ed81aafd2392..9467307487f7 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -18,6 +18,7 @@
#include <linux/utsname.h>
#include <linux/proc_ns.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
#include "util.h"
@@ -66,6 +67,9 @@ static struct msg_msg *alloc_msg(size_t len)
pseg = &msg->next;
while (len > 0) {
struct msg_msgseg *seg;
+
+ cond_resched();
+
alen = min(len, DATALEN_SEG);
seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL);
if (seg == NULL)
@@ -178,6 +182,8 @@ void free_msg(struct msg_msg *msg)
kfree(msg);
while (seg != NULL) {
struct msg_msgseg *tmp = seg->next;
+
+ cond_resched();
kfree(seg);
seg = tmp;
}
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index b57f929f1b46..cf7aa656b308 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1095,22 +1095,24 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
int err = 0;
struct audit_entry *entry;
- entry = audit_data_to_entry(data, datasz);
- if (IS_ERR(entry))
- return PTR_ERR(entry);
-
switch (type) {
case AUDIT_ADD_RULE:
+ entry = audit_data_to_entry(data, datasz);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
err = audit_add_rule(entry);
audit_log_rule_change("add_rule", &entry->rule, !err);
break;
case AUDIT_DEL_RULE:
+ entry = audit_data_to_entry(data, datasz);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
err = audit_del_rule(entry);
audit_log_rule_change("remove_rule", &entry->rule, !err);
break;
default:
- err = -EINVAL;
WARN_ON(1);
+ return -EINVAL;
}
if (err || type == AUDIT_DEL_RULE) {
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index a599351997ad..2ce1a5297b92 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -419,14 +419,19 @@ static struct cpuset *alloc_trial_cpuset(struct cpuset *cs)
if (!alloc_cpumask_var(&trial->cpus_allowed, GFP_KERNEL))
goto free_cs;
+ if (!alloc_cpumask_var(&trial->cpus_requested, GFP_KERNEL))
+ goto free_allowed;
if (!alloc_cpumask_var(&trial->effective_cpus, GFP_KERNEL))
goto free_cpus;
cpumask_copy(trial->cpus_allowed, cs->cpus_allowed);
+ cpumask_copy(trial->cpus_requested, cs->cpus_requested);
cpumask_copy(trial->effective_cpus, cs->effective_cpus);
return trial;
free_cpus:
+ free_cpumask_var(trial->cpus_requested);
+free_allowed:
free_cpumask_var(trial->cpus_allowed);
free_cs:
kfree(trial);
@@ -440,6 +445,7 @@ free_cs:
static void free_trial_cpuset(struct cpuset *trial)
{
free_cpumask_var(trial->effective_cpus);
+ free_cpumask_var(trial->cpus_requested);
free_cpumask_var(trial->cpus_allowed);
kfree(trial);
}
@@ -948,23 +954,23 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
return -EACCES;
/*
- * An empty cpus_allowed is ok only if the cpuset has no tasks.
+ * An empty cpus_requested is ok only if the cpuset has no tasks.
* Since cpulist_parse() fails on an empty mask, we special case
* that parsing. The validate_change() call ensures that cpusets
* with tasks have cpus.
*/
if (!*buf) {
- cpumask_clear(trialcs->cpus_allowed);
+ cpumask_clear(trialcs->cpus_requested);
} else {
retval = cpulist_parse(buf, trialcs->cpus_requested);
if (retval < 0)
return retval;
+ }
- if (!cpumask_subset(trialcs->cpus_requested, cpu_present_mask))
- return -EINVAL;
+ if (!cpumask_subset(trialcs->cpus_requested, cpu_present_mask))
+ return -EINVAL;
- cpumask_and(trialcs->cpus_allowed, trialcs->cpus_requested, cpu_active_mask);
- }
+ cpumask_and(trialcs->cpus_allowed, trialcs->cpus_requested, cpu_active_mask);
/* Nothing to do if the cpus didn't change */
if (cpumask_equal(cs->cpus_requested, trialcs->cpus_requested))
diff --git a/kernel/cred.c b/kernel/cred.c
index ff8606f77d90..098af0bc0b7e 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -447,6 +447,15 @@ int commit_creds(struct cred *new)
if (task->mm)
set_dumpable(task->mm, suid_dumpable);
task->pdeath_signal = 0;
+ /*
+ * If a task drops privileges and becomes nondumpable,
+ * the dumpability change must become visible before
+ * the credential change; otherwise, a __ptrace_may_access()
+ * racing with this change may be able to attach to a task it
+ * shouldn't be able to attach to (as if the task had dropped
+ * privileges without becoming nondumpable).
+ * Pairs with a read barrier in __ptrace_may_access().
+ */
smp_wmb();
}
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 424f5a5fa5a2..b128cc829bd8 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -49,14 +49,30 @@ static void perf_output_put_handle(struct perf_output_handle *handle)
unsigned long head;
again:
+ /*
+ * In order to avoid publishing a head value that goes backwards,
+ * we must ensure the load of @rb->head happens after we've
+ * incremented @rb->nest.
+ *
+ * Otherwise we can observe a @rb->head value before one published
+ * by an IRQ/NMI happening between the load and the increment.
+ */
+ barrier();
head = local_read(&rb->head);
/*
- * IRQ/NMI can happen here, which means we can miss a head update.
+ * IRQ/NMI can happen here and advance @rb->head, causing our
+ * load above to be stale.
*/
- if (!local_dec_and_test(&rb->nest))
+ /*
+ * If this isn't the outermost nesting, we don't have to update
+ * @rb->user_page->data_head.
+ */
+ if (local_read(&rb->nest) > 1) {
+ local_dec(&rb->nest);
goto out;
+ }
/*
* Since the mmap() consumer (userspace) can run on a different CPU:
@@ -88,9 +104,18 @@ again:
rb->user_page->data_head = head;
/*
- * Now check if we missed an update -- rely on previous implied
- * compiler barriers to force a re-read.
+ * We must publish the head before decrementing the nest count,
+ * otherwise an IRQ/NMI can publish a more recent head value and our
+ * write will (temporarily) publish a stale value.
+ */
+ barrier();
+ local_set(&rb->nest, 0);
+
+ /*
+ * Ensure we decrement @rb->nest before we validate the @rb->head.
+ * Otherwise we cannot be sure we caught the 'last' nested update.
*/
+ barrier();
if (unlikely(head != local_read(&rb->head))) {
local_inc(&rb->nest);
goto again;
diff --git a/kernel/fork.c b/kernel/fork.c
index b14c2b3a59fc..c9ebfd3082ff 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1770,7 +1770,7 @@ struct task_struct *fork_idle(int cpu)
cpu_to_node(cpu));
if (!IS_ERR(task)) {
init_idle_pids(task->pids);
- init_idle(task, cpu, false);
+ init_idle(task, cpu);
}
return task;
diff --git a/kernel/futex.c b/kernel/futex.c
index 39c2b3eda1b9..d24d164e9bdb 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -593,8 +593,8 @@ again:
* applies. If this is really a shmem page then the page lock
* will prevent unexpected transitions.
*/
- lock_page(page);
- shmem_swizzled = PageSwapCache(page) || page->mapping;
+ lock_page(page_head);
+ shmem_swizzled = PageSwapCache(page_head) || page_head->mapping;
unlock_page(page_head);
put_page(page_head);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 8303874c2a06..1aa33fe37aa8 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -292,6 +292,16 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
return -EPERM;
ok:
rcu_read_unlock();
+ /*
+ * If a task drops privileges and becomes nondumpable (through a syscall
+ * like setresuid()) while we are trying to access it, we must ensure
+ * that the dumpability is read after the credentials; otherwise,
+ * we may be able to attach to a task that we shouldn't be able to
+ * attach to (as if the task had dropped privileges without becoming
+ * nondumpable).
+ * Pairs with a write barrier in commit_creds().
+ */
+ smp_rmb();
mm = task->mm;
if (mm &&
((get_dumpable(mm) != SUID_DUMP_USER) &&
@@ -673,6 +683,10 @@ static int ptrace_peek_siginfo(struct task_struct *child,
if (arg.nr < 0)
return -EINVAL;
+ /* Ensure arg.off fits in an unsigned long */
+ if (arg.off > ULONG_MAX)
+ return 0;
+
if (arg.flags & PTRACE_PEEKSIGINFO_SHARED)
pending = &child->signal->shared_pending;
else
@@ -680,18 +694,20 @@ static int ptrace_peek_siginfo(struct task_struct *child,
for (i = 0; i < arg.nr; ) {
siginfo_t info;
- s32 off = arg.off + i;
+ unsigned long off = arg.off + i;
+ bool found = false;
spin_lock_irq(&child->sighand->siglock);
list_for_each_entry(q, &pending->list, list) {
if (!off--) {
+ found = true;
copy_siginfo(&info, &q->info);
break;
}
}
spin_unlock_irq(&child->sighand->siglock);
- if (off >= 0) /* beyond the end of the list */
+ if (!found) /* beyond the end of the list */
break;
#ifdef CONFIG_COMPAT
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index d89328e260df..041a02b334d7 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1603,6 +1603,10 @@ rcu_torture_cleanup(void)
cur_ops->cb_barrier();
return;
}
+ if (!cur_ops) {
+ torture_cleanup_end();
+ return;
+ }
rcu_torture_barrier_cleanup();
torture_stop_kthread(rcu_torture_stall, stall_task);
@@ -1741,6 +1745,7 @@ rcu_torture_init(void)
pr_alert(" %s", torture_ops[i]->name);
pr_alert("\n");
firsterr = -EINVAL;
+ cur_ops = NULL;
goto unwind;
}
if (cur_ops->fqs == NULL && fqs_duration != 0) {
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d6f209bb0305..ff59b245417f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2479,7 +2479,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
unsigned long flags;
int cpu;
- init_new_task_load(p, false);
+ init_new_task_load(p);
cpu = get_cpu();
__sched_fork(clone_flags, p);
@@ -5439,19 +5439,15 @@ void init_idle_bootup_task(struct task_struct *idle)
* init_idle - set up an idle thread for a given CPU
* @idle: task in question
* @cpu: cpu the idle task belongs to
- * @cpu_up: differentiate between initial boot vs hotplug
*
* NOTE: this function does not set the idle thread's NEED_RESCHED
* flag, to make booting more robust.
*/
-void init_idle(struct task_struct *idle, int cpu, bool cpu_up)
+void init_idle(struct task_struct *idle, int cpu)
{
struct rq *rq = cpu_rq(cpu);
unsigned long flags;
- if (!cpu_up)
- init_new_task_load(idle, true);
-
raw_spin_lock_irqsave(&idle->pi_lock, flags);
raw_spin_lock(&rq->lock);
@@ -8603,7 +8599,8 @@ void __init sched_init(void)
* but because we are the idle thread, we just pick up running again
* when this runqueue becomes "idle".
*/
- init_idle(current, smp_processor_id(), false);
+ init_idle(current, smp_processor_id());
+ init_new_task_load(current);
calc_load_update = jiffies + LOAD_FREQ;
@@ -9412,6 +9409,8 @@ static void cpu_cgroup_attach(struct cgroup_taskset *tset)
static int cpu_shares_write_u64(struct cgroup_subsys_state *css,
struct cftype *cftype, u64 shareval)
{
+ if (shareval > scale_load_down(ULONG_MAX))
+ shareval = MAX_SHARES;
return sched_group_set_shares(css_tg(css), scale_load(shareval));
}
@@ -9511,8 +9510,10 @@ int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
period = ktime_to_ns(tg->cfs_bandwidth.period);
if (cfs_quota_us < 0)
quota = RUNTIME_INF;
- else
+ else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC)
quota = (u64)cfs_quota_us * NSEC_PER_USEC;
+ else
+ return -EINVAL;
return tg_set_cfs_bandwidth(tg, period, quota);
}
@@ -9534,6 +9535,9 @@ int tg_set_cfs_period(struct task_group *tg, long cfs_period_us)
{
u64 quota, period;
+ if ((u64)cfs_period_us > U64_MAX / NSEC_PER_USEC)
+ return -EINVAL;
+
period = (u64)cfs_period_us * NSEC_PER_USEC;
quota = tg->cfs_bandwidth.quota;
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index ddcf7cfb7248..5337ac7fcba1 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -1544,7 +1544,7 @@ void free_task_load_ptrs(struct task_struct *p)
p->ravg.prev_window_cpu = NULL;
}
-void init_new_task_load(struct task_struct *p, bool idle_task)
+void init_new_task_load(struct task_struct *p)
{
int i;
u32 init_load_windows = sched_init_task_load_windows;
@@ -1571,9 +1571,6 @@ void init_new_task_load(struct task_struct *p, bool idle_task)
/* Don't have much choice. CPU frequency would be bogus */
BUG_ON(!p->ravg.curr_window_cpu || !p->ravg.prev_window_cpu);
- if (idle_task)
- return;
-
if (init_load_pct)
init_load_windows = div64_u64((u64)init_load_pct *
(u64)sched_ravg_window, 100);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 5d0b5bef0653..19cec5074f4f 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1154,7 +1154,7 @@ extern unsigned int __read_mostly sched_downmigrate;
extern unsigned int sysctl_sched_spill_nr_run;
extern unsigned int __read_mostly sched_load_granule;
-extern void init_new_task_load(struct task_struct *p, bool idle_task);
+extern void init_new_task_load(struct task_struct *p);
extern u64 sched_ktime_clock(void);
extern int got_boost_kick(void);
extern int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb);
@@ -1644,7 +1644,7 @@ static inline struct sched_cluster *rq_cluster(struct rq *rq)
return NULL;
}
-static inline void init_new_task_load(struct task_struct *p, bool idle_task)
+static inline void init_new_task_load(struct task_struct *p)
{
}
diff --git a/kernel/signal.c b/kernel/signal.c
index 96e8c3cbfa38..072fd152ab01 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2244,6 +2244,8 @@ relock:
if (signal_group_exit(signal)) {
ksig->info.si_signo = signr = SIGKILL;
sigdelset(&current->pending.signal, SIGKILL);
+ trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,
+ &sighand->action[SIGKILL - 1]);
recalc_sigpending();
goto fatal;
}
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 552e154fc77e..979248f5e21a 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -32,7 +32,7 @@ struct task_struct *idle_thread_get(unsigned int cpu)
if (!tsk)
return ERR_PTR(-ENOMEM);
- init_idle(tsk, cpu, true);
+ init_idle(tsk, cpu);
return tsk;
}
diff --git a/kernel/sys.c b/kernel/sys.c
index ede0c1f4b860..29413e2bee41 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1764,7 +1764,7 @@ static int validate_prctl_map(struct prctl_mm_map *prctl_map)
((unsigned long)prctl_map->__m1 __op \
(unsigned long)prctl_map->__m2) ? 0 : -EINVAL
error = __prctl_check_order(start_code, <, end_code);
- error |= __prctl_check_order(start_data, <, end_data);
+ error |= __prctl_check_order(start_data,<=, end_data);
error |= __prctl_check_order(start_brk, <=, brk);
error |= __prctl_check_order(arg_start, <=, arg_end);
error |= __prctl_check_order(env_start, <=, env_end);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 43a049f9264c..b25717eb3d3a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2782,8 +2782,10 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
if (neg)
continue;
val = convmul * val / convdiv;
- if ((min && val < *min) || (max && val > *max))
- continue;
+ if ((min && val < *min) || (max && val > *max)) {
+ err = -EINVAL;
+ break;
+ }
*i = val;
} else {
val = convdiv * (*i) / convmul;
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index ab861771e37f..0e0dc5d89911 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -633,7 +633,7 @@ static inline void process_adjtimex_modes(struct timex *txc,
time_constant = max(time_constant, 0l);
}
- if (txc->modes & ADJ_TAI && txc->constant > 0)
+ if (txc->modes & ADJ_TAI && txc->constant >= 0)
*time_tai = txc->constant;
if (txc->modes & ADJ_OFFSET)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 1235f9fd9fbd..d0451cfd9daa 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1289,9 +1289,6 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
char buf[32];
int len;
- if (*ppos)
- return 0;
-
if (unlikely(!id))
return -ENODEV;
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
index b4aacfc0b4b3..9c7b353aacb7 100644
--- a/lib/strncpy_from_user.c
+++ b/lib/strncpy_from_user.c
@@ -23,10 +23,11 @@
* hit it), 'max' is the address space maximum (and we return
* -EFAULT if we hit it).
*/
-static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
+static inline long do_strncpy_from_user(char *dst, const char __user *src,
+ unsigned long count, unsigned long max)
{
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
- long res = 0;
+ unsigned long res = 0;
/*
* Truncate 'max' to the user-specified limit, so that
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c
index 8e105ed4df12..9ff4f3bbb1aa 100644
--- a/lib/strnlen_user.c
+++ b/lib/strnlen_user.c
@@ -27,7 +27,7 @@
static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max)
{
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
- long align, res = 0;
+ unsigned long align, res = 0;
unsigned long c;
/*
@@ -41,7 +41,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count,
* Do everything aligned. But that means that we
* need to also expand the maximum..
*/
- align = (sizeof(long) - 1) & (unsigned long)src;
+ align = (sizeof(unsigned long) - 1) & (unsigned long)src;
src -= align;
max += align;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 3081f1234d4e..b12a49bf78de 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -670,6 +670,7 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi)
INIT_RADIX_TREE(&bdi->cgwb_tree, GFP_ATOMIC);
bdi->cgwb_congested_tree = RB_ROOT;
atomic_set(&bdi->usage_cnt, 1);
+ init_rwsem(&bdi->wb_switch_rwsem);
ret = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
if (!ret) {
diff --git a/mm/cma.c b/mm/cma.c
index 809f4555429a..664364b62782 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -101,8 +101,10 @@ static int __init cma_activate_area(struct cma *cma)
cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
- if (!cma->bitmap)
+ if (!cma->bitmap) {
+ cma->count = 0;
return -ENOMEM;
+ }
WARN_ON_ONCE(!pfn_valid(pfn));
zone = page_zone(pfn_to_page(pfn));
diff --git a/mm/cma_debug.c b/mm/cma_debug.c
index f8e4b60db167..da50dab56b70 100644
--- a/mm/cma_debug.c
+++ b/mm/cma_debug.c
@@ -57,7 +57,7 @@ static int cma_maxchunk_get(void *data, u64 *val)
mutex_lock(&cma->lock);
for (;;) {
start = find_next_zero_bit(cma->bitmap, bitmap_maxno, end);
- if (start >= cma->count)
+ if (start >= bitmap_maxno)
break;
end = find_next_bit(cma->bitmap, bitmap_maxno, start);
maxchunk = max(end - start, maxchunk);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 324b2953e57e..fd932e7a25dd 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1221,12 +1221,23 @@ void free_huge_page(struct page *page)
ClearPagePrivate(page);
/*
- * A return code of zero implies that the subpool will be under its
- * minimum size if the reservation is not restored after page is free.
- * Therefore, force restore_reserve operation.
+ * If PagePrivate() was set on page, page allocation consumed a
+ * reservation. If the page was associated with a subpool, there
+ * would have been a page reserved in the subpool before allocation
+ * via hugepage_subpool_get_pages(). Since we are 'restoring' the
+ * reservtion, do not call hugepage_subpool_put_pages() as this will
+ * remove the reserved page from the subpool.
*/
- if (hugepage_subpool_put_pages(spool, 1) == 0)
- restore_reserve = true;
+ if (!restore_reserve) {
+ /*
+ * A return code of zero implies that the subpool will be
+ * under its minimum size if the reservation is not restored
+ * after page is free. Therefore, force restore_reserve
+ * operation.
+ */
+ if (hugepage_subpool_put_pages(spool, 1) == 0)
+ restore_reserve = true;
+ }
spin_lock(&hugetlb_lock);
clear_page_huge_active(page);
@@ -3703,21 +3714,14 @@ backout_unlocked:
}
#ifdef CONFIG_SMP
-u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm,
- struct vm_area_struct *vma,
- struct address_space *mapping,
+u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping,
pgoff_t idx, unsigned long address)
{
unsigned long key[2];
u32 hash;
- if (vma->vm_flags & VM_SHARED) {
- key[0] = (unsigned long) mapping;
- key[1] = idx;
- } else {
- key[0] = (unsigned long) mm;
- key[1] = address >> huge_page_shift(h);
- }
+ key[0] = (unsigned long) mapping;
+ key[1] = idx;
hash = jhash2((u32 *)&key, sizeof(key)/sizeof(u32), 0);
@@ -3728,9 +3732,7 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm,
* For uniprocesor systems we always use a single mutex, so just
* return 0 and avoid the hashing overhead.
*/
-u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm,
- struct vm_area_struct *vma,
- struct address_space *mapping,
+u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping,
pgoff_t idx, unsigned long address)
{
return 0;
@@ -3776,7 +3778,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
* get spurious allocation failures if two CPUs race to instantiate
* the same page in the page cache.
*/
- hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, idx, address);
+ hash = hugetlb_fault_mutex_hash(h, mapping, idx, address);
mutex_lock(&hugetlb_fault_mutex_table[hash]);
entry = huge_ptep_get(ptep);
diff --git a/mm/list_lru.c b/mm/list_lru.c
index 786176b1a0ee..4aa714db2fcf 100644
--- a/mm/list_lru.c
+++ b/mm/list_lru.c
@@ -42,11 +42,7 @@ static void list_lru_unregister(struct list_lru *lru)
#ifdef CONFIG_MEMCG_KMEM
static inline bool list_lru_memcg_aware(struct list_lru *lru)
{
- /*
- * This needs node 0 to be always present, even
- * in the systems supporting sparse numa ids.
- */
- return !!lru->node[0].memcg_lrus;
+ return lru->memcg_aware;
}
static inline struct list_lru_one *
@@ -317,7 +313,7 @@ static int __memcg_init_list_lru_node(struct list_lru_memcg *memcg_lrus,
}
return 0;
fail:
- __memcg_destroy_list_lru_node(memcg_lrus, begin, i - 1);
+ __memcg_destroy_list_lru_node(memcg_lrus, begin, i);
return -ENOMEM;
}
@@ -389,6 +385,8 @@ static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
{
int i;
+ lru->memcg_aware = memcg_aware;
+
if (!memcg_aware)
return 0;
diff --git a/mm/mincore.c b/mm/mincore.c
index 14bb9fb37f0c..9700c2303941 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -165,6 +165,22 @@ out:
return 0;
}
+static inline bool can_do_mincore(struct vm_area_struct *vma)
+{
+ if (vma_is_anonymous(vma))
+ return true;
+ if (!vma->vm_file)
+ return false;
+ /*
+ * Reveal pagecache information only for non-anonymous mappings that
+ * correspond to the files the calling process could (if tried) open
+ * for writing; otherwise we'd be including shared non-exclusive
+ * mappings, which opens a side channel.
+ */
+ return inode_owner_or_capable(file_inode(vma->vm_file)) ||
+ inode_permission(file_inode(vma->vm_file), MAY_WRITE) == 0;
+}
+
/*
* Do a chunk of "sys_mincore()". We've already checked
* all the arguments, we hold the mmap semaphore: we should
@@ -185,8 +201,13 @@ static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *v
vma = find_vma(current->mm, addr);
if (!vma || addr < vma->vm_start)
return -ENOMEM;
- mincore_walk.mm = vma->vm_mm;
end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
+ if (!can_do_mincore(vma)) {
+ unsigned long pages = DIV_ROUND_UP(end - addr, PAGE_SIZE);
+ memset(vec, 1, pages);
+ return pages;
+ }
+ mincore_walk.mm = vma->vm_mm;
err = walk_page_range(addr, end, &mincore_walk);
if (err < 0)
return err;
diff --git a/mm/mmap.c b/mm/mmap.c
index ae4f0fc2f01b..3bb666ced2b8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -42,6 +42,7 @@
#include <linux/memory.h>
#include <linux/printk.h>
#include <linux/userfaultfd_k.h>
+#include <linux/mm.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -2435,7 +2436,8 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
vma = find_vma_prev(mm, addr, &prev);
if (vma && (vma->vm_start <= addr))
return vma;
- if (!prev || expand_stack(prev, addr))
+ /* don't alter vm_end if the coredump is running */
+ if (!prev || !mmget_still_valid(mm) || expand_stack(prev, addr))
return NULL;
if (prev->vm_flags & VM_LOCKED)
populate_vma_page_range(prev, addr, prev->vm_end, NULL);
@@ -2461,6 +2463,9 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
return vma;
if (!(vma->vm_flags & VM_GROWSDOWN))
return NULL;
+ /* don't alter vm_start if the coredump is running */
+ if (!mmget_still_valid(mm))
+ return NULL;
start = vma->vm_start;
if (expand_stack(vma, addr))
return NULL;
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 149f82bd83fd..6ba56f215229 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -443,9 +443,11 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
}
if (ax25->sk != NULL) {
+ local_bh_disable();
bh_lock_sock(ax25->sk);
sock_reset_flag(ax25->sk, SOCK_ZAPPED);
bh_unlock_sock(ax25->sk);
+ local_bh_enable();
}
put:
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ccddf348924b..1588d913c7a0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1177,14 +1177,6 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
return 0;
- /* 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.
- */
- if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE)
- return 0;
-
return 1;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index f2181624567a..1dbfbb4a41ce 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4558,7 +4558,6 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
skb_reset_mac_header(skb);
skb_gro_reset_offset(skb);
- eth = skb_gro_header_fast(skb, 0);
if (unlikely(skb_gro_header_hard(skb, hlen))) {
eth = skb_gro_header_slow(skb, hlen, 0);
if (unlikely(!eth)) {
@@ -4566,6 +4565,7 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
return NULL;
}
} else {
+ eth = (const struct ethhdr *)skb->data;
gro_pull_from_frag0(skb, hlen);
NAPI_GRO_CB(skb)->frag0 += hlen;
NAPI_GRO_CB(skb)->frag0_len -= hlen;
@@ -7022,7 +7022,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
refcnt = netdev_refcnt_read(dev);
- if (time_after(jiffies, warning_time + 10 * HZ)) {
+ if (refcnt && time_after(jiffies, warning_time + 10 * HZ)) {
pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n",
dev->name, refcnt);
warning_time = jiffies;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 9a53c66deb64..66428c0eb663 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -428,8 +428,13 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
if (rc >= 0)
info.n_priv_flags = rc;
}
- if (ops->get_regs_len)
- info.regdump_len = ops->get_regs_len(dev);
+ if (ops->get_regs_len) {
+ int ret = ops->get_regs_len(dev);
+
+ if (ret > 0)
+ info.regdump_len = ret;
+ }
+
if (ops->get_eeprom_len)
info.eedump_len = ops->get_eeprom_len(dev);
@@ -883,6 +888,9 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
return -EFAULT;
reglen = ops->get_regs_len(dev);
+ if (reglen <= 0)
+ return reglen;
+
if (regs.len > reglen)
regs.len = reglen;
@@ -893,13 +901,16 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
return -ENOMEM;
}
+ if (regs.len < reglen)
+ reglen = regs.len;
+
ops->get_regs(dev, &regs, regbuf);
ret = -EFAULT;
if (copy_to_user(useraddr, &regs, sizeof(regs)))
goto out;
useraddr += offsetof(struct ethtool_regs, data);
- if (regbuf && copy_to_user(useraddr, regbuf, regs.len))
+ if (copy_to_user(useraddr, regbuf, reglen))
goto out;
ret = 0;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index fef2043cdb1d..2572b51e86f4 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -30,6 +30,7 @@
#include <linux/times.h>
#include <net/net_namespace.h>
#include <net/neighbour.h>
+#include <net/arp.h>
#include <net/dst.h>
#include <net/sock.h>
#include <net/netevent.h>
@@ -2490,7 +2491,13 @@ int neigh_xmit(int index, struct net_device *dev,
if (!tbl)
goto out;
rcu_read_lock_bh();
- neigh = __neigh_lookup_noref(tbl, addr, dev);
+ if (index == NEIGH_ARP_TABLE) {
+ u32 key = *((u32 *)addr);
+
+ neigh = __ipv4_neigh_lookup_noref(dev, key);
+ } else {
+ neigh = __neigh_lookup_noref(tbl, addr, dev);
+ }
if (!neigh)
neigh = __neigh_create(tbl, addr, dev, false);
err = PTR_ERR(neigh);
@@ -2698,6 +2705,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
}
void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
+ __acquires(tbl->lock)
__acquires(rcu_bh)
{
struct neigh_seq_state *state = seq->private;
@@ -2708,6 +2716,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
rcu_read_lock_bh();
state->nht = rcu_dereference_bh(tbl->nht);
+ read_lock(&tbl->lock);
return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
}
@@ -2741,8 +2750,13 @@ out:
EXPORT_SYMBOL(neigh_seq_next);
void neigh_seq_stop(struct seq_file *seq, void *v)
+ __releases(tbl->lock)
__releases(rcu_bh)
{
+ struct neigh_seq_state *state = seq->private;
+ struct neigh_table *tbl = state->tbl;
+
+ read_unlock(&tbl->lock);
rcu_read_unlock_bh();
}
EXPORT_SYMBOL(neigh_seq_stop);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b6327601f979..4ea957c1e7ee 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3139,7 +3139,13 @@ static int pktgen_wait_thread_run(struct pktgen_thread *t)
{
while (thread_is_running(t)) {
+ /* note: 't' will still be around even after the unlock/lock
+ * cycle because pktgen_thread threads are only cleared at
+ * net exit
+ */
+ mutex_unlock(&pktgen_thread_lock);
msleep_interruptible(100);
+ mutex_lock(&pktgen_thread_lock);
if (signal_pending(current))
goto signal;
@@ -3154,6 +3160,10 @@ static int pktgen_wait_all_threads_run(struct pktgen_net *pn)
struct pktgen_thread *t;
int sig = 1;
+ /* prevent from racing with rmmod */
+ if (!try_module_get(THIS_MODULE))
+ return sig;
+
mutex_lock(&pktgen_thread_lock);
list_for_each_entry(t, &pn->pktgen_threads, th_list) {
@@ -3167,6 +3177,7 @@ static int pktgen_wait_all_threads_run(struct pktgen_net *pn)
t->control |= (T_STOP);
mutex_unlock(&pktgen_thread_lock);
+ module_put(THIS_MODULE);
return sig;
}
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index fcf327ebd134..bbcbbc1cc2cc 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -648,9 +648,9 @@ static int __init vti_init(void)
return err;
rtnl_link_failed:
- xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
-xfrm_tunnel_failed:
xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
+xfrm_tunnel_failed:
+ xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm_proto_comp_failed:
xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
xfrm_proto_ah_failed:
@@ -666,6 +666,7 @@ pernet_dev_failed:
static void __exit vti_fini(void)
{
rtnl_link_unregister(&vti_link_ops);
+ xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index b001ad668108..555586fc7840 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -303,6 +303,7 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE),
SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL),
SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS),
+ SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 81739ffc4168..a56b3eb930b9 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -36,6 +36,8 @@ static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
+static int tcp_min_snd_mss_min = TCP_MIN_SND_MSS;
+static int tcp_min_snd_mss_max = 65535;
static int ip_ttl_min = 1;
static int ip_ttl_max = 255;
static int tcp_syn_retries_min = 1;
@@ -994,6 +996,15 @@ static struct ctl_table ipv4_net_table[] = {
.proc_handler = proc_dointvec,
},
{
+ .procname = "tcp_min_snd_mss",
+ .data = &init_net.ipv4.sysctl_tcp_min_snd_mss,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &tcp_min_snd_mss_min,
+ .extra2 = &tcp_min_snd_mss_max,
+ },
+ {
.procname = "tcp_probe_threshold",
.data = &init_net.ipv4.sysctl_tcp_probe_threshold,
.maxlen = sizeof(int),
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 16d2b59989ec..0fe1eaf0bc31 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3207,6 +3207,7 @@ void __init tcp_init(void)
int max_rshare, max_wshare, cnt;
unsigned int i;
+ BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE);
sock_skb_cb_check_size(sizeof(struct tcp_skb_cb));
percpu_counter_init(&tcp_sockets_allocated, 0, GFP_KERNEL);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 95273c47a513..2fb43a1f259d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1276,7 +1276,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
TCP_SKB_CB(skb)->seq += shifted;
tcp_skb_pcount_add(prev, pcount);
- BUG_ON(tcp_skb_pcount(skb) < pcount);
+ WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount);
tcp_skb_pcount_add(skb, -pcount);
/* When we're adding to gso_segs == 1, gso_size will be zero,
@@ -1338,6 +1338,21 @@ static int skb_can_shift(const struct sk_buff *skb)
return !skb_headlen(skb) && skb_is_nonlinear(skb);
}
+int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
+ int pcount, int shiftlen)
+{
+ /* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE)
+ * Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need
+ * to make sure not storing more than 65535 * 8 bytes per skb,
+ * even if current MSS is bigger.
+ */
+ if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE))
+ return 0;
+ if (unlikely(tcp_skb_pcount(to) + pcount > 65535))
+ return 0;
+ return skb_shift(to, from, shiftlen);
+}
+
/* Try collapsing SACK blocks spanning across multiple skbs to a single
* skb.
*/
@@ -1349,6 +1364,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *prev;
int mss;
+ int next_pcount;
int pcount = 0;
int len;
int in_sack;
@@ -1443,7 +1459,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
if (!after(TCP_SKB_CB(skb)->seq + len, tp->snd_una))
goto fallback;
- if (!skb_shift(prev, skb, len))
+ if (!tcp_skb_shift(prev, skb, pcount, len))
goto fallback;
if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack))
goto out;
@@ -1462,11 +1478,11 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
goto out;
len = skb->len;
- if (skb_shift(prev, skb, len)) {
- pcount += tcp_skb_pcount(skb);
- tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0);
+ next_pcount = tcp_skb_pcount(skb);
+ if (tcp_skb_shift(prev, skb, next_pcount, len)) {
+ pcount += next_pcount;
+ tcp_shifted_skb(sk, skb, state, next_pcount, len, mss, 0);
}
-
out:
state->fack_count += pcount;
return prev;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d1b911cde946..d2d95cf398e8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2435,6 +2435,7 @@ static int __net_init tcp_sk_init(struct net *net)
net->ipv4.sysctl_tcp_ecn_fallback = 1;
net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS;
+ net->ipv4.sysctl_tcp_min_snd_mss = TCP_MIN_SND_MSS;
net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD;
net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9ada5e4a28e5..6f7303d51274 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1161,6 +1161,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
if (nsize < 0)
nsize = 0;
+ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) {
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
+ return -ENOMEM;
+ }
+
if (skb_unclone(skb, gfp))
return -ENOMEM;
@@ -1327,8 +1332,7 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
mss_now -= icsk->icsk_ext_hdr_len;
/* Then reserve room for full set of TCP options and 8 bytes of data */
- if (mss_now < 48)
- mss_now = 48;
+ mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss);
return mss_now;
}
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 2221e3c36bd5..28fed4ade750 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -166,6 +166,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
mss = min(net->ipv4.sysctl_tcp_base_mss, mss);
mss = max(mss, 68 - tp->tcp_header_len);
+ mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss);
icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
}
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 528f13718687..0a6bcf7e7b54 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -112,7 +112,8 @@ static void
_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
{
const struct iphdr *iph = ip_hdr(skb);
- u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
+ int ihl = iph->ihl;
+ u8 *xprth = skb_network_header(skb) + ihl * 4;
struct flowi4 *fl4 = &fl->u.ip4;
int oif = 0;
@@ -123,6 +124,11 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
fl4->flowi4_mark = skb->mark;
fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
+ fl4->flowi4_proto = iph->protocol;
+ fl4->daddr = reverse ? iph->saddr : iph->daddr;
+ fl4->saddr = reverse ? iph->daddr : iph->saddr;
+ fl4->flowi4_tos = iph->tos;
+
if (!ip_is_fragment(iph)) {
switch (iph->protocol) {
case IPPROTO_UDP:
@@ -134,7 +140,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ports;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
ports = (__be16 *)xprth;
fl4->fl4_sport = ports[!!reverse];
@@ -147,7 +153,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 2 - skb->data)) {
u8 *icmp;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
icmp = xprth;
fl4->fl4_icmp_type = icmp[0];
@@ -160,7 +166,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be32 *ehdr;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
ehdr = (__be32 *)xprth;
fl4->fl4_ipsec_spi = ehdr[0];
@@ -172,7 +178,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 8 - skb->data)) {
__be32 *ah_hdr;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
ah_hdr = (__be32 *)xprth;
fl4->fl4_ipsec_spi = ah_hdr[1];
@@ -184,7 +190,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ipcomp_hdr;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
ipcomp_hdr = (__be16 *)xprth;
fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
@@ -197,7 +203,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
__be16 *greflags;
__be32 *gre_hdr;
- xprth = skb_network_header(skb) + iph->ihl * 4;
+ xprth = skb_network_header(skb) + ihl * 4;
greflags = (__be16 *)xprth;
gre_hdr = (__be32 *)xprth;
@@ -214,10 +220,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
break;
}
}
- fl4->flowi4_proto = iph->protocol;
- fl4->daddr = reverse ? iph->saddr : iph->daddr;
- fl4->saddr = reverse ? iph->daddr : iph->saddr;
- fl4->flowi4_tos = iph->tos;
}
static inline int xfrm4_garbage_collect(struct dst_ops *ops)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index c6061f7343f1..8a6c682bfc22 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -254,9 +254,9 @@ struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label)
rcu_read_lock_bh();
for_each_sk_fl_rcu(np, sfl) {
struct ip6_flowlabel *fl = sfl->fl;
- if (fl->label == label) {
+
+ if (fl->label == label && atomic_inc_not_zero(&fl->users)) {
fl->lastuse = jiffies;
- atomic_inc(&fl->users);
rcu_read_unlock_bh();
return fl;
}
@@ -622,7 +622,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
goto done;
}
fl1 = sfl->fl;
- atomic_inc(&fl1->users);
+ if (!atomic_inc_not_zero(&fl1->users))
+ fl1 = NULL;
break;
}
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0ef8e114c8ab..30db0167bd19 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -283,7 +283,9 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
/* Binding to link-local address requires an interface */
if (!sk->sk_bound_dev_if)
goto out_unlock;
+ }
+ if (sk->sk_bound_dev_if) {
err = -ENODEV;
dev = dev_get_by_index_rcu(sock_net(sk),
sk->sk_bound_dev_if);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 56b72cada346..f9d493c59d6c 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -391,6 +391,10 @@ static void __exit xfrm6_tunnel_fini(void)
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
+ /* Someone maybe has gotten the xfrm6_tunnel_spi.
+ * So need to wait it.
+ */
+ rcu_barrier();
kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
}
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index fc60d9d738b5..cdb913e7627e 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -182,6 +182,7 @@ int lapb_unregister(struct net_device *dev)
lapb = __lapb_devtostruct(dev);
if (!lapb)
goto out;
+ lapb_put(lapb);
lapb_stop_t1timer(lapb);
lapb_stop_t2timer(lapb);
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c
index 94425e421213..9e4b6bcf6920 100644
--- a/net/llc/llc_output.c
+++ b/net/llc/llc_output.c
@@ -72,6 +72,8 @@ int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
if (likely(!rc))
rc = dev_queue_xmit(skb);
+ else
+ kfree_skb(skb);
return rc;
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d16f0aba664e..ec57374c7ca9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1104,9 +1104,6 @@ static void ieee80211_chswitch_work(struct work_struct *work)
goto out;
}
- /* XXX: shouldn't really modify cfg80211-owned data! */
- ifmgd->associated->channel = sdata->csa_chandef.chan;
-
ifmgd->csa_waiting_bcn = true;
ieee80211_sta_reset_beacon_monitor(sdata);
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index a2340748ec86..d7888924166e 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -725,12 +725,14 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool,
wait_clean_list_grace();
list_to_llist_nodes(pool, &unmap_list, &clean_nodes, &clean_tail);
- if (ibmr_ret)
+ if (ibmr_ret) {
*ibmr_ret = llist_entry(clean_nodes, struct rds_ib_mr, llnode);
-
+ clean_nodes = clean_nodes->next;
+ }
/* more than one entry in llist nodes */
- if (clean_nodes->next)
- llist_add_batch(clean_nodes->next, clean_tail, &pool->clean_list);
+ if (clean_nodes)
+ llist_add_batch(clean_nodes, clean_tail,
+ &pool->clean_list);
}
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index a06c9d6bfc9c..05c7a66f64da 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -142,16 +142,6 @@ static u64 psched_ns_t2l(const struct psched_ratecfg *r,
return len;
}
-/*
- * Return length of individual segments of a gso packet,
- * including all headers (MAC, IP, TCP/UDP)
- */
-static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
-{
- unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
- return hdr_len + skb_gso_transport_seglen(skb);
-}
-
/* GSO packet is too big, segment it so that tbf can transmit
* each segment in time
*/
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e2bdb07a49a2..c306e9bc1621 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -70,9 +70,6 @@ static int __net_init tipc_init_net(struct net *net)
goto out_nametbl;
INIT_LIST_HEAD(&tn->dist_queue);
- err = tipc_topsrv_start(net);
- if (err)
- goto out_subscr;
err = tipc_bcast_init(net);
if (err)
@@ -81,8 +78,6 @@ static int __net_init tipc_init_net(struct net *net)
return 0;
out_bclink:
- tipc_bcast_stop(net);
-out_subscr:
tipc_nametbl_stop(net);
out_nametbl:
tipc_sk_rht_destroy(net);
@@ -92,7 +87,6 @@ out_sk_rht:
static void __net_exit tipc_exit_net(struct net *net)
{
- tipc_topsrv_stop(net);
tipc_net_stop(net);
tipc_bcast_stop(net);
tipc_nametbl_stop(net);
@@ -106,6 +100,11 @@ static struct pernet_operations tipc_net_ops = {
.size = sizeof(struct tipc_net),
};
+static struct pernet_operations tipc_topsrv_net_ops = {
+ .init = tipc_topsrv_init_net,
+ .exit = tipc_topsrv_exit_net,
+};
+
static int __init tipc_init(void)
{
int err;
@@ -126,10 +125,6 @@ static int __init tipc_init(void)
if (err)
goto out_netlink_compat;
- err = tipc_socket_init();
- if (err)
- goto out_socket;
-
err = tipc_register_sysctl();
if (err)
goto out_sysctl;
@@ -138,6 +133,14 @@ static int __init tipc_init(void)
if (err)
goto out_pernet;
+ err = tipc_socket_init();
+ if (err)
+ goto out_socket;
+
+ err = register_pernet_subsys(&tipc_topsrv_net_ops);
+ if (err)
+ goto out_pernet_topsrv;
+
err = tipc_bearer_setup();
if (err)
goto out_bearer;
@@ -145,12 +148,14 @@ 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);
+out_pernet_topsrv:
+ tipc_socket_stop();
+out_socket:
unregister_pernet_subsys(&tipc_net_ops);
out_pernet:
tipc_unregister_sysctl();
out_sysctl:
- tipc_socket_stop();
-out_socket:
tipc_netlink_compat_stop();
out_netlink_compat:
tipc_netlink_stop();
@@ -162,10 +167,11 @@ out_netlink:
static void __exit tipc_exit(void)
{
tipc_bearer_cleanup();
+ unregister_pernet_subsys(&tipc_topsrv_net_ops);
+ tipc_socket_stop();
unregister_pernet_subsys(&tipc_net_ops);
tipc_netlink_stop();
tipc_netlink_compat_stop();
- tipc_socket_stop();
tipc_unregister_sysctl();
pr_info("Deactivated\n");
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 500c9e614a06..4f80f00cd8f9 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -306,7 +306,7 @@ static void *tipc_subscrb_connect_cb(int conid)
return (void *)tipc_subscrb_create(conid);
}
-int tipc_topsrv_start(struct net *net)
+static int tipc_topsrv_start(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
const char name[] = "topology_server";
@@ -344,7 +344,7 @@ int tipc_topsrv_start(struct net *net)
return tipc_server_start(topsrv);
}
-void tipc_topsrv_stop(struct net *net)
+static void tipc_topsrv_stop(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_server *topsrv = tn->topsrv;
@@ -353,3 +353,13 @@ void tipc_topsrv_stop(struct net *net)
kfree(topsrv->saddr);
kfree(topsrv);
}
+
+int __net_init tipc_topsrv_init_net(struct net *net)
+{
+ return tipc_topsrv_start(net);
+}
+
+void __net_exit tipc_topsrv_exit_net(struct net *net)
+{
+ tipc_topsrv_stop(net);
+}
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 92ee18cc5fe6..e9aa8c7a6fec 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -77,7 +77,8 @@ int tipc_subscrp_check_overlap(struct tipc_subscription *sub, u32 found_lower,
void tipc_subscrp_report_overlap(struct tipc_subscription *sub,
u32 found_lower, u32 found_upper, u32 event,
u32 port_ref, u32 node, int must);
-int tipc_topsrv_start(struct net *net);
-void tipc_topsrv_stop(struct net *net);
+
+int __net_init tipc_topsrv_init_net(struct net *net);
+void __net_exit tipc_topsrv_exit_net(struct net *net);
#endif
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bae775626129..a54730b52083 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -13475,6 +13475,11 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
wdev->chandef = *chandef;
wdev->preset_chandef = *chandef;
+
+ if (wdev->iftype == NL80211_IFTYPE_STATION &&
+ !WARN_ON(!wdev->current_bss))
+ wdev->current_bss->pub.channel = chandef->chan;
+
nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
NL80211_CMD_CH_SWITCH_NOTIFY, 0);
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 9d57500bbbbc..4804f29fd011 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1348,7 +1348,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
ret = verify_policy_dir(p->dir);
if (ret)
return ret;
- if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir))
+ if (p->index && (xfrm_policy_id2dir(p->index) != p->dir))
return -EINVAL;
return 0;
diff --git a/scripts/coccinelle/api/stream_open.cocci b/scripts/coccinelle/api/stream_open.cocci
new file mode 100644
index 000000000000..350145da7669
--- /dev/null
+++ b/scripts/coccinelle/api/stream_open.cocci
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+// Author: Kirill Smelkov (kirr@nexedi.com)
+//
+// Search for stream-like files that are using nonseekable_open and convert
+// them to stream_open. A stream-like file is a file that does not use ppos in
+// its read and write. Rationale for the conversion is to avoid deadlock in
+// between read and write.
+
+virtual report
+virtual patch
+virtual explain // explain decisions in the patch (SPFLAGS="-D explain")
+
+// stream-like reader & writer - ones that do not depend on f_pos.
+@ stream_reader @
+identifier readstream, ppos;
+identifier f, buf, len;
+type loff_t;
+@@
+ ssize_t readstream(struct file *f, char *buf, size_t len, loff_t *ppos)
+ {
+ ... when != ppos
+ }
+
+@ stream_writer @
+identifier writestream, ppos;
+identifier f, buf, len;
+type loff_t;
+@@
+ ssize_t writestream(struct file *f, const char *buf, size_t len, loff_t *ppos)
+ {
+ ... when != ppos
+ }
+
+
+// a function that blocks
+@ blocks @
+identifier block_f;
+identifier wait_event =~ "^wait_event_.*";
+@@
+ block_f(...) {
+ ... when exists
+ wait_event(...)
+ ... when exists
+ }
+
+// stream_reader that can block inside.
+//
+// XXX wait_* can be called not directly from current function (e.g. func -> f -> g -> wait())
+// XXX currently reader_blocks supports only direct and 1-level indirect cases.
+@ reader_blocks_direct @
+identifier stream_reader.readstream;
+identifier wait_event =~ "^wait_event_.*";
+@@
+ readstream(...)
+ {
+ ... when exists
+ wait_event(...)
+ ... when exists
+ }
+
+@ reader_blocks_1 @
+identifier stream_reader.readstream;
+identifier blocks.block_f;
+@@
+ readstream(...)
+ {
+ ... when exists
+ block_f(...)
+ ... when exists
+ }
+
+@ reader_blocks depends on reader_blocks_direct || reader_blocks_1 @
+identifier stream_reader.readstream;
+@@
+ readstream(...) {
+ ...
+ }
+
+
+// file_operations + whether they have _any_ .read, .write, .llseek ... at all.
+//
+// XXX add support for file_operations xxx[N] = ... (sound/core/pcm_native.c)
+@ fops0 @
+identifier fops;
+@@
+ struct file_operations fops = {
+ ...
+ };
+
+@ has_read @
+identifier fops0.fops;
+identifier read_f;
+@@
+ struct file_operations fops = {
+ .read = read_f,
+ };
+
+@ has_read_iter @
+identifier fops0.fops;
+identifier read_iter_f;
+@@
+ struct file_operations fops = {
+ .read_iter = read_iter_f,
+ };
+
+@ has_write @
+identifier fops0.fops;
+identifier write_f;
+@@
+ struct file_operations fops = {
+ .write = write_f,
+ };
+
+@ has_write_iter @
+identifier fops0.fops;
+identifier write_iter_f;
+@@
+ struct file_operations fops = {
+ .write_iter = write_iter_f,
+ };
+
+@ has_llseek @
+identifier fops0.fops;
+identifier llseek_f;
+@@
+ struct file_operations fops = {
+ .llseek = llseek_f,
+ };
+
+@ has_no_llseek @
+identifier fops0.fops;
+@@
+ struct file_operations fops = {
+ .llseek = no_llseek,
+ };
+
+@ has_mmap @
+identifier fops0.fops;
+identifier mmap_f;
+@@
+ struct file_operations fops = {
+ .mmap = mmap_f,
+ };
+
+@ has_copy_file_range @
+identifier fops0.fops;
+identifier copy_file_range_f;
+@@
+ struct file_operations fops = {
+ .copy_file_range = copy_file_range_f,
+ };
+
+@ has_remap_file_range @
+identifier fops0.fops;
+identifier remap_file_range_f;
+@@
+ struct file_operations fops = {
+ .remap_file_range = remap_file_range_f,
+ };
+
+@ has_splice_read @
+identifier fops0.fops;
+identifier splice_read_f;
+@@
+ struct file_operations fops = {
+ .splice_read = splice_read_f,
+ };
+
+@ has_splice_write @
+identifier fops0.fops;
+identifier splice_write_f;
+@@
+ struct file_operations fops = {
+ .splice_write = splice_write_f,
+ };
+
+
+// file_operations that is candidate for stream_open conversion - it does not
+// use mmap and other methods that assume @offset access to file.
+//
+// XXX for simplicity require no .{read/write}_iter and no .splice_{read/write} for now.
+// XXX maybe_steam.fops cannot be used in other rules - it gives "bad rule maybe_stream or bad variable fops".
+@ maybe_stream depends on (!has_llseek || has_no_llseek) && !has_mmap && !has_copy_file_range && !has_remap_file_range && !has_read_iter && !has_write_iter && !has_splice_read && !has_splice_write @
+identifier fops0.fops;
+@@
+ struct file_operations fops = {
+ };
+
+
+// ---- conversions ----
+
+// XXX .open = nonseekable_open -> .open = stream_open
+// XXX .open = func -> openfunc -> nonseekable_open
+
+// read & write
+//
+// if both are used in the same file_operations together with an opener -
+// under that conditions we can use stream_open instead of nonseekable_open.
+@ fops_rw depends on maybe_stream @
+identifier fops0.fops, openfunc;
+identifier stream_reader.readstream;
+identifier stream_writer.writestream;
+@@
+ struct file_operations fops = {
+ .open = openfunc,
+ .read = readstream,
+ .write = writestream,
+ };
+
+@ report_rw depends on report @
+identifier fops_rw.openfunc;
+position p1;
+@@
+ openfunc(...) {
+ <...
+ nonseekable_open@p1
+ ...>
+ }
+
+@ script:python depends on report && reader_blocks @
+fops << fops0.fops;
+p << report_rw.p1;
+@@
+coccilib.report.print_report(p[0],
+ "ERROR: %s: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix." % (fops,))
+
+@ script:python depends on report && !reader_blocks @
+fops << fops0.fops;
+p << report_rw.p1;
+@@
+coccilib.report.print_report(p[0],
+ "WARNING: %s: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+
+@ explain_rw_deadlocked depends on explain && reader_blocks @
+identifier fops_rw.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ nonseekable_open /* read & write (was deadlock) */
+ ...>
+ }
+
+
+@ explain_rw_nodeadlock depends on explain && !reader_blocks @
+identifier fops_rw.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ nonseekable_open /* read & write (no direct deadlock) */
+ ...>
+ }
+
+@ patch_rw depends on patch @
+identifier fops_rw.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ stream_open
+ ...>
+ }
+
+
+// read, but not write
+@ fops_r depends on maybe_stream && !has_write @
+identifier fops0.fops, openfunc;
+identifier stream_reader.readstream;
+@@
+ struct file_operations fops = {
+ .open = openfunc,
+ .read = readstream,
+ };
+
+@ report_r depends on report @
+identifier fops_r.openfunc;
+position p1;
+@@
+ openfunc(...) {
+ <...
+ nonseekable_open@p1
+ ...>
+ }
+
+@ script:python depends on report @
+fops << fops0.fops;
+p << report_r.p1;
+@@
+coccilib.report.print_report(p[0],
+ "WARNING: %s: .read() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+@ explain_r depends on explain @
+identifier fops_r.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ nonseekable_open /* read only */
+ ...>
+ }
+
+@ patch_r depends on patch @
+identifier fops_r.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ stream_open
+ ...>
+ }
+
+
+// write, but not read
+@ fops_w depends on maybe_stream && !has_read @
+identifier fops0.fops, openfunc;
+identifier stream_writer.writestream;
+@@
+ struct file_operations fops = {
+ .open = openfunc,
+ .write = writestream,
+ };
+
+@ report_w depends on report @
+identifier fops_w.openfunc;
+position p1;
+@@
+ openfunc(...) {
+ <...
+ nonseekable_open@p1
+ ...>
+ }
+
+@ script:python depends on report @
+fops << fops0.fops;
+p << report_w.p1;
+@@
+coccilib.report.print_report(p[0],
+ "WARNING: %s: .write() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+@ explain_w depends on explain @
+identifier fops_w.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ nonseekable_open /* write only */
+ ...>
+ }
+
+@ patch_w depends on patch @
+identifier fops_w.openfunc;
+@@
+ openfunc(...) {
+ <...
+- nonseekable_open
++ stream_open
+ ...>
+ }
+
+
+// no read, no write - don't change anything
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index f04714d70bf7..a42e2ce4a726 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -550,10 +550,10 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
list_del_init(list);
grp->exclusive = 0;
write_unlock_irq(&grp->list_lock);
- up_write(&grp->list_mutex);
if (!empty)
unsubscribe_port(client, port, grp, &subs->info, ack);
+ up_write(&grp->list_mutex);
}
/* connect two ports */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 74c9600876d6..ef8955abd918 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1707,9 +1707,6 @@ static int azx_first_init(struct azx *chip)
chip->msi = 0;
}
- if (azx_acquire_irq(chip, 0) < 0)
- return -EBUSY;
-
pci_set_master(pci);
synchronize_irq(bus->irq);
@@ -1820,6 +1817,9 @@ static int azx_first_init(struct azx *chip)
return -ENODEV;
}
+ if (azx_acquire_irq(chip, 0) < 0)
+ return -EBUSY;
+
strcpy(card->driver, "HDA-Intel");
strlcpy(card->shortname, driver_short_names[chip->driver_type],
sizeof(card->shortname));
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index a8045b8a2a18..b249b1b85746 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1636,9 +1636,11 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid;
jack = snd_hda_jack_tbl_get(codec, pin_nid);
- if (jack)
+ if (jack) {
jack->block_report = !ret;
-
+ jack->pin_sense = (eld->monitor_present && eld->eld_valid) ?
+ AC_PINSENSE_PRESENCE : 0;
+ }
mutex_unlock(&per_pin->lock);
snd_hda_power_down_pm(codec);
return ret;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 5d8ac2d798df..68d96c2e8cde 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -772,11 +772,10 @@ static int alc_init(struct hda_codec *codec)
if (spec->init_hook)
spec->init_hook(codec);
+ snd_hda_gen_init(codec);
alc_fix_pll(codec);
alc_auto_init_amp(codec, spec->init_amp);
- snd_hda_gen_init(codec);
-
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
return 0;
@@ -5779,7 +5778,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
- SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
+ SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
@@ -6237,7 +6236,7 @@ static int patch_alc269(struct hda_codec *codec)
spec = codec->spec;
spec->gen.shared_mic_vref_pin = 0x18;
- codec->power_save_node = 1;
+ codec->power_save_node = 0;
#ifdef CONFIG_PM
codec->patch_ops.suspend = alc269_suspend;
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index d562e1b9a5d1..5b079709ec8a 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -561,6 +561,7 @@ static int cs42xx8_runtime_resume(struct device *dev)
msleep(5);
regcache_cache_only(cs42xx8->regmap, false);
+ regcache_mark_dirty(cs42xx8->regmap);
ret = regcache_sync(cs42xx8->regmap);
if (ret) {
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 584aab83e478..3e65dc74eb33 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1209,14 +1209,14 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
&max98090_right_rcv_mixer_controls[0],
ARRAY_SIZE(max98090_right_rcv_mixer_controls)),
- SND_SOC_DAPM_MUX("LINMOD Mux", M98090_REG_LOUTR_MIXER,
- M98090_LINMOD_SHIFT, 0, &max98090_linmod_mux),
+ SND_SOC_DAPM_MUX("LINMOD Mux", SND_SOC_NOPM, 0, 0,
+ &max98090_linmod_mux),
- SND_SOC_DAPM_MUX("MIXHPLSEL Mux", M98090_REG_HP_CONTROL,
- M98090_MIXHPLSEL_SHIFT, 0, &max98090_mixhplsel_mux),
+ SND_SOC_DAPM_MUX("MIXHPLSEL Mux", SND_SOC_NOPM, 0, 0,
+ &max98090_mixhplsel_mux),
- SND_SOC_DAPM_MUX("MIXHPRSEL Mux", M98090_REG_HP_CONTROL,
- M98090_MIXHPRSEL_SHIFT, 0, &max98090_mixhprsel_mux),
+ SND_SOC_DAPM_MUX("MIXHPRSEL Mux", SND_SOC_NOPM, 0, 0,
+ &max98090_mixhprsel_mux),
SND_SOC_DAPM_PGA("HP Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_HPLEN_SHIFT, 0, NULL, 0),
diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
index 91879ea95415..01aa75cde571 100644
--- a/sound/soc/codecs/rt5677-spi.c
+++ b/sound/soc/codecs/rt5677-spi.c
@@ -60,13 +60,15 @@ static DEFINE_MUTEX(spi_mutex);
* RT5677_SPI_READ/WRITE_32: Transfer 4 bytes
* RT5677_SPI_READ/WRITE_BURST: Transfer any multiples of 8 bytes
*
- * For example, reading 260 bytes at 0x60030002 uses the following commands:
- * 0x60030002 RT5677_SPI_READ_16 2 bytes
+ * Note:
+ * 16 Bit writes and reads are restricted to the address range
+ * 0x18020000 ~ 0x18021000
+ *
+ * For example, reading 256 bytes at 0x60030004 uses the following commands:
* 0x60030004 RT5677_SPI_READ_32 4 bytes
* 0x60030008 RT5677_SPI_READ_BURST 240 bytes
* 0x600300F8 RT5677_SPI_READ_BURST 8 bytes
* 0x60030100 RT5677_SPI_READ_32 4 bytes
- * 0x60030104 RT5677_SPI_READ_16 2 bytes
*
* Input:
* @read: true for read commands; false for write commands
@@ -81,15 +83,13 @@ static u8 rt5677_spi_select_cmd(bool read, u32 align, u32 remain, u32 *len)
{
u8 cmd;
- if (align == 2 || align == 6 || remain == 2) {
- cmd = RT5677_SPI_READ_16;
- *len = 2;
- } else if (align == 4 || remain <= 6) {
+ if (align == 4 || remain <= 4) {
cmd = RT5677_SPI_READ_32;
*len = 4;
} else {
cmd = RT5677_SPI_READ_BURST;
- *len = min_t(u32, remain & ~7, RT5677_SPI_BURST_LEN);
+ *len = (((remain - 1) >> 3) + 1) << 3;
+ *len = min_t(u32, *len, RT5677_SPI_BURST_LEN);
}
return read ? cmd : cmd + 1;
}
@@ -110,7 +110,7 @@ static void rt5677_spi_reverse(u8 *dst, u32 dstlen, const u8 *src, u32 srclen)
}
}
-/* Read DSP address space using SPI. addr and len have to be 2-byte aligned. */
+/* Read DSP address space using SPI. addr and len have to be 4-byte aligned. */
int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
{
u32 offset;
@@ -126,7 +126,7 @@ int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
if (!g_spi)
return -ENODEV;
- if ((addr & 1) || (len & 1)) {
+ if ((addr & 3) || (len & 3)) {
dev_err(&g_spi->dev, "Bad read align 0x%x(%zu)\n", addr, len);
return -EACCES;
}
@@ -161,13 +161,13 @@ int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
}
EXPORT_SYMBOL_GPL(rt5677_spi_read);
-/* Write DSP address space using SPI. addr has to be 2-byte aligned.
- * If len is not 2-byte aligned, an extra byte of zero is written at the end
+/* Write DSP address space using SPI. addr has to be 4-byte aligned.
+ * If len is not 4-byte aligned, then extra zeros are written at the end
* as padding.
*/
int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)
{
- u32 offset, len_with_pad = len;
+ u32 offset;
int status = 0;
struct spi_transfer t;
struct spi_message m;
@@ -180,22 +180,19 @@ int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)
if (!g_spi)
return -ENODEV;
- if (addr & 1) {
+ if (addr & 3) {
dev_err(&g_spi->dev, "Bad write align 0x%x(%zu)\n", addr, len);
return -EACCES;
}
- if (len & 1)
- len_with_pad = len + 1;
-
memset(&t, 0, sizeof(t));
t.tx_buf = buf;
t.speed_hz = RT5677_SPI_FREQ;
spi_message_init_with_transfers(&m, &t, 1);
- for (offset = 0; offset < len_with_pad;) {
+ for (offset = 0; offset < len;) {
spi_cmd = rt5677_spi_select_cmd(false, (addr + offset) & 7,
- len_with_pad - offset, &t.len);
+ len - offset, &t.len);
/* Construct SPI message header */
buf[0] = spi_cmd;
diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
index fe455c9b8c25..94122de3e758 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -3421,8 +3421,8 @@ static const struct snd_soc_dapm_widget msm_anlg_cdc_dapm_widgets[] = {
msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM,
- 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_spk_pa,
+ SND_SOC_DAPM_PGA_E("SPK PA", MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL,
+ 7, 0, NULL, 0, msm_anlg_cdc_codec_enable_spk_pa,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA_E("LINEOUT PA", MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL,
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 2ccb8bccc9d4..512ec25c9ead 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -43,6 +43,7 @@
#define MCASP_MAX_AFIFO_DEPTH 64
+#ifdef CONFIG_PM
static u32 context_regs[] = {
DAVINCI_MCASP_TXFMCTL_REG,
DAVINCI_MCASP_RXFMCTL_REG,
@@ -65,6 +66,7 @@ struct davinci_mcasp_context {
u32 *xrsr_regs; /* for serializer configuration */
bool pm_state;
};
+#endif
struct davinci_mcasp_ruledata {
struct davinci_mcasp *mcasp;
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3066e068aae5..d420995ed45b 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -171,16 +171,17 @@ config SND_MPC52xx_SOC_EFIKA
endif # SND_POWERPC_SOC
+config SND_SOC_IMX_PCM_FIQ
+ tristate
+ default y if SND_SOC_IMX_SSI=y && (SND_SOC_FSL_SSI=m || SND_SOC_FSL_SPDIF=m) && (MXC_TZIC || MXC_AVIC)
+ select FIQ
+
if SND_IMX_SOC
config SND_SOC_IMX_SSI
tristate
select SND_SOC_FSL_UTILS
-config SND_SOC_IMX_PCM_FIQ
- tristate
- select FIQ
-
comment "SoC Audio support for Freescale i.MX boards:"
config SND_MXC_SOC_WM1133_EV1
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 883087f2b092..38132143b7d5 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -119,13 +119,13 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev,
"fsl,mux-int-port node missing or invalid.\n");
- return ret;
+ goto err;
}
ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port);
if (ret) {
dev_err(&pdev->dev,
"fsl,mux-ext-port node missing or invalid.\n");
- return ret;
+ goto err;
}
/*
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 08b460ba06ef..61d2d955f26a 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -260,12 +260,14 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
case SND_SOC_DAIFMT_CBS_CFS:
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
+ sai->is_slave_mode = false;
break;
case SND_SOC_DAIFMT_CBM_CFM:
sai->is_slave_mode = true;
break;
case SND_SOC_DAIFMT_CBS_CFM:
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
+ sai->is_slave_mode = false;
break;
case SND_SOC_DAIFMT_CBM_CFS:
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c
index b9e42b503a37..4f8bdb7650e8 100644
--- a/sound/soc/fsl/fsl_utils.c
+++ b/sound/soc/fsl/fsl_utils.c
@@ -75,6 +75,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
iprop = of_get_property(dma_np, "cell-index", NULL);
if (!iprop) {
of_node_put(dma_np);
+ of_node_put(dma_channel_np);
return -EINVAL;
}
*dma_id = be32_to_cpup(iprop);
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 9c272d554a95..34544802c6ed 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2376,6 +2376,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
if (! kctl) {
usb_audio_err(state->chip, "cannot malloc kcontrol\n");
+ for (i = 0; i < desc->bNrInPins; i++)
+ kfree(namelist[i]);
kfree(namelist);
kfree(cval);
return -ENOMEM;
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
index 5ad9ee1dd7f6..57187d6790c1 100644
--- a/tools/include/linux/bitops.h
+++ b/tools/include/linux/bitops.h
@@ -3,17 +3,14 @@
#include <asm/types.h>
#include <linux/kernel.h>
-#include <linux/compiler.h>
-
#ifndef __WORDSIZE
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
#endif
#define BITS_PER_LONG __WORDSIZE
+#include <linux/bits.h>
+#include <linux/compiler.h>
-#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
-#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h
new file mode 100644
index 000000000000..2b7b532c1d51
--- /dev/null
+++ b/tools/include/linux/bits.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_BITS_H
+#define __LINUX_BITS_H
+#include <asm/bitsperlong.h>
+
+#define BIT(nr) (1UL << (nr))
+#define BIT_ULL(nr) (1ULL << (nr))
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG))
+#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
+#define BITS_PER_BYTE 8
+
+/*
+ * Create a contiguous bitmask starting at bit position @l and ending at
+ * position @h. For example
+ * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
+ */
+#define GENMASK(h, l) \
+ (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+#define GENMASK_ULL(h, l) \
+ (((~0ULL) - (1ULL << (l)) + 1) & \
+ (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
+
+#endif /* __LINUX_BITS_H */
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 73d192f57dc3..df41deed0320 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -32,6 +32,10 @@
#include <numa.h>
#include <numaif.h>
+#ifndef RUSAGE_THREAD
+# define RUSAGE_THREAD 1
+#endif
+
/*
* Regular printout to the terminal, supressed if -q is specified:
*/
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 62b38f2ff60d..c1944765533c 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -58,6 +58,7 @@ enum intel_pt_pkt_state {
INTEL_PT_STATE_NO_IP,
INTEL_PT_STATE_ERR_RESYNC,
INTEL_PT_STATE_IN_SYNC,
+ INTEL_PT_STATE_TNT_CONT,
INTEL_PT_STATE_TNT,
INTEL_PT_STATE_TIP,
INTEL_PT_STATE_TIP_PGD,
@@ -72,8 +73,9 @@ static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
case INTEL_PT_STATE_NO_IP:
case INTEL_PT_STATE_ERR_RESYNC:
case INTEL_PT_STATE_IN_SYNC:
- case INTEL_PT_STATE_TNT:
+ case INTEL_PT_STATE_TNT_CONT:
return true;
+ case INTEL_PT_STATE_TNT:
case INTEL_PT_STATE_TIP:
case INTEL_PT_STATE_TIP_PGD:
case INTEL_PT_STATE_FUP:
@@ -854,16 +856,20 @@ static uint64_t intel_pt_next_period(struct intel_pt_decoder *decoder)
timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
masked_timestamp = timestamp & decoder->period_mask;
if (decoder->continuous_period) {
- if (masked_timestamp != decoder->last_masked_timestamp)
+ if (masked_timestamp > decoder->last_masked_timestamp)
return 1;
} else {
timestamp += 1;
masked_timestamp = timestamp & decoder->period_mask;
- if (masked_timestamp != decoder->last_masked_timestamp) {
+ if (masked_timestamp > decoder->last_masked_timestamp) {
decoder->last_masked_timestamp = masked_timestamp;
decoder->continuous_period = true;
}
}
+
+ if (masked_timestamp < decoder->last_masked_timestamp)
+ return decoder->period_ticks;
+
return decoder->period_ticks - (timestamp - masked_timestamp);
}
@@ -892,7 +898,10 @@ static void intel_pt_sample_insn(struct intel_pt_decoder *decoder)
case INTEL_PT_PERIOD_TICKS:
timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
masked_timestamp = timestamp & decoder->period_mask;
- decoder->last_masked_timestamp = masked_timestamp;
+ if (masked_timestamp > decoder->last_masked_timestamp)
+ decoder->last_masked_timestamp = masked_timestamp;
+ else
+ decoder->last_masked_timestamp += decoder->period_ticks;
break;
case INTEL_PT_PERIOD_NONE:
case INTEL_PT_PERIOD_MTC:
@@ -1141,7 +1150,9 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
return -ENOENT;
}
decoder->tnt.count -= 1;
- if (!decoder->tnt.count)
+ if (decoder->tnt.count)
+ decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
+ else
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
decoder->tnt.payload <<= 1;
decoder->state.from_ip = decoder->ip;
@@ -1172,7 +1183,9 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
decoder->tnt.count -= 1;
- if (!decoder->tnt.count)
+ if (decoder->tnt.count)
+ decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
+ else
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
if (decoder->tnt.payload & BIT63) {
decoder->tnt.payload <<= 1;
@@ -1192,8 +1205,11 @@ static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
return 0;
}
decoder->ip += intel_pt_insn.length;
- if (!decoder->tnt.count)
+ if (!decoder->tnt.count) {
+ decoder->sample_timestamp = decoder->timestamp;
+ decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
return -EAGAIN;
+ }
decoder->tnt.payload <<= 1;
continue;
}
@@ -2116,6 +2132,7 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
err = intel_pt_walk_trace(decoder);
break;
case INTEL_PT_STATE_TNT:
+ case INTEL_PT_STATE_TNT_CONT:
err = intel_pt_walk_tnt(decoder);
if (err == -EAGAIN)
err = intel_pt_walk_trace(decoder);
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index accb7ece1d3c..3d7af024c73f 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -1,4 +1,5 @@
#include "util.h"
+#include <linux/compiler.h>
#include "linux/string.h"
#define K 1024LL
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index dcc659017976..ee5d1dfe13da 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -76,7 +76,6 @@
#include <sys/ttydefaults.h>
#include <api/fs/tracing_path.h>
#include <termios.h>
-#include <linux/bitops.h>
#include <termios.h>
extern const char *graph_line;