From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752942AbdJLSh1 (ORCPT ); Thu, 12 Oct 2017 14:37:27 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:40828 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751067AbdJLShR (ORCPT ); Thu, 12 Oct 2017 14:37:17 -0400 Date: Thu, 12 Oct 2017 19:36:57 +0100 From: Ben Hutchings To: linux-kernel@vger.kernel.org, Andrew Morton , torvalds@linux-foundation.org, Jiri Slaby , stable@vger.kernel.org Cc: lwn@lwn.net Message-ID: <20171012183657.GJ2971@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="Mit9XoPEfICDqq/V" Content-Disposition: inline X-Mailer: LinuxStableQueue (scripts by bwh) User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: ben@decadent.org.uk Subject: Linux 3.16.49 X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on shadbolt.decadent.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --Mit9XoPEfICDqq/V Content-Type: multipart/mixed; boundary="Ah40dssYA/cDqAW1" Content-Disposition: inline --Ah40dssYA/cDqAW1 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I'm announcing the release of the 3.16.49 kernel. All users of the 3.16 kernel series should upgrade. The updated 3.16.y git tree can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable= =2Egit linux-3.16.y and can be browsed at the normal kernel.org git web browser: https://git.kernel.org/?p=3Dlinux/kernel/git/stable/linux-stable.git The diff from 3.16.48 is attached to this message. Ben. ------------ Documentation/DMA-API.txt | 2 +- Documentation/cgroups/cpusets.txt | 6 +- Makefile | 2 +- arch/arm/include/asm/xen/events.h | 2 +- arch/arm/mach-omap2/sleep34xx.S | 22 +-- arch/arm64/include/asm/elf.h | 11 +- arch/arm64/include/asm/ptrace.h | 34 +---- arch/arm64/kernel/ptrace.c | 89 ++++++++++- arch/arm64/kernel/signal.c | 4 +- arch/arm64/kernel/signal32.c | 2 +- arch/m32r/include/asm/io.h | 11 +- arch/mips/include/asm/branch.h | 5 +- arch/mips/include/asm/kvm_host.h | 1 + arch/mips/include/asm/processor.h | 2 +- arch/mips/kernel/branch.c | 8 +- arch/mips/kernel/module-rela.c | 19 ++- arch/mips/kernel/module.c | 43 ++++-- arch/mips/kernel/ptrace.c | 2 +- arch/mips/kernel/scall32-o32.S | 2 +- arch/mips/kernel/scall64-64.S | 2 +- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- arch/mips/kernel/syscall.c | 15 +- arch/mips/kvm/kvm_locore.S | 1 + arch/mips/kvm/kvm_mips.c | 11 +- arch/mips/kvm/kvm_mips_int.h | 2 + arch/mips/math-emu/cp1emu.c | 38 +++++ arch/parisc/include/asm/dma-mapping.h | 11 +- arch/parisc/kernel/syscall_table.S | 2 +- arch/parisc/mm/fault.c | 2 +- arch/powerpc/include/asm/atomic.h | 4 +- arch/powerpc/include/asm/reg.h | 2 +- arch/powerpc/lib/sstep.c | 13 ++ arch/s390/include/asm/syscall.h | 8 +- arch/sparc/include/asm/head_64.h | 4 + arch/sparc/include/asm/ttable.h | 8 +- arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/cherrs.S | 14 +- arch/sparc/kernel/entry.S | 17 +++ arch/sparc/kernel/fpu_traps.S | 11 +- arch/sparc/kernel/head_64.S | 24 +-- arch/sparc/kernel/misctrap.S | 12 +- arch/sparc/kernel/pci.c | 17 +++ arch/sparc/kernel/rtrap_64.S | 57 ++----- arch/sparc/kernel/signal32.c | 46 ++++-- arch/sparc/kernel/signal_32.c | 41 ++++-- arch/sparc/kernel/signal_64.c | 33 +++-- arch/sparc/kernel/sigutil_32.c | 9 +- arch/sparc/kernel/sigutil_64.c | 10 +- arch/sparc/kernel/spiterrs.S | 18 +-- arch/sparc/kernel/syscalls.S | 36 +++++ arch/sparc/kernel/urtt_fill.S | 98 +++++++++++++ arch/sparc/kernel/utrap.S | 3 +- arch/sparc/kernel/vmlinux.lds.S | 4 + arch/sparc/kernel/winfixup.S | 3 +- arch/sparc/mm/init_64.c | 10 +- arch/x86/boot/compressed/Makefile | 3 + arch/x86/boot/compressed/efi_stub_64.S | 25 ---- arch/x86/boot/compressed/efi_thunk_64.S | 196 +++++++++++++++++++++= ++++ arch/x86/crypto/sha1_ssse3_glue.c | 3 +- arch/x86/include/asm/xen/hypercall.h | 3 + arch/x86/include/uapi/asm/msr-index.h | 2 + arch/x86/kernel/cpu/perf_event_intel.c | 12 +- arch/x86/kernel/nmi_selftest.c | 2 +- arch/x86/kvm/cpuid.h | 9 ++ arch/x86/kvm/vmx.c | 16 +- arch/x86/pci/fixup.c | 52 ++++++- arch/x86/platform/efi/efi_stub_64.S | 161 -------------------- arch/x86/platform/efi/efi_thunk_64.S | 121 ++++++++++++--- drivers/acpi/ec.c | 4 +- drivers/base/power/domain.c | 4 +- drivers/base/power/sysfs.c | 2 + drivers/char/tpm/tpm-sysfs.c | 3 +- drivers/crypto/atmel-sha.c | 4 +- drivers/crypto/caam/caamhash.c | 2 +- drivers/crypto/caam/key_gen.c | 2 +- drivers/crypto/talitos.c | 7 +- drivers/gpu/drm/drm_irq.c | 3 +- drivers/gpu/drm/i915/i915_dma.c | 8 +- drivers/gpu/drm/i915/intel_display.c | 11 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 20 +++ drivers/gpu/drm/msm/hdmi/hdmi_audio.c | 6 +- drivers/gpu/drm/radeon/atombios_encoders.c | 13 +- drivers/i2c/busses/i2c-cadence.c | 6 +- drivers/iio/accel/st_accel_spi.c | 4 - drivers/iio/magnetometer/st_magn_spi.c | 2 - drivers/infiniband/core/cache.c | 61 ++++---- drivers/infiniband/core/device.c | 26 +--- drivers/infiniband/core/uverbs_cmd.c | 9 ++ drivers/input/serio/i8042.c | 12 +- drivers/input/touchscreen/ads7846.c | 8 +- drivers/macintosh/therm_windtunnel.c | 1 + drivers/md/dm.c | 55 +++++++ drivers/md/raid1.c | 5 +- drivers/md/raid5.c | 5 +- drivers/media/pci/saa7164/saa7164-buffer.c | 4 +- drivers/media/pci/saa7164/saa7164-bus.c | 96 ++++++------ drivers/media/pci/saa7164/saa7164-core.c | 13 +- drivers/media/pci/saa7164/saa7164-fw.c | 6 +- drivers/media/pci/saa7164/saa7164-types.h | 4 +- drivers/media/pci/saa7164/saa7164.h | 4 +- drivers/media/rc/mceusb.c | 5 + drivers/misc/ad525x_dpot.c | 2 +- drivers/misc/enclosure.c | 14 +- drivers/net/ethernet/intel/e1000e/netdev.c | 33 ++++- drivers/net/hyperv/netvsc_drv.c | 19 ++- drivers/net/vxlan.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 - drivers/net/wireless/ath/ath9k/tx99.c | 13 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 32 +++- drivers/net/wireless/libertas/mesh.c | 5 +- drivers/net/wireless/mwifiex/cfg80211.c | 37 ++--- drivers/net/wireless/mwifiex/fw.h | 5 - drivers/net/wireless/mwifiex/uap_cmd.c | 22 --- drivers/net/wireless/ti/wlcore/spi.c | 3 +- drivers/parisc/ccio-dma.c | 12 ++ drivers/parisc/dino.c | 5 +- drivers/parisc/lba_pci.c | 6 +- drivers/parisc/sba_iommu.c | 14 ++ drivers/pci/pci-driver.c | 1 + drivers/pci/pci-sysfs.c | 18 +-- drivers/pci/quirks.c | 14 +- drivers/pinctrl/pinctrl-imx.c | 12 +- drivers/rtc/rtc-nuc900.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 3 +- drivers/scsi/scsi_scan.c | 5 +- drivers/scsi/scsi_sysfs.c | 8 +- drivers/scsi/scsi_transport_iscsi.c | 2 +- drivers/scsi/sun_esp.c | 9 +- drivers/scsi/virtio_scsi.c | 12 ++ drivers/spi/spi-atmel.c | 24 ++- drivers/staging/comedi/comedi_fops.c | 1 + drivers/staging/usbip/stub_main.c | 4 + drivers/staging/usbip/stub_tx.c | 4 + drivers/target/iscsi/iscsi_target_configfs.c | 3 + drivers/target/iscsi/iscsi_target_core.h | 9 ++ drivers/target/iscsi/iscsi_target_nego.c | 6 +- drivers/target/iscsi/iscsi_target_parameters.c | 41 ++++-- drivers/target/iscsi/iscsi_target_parameters.h | 2 +- drivers/target/iscsi/iscsi_target_tpg.c | 19 +++ drivers/target/iscsi/iscsi_target_tpg.h | 1 + drivers/target/target_core_transport.c | 9 ++ drivers/tty/serial/samsung.c | 4 +- drivers/tty/serial/sccnxp.c | 15 +- drivers/tty/vt/vt.c | 6 +- drivers/usb/core/quirks.c | 4 + drivers/usb/host/xhci-hub.c | 3 + drivers/usb/host/xhci-pci.c | 12 ++ drivers/usb/host/xhci.h | 1 + drivers/usb/musb/musb_cppi41.c | 24 +-- drivers/usb/serial/cp210x.c | 1 + drivers/usb/serial/option.c | 4 + drivers/usb/serial/qcserial.c | 1 + drivers/vfio/vfio.c | 46 +++++- drivers/video/fbdev/aty/atyfb_base.c | 2 +- fs/btrfs/acl.c | 19 ++- fs/btrfs/extent-tree.c | 2 +- fs/btrfs/file.c | 5 +- fs/btrfs/ioctl.c | 2 +- fs/cifs/cifs_fs_sb.h | 4 + fs/cifs/cifsfs.c | 17 ++- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 80 +++++++++- fs/cifs/dir.c | 20 ++- fs/cifs/file.c | 5 +- fs/cifs/inode.c | 22 ++- fs/dcache.c | 5 +- fs/exec.c | 4 +- fs/ext2/acl.c | 43 ++++-- fs/ext3/acl.c | 21 ++- fs/ext4/acl.c | 25 +++- fs/f2fs/acl.c | 7 +- fs/f2fs/gc.c | 9 +- fs/f2fs/inode.c | 1 + fs/hfsplus/posix_acl.c | 30 ++-- fs/jfs/acl.c | 24 ++- fs/proc/proc_sysctl.c | 10 +- fs/reiserfs/xattr_acl.c | 17 ++- fs/ubifs/journal.c | 8 +- fs/ubifs/tnc.c | 2 + fs/ubifs/ubifs.h | 1 + fs/ubifs/xattr.c | 22 +++ fs/udf/file.c | 9 +- fs/udf/inode.c | 4 +- fs/xfs/xfs_acl.c | 6 +- fs/xfs/xfs_acl.h | 1 + fs/xfs/xfs_dinode.h | 9 +- fs/xfs/xfs_iops.c | 4 +- include/linux/cpumask.h | 17 +++ include/linux/cpuset.h | 4 +- include/linux/net.h | 17 +++ include/linux/pci_ids.h | 7 + include/linux/sched.h | 34 ++++- include/linux/usb/hcd.h | 4 +- include/linux/vfio.h | 2 + include/rdma/ib_verbs.h | 34 +++++ include/scsi/scsi_device.h | 1 + include/uapi/linux/v4l2-dv-timings.h | 30 ++-- kernel/cpuset.c | 9 +- kernel/events/core.c | 15 +- kernel/sched/core.c | 102 +++++++++---- kernel/seccomp.c | 2 +- kernel/sys.c | 4 +- lib/cpumask.c | 32 ++++ mm/memory.c | 14 +- mm/mmap.c | 8 +- mm/slab.c | 4 +- mm/swap.c | 9 +- net/bluetooth/l2cap_core.c | 80 +++++----- net/bluetooth/smp.c | 5 +- net/ipv4/fib_frontend.c | 6 +- net/ipv4/fib_semantics.c | 2 + net/ipv4/ip_output.c | 3 +- net/ipv4/tcp_output.c | 1 + net/ipv6/addrconf.c | 23 +-- net/ipv6/ip6_fib.c | 6 +- net/iucv/af_iucv.c | 8 +- net/l2tp/l2tp_ip.c | 2 +- net/nfc/core.c | 31 ++-- net/sched/cls_api.c | 3 +- net/sunrpc/auth_gss/gss_krb5_crypto.c | 3 +- net/wireless/nl80211.c | 11 +- scripts/tags.sh | 6 + security/apparmor/domain.c | 4 +- sound/pci/oxygen/oxygen_mixer.c | 2 +- sound/soc/soc-compress.c | 6 +- tools/lib/lockdep/uinclude/linux/lockdep.h | 2 +- virt/kvm/vfio.c | 27 +++- 229 files changed, 2414 insertions(+), 1043 deletions(-) Abhilash Kesavan (1): m32r: add definition of ioremap_wc to io.h Adam Borowski (1): vt: fix unchecked __put_user() in tioclinux ioctls Alex Williamson (2): vfio: Fix group release deadlock vfio: New external user group/file match Andrea Arcangeli (1): mm: thp: fix SMP race condition between THP page fault and MADV_DONTN= EED Andrey Gelman (1): Input: ads7846 - correct the value got from SPI Andrey Ryabinin (1): perf/x86: Fix undefined shift on 32-bit kernels Anton Blanchard (1): powerpc: Fix emulation of mfocrf in emulate_step() Arnd Bergmann (2): wlcore: fix 64K page support xen: avoid type warning in xchg_xen_ulong Aurelien Aptel (1): fs/cifs: make share unaccessible at root level mountable Babu Moger (1): sparc/PCI: Fix for panic while enabling SR-IOV Ben Hutchings (4): tools/lib/lockdep: Reduce MAX_LOCK_DEPTH to avoid overflowing lock_ch= ain/: Depth ext3: Don't clear SGID when inheriting ACLs ext3: preserve i_mode if ext2_set_acl() fails Linux 3.16.49 Ben Seri (1): Bluetooth: Properly check L2CAP config option output buffer length Benjamin Herrenschmidt (1): usb: Fix typo in the definition of Endpoint[out]Request Bin Liu (2): usb: musb: cppi41: correct the macro name EP_MODE_AUTOREG_* usb: musb: cppi41: improve rx channel abort routine Bjorn Helgaas (3): PCI: Correct PCI_STD_RESOURCE_END usage PCI: Mark Haswell Power Control Unit as having non-compliant BARs PCI: Work around poweroff & suspend-to-RAM issue on Macbook Pro 11 Bj=C3=B8rn Mork (1): USB: serial: qcserial: new Sierra Wireless EM7305 device ID Boris Pismenny (1): RDMA/uverbs: Check port number supplied by user verbs cmds Brian Norris (1): mwifiex: fixup error cases in mwifiex_add_virtual_intf() Chanwoo Choi (1): serial: samsung: Reorder the sequence of clock control when call s3c2= 4xx_serial_set_termios() Chen Hong (1): Input: i8042 - fix crash at boot time Chen Yu (1): PCI/PM: Restore the status of PCI devices across hibernation Chris Wilson (1): e1000e: Undo e1000e_pm_freeze if __e1000_shutdown fails Cyrille Pitchen (1): spi: atmel: fix corrupted data issue on SAM9 family SoCs Dan Bogdan Nechita (1): misc: ad525x_dpot: Fix the enabling of the "otpXen" attributes Dan Carpenter (5): x86/nmi: Fix timeout test in test_nmi_ipi() scsi: bnx2i: missing error code in bnx2i_ep_connect() libertas: Fix lbs_prb_rsp_limit_set() rtc: rtc-nuc900: fix loop timeout test PM / QoS: return -EINVAL for bogus strings Dave Martin (1): arm64: ptrace: Avoid setting compat FP[SC]R to garbage if get_user fa= ils David Ertman (1): e1000e: Fix Runtime PM blocks EEE link negotiation in S5 David S. Miller (5): sparc64: Fix bootup regressions on some Kconfig combinations. sparc64: Fix sparc64_set_context stack handling. sparc64: Take ctx_alloc_lock properly in hugetlb_setup(). sparc: Harden signal return frame checks. sparc64: Fix return from trap window fill crashes. Devin Heitmueller (1): Add USB quirk for HVR-950q to avoid intermittent device resets Dong Aisheng (1): pinctrl: imx: fix debug message for SHARE_MUX_CONF_REG case Dong Bo (1): arm64: Preventing READ_IMPLIES_EXEC propagation Emmanuel Grumbach (1): iwlwifi: mvm: fix the recovery flow while connecting Eric Biggers (1): parisc: use compat_sys_keyctl() Ernesto A. Fern=C3=A1ndez (6): ext2: preserve i_mode if ext2_set_acl() fails reiserfs: preserve i_mode if __reiserfs_set_acl() fails jfs: preserve i_mode if __jfs_set_acl() fails ext4: preserve i_mode if __ext4_set_acl() fails f2fs: preserve i_mode if __f2fs_set_acl() fails btrfs: preserve i_mode if __btrfs_set_acl() fails Ewan D. Milne (1): scsi: Add STARGET_CREATED_REMOVE state to scsi_target_state Filipe Manana (1): Btrfs: fix invalid extent maps due to hole punching Ganapathi Bhat (1): mwifiex: do not update MCS set from hostapd Gilad Ben-Yossef (1): crypto: atmel - only treat EBUSY as transient if backlog Hans Verkuil (2): saa7164: fix sparse warnings v4l2-dv-timings.h: fix polarity for 4k formats Helge Deller (2): parisc: Report SIGSEGV instead of SIGBUS when running out of stack mm: fix overflow check in expand_upwards() Herbert Xu (1): crypto: sha1-ssse3 - Disable avx2 Horia Geant=C4=83 (1): crypto: caam - fix signals handling Ian Abbott (1): staging: comedi: fix clean-up of comedi_class in comedi_init() Ira Weiny (1): IB/core: Create common start/end port functions Jaegeuk Kim (3): f2fs: load inode's flag from disk f2fs: try to freeze in gc and discard threads f2fs: Don't clear SGID when inheriting ACLs Jamal Hadi Salim (2): net: reflect mark on tcp syn ack packets net sched filters: fix notification of filter delete with proper hand= le James Hogan (5): MIPS: Fix mips_atomic_set() retry condition MIPS: Save static registers before sysmips MIPS: Fix mips_atomic_set() with EVA MIPS: Negate error syscall return in trace MIPS: KVM: Fix modular KVM under QEMU Jan Kara (9): udf: Fix races with i_size changes during readpage udf: Fix deadlock between writeback and udf_setsize() xfs: Don't clear SGID when inheriting ACLs btrfs: Don't clear SGID when inheriting ACLs ext2: Don't clear SGID when inheriting ACLs hfsplus: Don't clear SGID when inheriting ACLs reiserfs: Don't clear SGID when inheriting ACLs jfs: Don't clear SGID when inheriting ACLs ext4: Don't clear SGID when inheriting ACLs Jan Willeke (1): s390/seccomp: fix error return for filtered system calls Jarkko Sakkinen (1): tpm: fix a kernel memory leak in tpm-sysfs.c Jason A. Donenfeld (4): Bluetooth: use constant time memory comparison for secret values sunrpc: use constant time memory comparison for mac net_dbg_ratelimited: turn into no-op when !DEBUG net: Don't forget pr_fmt on net_dbg_ratelimited for CONFIG_DYNAMIC_DE= BUG Jason S. McMullan (3): PCI: Support PCIe devices with short cfg_size PCI: Add Netronome vendor and device IDs PCI: Limit config space size for Netronome NFP6000 family Javier Martinez Canillas (1): macintosh/therm_windtunnel: Export I2C module alias information Jeremie Rapin (1): USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick Jiahau Chang (1): xhci: Limit USB2 port wake support for AMD Promontory hosts Jiang Yi (1): target: Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce Jim Mattson (4): kvm: vmx: Do not disable intercepts for BNDCFGS kvm: x86: Guest BNDCFGS requires guest MPX support kvm: vmx: Check value written to IA32_BNDCFGS kvm: nVMX: Don't allow L2 to access the hardware CR8 Jiri Olsa (1): s390/syscalls: Fix out of bounds arguments access Johan Hovold (4): mceusb: fix memory leaks in error path USB: serial: option: add two Longcheer device ids NFC: fix broken device allocation scsi: sun_esp: fix device reference leaks Josef Bacik (1): Btrfs: don't use src fd for printk Kees Cook (1): sched: move no_new_privs into new atomic flags Krzysztof Kozlowski (1): PM / Domains: Fix unsafe iteration over modified list of device links Lauro Ramos Venancio (1): sched/topology: Refactor function build_overlap_sched_groups() Liu Bo (1): Btrfs: skip commit transaction if we don't have enough pinned bytes Liviu Dudau (1): drm/msm/hdmi: Use bitwise operators when building register values Lorenzo Bianconi (2): iio: accel: st_accel_spi: fix spi_device_id table iio: magnetometer: st_magn_spi: fix spi_device_id table Lubomir Rintel (1): ipv6: always add flag an address that failed DAD with DADFAILED Luis R. Rodriguez (1): sysctl: fix lax sysctl_check_table() sanity check Lukasz Odzioba (1): mm/swap.c: flush lru pvecs on compound page arrival Lv Zheng (1): Revert "ACPI / EC: Add support to disallow QR_EC to be issued before = completing previous QR_EC" Maciej W. Rozycki (4): MIPS: math-emu: Prevent wrong ISA mode instruction emulation MIPS: Actually decode JALX in `__compute_return_epc_for_insn' MIPS: Fix unaligned PC interpretation in `compute_return_epc' MIPS: Send SIGILL for BPOSGE32 in `__compute_return_epc_for_insn' Marek Marczykowski-G=C3=B3recki (1): x86/xen: allow userspace access during hypercalls Mario Kleiner (1): drm/radeon: Fix eDP for single-display iMac10,1 (v2) Mark Rutland (1): arm64: Rework valid_user_regs Martin Hicks (1): crypto: talitos - Extend max key length for SHA384/512-HMAC and AEAD Mateusz Jurczyk (1): af_iucv: Move sockaddr length checks to before accessing sa_family in= bind and connect handlers Matt Fleming (1): x86/efi: Avoid triple faults during EFI mixed mode calls Matt Weber (1): i2c: cadance: fix ctrl/addr reg write order Maurizio Lombardi (1): scsi: ses: do not add a device to an enclosure if enclosure_add_links= () fails. Miaoqing Pan (2): ath9k: fix tx99 use after free ath9k: fix tx99 bus error Michael Ellerman (1): powerpc/64: Fix atomic64_inc_not_zero() to return an int Michael Grzeschik (1): usb: usbip: set buffer pointers to NULL after free Michal Hocko (1): mm/mmap.c: do not blow on PROT_NONE MAP_FIXED holes in the stack Mike Frysinger (1): sparc: Fix system call tracing register handling. Mikulas Patocka (2): md: don't use flush_signals in userspace processes dm: flush queued bios when process blocks to avoid deadlock Nicholas Bellinger (1): iscsi-target: Add login_keys_workaround attribute for non RFC initiat= ors Oliver O'Halloran (1): powerpc/asm: Mark cr0 as clobbered in mftb() Palik, Imre (1): perf/x86: Honor the architectural performance monitoring version Paolo Abeni (2): net/route: enforce hoplimit max value ipv4/fib: don't warn when primary address is missing if in_dev is dead Paolo Bonzini (1): scsi: virtio_scsi: let host do exception handling Paul Burton (2): MIPS: Bail on unsupported module relocs MIPS: module: Ensure we always clean up r_mips_hi16_list Paul H=C3=BCber (1): l2tp: avoid use-after-free caused by l2tp_ip_backlog_recv Peter Zijlstra (5): sched/fair, cpumask: Export for_each_cpu_wrap() sched/topology: Fix building of overlapping sched-groups sched/topology: Fix overlapping sched_group_mask sched/topology: Fix overlapping sched_group_capacity perf/core: Correct event creation with PERF_FORMAT_GROUP Rabin Vincent (1): CIFS: fix circular locking dependency Ralf Baechle (1): MIPS: Fix 64k page support for 32 bit kernels. Richard Wareing (1): xfs: XFS_IS_REALTIME_INODE() should be false if no rt device present Richard Weinberger (2): ubifs: Correctly evict xattr inodes ubifs: Don't leak kernel memory to the MTD Rob Clark (1): drm/irq: BUG_ON() -> WARN_ON() Roopa Prabhu (1): vxlan: dont migrate permanent fdb entries during learn Sabrina Dubroca (1): ipv6: dad: don't remove dynamic addresses if link is down Sachin Prabhu (5): Fix memory leaks in cifs_do_mount() Compare prepaths when comparing superblocks Move check for prefix path to within cifs_get_root() Fix regression which breaks DFS mounting Fix match_prepath() Sahitya Tummala (1): fs/dcache.c: fix spin lockup issue on nlru->lock Satish Babu Patakokila (1): ASoC: compress: Derive substream from stream based on direction Simon Horman (2): PCI: Add Netronome NFP4000 PF device ID PCI: Limit config space size for Netronome NFP4000 Srinivas Dasari (3): cfg80211: Check if PMKID attribute is of expected size cfg80211: Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE cfg80211: Validate frequencies nested in NL80211_ATTR_SCAN_FREQUENCIES Stephen Hemminger (1): netvsc: fix incorrect receive checksum offloading Steven Toth (1): saa7164: fix double fetch PCIe access condition Sudip Mukherjee (1): m32r: add io*_rep helpers Thomas Bogendoerfer (2): Fix serial console on SNI RM400 machines parisc: DMA API: return error instead of BUG_ON for dma ops on non dm= a devs Tim Bingham (1): net: Implement net_dbg_ratelimited() for CONFIG_DYNAMIC_DEBUG case Tomer Barletz (1): ALSA: oxygen: Fix logical-not-parentheses warning Tony Lindgren (1): ARM: OMAP3: Fix booting with thumb2 kernel Ville Syrj=C3=A4l=C3=A4 (2): drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail drm/i915: Disable MSI for all pre-gen5 Vladis Dronov (2): nl80211: check for the required netlink attributes presence video: fbdev: aty: do not leak uninitialized padding in clk to usersp= ace Wolfram Sang (1): Documentation: DMA API: fix a typo in a function name Xin Long (1): scsi: scsi_transport_iscsi: fix the issue that iscsi_if_rx doesn't pa= rse nlmsg properly Yuval Shaia (1): IB/core: Add inline function to validate port Zefan Li (3): sched: fix confusing PFA_NO_NEW_PRIVS constant sched: add macros to define bitops for task atomic flags cpuset: PF_SPREAD_PAGE and PF_SPREAD_SLAB should be atomic flags Zhihui Zhang (1): sched: Rename a misleading variable in build_overlap_sched_groups() --Ah40dssYA/cDqAW1 Content-Type: text/x-diff; charset=UTF-8; name="linux-3.16.49.patch" Content-Disposition: attachment; filename="linux-3.16.49.patch" Content-Transfer-Encoding: quoted-printable diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 52088408668a..8a320ab1f43d 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -691,7 +691,7 @@ of preallocated entries is defined per architecture. If= it is too low for you boot with 'dma_debug_entries=3D' to overwrite the architectural default. =20 -void debug_dmap_mapping_error(struct device *dev, dma_addr_t dma_addr); +void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); =20 dma-debug interface debug_dma_mapping_error() to debug drivers that fail to check DMA mapping errors on addresses returned by dma_map_single() and diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpus= ets.txt index 7740038d82bc..3c94ff3f9693 100644 --- a/Documentation/cgroups/cpusets.txt +++ b/Documentation/cgroups/cpusets.txt @@ -345,14 +345,14 @@ the named feature on. The implementation is simple. =20 Setting the flag 'cpuset.memory_spread_page' turns on a per-process flag -PF_SPREAD_PAGE for each task that is in that cpuset or subsequently +PFA_SPREAD_PAGE for each task that is in that cpuset or subsequently joins that cpuset. The page allocation calls for the page cache -is modified to perform an inline check for this PF_SPREAD_PAGE task +is modified to perform an inline check for this PFA_SPREAD_PAGE task flag, and if set, a call to a new routine cpuset_mem_spread_node() returns the node to prefer for the allocation. =20 Similarly, setting 'cpuset.memory_spread_slab' turns on the flag -PF_SPREAD_SLAB, and appropriately marked slab caches will allocate +PFA_SPREAD_SLAB, and appropriately marked slab caches will allocate pages from the node returned by cpuset_mem_spread_node(). =20 The cpuset_mem_spread_node() routine is also simple. It uses the diff --git a/Makefile b/Makefile index 890d673d9391..f15a93eded21 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION =3D 3 PATCHLEVEL =3D 16 -SUBLEVEL =3D 48 +SUBLEVEL =3D 49 EXTRAVERSION =3D NAME =3D Museum of Fishiegoodies =20 diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/e= vents.h index 8b1f37bfeeec..b7aadab9b0e8 100644 --- a/arch/arm/include/asm/xen/events.h +++ b/arch/arm/include/asm/xen/events.h @@ -16,7 +16,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) return raw_irqs_disabled_flags(regs->ARM_cpsr); } =20 -#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \ +#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((long long*)(p= tr),\ atomic64_t, \ counter), (val)) =20 diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34x= x.S index d1dedc8195ed..eafd120b53f1 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -203,23 +203,8 @@ ENTRY(omap34xx_cpu_suspend) */ ldr r1, kernel_flush blx r1 - /* - * The kernel doesn't interwork: v7_flush_dcache_all in particluar will - * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. - * This sequence switches back to ARM. Note that .align may insert a - * nop: bx pc needs to be word-aligned in order to work. - */ - THUMB( .thumb ) - THUMB( .align ) - THUMB( bx pc ) - THUMB( nop ) - .arm - b omap3_do_wfi - -/* - * Local variables - */ +ENDPROC(omap34xx_cpu_suspend) omap3_do_wfi_sram_addr: .word omap3_do_wfi_sram kernel_flush: @@ -364,10 +349,7 @@ ENTRY(omap3_do_wfi) * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ ldmfd sp!, {r4 - r11, pc} @ restore regs and return - -/* - * Local variables - */ +ENDPROC(omap3_do_wfi) sdrc_power: .word SDRC_POWER_V cm_idlest1_core: diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 922ff638669e..713852f1b1ff 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -135,7 +135,11 @@ extern unsigned long randomize_et_dyn(unsigned long ba= se); */ #define ELF_PLAT_INIT(_r, load_addr) (_r)->regs[0] =3D 0 =20 -#define SET_PERSONALITY(ex) clear_thread_flag(TIF_32BIT); +#define SET_PERSONALITY(ex) \ +({ \ + clear_thread_flag(TIF_32BIT); \ + current->personality &=3D ~READ_IMPLIES_EXEC; \ +}) =20 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes= */ #define ARCH_DLINFO \ @@ -183,6 +187,11 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT= _ELF_NGREG]; ((x)->e_flags & EF_ARM_EABI_MASK)) =20 #define compat_start_thread compat_start_thread +/* + * Unlike the native SET_PERSONALITY macro, the compat version inherits + * READ_IMPLIES_EXEC across a fork() since this is the behaviour on + * arch/arm/. + */ #define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT); #define COMPAT_ARCH_DLINFO extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrac= e.h index 88d6e2436808..300a382ed88f 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -58,6 +58,8 @@ #define COMPAT_PSR_Z_BIT 0x40000000 #define COMPAT_PSR_N_BIT 0x80000000 #define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */ +#define COMPAT_PSR_GE_MASK 0x000f0000 + /* * These are 'magic' values for PTRACE_PEEKUSR that return info about wher= e a * process is located in memory. @@ -144,35 +146,9 @@ static inline unsigned long regs_return_value(struct p= t_regs *regs) return regs->regs[0]; } =20 -/* - * Are the current registers suitable for user mode? (used to maintain - * security in signal handlers) - */ -static inline int valid_user_regs(struct user_pt_regs *regs) -{ - if (user_mode(regs) && (regs->pstate & PSR_I_BIT) =3D=3D 0) { - regs->pstate &=3D ~(PSR_F_BIT | PSR_A_BIT); - - /* The T bit is reserved for AArch64 */ - if (!(regs->pstate & PSR_MODE32_BIT)) - regs->pstate &=3D ~COMPAT_PSR_T_BIT; - - return 1; - } - - /* - * Force PSR to something logical... - */ - regs->pstate &=3D PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \ - COMPAT_PSR_T_BIT | PSR_MODE32_BIT; - - if (!(regs->pstate & PSR_MODE32_BIT)) { - regs->pstate &=3D ~COMPAT_PSR_T_BIT; - regs->pstate |=3D PSR_MODE_EL0t; - } - - return 0; -} +/* We must avoid circular header include via sched.h */ +struct task_struct; +int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task); =20 #define instruction_pointer(regs) ((unsigned long)(regs)->pc) =20 diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 07c5f63a3362..53bdc598d1c1 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -45,6 +45,10 @@ #define CREATE_TRACE_POINTS #include =20 +#ifndef DBG_SPSR_SS +#define DBG_SPSR_SS (1 << 21) +#endif + /* * TODO: does not yet catch signals sent when the child dies. * in exit.c or in signal.c. @@ -501,7 +505,7 @@ static int gpr_set(struct task_struct *target, const st= ruct user_regset *regset, if (ret) return ret; =20 - if (!valid_user_regs(&newregs)) + if (!valid_user_regs(&newregs, target)) return -EINVAL; =20 task_pt_regs(target)->user_regs =3D newregs; @@ -733,7 +737,7 @@ static int compat_gpr_set(struct task_struct *target, =20 } =20 - if (valid_user_regs(&newregs.user_regs)) + if (valid_user_regs(&newregs.user_regs, target)) *task_pt_regs(target) =3D newregs; else ret =3D -EINVAL; @@ -787,8 +791,10 @@ static int compat_vfp_set(struct task_struct *target, =20 if (count && !ret) { ret =3D get_user(fpscr, (compat_ulong_t *)ubuf); - uregs->fpsr =3D fpscr & VFP_FPSCR_STAT_MASK; - uregs->fpcr =3D fpscr & VFP_FPSCR_CTRL_MASK; + if (!ret) { + uregs->fpsr =3D fpscr & VFP_FPSCR_STAT_MASK; + uregs->fpcr =3D fpscr & VFP_FPSCR_CTRL_MASK; + } } =20 fpsimd_flush_task_state(target); @@ -1136,3 +1142,78 @@ asmlinkage void syscall_trace_exit(struct pt_regs *r= egs) if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT); } + +/* + * Bits which are always architecturally RES0 per ARM DDI 0487A.h + * Userspace cannot use these until they have an architectural meaning. + * We also reserve IL for the kernel; SS is handled dynamically. + */ +#define SPSR_EL1_AARCH64_RES0_BITS \ + (GENMASK_ULL(63,32) | GENMASK_ULL(27, 22) | GENMASK_ULL(20, 10) | \ + GENMASK_ULL(5, 5)) +#define SPSR_EL1_AARCH32_RES0_BITS \ + (GENMASK_ULL(63,32) | GENMASK_ULL(24, 22) | GENMASK_ULL(20,20)) + +static int valid_compat_regs(struct user_pt_regs *regs) +{ + regs->pstate &=3D ~SPSR_EL1_AARCH32_RES0_BITS; + + /* Force kernel endianness on user space */ + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) + regs->pstate |=3D COMPAT_PSR_E_BIT; + else + regs->pstate &=3D ~COMPAT_PSR_E_BIT; + + if (user_mode(regs) && (regs->pstate & PSR_MODE32_BIT) && + (regs->pstate & COMPAT_PSR_A_BIT) =3D=3D 0 && + (regs->pstate & COMPAT_PSR_I_BIT) =3D=3D 0 && + (regs->pstate & COMPAT_PSR_F_BIT) =3D=3D 0) { + return 1; + } + + /* + * Force PSR to a valid 32-bit EL0t, preserving the same bits as + * arch/arm. + */ + regs->pstate &=3D COMPAT_PSR_N_BIT | COMPAT_PSR_Z_BIT | + COMPAT_PSR_C_BIT | COMPAT_PSR_V_BIT | + COMPAT_PSR_Q_BIT | COMPAT_PSR_IT_MASK | + COMPAT_PSR_GE_MASK | COMPAT_PSR_E_BIT | + COMPAT_PSR_T_BIT; + regs->pstate |=3D PSR_MODE32_BIT; + + return 0; +} + +static int valid_native_regs(struct user_pt_regs *regs) +{ + regs->pstate &=3D ~SPSR_EL1_AARCH64_RES0_BITS; + + if (user_mode(regs) && !(regs->pstate & PSR_MODE32_BIT) && + (regs->pstate & PSR_D_BIT) =3D=3D 0 && + (regs->pstate & PSR_A_BIT) =3D=3D 0 && + (regs->pstate & PSR_I_BIT) =3D=3D 0 && + (regs->pstate & PSR_F_BIT) =3D=3D 0) { + return 1; + } + + /* Force PSR to a valid 64-bit EL0t */ + regs->pstate &=3D PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT; + + return 0; +} + +/* + * Are the current registers suitable for user mode? (used to maintain + * security in signal handlers) + */ +int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task) +{ + if (!test_tsk_thread_flag(task, TIF_SINGLESTEP)) + regs->pstate &=3D ~DBG_SPSR_SS; + + if (is_compat_thread(task_thread_info(task))) + return valid_compat_regs(regs); + else + return valid_native_regs(regs); +} diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 6357b9c6c90e..d1ae7c217ba9 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -115,7 +115,7 @@ static int restore_sigframe(struct pt_regs *regs, */ regs->syscallno =3D ~0UL; =20 - err |=3D !valid_user_regs(®s->user_regs); + err |=3D !valid_user_regs(®s->user_regs, current); =20 if (err =3D=3D 0) { struct fpsimd_context *fpsimd_ctx =3D @@ -322,7 +322,7 @@ static void handle_signal(unsigned long sig, struct k_s= igaction *ka, /* * Check that the resulting registers are actually sane. */ - ret |=3D !valid_user_regs(®s->user_regs); + ret |=3D !valid_user_regs(®s->user_regs, current); =20 if (ret !=3D 0) { force_sigsegv(sig, tsk); diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index e3ac8f0c0fc7..03520c650701 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -350,7 +350,7 @@ static int compat_restore_sigframe(struct pt_regs *regs, */ regs->syscallno =3D ~0UL; =20 - err |=3D !valid_user_regs(®s->user_regs); + err |=3D !valid_user_regs(®s->user_regs, current); =20 aux =3D (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; if (err =3D=3D 0) diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h index 4010f1fc5b65..cea944caca61 100644 --- a/arch/m32r/include/asm/io.h +++ b/arch/m32r/include/asm/io.h @@ -67,6 +67,7 @@ static inline void __iomem *ioremap(unsigned long offset,= unsigned long size) =20 extern void iounmap(volatile void __iomem *addr); #define ioremap_nocache(off,size) ioremap(off,size) +#define ioremap_wc ioremap_nocache =20 /* * IO bus memory addresses are also 1:1 with the physical address @@ -162,13 +163,21 @@ static inline void _writel(unsigned long l, unsigned = long addr) #define __raw_writew writew #define __raw_writel writel =20 -#define ioread8 read +#define ioread8 readb #define ioread16 readw #define ioread32 readl #define iowrite8 writeb #define iowrite16 writew #define iowrite32 writel =20 +#define ioread8_rep(p, dst, count) insb((unsigned long)(p), (dst), (count)) +#define ioread16_rep(p, dst, count) insw((unsigned long)(p), (dst), (count= )) +#define ioread32_rep(p, dst, count) insl((unsigned long)(p), (dst), (count= )) + +#define iowrite8_rep(p, src, count) outsb((unsigned long)(p), (src), (coun= t)) +#define iowrite16_rep(p, src, count) outsw((unsigned long)(p), (src), (cou= nt)) +#define iowrite32_rep(p, src, count) outsl((unsigned long)(p), (src), (cou= nt)) + #define mmiowb() =20 #define flush_write_buffers() do { } while (0) /* M32R_FIXME */ diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h index de781cf54bc7..da80878f2c0d 100644 --- a/arch/mips/include/asm/branch.h +++ b/arch/mips/include/asm/branch.h @@ -74,10 +74,7 @@ static inline int compute_return_epc(struct pt_regs *reg= s) return __microMIPS_compute_return_epc(regs); if (cpu_has_mips16) return __MIPS16e_compute_return_epc(regs); - return regs->cp0_epc; - } - - if (!delay_slot(regs)) { + } else if (!delay_slot(regs)) { regs->cp0_epc +=3D 4; return 0; } diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_h= ost.h index f8cdc274173a..e31b2461cf40 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -378,6 +378,7 @@ struct kvm_mips_tlb { #define KVM_MIPS_GUEST_TLB_SIZE 64 struct kvm_vcpu_arch { void *host_ebase, *guest_ebase; + int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); unsigned long host_stack; unsigned long host_gp; =20 diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/proc= essor.h index ad70cba8daff..3a05491b851e 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -51,7 +51,7 @@ extern unsigned int vced_count, vcei_count; * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ -#define TASK_SIZE 0x7fff8000UL +#define TASK_SIZE 0x80000000UL #endif =20 #ifdef __KERNEL__ diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 4d7d99d601cc..5d34d60919f1 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -396,7 +396,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs) * * @regs: Pointer to pt_regs * @insn: branch instruction to decode - * @returns: -EFAULT on error and forces SIGBUS, and on success + * @returns: -EFAULT on error and forces SIGILL, and on success * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after * evaluating the branch. */ @@ -493,6 +493,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, /* * These are unconditional and in j_format. */ + case jalx_op: case jal_op: regs->regs[31] =3D regs->cp0_epc + 8; case j_op: @@ -632,8 +633,9 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, return ret; =20 sigill: - printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->com= m); - force_sig(SIGBUS, current); + pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n", + current->comm); + force_sig(SIGILL, current); return -EFAULT; } EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn); diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c index 2b70723071c3..9083d63b765c 100644 --- a/arch/mips/kernel/module-rela.c +++ b/arch/mips/kernel/module-rela.c @@ -109,9 +109,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *= strtab, struct module *me) { Elf_Mips_Rela *rel =3D (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; int res; =20 @@ -134,9 +135,21 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *= strtab, return -ENOENT; } =20 - v =3D sym->st_value + rel[i].r_addend; + type =3D ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rela)) + handler =3D reloc_handlers_rela[type]; + else + handler =3D NULL; =20 - res =3D reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); + if (!handler) { + pr_err("%s: Unknown relocation type %u\n", + me->name, type); + return -EINVAL; + } + + v =3D sym->st_value + rel[i].r_addend; + res =3D handler(me, location, v); if (res) return res; } diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 2a52568dbcd6..cd4c8412869d 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -197,11 +197,12 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *str= tab, struct module *me) { Elf_Mips_Rel *rel =3D (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; - int res; + int err =3D 0; =20 pr_debug("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -220,30 +221,46 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *str= tab, continue; printk(KERN_WARNING "%s: Unknown symbol %s\n", me->name, strtab + sym->st_name); - return -ENOENT; + err =3D -ENOENT; + goto out; } =20 - v =3D sym->st_value; + type =3D ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rel)) + handler =3D reloc_handlers_rel[type]; + else + handler =3D NULL; + + if (!handler) { + pr_err("%s: Unknown relocation type %u\n", + me->name, type); + err =3D -EINVAL; + goto out; + } =20 - res =3D reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v); - if (res) - return res; + v =3D sym->st_value; + err =3D handler(me, location, v); + if (err) + goto out; } =20 +out: /* - * Normally the hi16 list should be deallocated at this point. A + * Normally the hi16 list should be deallocated at this point. A * malformed binary however could contain a series of R_MIPS_HI16 - * relocations not followed by a R_MIPS_LO16 relocation. In that - * case, free up the list and return an error. + * relocations not followed by a R_MIPS_LO16 relocation, or if we hit + * an error processing a reloc we might have gotten here before + * reaching the R_MIPS_LO16. In either case, free up the list and + * return an error. */ if (me->arch.r_mips_hi16_list) { free_relocation_chain(me->arch.r_mips_hi16_list); me->arch.r_mips_hi16_list =3D NULL; - - return -ENOEXEC; + err =3D err ?: -ENOEXEC; } =20 - return 0; + return err; } =20 /* Given an address, look for it in the module exception tables. */ diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index aae71198b515..cdb8cc7800a2 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -804,7 +804,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *reg= s) audit_syscall_exit(regs); =20 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_exit(regs, regs->regs[2]); + trace_sys_exit(regs, regs_return_value(regs)); =20 if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, 0); diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 3245474f19d5..bc1d0c710269 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -363,7 +363,7 @@ EXPORT(sys_call_table) PTR sys_writev PTR sys_cacheflush PTR sys_cachectl - PTR sys_sysmips + PTR __sys_sysmips PTR sys_ni_syscall /* 4150 */ PTR sys_getsid PTR sys_fdatasync diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index b204352a7d56..45c539b085e2 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -318,7 +318,7 @@ EXPORT(sys_call_table) PTR sys_sched_getaffinity PTR sys_cacheflush PTR sys_cachectl - PTR sys_sysmips + PTR __sys_sysmips PTR sys_io_setup /* 5200 */ PTR sys_io_destroy PTR sys_io_getevents diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 28a2cb2c6c9b..e1eeb09fc2eb 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -307,7 +307,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_sched_getaffinity PTR sys_cacheflush PTR sys_cachectl - PTR sys_sysmips + PTR __sys_sysmips PTR compat_sys_io_setup /* 6200 */ PTR sys_io_destroy PTR compat_sys_io_getevents diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 3b726b9229b4..37361502d63b 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -358,7 +358,7 @@ EXPORT(sys32_call_table) PTR compat_sys_writev PTR sys_cacheflush PTR sys_cachectl - PTR sys_sysmips + PTR __sys_sysmips PTR sys_ni_syscall /* 4150 */ PTR sys_getsid PTR sys_fdatasync diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 4a4f9dda5658..1c864e20156f 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -28,6 +28,7 @@ #include =20 #include +#include #include #include #include @@ -137,10 +138,12 @@ static inline int mips_atomic_set(unsigned long addr,= unsigned long new) __asm__ __volatile__ ( " .set arch=3Dr4000 \n" " li %[err], 0 \n" - "1: ll %[old], (%[addr]) \n" + "1: \n" + user_ll("%[old]", "(%[addr])") " move %[tmp], %[new] \n" - "2: sc %[tmp], (%[addr]) \n" - " bnez %[tmp], 4f \n" + "2: \n" + user_sc("%[tmp]", "(%[addr])") + " beqz %[tmp], 4f \n" "3: \n" " .subsection 2 \n" "4: b 1b \n" @@ -197,6 +200,12 @@ static inline int mips_atomic_set(unsigned long addr, = unsigned long new) unreachable(); } =20 +/* + * mips_atomic_set() normally returns directly via syscall_exit potentially + * clobbering static registers, so be sure to preserve them. + */ +save_static_function(sys_sysmips); + SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2) { switch (cmd) { diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S index fc24acb3a837..a397c959a391 100644 --- a/arch/mips/kvm/kvm_locore.S +++ b/arch/mips/kvm/kvm_locore.S @@ -229,6 +229,7 @@ FEXPORT(__kvm_mips_load_k0k1) =20 /* Jump to guest */ eret +EXPORT(__kvm_mips_vcpu_run_end) =20 VECTOR(MIPSX(exception), unknown) /* diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index 263c6c1c9bbb..64f14f6bca52 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -342,6 +342,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,= unsigned int id) memcpy(gebase + offset, mips32_GuestException, mips32_GuestExceptionEnd - mips32_GuestException); =20 +#ifdef MODULE + offset +=3D mips32_GuestExceptionEnd - mips32_GuestException; + memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run, + __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run); + vcpu->arch.vcpu_run =3D gebase + offset; +#else + vcpu->arch.vcpu_run =3D __kvm_mips_vcpu_run; +#endif + /* Invalidate the icache for these ranges */ flush_icache_range((unsigned long)gebase, (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); @@ -426,7 +435,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, stru= ct kvm_run *run) =20 kvm_guest_enter(); =20 - r =3D __kvm_mips_vcpu_run(run, vcpu); + r =3D vcpu->arch.vcpu_run(run, vcpu); =20 kvm_guest_exit(); local_irq_enable(); diff --git a/arch/mips/kvm/kvm_mips_int.h b/arch/mips/kvm/kvm_mips_int.h index 20da7d29eede..bf41ea36210e 100644 --- a/arch/mips/kvm/kvm_mips_int.h +++ b/arch/mips/kvm/kvm_mips_int.h @@ -27,6 +27,8 @@ #define MIPS_EXC_MAX 12 /* XXXSL More to follow */ =20 +extern char __kvm_mips_vcpu_run_end[]; + #define C_TI (_ULCAST_(1) << 30) =20 #define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0) diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 22a2e15bd91b..bd0ad058c135 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1856,6 +1856,35 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_= fpu_struct *ctx, return 0; } =20 +/* + * Emulate FPU instructions. + * + * If we use FPU hardware, then we have been typically called to handle + * an unimplemented operation, such as where an operand is a NaN or + * denormalized. In that case exit the emulation loop after a single + * iteration so as to let hardware execute any subsequent instructions. + * + * If we have no FPU hardware or it has been disabled, then continue + * emulating floating-point instructions until one of these conditions + * has occurred: + * + * - a non-FPU instruction has been encountered, + * + * - an attempt to emulate has ended with a signal, + * + * - the ISA mode has been switched. + * + * We need to terminate the emulation loop if we got switched to the + * MIPS16 mode, whether supported or not, so that we do not attempt + * to emulate a MIPS16 instruction as a regular MIPS FPU instruction. + * Similarly if we got switched to the microMIPS mode and only the + * regular MIPS mode is supported, so that we do not attempt to emulate + * a microMIPS instruction as a regular MIPS FPU instruction. Or if + * we got switched to the regular MIPS mode and only the microMIPS mode + * is supported, so that we do not attempt to emulate a regular MIPS + * instruction that should cause an Address Error exception instead. + * For simplicity we always terminate upon an ISA mode switch. + */ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *= ctx, int has_fpu, void *__user *fault_addr) { @@ -1943,6 +1972,15 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, st= ruct mips_fpu_struct *ctx, break; if (sig) break; + /* + * We have to check for the ISA bit explicitly here, + * because `get_isa16_mode' may return 0 if support + * for code compression has been globally disabled, + * or otherwise we may produce the wrong signal or + * even proceed successfully where we must not. + */ + if ((xcp->cp0_epc ^ prevepc) & 0x1) + break; =20 cond_resched(); } while (xcp->cp0_epc > prevepc); diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/as= m/dma-mapping.h index d0eae5f2bd87..4fb62add2636 100644 --- a/arch/parisc/include/asm/dma-mapping.h +++ b/arch/parisc/include/asm/dma-mapping.h @@ -39,6 +39,8 @@ struct hppa_dma_ops { ** flush/purge and allocate "regular" cacheable pages for everything. */ =20 +#define DMA_ERROR_CODE (~(dma_addr_t)0) + #ifdef CONFIG_PA11 extern struct hppa_dma_ops pcxl_dma_ops; extern struct hppa_dma_ops pcx_dma_ops; @@ -209,12 +211,13 @@ parisc_walk_tree(struct device *dev) break; } } - BUG_ON(!dev->platform_data); return dev->platform_data; } - =09 -#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu) -=09 + +#define GET_IOC(dev) ({ \ + void *__pdata =3D parisc_walk_tree(dev); \ + __pdata ? HBA_DATA(__pdata)->iommu : NULL; \ +}) =20 #ifdef CONFIG_IOMMU_CCIO struct parisc_device; diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscal= l_table.S index 3cd1c435c306..cd734c18de6b 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -361,7 +361,7 @@ ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */ ENTRY_SAME(add_key) ENTRY_SAME(request_key) /* 265 */ - ENTRY_SAME(keyctl) + ENTRY_COMP(keyctl) ENTRY_SAME(ioprio_set) ENTRY_SAME(ioprio_get) ENTRY_SAME(inotify_init) diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 50d64a7fc672..3b7c02f9b726 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -303,7 +303,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long = code, case 15: /* Data TLB miss fault/Data page fault */ /* send SIGSEGV when outside of vma */ if (!vma || - address < vma->vm_start || address > vma->vm_end) { + address < vma->vm_start || address >=3D vma->vm_end) { si.si_signo =3D SIGSEGV; si.si_code =3D SEGV_MAPERR; break; diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/a= tomic.h index 28992d012926..f7f16e9852d8 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -497,7 +497,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v= , long a, long u) * Atomically increments @v by 1, so long as @v is non-zero. * Returns non-zero if @v was non-zero, and zero otherwise. */ -static __inline__ long atomic64_inc_not_zero(atomic64_t *v) +static __inline__ int atomic64_inc_not_zero(atomic64_t *v) { long t1, t2; =20 @@ -516,7 +516,7 @@ static __inline__ long atomic64_inc_not_zero(atomic64_t= *v) : "r" (&v->counter) : "cc", "xer", "memory"); =20 - return t1; + return t1 !=3D 0; } =20 #endif /* __powerpc64__ */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index e0b1b8482735..ab6dd3e5f176 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1226,7 +1226,7 @@ " .llong 0\n" \ ".previous" \ : "=3Dr" (rval) \ - : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL)); \ + : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ rval;}) #else #define mftb() ({unsigned long rval; \ diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 5c09f365c842..74f81c4d7cb6 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -938,6 +938,19 @@ int __kprobes emulate_step(struct pt_regs *regs, unsig= ned int instr) goto instr_done; #endif case 19: /* mfcr */ + if ((instr >> 20) & 1) { + imm =3D 0xf0000000UL; + for (sh =3D 0; sh < 8; ++sh) { + if (instr & (0x80000 >> sh)) { + regs->gpr[rd] =3D regs->ccr & imm; + break; + } + imm >>=3D 4; + } + + goto instr_done; + } + regs->gpr[rd] =3D regs->ccr; regs->gpr[rd] &=3D 0xffffffffUL; goto instr_done; diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscal= l.h index abad78d5b10c..13243715e5ad 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h @@ -54,7 +54,7 @@ static inline void syscall_set_return_value(struct task_s= truct *task, struct pt_regs *regs, int error, long val) { - regs->gprs[2] =3D error ? -error : val; + regs->gprs[2] =3D error ? error : val; } =20 static inline void syscall_get_arguments(struct task_struct *task, @@ -64,6 +64,12 @@ static inline void syscall_get_arguments(struct task_str= uct *task, { unsigned long mask =3D -1UL; =20 + /* + * No arguments for this syscall, there's nothing to do. + */ + if (!n) + return; + BUG_ON(i + n > 6); #ifdef CONFIG_COMPAT if (test_tsk_thread_flag(task, TIF_31BIT)) diff --git a/arch/sparc/include/asm/head_64.h b/arch/sparc/include/asm/head= _64.h index 10e9dabc4c41..f0700cfeedd7 100644 --- a/arch/sparc/include/asm/head_64.h +++ b/arch/sparc/include/asm/head_64.h @@ -15,6 +15,10 @@ =20 #define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) =20 +#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE) +#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV) +#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_A= G) + #define __CHEETAH_ID 0x003e0014 #define __JALAPENO_ID 0x003e0016 #define __SERRANO_ID 0x003e0022 diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttabl= e.h index 71b5a67522ab..781b9f1dbdc2 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h @@ -589,8 +589,8 @@ user_rtt_fill_64bit: \ restored; \ nop; nop; nop; nop; nop; nop; \ nop; nop; nop; nop; nop; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup_dax; \ + ba,a,pt %xcc, user_rtt_fill_fixup_mna; \ ba,a,pt %xcc, user_rtt_fill_fixup; =20 =20 @@ -652,8 +652,8 @@ user_rtt_fill_32bit: \ restored; \ nop; nop; nop; nop; nop; \ nop; nop; nop; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup_dax; \ + ba,a,pt %xcc, user_rtt_fill_fixup_mna; \ ba,a,pt %xcc, user_rtt_fill_fixup; =20 =20 diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 7cf9c6ea3f1f..fdb13327fded 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o :=3D -pg CFLAGS_REMOVE_pcr.o :=3D -pg endif =20 +obj-$(CONFIG_SPARC64) +=3D urtt_fill.o obj-$(CONFIG_SPARC32) +=3D entry.o wof.o wuf.o obj-$(CONFIG_SPARC32) +=3D etrap_32.o obj-$(CONFIG_SPARC32) +=3D rtrap_32.o diff --git a/arch/sparc/kernel/cherrs.S b/arch/sparc/kernel/cherrs.S index 4ee1ad420862..655628def68e 100644 --- a/arch/sparc/kernel/cherrs.S +++ b/arch/sparc/kernel/cherrs.S @@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt global= s safely. */ subcc %g1, %g2, %g1 ! Next cacheline bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common =20 do_dcpe_tl1_fatal: sethi %hi(1f), %g7 @@ -224,8 +223,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt global= s safely. */ mov 0x2, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_dcpe_tl1,.-do_dcpe_tl1 =20 .globl do_icpe_tl1 @@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt global= s safely. */ subcc %g1, %g2, %g1 bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common =20 do_icpe_tl1_fatal: sethi %hi(1f), %g7 @@ -269,8 +266,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt global= s safely. */ mov 0x3, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_icpe_tl1,.-do_icpe_tl1 =09 .type dcpe_icpe_tl1_common,#function @@ -456,7 +452,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt global= s safely. */ cmp %g2, 0x63 be c_cee nop - ba,pt %xcc, c_deferred + ba,a,pt %xcc, c_deferred .size __cheetah_log_error,.-__cheetah_log_error =20 /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 33c02b15f478..a83707c83be8 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -948,7 +948,24 @@ SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last cmp %o0, 0 bne 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ld [%sp + STACKFRAME_SZ + PT_G1], %g1 + sethi %hi(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I0], %i0 + or %l7, %lo(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I1], %i1 + ld [%sp + STACKFRAME_SZ + PT_I2], %i2 + ld [%sp + STACKFRAME_SZ + PT_I3], %i3 + ld [%sp + STACKFRAME_SZ + PT_I4], %i4 + ld [%sp + STACKFRAME_SZ + PT_I5], %i5 + cmp %g1, NR_syscalls + bgeu 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + ld [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3 diff --git a/arch/sparc/kernel/fpu_traps.S b/arch/sparc/kernel/fpu_traps.S index a6864826a4bd..336d2750fe78 100644 --- a/arch/sparc/kernel/fpu_traps.S +++ b/arch/sparc/kernel/fpu_traps.S @@ -100,8 +100,8 @@ fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 - b,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32 @@ -144,8 +144,8 @@ fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 - ba,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1 =20 @@ -197,8 +197,7 @@ fp_other_bounce: call do_fpother add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size fp_other_bounce,.-fp_other_bounce =20 .align 32 diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 3d61fcae7ee3..8ff57630a486 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -461,9 +461,8 @@ subcc %g3, 1, %g3 bne,pt %xcc, 41b add %g1, 1, %g1 - mov SUN4V_CHIP_SPARC64X, %g4 ba,pt %xcc, 5f - nop + mov SUN4V_CHIP_SPARC64X, %g4 =20 49: mov SUN4V_CHIP_UNKNOWN, %g4 @@ -548,8 +547,7 @@ stxa %g0, [%g7] ASI_DMMU membar #Sync =20 - ba,pt %xcc, sun4u_continue - nop + ba,a,pt %xcc, sun4u_continue =20 sun4v_init: /* Set ctx 0 */ @@ -560,14 +558,12 @@ mov SECONDARY_CONTEXT, %g7 stxa %g0, [%g7] ASI_MMU membar #Sync - ba,pt %xcc, niagara_tlb_fixup - nop + ba,a,pt %xcc, niagara_tlb_fixup =20 sun4u_continue: BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) =20 - ba,pt %xcc, spitfire_tlb_fixup - nop + ba,a,pt %xcc, spitfire_tlb_fixup =20 niagara_tlb_fixup: mov 3, %g2 /* Set TLB type to hypervisor. */ @@ -639,8 +635,7 @@ call hypervisor_patch_cachetlbops nop =20 - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done =20 cheetah_tlb_fixup: mov 2, %g2 /* Set TLB type to cheetah+. */ @@ -659,8 +654,7 @@ call cheetah_patch_cachetlbops nop =20 - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done =20 spitfire_tlb_fixup: /* Set TLB type to spitfire. */ @@ -782,8 +776,7 @@ call %o1 add %sp, (2047 + 128), %o0 =20 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f =20 1: sethi %hi(sparc64_ttable_tl0), %o0 set prom_set_trap_table_name, %g2 @@ -822,8 +815,7 @@ =20 BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) =20 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f =20 /* Disable STICK_INT interrupts. */ 1: diff --git a/arch/sparc/kernel/misctrap.S b/arch/sparc/kernel/misctrap.S index 753b4f031bfb..34b4933900bf 100644 --- a/arch/sparc/kernel/misctrap.S +++ b/arch/sparc/kernel/misctrap.S @@ -18,8 +18,7 @@ 109: or %g7, %lo(109b), %g7 call do_privact add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __do_privact,.-__do_privact =20 .type do_mna,#function @@ -46,8 +45,7 @@ mov %l5, %o2 call mem_address_unaligned add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_mna,.-do_mna =20 .type do_lddfmna,#function @@ -65,8 +63,7 @@ mov %l5, %o2 call handle_lddfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_lddfmna,.-do_lddfmna =20 .type do_stdfmna,#function @@ -84,8 +81,7 @@ mov %l5, %o2 call handle_stdfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_stdfmna,.-do_stdfmna =20 .type breakpoint_trap,#function diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 539babf00bb2..fce61b57d41c 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -930,6 +930,23 @@ void pcibios_set_master(struct pci_dev *dev) /* No special bus mastering setup handling */ } =20 +#ifdef CONFIG_PCI_IOV +int pcibios_add_device(struct pci_dev *dev) +{ + struct pci_dev *pdev; + + /* Add sriov arch specific initialization here. + * Copy dev_archdata from PF to VF + */ + if (dev->is_virtfn) { + pdev =3D dev->physfn; + memcpy(&dev->dev.archdata, &pdev->dev.archdata, + sizeof(struct dev_archdata)); + } + return 0; +} +#endif /* CONFIG_PCI_IOV */ + static int __init pcibios_init(void) { pci_dfl_cache_line_size =3D 64 >> 2; diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 39f0c662f4c8..8de386dc8150 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -14,10 +14,6 @@ #include #include =20 -#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE) -#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV) -#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_= AG) - #ifdef CONFIG_CONTEXT_TRACKING # define SCHEDULE_USER schedule_user #else @@ -236,52 +232,17 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 wrpr %g1, %cwp ba,a,pt %xcc, user_rtt_fill_64bit =20 -user_rtt_fill_fixup: - rdpr %cwp, %g1 - add %g1, 1, %g1 - wrpr %g1, 0x0, %cwp - - rdpr %wstate, %g2 - sll %g2, 3, %g2 - wrpr %g2, 0x0, %wstate - - /* We know %canrestore and %otherwin are both zero. */ - - sethi %hi(sparc64_kern_pri_context), %g2 - ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2 - mov PRIMARY_CONTEXT, %g1 - -661: stxa %g2, [%g1] ASI_DMMU - .section .sun4v_1insn_patch, "ax" - .word 661b - stxa %g2, [%g1] ASI_MMU - .previous - - sethi %hi(KERNBASE), %g1 - flush %g1 +user_rtt_fill_fixup_dax: + ba,pt %xcc, user_rtt_fill_fixup_common + mov 1, %g3 =20 - or %g4, FAULT_CODE_WINFIXUP, %g4 - stb %g4, [%g6 + TI_FAULT_CODE] - stx %g5, [%g6 + TI_FAULT_ADDR] +user_rtt_fill_fixup_mna: + ba,pt %xcc, user_rtt_fill_fixup_common + mov 2, %g3 =20 - mov %g6, %l1 - wrpr %g0, 0x0, %tl - -661: nop - .section .sun4v_1insn_patch, "ax" - .word 661b - SET_GL(0) - .previous - - wrpr %g0, RTRAP_PSTATE, %pstate - - mov %l1, %g6 - ldx [%g6 + TI_TASK], %g4 - LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3) - call do_sparc64_fault - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop +user_rtt_fill_fixup: + ba,pt %xcc, user_rtt_fill_fixup_common + clr %g3 =20 user_rtt_pre_restore: add %g1, 1, %g1 diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 62deba7be1a9..05a36431103c 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_si= ginfo_t __user *from) return 0; } =20 +/* Checks if the fp is valid. We always build signal frames which are + * 16-byte aligned, therefore we can always enforce that the restore + * frame has that property as well. + */ +static bool invalid_frame_pointer(void __user *fp, int fplen) +{ + if ((((unsigned long) fp) & 15) || + ((unsigned long)fp) > 0x100000000ULL - fplen) + return true; + return false; +} + void do_sigreturn32(struct pt_regs *regs) { struct signal_frame32 __user *sf; compat_uptr_t fpu_save; compat_uptr_t rwin_save; - unsigned int psr; + unsigned int psr, ufp; unsigned pc, npc; sigset_t set; compat_sigset_t seta; @@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs) sf =3D (struct signal_frame32 __user *) regs->u_regs[UREG_FP]; =20 /* 1. Make sure we are not getting garbage from the user */ - if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || - (((unsigned long) sf) & 3)) + if (invalid_frame_pointer(sf, sizeof(*sf))) + goto segv; + + if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP])) + goto segv; + + if (ufp & 0x7) goto segv; =20 - if (get_user(pc, &sf->info.si_regs.pc) || + if (__get_user(pc, &sf->info.si_regs.pc) || __get_user(npc, &sf->info.si_regs.npc)) goto segv; =20 @@ -227,7 +244,7 @@ void do_sigreturn32(struct pt_regs *regs) asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) { struct rt_signal_frame32 __user *sf; - unsigned int psr, pc, npc; + unsigned int psr, pc, npc, ufp; compat_uptr_t fpu_save; compat_uptr_t rwin_save; sigset_t set; @@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *reg= s) sf =3D (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP]; =20 /* 1. Make sure we are not getting garbage from the user */ - if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || - (((unsigned long) sf) & 3)) + if (invalid_frame_pointer(sf, sizeof(*sf))) goto segv; =20 - if (get_user(pc, &sf->regs.pc) ||=20 + if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) + goto segv; + + if (ufp & 0x7) + goto segv; + + if (__get_user(pc, &sf->regs.pc) ||=20 __get_user(npc, &sf->regs.npc)) goto segv; =20 @@ -307,14 +329,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) force_sig(SIGSEGV, current); } =20 -/* Checks if the fp is valid */ -static int invalid_frame_pointer(void __user *fp, int fplen) -{ - if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - = fplen) - return 1; - return 0; -} - static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *reg= s, unsigned long framesize) { unsigned long sp; diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 9ee72fc8e0e4..8492291424ab 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -60,10 +60,22 @@ struct rt_signal_frame { #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) =20 +/* Checks if the fp is valid. We always build signal frames which are + * 16-byte aligned, therefore we can always enforce that the restore + * frame has that property as well. + */ +static inline bool invalid_frame_pointer(void __user *fp, int fplen) +{ + if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen)) + return true; + + return false; +} + asmlinkage void do_sigreturn(struct pt_regs *regs) { + unsigned long up_psr, pc, npc, ufp; struct signal_frame __user *sf; - unsigned long up_psr, pc, npc; sigset_t set; __siginfo_fpu_t __user *fpu_save; __siginfo_rwin_t __user *rwin_save; @@ -77,10 +89,13 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) sf =3D (struct signal_frame __user *) regs->u_regs[UREG_FP]; =20 /* 1. Make sure we are not getting garbage from the user */ - if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) + if (!invalid_frame_pointer(sf, sizeof(*sf))) + goto segv_and_exit; + + if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP])) goto segv_and_exit; =20 - if (((unsigned long) sf) & 3) + if (ufp & 0x7) goto segv_and_exit; =20 err =3D __get_user(pc, &sf->info.si_regs.pc); @@ -127,7 +142,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) asmlinkage void do_rt_sigreturn(struct pt_regs *regs) { struct rt_signal_frame __user *sf; - unsigned int psr, pc, npc; + unsigned int psr, pc, npc, ufp; __siginfo_fpu_t __user *fpu_save; __siginfo_rwin_t __user *rwin_save; sigset_t set; @@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) =20 synchronize_user_stack(); sf =3D (struct rt_signal_frame __user *) regs->u_regs[UREG_FP]; - if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || - (((unsigned long) sf) & 0x03)) + if (!invalid_frame_pointer(sf, sizeof(*sf))) + goto segv; + + if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) + goto segv; + + if (ufp & 0x7) goto segv; =20 err =3D __get_user(pc, &sf->regs.pc); @@ -178,15 +198,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) force_sig(SIGSEGV, current); } =20 -/* Checks if the fp is valid */ -static inline int invalid_frame_pointer(void __user *fp, int fplen) -{ - if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen)) - return 1; - - return 0; -} - static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_re= gs *regs, unsigned long framesize) { unsigned long sp =3D regs->u_regs[UREG_FP]; diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 1a6999868031..9acf9822cbbd 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) unsigned char fenab; int err; =20 - flush_user_windows(); + synchronize_user_stack(); if (get_thread_wsaved() || (((unsigned long)ucp) & (sizeof(unsigned long)-1)) || (!__access_ok(ucp, sizeof(*ucp)))) @@ -234,6 +234,17 @@ asmlinkage void sparc64_get_context(struct pt_regs *re= gs) goto out; } =20 +/* Checks if the fp is valid. We always build rt signal frames which + * are 16-byte aligned, therefore we can always enforce that the + * restore frame has that property as well. + */ +static bool invalid_frame_pointer(void __user *fp) +{ + if (((unsigned long) fp) & 15) + return true; + return false; +} + struct rt_signal_frame { struct sparc_stackf ss; siginfo_t info; @@ -246,8 +257,8 @@ struct rt_signal_frame { =20 void do_rt_sigreturn(struct pt_regs *regs) { + unsigned long tpc, tnpc, tstate, ufp; struct rt_signal_frame __user *sf; - unsigned long tpc, tnpc, tstate; __siginfo_fpu_t __user *fpu_save; __siginfo_rwin_t __user *rwin_save; sigset_t set; @@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *regs) (regs->u_regs [UREG_FP] + STACK_BIAS); =20 /* 1. Make sure we are not getting garbage from the user */ - if (((unsigned long) sf) & 3) + if (invalid_frame_pointer(sf)) + goto segv; + + if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) goto segv; =20 - err =3D get_user(tpc, &sf->regs.tpc); + if ((ufp + STACK_BIAS) & 0x7) + goto segv; + + err =3D __get_user(tpc, &sf->regs.tpc); err |=3D __get_user(tnpc, &sf->regs.tnpc); if (test_thread_flag(TIF_32BIT)) { tpc &=3D 0xffffffff; @@ -308,14 +325,6 @@ void do_rt_sigreturn(struct pt_regs *regs) force_sig(SIGSEGV, current); } =20 -/* Checks if the fp is valid */ -static int invalid_frame_pointer(void __user *fp) -{ - if (((unsigned long) fp) & 15) - return 1; - return 0; -} - static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_re= gs *regs, unsigned long framesize) { unsigned long sp =3D regs->u_regs[UREG_FP] + STACK_BIAS; diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c index 0f6eebe71e6c..e5fe8cef9a69 100644 --- a/arch/sparc/kernel/sigutil_32.c +++ b/arch/sparc/kernel/sigutil_32.c @@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t= __user *fpu) int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) { int err; + + if (((unsigned long) fpu) & 3) + return -EFAULT; + #ifdef CONFIG_SMP if (test_tsk_thread_flag(current, TIF_USEDFPU)) regs->psr &=3D ~PSR_EF; @@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp) struct thread_info *t =3D current_thread_info(); int i, wsaved, err; =20 - __get_user(wsaved, &rp->wsaved); + if (((unsigned long) rp) & 3) + return -EFAULT; + + get_user(wsaved, &rp->wsaved); if (wsaved > NSWINS) return -EFAULT; =20 diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c index 387834a9c56a..36aadcbeac69 100644 --- a/arch/sparc/kernel/sigutil_64.c +++ b/arch/sparc/kernel/sigutil_64.c @@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fp= u_t __user *fpu) unsigned long fprs; int err; =20 - err =3D __get_user(fprs, &fpu->si_fprs); + if (((unsigned long) fpu) & 7) + return -EFAULT; + + err =3D get_user(fprs, &fpu->si_fprs); fprs_write(0); regs->tstate &=3D ~TSTATE_PEF; if (fprs & FPRS_DL) @@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp) struct thread_info *t =3D current_thread_info(); int i, wsaved, err; =20 - __get_user(wsaved, &rp->wsaved); + if (((unsigned long) rp) & 7) + return -EFAULT; + + get_user(wsaved, &rp->wsaved); if (wsaved > NSWINS) return -EFAULT; =20 diff --git a/arch/sparc/kernel/spiterrs.S b/arch/sparc/kernel/spiterrs.S index c357e40ffd01..4a73009f66a5 100644 --- a/arch/sparc/kernel/spiterrs.S +++ b/arch/sparc/kernel/spiterrs.S @@ -85,8 +85,7 @@ ba,pt %xcc, etraptl1 rd %pc, %g7 =20 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f =20 1: ba,pt %xcc, etrap_irq rd %pc, %g7 @@ -100,8 +99,7 @@ mov %l5, %o2 call spitfire_access_error add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_access_error,.-__spitfire_access_error =20 /* This is the trap handler entry point for ECC correctable @@ -179,8 +177,7 @@ mov %l5, %o2 call spitfire_data_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exce= ption_tl1 =20 .type __spitfire_data_access_exception,#function @@ -200,8 +197,7 @@ mov %l5, %o2 call spitfire_data_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception,.-__spitfire_data_access_exception =20 .type __spitfire_insn_access_exception_tl1,#function @@ -220,8 +216,7 @@ mov %l5, %o2 call spitfire_insn_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exce= ption_tl1 =20 .type __spitfire_insn_access_exception,#function @@ -240,6 +235,5 @@ mov %l5, %o2 call spitfire_insn_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 33a17e7b3ccd..6ec7531f27fc 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -148,7 +148,25 @@ sys_vfork: /* Under Linux, vfork and fork are just spe= cial cases of clone. */ add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 srl %i0, 0, %o0 + lduw [%l7 + %l4], %l7 srl %i4, 0, %o4 srl %i1, 0, %o1 srl %i2, 0, %o2 @@ -160,7 +178,25 @@ sys_vfork: /* Under Linux, vfork and fork are just spe= cial cases of clone. */ add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + lduw [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3 diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S new file mode 100644 index 000000000000..5604a2b051d4 --- /dev/null +++ b/arch/sparc/kernel/urtt_fill.S @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include + + .text + .align 8 + .globl user_rtt_fill_fixup_common +user_rtt_fill_fixup_common: + rdpr %cwp, %g1 + add %g1, 1, %g1 + wrpr %g1, 0x0, %cwp + + rdpr %wstate, %g2 + sll %g2, 3, %g2 + wrpr %g2, 0x0, %wstate + + /* We know %canrestore and %otherwin are both zero. */ + + sethi %hi(sparc64_kern_pri_context), %g2 + ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2 + mov PRIMARY_CONTEXT, %g1 + +661: stxa %g2, [%g1] ASI_DMMU + .section .sun4v_1insn_patch, "ax" + .word 661b + stxa %g2, [%g1] ASI_MMU + .previous + + sethi %hi(KERNBASE), %g1 + flush %g1 + + mov %g4, %l4 + mov %g5, %l5 + brnz,pn %g3, 1f + mov %g3, %l3 + + or %g4, FAULT_CODE_WINFIXUP, %g4 + stb %g4, [%g6 + TI_FAULT_CODE] + stx %g5, [%g6 + TI_FAULT_ADDR] +1: + mov %g6, %l1 + wrpr %g0, 0x0, %tl + +661: nop + .section .sun4v_1insn_patch, "ax" + .word 661b + SET_GL(0) + .previous + + wrpr %g0, RTRAP_PSTATE, %pstate + + mov %l1, %g6 + ldx [%g6 + TI_TASK], %g4 + LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3) + + brnz,pn %l3, 1f + nop + + call do_sparc64_fault + add %sp, PTREGS_OFF, %o0 + ba,pt %xcc, rtrap + nop + +1: cmp %g3, 2 + bne,pn %xcc, 2f + nop + + sethi %hi(tlb_type), %g1 + lduw [%g1 + %lo(tlb_type)], %g1 + cmp %g1, 3 + bne,pt %icc, 1f + add %sp, PTREGS_OFF, %o0 + mov %l4, %o2 + call sun4v_do_mna + mov %l5, %o1 + ba,a,pt %xcc, rtrap +1: mov %l4, %o1 + mov %l5, %o2 + call mem_address_unaligned + nop + ba,a,pt %xcc, rtrap + +2: sethi %hi(tlb_type), %g1 + mov %l4, %o1 + lduw [%g1 + %lo(tlb_type)], %g1 + mov %l5, %o2 + cmp %g1, 3 + bne,pt %icc, 1f + add %sp, PTREGS_OFF, %o0 + call sun4v_data_access_exception + nop + ba,a,pt %xcc, rtrap + +1: call spitfire_data_access_exception + nop + ba,a,pt %xcc, rtrap diff --git a/arch/sparc/kernel/utrap.S b/arch/sparc/kernel/utrap.S index b7f0f3f3a909..c731e8023d3e 100644 --- a/arch/sparc/kernel/utrap.S +++ b/arch/sparc/kernel/utrap.S @@ -11,8 +11,7 @@ utrap_trap: /* %g3=3Dhandler,%g4=3Dlevel */ mov %l4, %o1 call bad_trap add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap =20 invoke_utrap: sllx %g3, 3, %g3 diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.ld= s.S index 09243057cb0b..7028b4dab903 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -33,6 +33,10 @@ ENTRY(_start) jiffies =3D jiffies_64; #endif =20 +#ifdef CONFIG_SPARC64 +ASSERT((swapper_tsb =3D=3D 0x0000000000408000), "Error: sparc64 early asse= mbler too large") +#endif + SECTIONS { #ifdef CONFIG_SPARC64 diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index 1e67ce958369..855019a8590e 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S @@ -32,8 +32,7 @@ rd %pc, %g7 call do_sparc64_fault add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap =20 /* Be very careful about usage of the trap globals here. * You cannot touch %g5 as that has the fault information. diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index bbb9371f519b..baea27e341e6 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2682,9 +2682,10 @@ void hugetlb_setup(struct pt_regs *regs) * the Data-TLB for huge pages. */ if (tlb_type =3D=3D cheetah_plus) { + bool need_context_reload =3D false; unsigned long ctx; =20 - spin_lock(&ctx_alloc_lock); + spin_lock_irq(&ctx_alloc_lock); ctx =3D mm->context.sparc64_ctx_val; ctx &=3D ~CTX_PGSZ_MASK; ctx |=3D CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT; @@ -2703,9 +2704,12 @@ void hugetlb_setup(struct pt_regs *regs) * also executing in this address space. */ mm->context.sparc64_ctx_val =3D ctx; - on_each_cpu(context_reload, mm, 0); + need_context_reload =3D true; } - spin_unlock(&ctx_alloc_lock); + spin_unlock_irq(&ctx_alloc_lock); + + if (need_context_reload) + on_each_cpu(context_reload, mm, 0); } } #endif diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/M= akefile index 67e9f5cc91ed..8036ebb0db3d 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -34,6 +34,9 @@ $(obj)/eboot.o: KBUILD_CFLAGS +=3D -fshort-wchar -mno-red= -zone =20 ifeq ($(CONFIG_EFI_STUB), y) VMLINUX_OBJS +=3D $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o +ifeq ($(CONFIG_EFI_MIXED), y) + VMLINUX_OBJS +=3D $(obj)/efi_thunk_$(BITS).o +endif endif =20 $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE diff --git a/arch/x86/boot/compressed/efi_stub_64.S b/arch/x86/boot/compres= sed/efi_stub_64.S index 7ff3632806b1..99494dff2113 100644 --- a/arch/x86/boot/compressed/efi_stub_64.S +++ b/arch/x86/boot/compressed/efi_stub_64.S @@ -3,28 +3,3 @@ #include =20 #include "../../platform/efi/efi_stub_64.S" - -#ifdef CONFIG_EFI_MIXED - .code64 - .text -ENTRY(efi64_thunk) - push %rbp - push %rbx - - subq $16, %rsp - leaq efi_exit32(%rip), %rax - movl %eax, 8(%rsp) - leaq efi_gdt64(%rip), %rax - movl %eax, 4(%rsp) - movl %eax, 2(%rax) /* Fixup the gdt base address */ - leaq efi32_boot_gdt(%rip), %rax - movl %eax, (%rsp) - - call __efi64_thunk - - addq $16, %rsp - pop %rbx - pop %rbp - ret -ENDPROC(efi64_thunk) -#endif /* CONFIG_EFI_MIXED */ diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compre= ssed/efi_thunk_64.S new file mode 100644 index 000000000000..630384a4c14a --- /dev/null +++ b/arch/x86/boot/compressed/efi_thunk_64.S @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming + * + * Early support for invoking 32-bit EFI services from a 64-bit kernel. + * + * Because this thunking occurs before ExitBootServices() we have to + * restore the firmware's 32-bit GDT before we make EFI serivce calls, + * since the firmware's 32-bit IDT is still currently installed and it + * needs to be able to service interrupts. + * + * On the plus side, we don't have to worry about mangling 64-bit + * addresses into 32-bits because we're executing with an identify + * mapped pagetable and haven't transitioned to 64-bit virtual addresses + * yet. + */ + +#include +#include +#include +#include +#include + + .code64 + .text +ENTRY(efi64_thunk) + push %rbp + push %rbx + + subq $8, %rsp + leaq efi_exit32(%rip), %rax + movl %eax, 4(%rsp) + leaq efi_gdt64(%rip), %rax + movl %eax, (%rsp) + movl %eax, 2(%rax) /* Fixup the gdt base address */ + + movl %ds, %eax + push %rax + movl %es, %eax + push %rax + movl %ss, %eax + push %rax + + /* + * Convert x86-64 ABI params to i386 ABI + */ + subq $32, %rsp + movl %esi, 0x0(%rsp) + movl %edx, 0x4(%rsp) + movl %ecx, 0x8(%rsp) + movq %r8, %rsi + movl %esi, 0xc(%rsp) + movq %r9, %rsi + movl %esi, 0x10(%rsp) + + sgdt save_gdt(%rip) + + leaq 1f(%rip), %rbx + movq %rbx, func_rt_ptr(%rip) + + /* + * Switch to gdt with 32-bit segments. This is the firmware GDT + * that was installed when the kernel started executing. This + * pointer was saved at the EFI stub entry point in head_64.S. + */ + leaq efi32_boot_gdt(%rip), %rax + lgdt (%rax) + + pushq $__KERNEL_CS + leaq efi_enter32(%rip), %rax + pushq %rax + lretq + +1: addq $32, %rsp + + lgdt save_gdt(%rip) + + pop %rbx + movl %ebx, %ss + pop %rbx + movl %ebx, %es + pop %rbx + movl %ebx, %ds + + /* + * Convert 32-bit status code into 64-bit. + */ + test %rax, %rax + jz 1f + movl %eax, %ecx + andl $0x0fffffff, %ecx + andl $0xf0000000, %eax + shl $32, %rax + or %rcx, %rax +1: + addq $8, %rsp + pop %rbx + pop %rbp + ret +ENDPROC(efi64_thunk) + +ENTRY(efi_exit32) + movq func_rt_ptr(%rip), %rax + push %rax + mov %rdi, %rax + ret +ENDPROC(efi_exit32) + + .code32 +/* + * EFI service pointer must be in %edi. + * + * The stack should represent the 32-bit calling convention. + */ +ENTRY(efi_enter32) + movl $__KERNEL_DS, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + + /* Reload pgtables */ + movl %cr3, %eax + movl %eax, %cr3 + + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + + /* Disable long mode via EFER */ + movl $MSR_EFER, %ecx + rdmsr + btrl $_EFER_LME, %eax + wrmsr + + call *%edi + + /* We must preserve return value */ + movl %eax, %edi + + /* + * Some firmware will return with interrupts enabled. Be sure to + * disable them before we switch GDTs. + */ + cli + + movl 56(%esp), %eax + movl %eax, 2(%eax) + lgdtl (%eax) + + movl %cr4, %eax + btsl $(X86_CR4_PAE_BIT), %eax + movl %eax, %cr4 + + movl %cr3, %eax + movl %eax, %cr3 + + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + xorl %eax, %eax + lldt %ax + + movl 60(%esp), %eax + pushl $__KERNEL_CS + pushl %eax + + /* Enable paging */ + movl %cr0, %eax + btsl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + lret +ENDPROC(efi_enter32) + + .data + .balign 8 + .global efi32_boot_gdt +efi32_boot_gdt: .word 0 + .quad 0 + +save_gdt: .word 0 + .quad 0 +func_rt_ptr: .quad 0 + + .global efi_gdt64 +efi_gdt64: + .word efi_gdt64_end - efi_gdt64 + .long 0 /* Filled out by user */ + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ +efi_gdt64_end: diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3= _glue.c index 6c20fe04a738..ba9c75c5a432 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c @@ -224,7 +224,8 @@ static bool __init avx_usable(void) #ifdef CONFIG_AS_AVX2 static bool __init avx2_usable(void) { - if (avx_usable() && cpu_has_avx2 && boot_cpu_has(X86_FEATURE_BMI1) && + if (false && avx_usable() && cpu_has_avx2 && + boot_cpu_has(X86_FEATURE_BMI1) && boot_cpu_has(X86_FEATURE_BMI2)) return true; =20 diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xe= n/hypercall.h index ca08a27b90b3..4ad5a91aea79 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -43,6 +43,7 @@ =20 #include #include +#include =20 #include #include @@ -213,10 +214,12 @@ privcmd_call(unsigned call, __HYPERCALL_DECLS; __HYPERCALL_5ARG(a1, a2, a3, a4, a5); =20 + stac(); asm volatile("call *%[call]" : __HYPERCALL_5PARAM : [call] "a" (&hypercall_page[call]) : __HYPERCALL_CLOBBER5); + clac(); =20 return (long)__res; } diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/= asm/msr-index.h index 7db049a7f7ab..392ef72ea41c 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -298,6 +298,8 @@ #define MSR_IA32_TSC_ADJUST 0x0000003b #define MSR_IA32_BNDCFGS 0x00000d90 =20 +#define MSR_IA32_BNDCFGS_RSVD 0x00000ffc + #define FEATURE_CONTROL_LOCKED (1<<0) #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/p= erf_event_intel.c index 38b5a3514c7d..73112b9023cd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -2642,13 +2642,13 @@ __init int intel_pmu_init(void) * counter, so do not extend mask to generic counters */ for_each_event_constraint(c, x86_pmu.event_constraints) { - if (c->cmask !=3D FIXED_EVENT_FLAGS - || c->idxmsk64 =3D=3D INTEL_PMC_MSK_FIXED_REF_CYCLES) { - continue; + if (c->cmask =3D=3D FIXED_EVENT_FLAGS + && c->idxmsk64 !=3D INTEL_PMC_MSK_FIXED_REF_CYCLES) { + c->idxmsk64 |=3D (1ULL << x86_pmu.num_counters) - 1; } - - c->idxmsk64 |=3D (1ULL << x86_pmu.num_counters) - 1; - c->weight +=3D x86_pmu.num_counters; + c->idxmsk64 &=3D + ~(~0ULL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed)); + c->weight =3D hweight64(c->idxmsk64); } } =20 diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index 6d9582ec0324..d27f8d84c4ff 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c @@ -78,7 +78,7 @@ static void __init test_nmi_ipi(struct cpumask *mask) =20 /* Don't wait longer than a second */ timeout =3D USEC_PER_SEC; - while (!cpumask_empty(mask) && timeout--) + while (!cpumask_empty(mask) && --timeout) udelay(1); =20 /* What happens if we timeout, do we still unregister?? */ diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index f9087315e0cd..06fa616e3f69 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -95,4 +95,13 @@ static inline bool guest_cpuid_has_gbpages(struct kvm_vc= pu *vcpu) best =3D kvm_find_cpuid_entry(vcpu, 0x80000001, 0); return best && (best->edx & bit(X86_FEATURE_GBPAGES)); } + +static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + + best =3D kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->ebx & bit(X86_FEATURE_MPX)); +} + #endif diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 56772d2781b0..50a1d48b1419 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2514,7 +2514,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr= _index, u64 *pdata) data =3D vmcs_readl(GUEST_SYSENTER_ESP); break; case MSR_IA32_BNDCFGS: - if (!vmx_mpx_supported()) + if (!vmx_mpx_supported() || !guest_cpuid_has_mpx(vcpu)) return 1; data =3D vmcs_read64(GUEST_BNDCFGS); break; @@ -2587,7 +2587,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct= msr_data *msr_info) vmcs_writel(GUEST_SYSENTER_ESP, data); break; case MSR_IA32_BNDCFGS: - if (!vmx_mpx_supported()) + if (!vmx_mpx_supported() || !guest_cpuid_has_mpx(vcpu)) + return 1; + if (is_noncanonical_address(data & PAGE_MASK) || + (data & MSR_IA32_BNDCFGS_RSVD)) return 1; vmcs_write64(GUEST_BNDCFGS, data); break; @@ -8045,6 +8048,14 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, st= ruct vmcs12 *vmcs12) exec_control &=3D ~CPU_BASED_VIRTUAL_NMI_PENDING; exec_control &=3D ~CPU_BASED_TPR_SHADOW; exec_control |=3D vmcs12->cpu_based_vm_exec_control; + + if (!(exec_control & CPU_BASED_TPR_SHADOW)) { +#ifdef CONFIG_X86_64 + exec_control |=3D CPU_BASED_CR8_LOAD_EXITING | + CPU_BASED_CR8_STORE_EXITING; +#endif + } + /* * Merging of IO and MSR bitmaps not currently supported. * Rather, exit every time. @@ -9048,7 +9059,6 @@ static int __init vmx_init(void) vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); - vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); =20 memcpy(vmx_msr_bitmap_legacy_x2apic, vmx_msr_bitmap_legacy, PAGE_SIZE); diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 156fbb69031c..4c0cfc53263b 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -555,15 +555,53 @@ static void twinhead_reserve_killing_zone(struct pci_= dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_kil= ling_zone); =20 /* - * Broadwell EP Home Agent BARs erroneously return non-zero values when re= ad. + * Device [8086:2fc0] + * Erratum HSE43 + * CONFIG_TDP_NOMINAL CSR Implemented at Incorrect Offset + * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-= update.html * - * See http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-s= pec-update.html - * entry BDF2. + * Devices [8086:6f60,6fa0,6fc0] + * Erratum BDF2 + * PCI BARs in the Home Agent Will Return Non-Zero Values During Enumerati= on + * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-= update.html */ -static void pci_bdwep_bar(struct pci_dev *dev) +static void pci_invalid_bar(struct pci_dev *dev) { dev->non_compliant_bars =3D 1; } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_bdwep_bar); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar); + +/* + * Apple MacBook Pro: Avoid [mem 0x7fa00000-0x7fbfffff] + * + * Using the [mem 0x7fa00000-0x7fbfffff] region, e.g., by assigning it to + * the 00:1c.0 Root Port, causes a conflict with [io 0x1804], which is used + * for soft poweroff and suspend-to-RAM. + * + * As far as we know, this is related to the address space, not to the Root + * Port itself. Attaching the quirk to the Root Port is a convenience, but + * it could probably also be a standalone DMI quirk. + * + * https://bugzilla.kernel.org/show_bug.cgi?id=3D103211 + */ +static void quirk_apple_mbp_poweroff(struct pci_dev *pdev) +{ + struct device *dev =3D &pdev->dev; + struct resource *res; + + if ((!dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") && + !dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5")) || + pdev->bus->number !=3D 0 || pdev->devfn !=3D PCI_DEVFN(0x1c, 0)) + return; + + res =3D request_mem_region(0x7fa00000, 0x200000, + "MacBook Pro poweroff workaround"); + if (res) + dev_info(dev, "claimed %s %pR\n", res->name, res); + else + dev_info(dev, "can't work around MacBook Pro poweroff issue\n"); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_powe= roff); diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/ef= i_stub_64.S index 5fcda7272550..86d0f9e08dd9 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -91,167 +91,6 @@ ENTRY(efi_call) ret ENDPROC(efi_call) =20 -#ifdef CONFIG_EFI_MIXED - -/* - * We run this function from the 1:1 mapping. - * - * This function must be invoked with a 1:1 mapped stack. - */ -ENTRY(__efi64_thunk) - movl %ds, %eax - push %rax - movl %es, %eax - push %rax - movl %ss, %eax - push %rax - - subq $32, %rsp - movl %esi, 0x0(%rsp) - movl %edx, 0x4(%rsp) - movl %ecx, 0x8(%rsp) - movq %r8, %rsi - movl %esi, 0xc(%rsp) - movq %r9, %rsi - movl %esi, 0x10(%rsp) - - sgdt save_gdt(%rip) - - leaq 1f(%rip), %rbx - movq %rbx, func_rt_ptr(%rip) - - /* Switch to gdt with 32-bit segments */ - movl 64(%rsp), %eax - lgdt (%rax) - - leaq efi_enter32(%rip), %rax - pushq $__KERNEL_CS - pushq %rax - lretq - -1: addq $32, %rsp - - lgdt save_gdt(%rip) - - pop %rbx - movl %ebx, %ss - pop %rbx - movl %ebx, %es - pop %rbx - movl %ebx, %ds - - /* - * Convert 32-bit status code into 64-bit. - */ - test %rax, %rax - jz 1f - movl %eax, %ecx - andl $0x0fffffff, %ecx - andl $0xf0000000, %eax - shl $32, %rax - or %rcx, %rax -1: - ret -ENDPROC(__efi64_thunk) - -ENTRY(efi_exit32) - movq func_rt_ptr(%rip), %rax - push %rax - mov %rdi, %rax - ret -ENDPROC(efi_exit32) - - .code32 -/* - * EFI service pointer must be in %edi. - * - * The stack should represent the 32-bit calling convention. - */ -ENTRY(efi_enter32) - movl $__KERNEL_DS, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %ss - - /* Reload pgtables */ - movl %cr3, %eax - movl %eax, %cr3 - - /* Disable paging */ - movl %cr0, %eax - btrl $X86_CR0_PG_BIT, %eax - movl %eax, %cr0 - - /* Disable long mode via EFER */ - movl $MSR_EFER, %ecx - rdmsr - btrl $_EFER_LME, %eax - wrmsr - - call *%edi - - /* We must preserve return value */ - movl %eax, %edi - - /* - * Some firmware will return with interrupts enabled. Be sure to - * disable them before we switch GDTs. - */ - cli - - movl 68(%esp), %eax - movl %eax, 2(%eax) - lgdtl (%eax) - - movl %cr4, %eax - btsl $(X86_CR4_PAE_BIT), %eax - movl %eax, %cr4 - - movl %cr3, %eax - movl %eax, %cr3 - - movl $MSR_EFER, %ecx - rdmsr - btsl $_EFER_LME, %eax - wrmsr - - xorl %eax, %eax - lldt %ax - - movl 72(%esp), %eax - pushl $__KERNEL_CS - pushl %eax - - /* Enable paging */ - movl %cr0, %eax - btsl $X86_CR0_PG_BIT, %eax - movl %eax, %cr0 - lret -ENDPROC(efi_enter32) - - .data - .balign 8 - .global efi32_boot_gdt -efi32_boot_gdt: .word 0 - .quad 0 - -save_gdt: .word 0 - .quad 0 -func_rt_ptr: .quad 0 - - .global efi_gdt64 -efi_gdt64: - .word efi_gdt64_end - efi_gdt64 - .long 0 /* Filled out by user */ - .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00af9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf92000000ffff /* __KERNEL_DS */ - .quad 0x0080890000000000 /* TS descriptor */ - .quad 0x0000000000000000 /* TS continued */ -efi_gdt64_end: -#endif /* CONFIG_EFI_MIXED */ - .data ENTRY(efi_scratch) .fill 3,8,0 diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/e= fi_thunk_64.S index 8806fa73e6e6..ff85d28c50f2 100644 --- a/arch/x86/platform/efi/efi_thunk_64.S +++ b/arch/x86/platform/efi/efi_thunk_64.S @@ -1,9 +1,26 @@ /* * Copyright (C) 2014 Intel Corporation; author Matt Fleming + * + * Support for invoking 32-bit EFI runtime services from a 64-bit + * kernel. + * + * The below thunking functions are only used after ExitBootServices() + * has been called. This simplifies things considerably as compared with + * the early EFI thunking because we can leave all the kernel state + * intact (GDT, IDT, etc) and simply invoke the the 32-bit EFI runtime + * services from __KERNEL32_CS. This means we can continue to service + * interrupts across an EFI mixed mode call. + * + * We do however, need to handle the fact that we're running in a full + * 64-bit virtual address space. Things like the stack and instruction + * addresses need to be accessible by the 32-bit firmware, so we rely on + * using the identity mappings in the EFI page table to access the stack + * and kernel text (see efi_setup_page_tables()). */ =20 #include #include +#include =20 .text .code64 @@ -33,14 +50,6 @@ ENTRY(efi64_thunk) leaq efi_exit32(%rip), %rbx subq %rax, %rbx movl %ebx, 8(%rsp) - leaq efi_gdt64(%rip), %rbx - subq %rax, %rbx - movl %ebx, 2(%ebx) - movl %ebx, 4(%rsp) - leaq efi_gdt32(%rip), %rbx - subq %rax, %rbx - movl %ebx, 2(%ebx) - movl %ebx, (%rsp) =20 leaq __efi64_thunk(%rip), %rbx subq %rax, %rbx @@ -52,14 +61,92 @@ ENTRY(efi64_thunk) retq ENDPROC(efi64_thunk) =20 - .data -efi_gdt32: - .word efi_gdt32_end - efi_gdt32 - .long 0 /* Filled out above */ - .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00cf9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf93000000ffff /* __KERNEL_DS */ -efi_gdt32_end: +/* + * We run this function from the 1:1 mapping. + * + * This function must be invoked with a 1:1 mapped stack. + */ +ENTRY(__efi64_thunk) + movl %ds, %eax + push %rax + movl %es, %eax + push %rax + movl %ss, %eax + push %rax + + subq $32, %rsp + movl %esi, 0x0(%rsp) + movl %edx, 0x4(%rsp) + movl %ecx, 0x8(%rsp) + movq %r8, %rsi + movl %esi, 0xc(%rsp) + movq %r9, %rsi + movl %esi, 0x10(%rsp) + + leaq 1f(%rip), %rbx + movq %rbx, func_rt_ptr(%rip) + + /* Switch to 32-bit descriptor */ + pushq $__KERNEL32_CS + leaq efi_enter32(%rip), %rax + pushq %rax + lretq + +1: addq $32, %rsp + + pop %rbx + movl %ebx, %ss + pop %rbx + movl %ebx, %es + pop %rbx + movl %ebx, %ds =20 + /* + * Convert 32-bit status code into 64-bit. + */ + test %rax, %rax + jz 1f + movl %eax, %ecx + andl $0x0fffffff, %ecx + andl $0xf0000000, %eax + shl $32, %rax + or %rcx, %rax +1: + ret +ENDPROC(__efi64_thunk) + +ENTRY(efi_exit32) + movq func_rt_ptr(%rip), %rax + push %rax + mov %rdi, %rax + ret +ENDPROC(efi_exit32) + + .code32 +/* + * EFI service pointer must be in %edi. + * + * The stack should represent the 32-bit calling convention. + */ +ENTRY(efi_enter32) + movl $__KERNEL_DS, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + + call *%edi + + /* We must preserve return value */ + movl %eax, %edi + + movl 72(%esp), %eax + pushl $__KERNEL_CS + pushl %eax + + lret +ENDPROC(efi_enter32) + + .data + .balign 8 +func_rt_ptr: .quad 0 efi_saved_sp: .quad 0 diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 4b45f55dd6a9..745c6ac2fead 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -299,11 +299,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_e= c *ec, /* following two actions should be kept atomic */ ec->curr =3D t; start_transaction(ec); + if (ec->curr->command =3D=3D ACPI_EC_COMMAND_QUERY) + clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); spin_unlock_irqrestore(&ec->lock, tmp); ret =3D ec_poll(ec); spin_lock_irqsave(&ec->lock, tmp); - if (ec->curr->command =3D=3D ACPI_EC_COMMAND_QUERY) - clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); ec->curr =3D NULL; spin_unlock_irqrestore(&ec->lock, tmp); return ret; diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index eee55c1e5fde..5f2e21e9fbb1 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1704,7 +1704,7 @@ int pm_genpd_add_subdomain_names(const char *master_n= ame, int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *subdomain) { - struct gpd_link *link; + struct gpd_link *l, *link; int ret =3D -EINVAL; =20 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) @@ -1713,7 +1713,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domai= n *genpd, start: genpd_acquire_lock(genpd); =20 - list_for_each_entry(link, &genpd->master_links, master_node) { + list_for_each_entry_safe(link, l, &genpd->master_links, master_node) { if (link->slave !=3D subdomain) continue; =20 diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 95b181d1ca6d..0ed019c8012f 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -272,6 +272,8 @@ static ssize_t pm_qos_latency_tolerance_store(struct de= vice *dev, value =3D PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; else if (!strcmp(buf, "any") || !strcmp(buf, "any\n")) value =3D PM_QOS_LATENCY_ANY; + else + return -EINVAL; } ret =3D dev_pm_qos_update_user_latency_tolerance(dev, value); return ret < 0 ? ret : n; diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c index 01730a27ae07..994fb055e99d 100644 --- a/drivers/char/tpm/tpm-sysfs.c +++ b/drivers/char/tpm/tpm-sysfs.c @@ -54,9 +54,10 @@ static ssize_t pubek_show(struct device *dev, struct dev= ice_attribute *attr, ssize_t err; int i, rc; char *str =3D buf; - struct tpm_chip *chip =3D dev_get_drvdata(dev); =20 + memset(&tpm_cmd, 0, sizeof(tpm_cmd)); + tpm_cmd.header.in =3D tpm_readpubek_header; err =3D transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, "attempting to read the PUBEK"); diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 0618be06b9fb..e4ccf1046765 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -957,7 +957,9 @@ static int atmel_sha_finup(struct ahash_request *req) ctx->flags |=3D SHA_FLAGS_FINUP; =20 err1 =3D atmel_sha_update(req); - if (err1 =3D=3D -EINPROGRESS || err1 =3D=3D -EBUSY) + if (err1 =3D=3D -EINPROGRESS || + (err1 =3D=3D -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) return err1; =20 /* diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index 4f03b1a14d62..80f3f9b64033 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -478,7 +478,7 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, c= onst u8 *key_in, ret =3D caam_jr_enqueue(jrdev, desc, split_key_done, &result); if (!ret) { /* in progress */ - wait_for_completion_interruptible(&result.completion); + wait_for_completion(&result.completion); ret =3D result.err; #ifdef DEBUG print_hex_dump(KERN_ERR, diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index e1eaf4ff9762..3ce1d5cdcbd2 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c @@ -103,7 +103,7 @@ int gen_split_key(struct device *jrdev, u8 *key_out, in= t split_key_len, ret =3D caam_jr_enqueue(jrdev, desc, split_key_done, &result); if (!ret) { /* in progress */ - wait_for_completion_interruptible(&result.completion); + wait_for_completion(&result.completion); ret =3D result.err; #ifdef DEBUG print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ", diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index da328ed633fb..c6bd28c59d65 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -634,7 +634,7 @@ static void talitos_unregister_rng(struct device *dev) * crypto alg */ #define TALITOS_CRA_PRIORITY 3000 -#define TALITOS_MAX_KEY_SIZE 96 +#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE) #define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK= _SIZE */ =20 #define MD5_BLOCK_SIZE 64 @@ -1324,6 +1324,11 @@ static int ablkcipher_setkey(struct crypto_ablkciphe= r *cipher, { struct talitos_ctx *ctx =3D crypto_ablkcipher_ctx(cipher); =20 + if (keylen > TALITOS_MAX_KEY_SIZE) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + memcpy(&ctx->key, key, keylen); ctx->keylen =3D keylen; =20 diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0de123afdb34..990e5ac8b18d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -973,7 +973,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_get); */ void drm_vblank_put(struct drm_device *dev, int crtc) { - BUG_ON(atomic_read(&dev->vblank[crtc].refcount) =3D=3D 0); + if (WARN_ON(atomic_read(&dev->vblank[crtc].refcount) =3D=3D 0)) + return; =20 /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dm= a.c index 646b68a58979..8bf2ae01b539 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1747,10 +1747,12 @@ int i915_driver_load(struct drm_device *dev, unsign= ed long flags) * and the registers being closely associated. * * According to chipset errata, on the 965GM, MSI interrupts may - * be lost or delayed, but we use them anyways to avoid - * stuck interrupts on some machines. + * be lost or delayed, and was defeatured. MSI interrupts seem to + * get lost on g4x as well, and interrupt delivery seems to stay + * properly dead afterwards. So we'll just disable them for all + * pre-gen5 chipsets. */ - if (!IS_I945G(dev) && !IS_I945GM(dev)) + if (INTEL_INFO(dev)->gen >=3D 5) pci_enable_msi(dev->pdev); =20 intel_device_info_runtime_init(dev); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/in= tel_display.c index 03c76d17f0de..3a3afe1b15bd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -369,7 +369,7 @@ static void vlv_clock(int refclk, intel_clock_t *clock) /** * Returns whether any output on the specified pipe is of the specified ty= pe */ -static bool intel_pipe_has_type(struct drm_crtc *crtc, int type) +bool intel_pipe_has_type(struct drm_crtc *crtc, int type) { struct drm_device *dev =3D crtc->dev; struct intel_encoder *encoder; @@ -10313,6 +10313,15 @@ static void update_scanline_offset(struct intel_cr= tc *crtc) * type. For DP ports it behaves like most other platforms, but on HDMI * there's an extra 1 line difference. So we need to add two instead of * one to the value. + * + * On VLV/CHV DSI the scanline counter would appear to increment + * approx. 1/3 of a scanline before start of vblank. Unfortunately + * that means we can't tell whether we're in vblank or not while + * we're on that particular line. We must still set scanline_offset + * to 1 so that the vblank timestamps come out correct when we query + * the scanline counter from within the vblank interrupt handler. + * However if queried just before the start of vblank we'll get an + * answer that's slightly in the future. */ if (IS_GEN2(dev)) { const struct drm_display_mode *mode =3D &crtc->config.adjusted_mode; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_= drv.h index 4a2dbcbf13f3..508e4d8ae68d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -721,6 +721,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, const char *intel_output_name(int output); bool intel_has_pending_fb_unpin(struct drm_device *dev); int intel_pch_rawclk(struct drm_device *dev); +bool intel_pipe_has_type(struct drm_crtc *crtc, int type); int valleyview_cur_cdclk(struct drm_i915_private *dev_priv); void intel_mark_busy(struct drm_device *dev); void intel_mark_fb_busy(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/int= el_sprite.c index 9a17b4e92ef4..1d1207ed2abe 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -53,6 +53,8 @@ static bool intel_pipe_update_start(struct intel_crtc *cr= tc, uint32_t *start_vbl enum pipe pipe =3D crtc->pipe; long timeout =3D msecs_to_jiffies_timeout(1); int scanline, min, max, vblank_start; + bool need_vlv_dsi_wa =3D (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) && + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DSI); DEFINE_WAIT(wait); =20 WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); @@ -104,6 +106,24 @@ static bool intel_pipe_update_start(struct intel_crtc = *crtc, uint32_t *start_vbl =20 drm_vblank_put(dev, pipe); =20 + /* + * On VLV/CHV DSI the scanline counter would appear to + * increment approx. 1/3 of a scanline before start of vblank. + * The registers still get latched at start of vblank however. + * This means we must not write any registers on the first + * line of vblank (since not the whole line is actually in + * vblank). And unfortunately we can't use the interrupt to + * wait here since it will fire too soon. We could use the + * frame start interrupt instead since it will fire after the + * critical scanline, but that would require more changes + * in the interrupt code. So for now we'll just do the nasty + * thing and poll for the bad scanline to pass us by. + * + * FIXME figure out if BXT+ DSI suffers from this as well + */ + while (need_vlv_dsi_wa && scanline =3D=3D vblank_start) + scanline =3D intel_get_crtc_scanline(crtc); + *start_vbl_count =3D dev->driver->get_vblank_counter(dev, pipe); =20 trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hd= mi/hdmi_audio.c index 872485f60134..9c7975718c77 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c @@ -182,10 +182,10 @@ int hdmi_audio_update(struct hdmi *hdmi) /* configure infoframe: */ hdmi_audio_infoframe_pack(info, buf, sizeof(buf)); hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, - (buf[3] << 0) || (buf[4] << 8) || - (buf[5] << 16) || (buf[6] << 24)); + (buf[3] << 0) | (buf[4] << 8) | + (buf[5] << 16) | (buf[6] << 24)); hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1, - (buf[7] << 0) || (buf[8] << 8)); + (buf[7] << 0) | (buf[8] << 8)); =20 hdmi_write(hdmi, REG_HDMI_GC, 0); =20 diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/r= adeon/atombios_encoders.c index d38799899ca9..5c1a3e5e3fb4 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -29,6 +29,7 @@ #include "radeon.h" #include "atom.h" #include +#include =20 extern int atom_debug; =20 @@ -2095,9 +2096,17 @@ static int radeon_atom_pick_dig_encoder(struct drm_e= ncoder *encoder) } } =20 - /* on DCE32 and encoder can driver any block so just crtc id */ + /* + * On DCE32 any encoder can drive any block so usually just use crtc id, + * but Apple thinks different at least on iMac10,1, so there use linkb, + * otherwise the internal eDP panel will stay dark. + */ if (ASIC_IS_DCE32(rdev)) { - return radeon_crtc->crtc_id; + if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1")) + return (dig->linkb) ? 1 : 0; + else + return radeon_crtc->crtc_id; + } =20 /* on DCE3 - LVTMA can only be driven by DIGB */ diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cade= nce.c index c604f4c3ac0d..4c4aee58c741 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -340,14 +340,14 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) CDNS_I2C_XFER_SIZE_OFFSET); else cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); + /* Set the slave address in address register - triggers operation */ + cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, + CDNS_I2C_ADDR_OFFSET); /* Clear the bus hold flag if bytes to receive is less than FIFO size */ if (!id->bus_hold_flag && ((id->p_msg->flags & I2C_M_RECV_LEN) !=3D I2C_M_RECV_LEN) && (id->recv_count <=3D CDNS_I2C_FIFO_DEPTH)) cdns_i2c_clear_bus_hold(id); - /* Set the slave address in address register - triggers operation */ - cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, - CDNS_I2C_ADDR_OFFSET); cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); } =20 diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_= spi.c index 195639646e34..d0e1acd7c66b 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -48,15 +48,11 @@ static int st_accel_spi_remove(struct spi_device *spi) } =20 static const struct spi_device_id st_accel_id_table[] =3D { - { LSM303DLH_ACCEL_DEV_NAME }, - { LSM303DLHC_ACCEL_DEV_NAME }, { LIS3DH_ACCEL_DEV_NAME }, { LSM330D_ACCEL_DEV_NAME }, { LSM330DL_ACCEL_DEV_NAME }, { LSM330DLC_ACCEL_DEV_NAME }, { LIS331DLH_ACCEL_DEV_NAME }, - { LSM303DL_ACCEL_DEV_NAME }, - { LSM303DLM_ACCEL_DEV_NAME }, { LSM330_ACCEL_DEV_NAME }, {}, }; diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetome= ter/st_magn_spi.c index a6143ea51dfc..d28685bec34e 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -49,8 +49,6 @@ static int st_magn_spi_remove(struct spi_device *spi) } =20 static const struct spi_device_id st_magn_id_table[] =3D { - { LSM303DLHC_MAGN_DEV_NAME }, - { LSM303DLM_MAGN_DEV_NAME }, { LIS3MDL_MAGN_DEV_NAME }, {}, }; diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cach= e.c index 80f6cf2449fb..896e5e6b0a02 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -58,17 +58,6 @@ struct ib_update_work { u8 port_num; }; =20 -static inline int start_port(struct ib_device *device) -{ - return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? 0 : 1; -} - -static inline int end_port(struct ib_device *device) -{ - return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? - 0 : device->phys_port_cnt; -} - int ib_get_cached_gid(struct ib_device *device, u8 port_num, int index, @@ -78,12 +67,12 @@ int ib_get_cached_gid(struct ib_device *device, unsigned long flags; int ret =3D 0; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 read_lock_irqsave(&device->cache.lock, flags); =20 - cache =3D device->cache.gid_cache[port_num - start_port(device)]; + cache =3D device->cache.gid_cache[port_num - rdma_start_port(device)]; =20 if (index < 0 || index >=3D cache->table_len) ret =3D -EINVAL; @@ -112,11 +101,11 @@ int ib_find_cached_gid(struct ib_device *device, =20 read_lock_irqsave(&device->cache.lock, flags); =20 - for (p =3D 0; p <=3D end_port(device) - start_port(device); ++p) { + for (p =3D 0; p <=3D rdma_end_port(device) - rdma_start_port(device); ++p= ) { cache =3D device->cache.gid_cache[p]; for (i =3D 0; i < cache->table_len; ++i) { if (!memcmp(gid, &cache->table[i], sizeof *gid)) { - *port_num =3D p + start_port(device); + *port_num =3D p + rdma_start_port(device); if (index) *index =3D i; ret =3D 0; @@ -140,12 +129,12 @@ int ib_get_cached_pkey(struct ib_device *device, unsigned long flags; int ret =3D 0; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 read_lock_irqsave(&device->cache.lock, flags); =20 - cache =3D device->cache.pkey_cache[port_num - start_port(device)]; + cache =3D device->cache.pkey_cache[port_num - rdma_start_port(device)]; =20 if (index < 0 || index >=3D cache->table_len) ret =3D -EINVAL; @@ -169,12 +158,12 @@ int ib_find_cached_pkey(struct ib_device *device, int ret =3D -ENOENT; int partial_ix =3D -1; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 read_lock_irqsave(&device->cache.lock, flags); =20 - cache =3D device->cache.pkey_cache[port_num - start_port(device)]; + cache =3D device->cache.pkey_cache[port_num - rdma_start_port(device)]; =20 *index =3D -1; =20 @@ -209,12 +198,12 @@ int ib_find_exact_cached_pkey(struct ib_device *devic= e, int i; int ret =3D -ENOENT; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 read_lock_irqsave(&device->cache.lock, flags); =20 - cache =3D device->cache.pkey_cache[port_num - start_port(device)]; + cache =3D device->cache.pkey_cache[port_num - rdma_start_port(device)]; =20 *index =3D -1; =20 @@ -238,11 +227,11 @@ int ib_get_cached_lmc(struct ib_device *device, unsigned long flags; int ret =3D 0; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 read_lock_irqsave(&device->cache.lock, flags); - *lmc =3D device->cache.lmc_cache[port_num - start_port(device)]; + *lmc =3D device->cache.lmc_cache[port_num - rdma_start_port(device)]; read_unlock_irqrestore(&device->cache.lock, flags); =20 return ret; @@ -303,13 +292,13 @@ static void ib_cache_update(struct ib_device *device, =20 write_lock_irq(&device->cache.lock); =20 - old_pkey_cache =3D device->cache.pkey_cache[port - start_port(device)]; - old_gid_cache =3D device->cache.gid_cache [port - start_port(device)]; + old_pkey_cache =3D device->cache.pkey_cache[port - rdma_start_port(device= )]; + old_gid_cache =3D device->cache.gid_cache [port - rdma_start_port(device= )]; =20 - device->cache.pkey_cache[port - start_port(device)] =3D pkey_cache; - device->cache.gid_cache [port - start_port(device)] =3D gid_cache; + device->cache.pkey_cache[port - rdma_start_port(device)] =3D pkey_cache; + device->cache.gid_cache [port - rdma_start_port(device)] =3D gid_cache; =20 - device->cache.lmc_cache[port - start_port(device)] =3D tprops->lmc; + device->cache.lmc_cache[port - rdma_start_port(device)] =3D tprops->lmc; =20 write_unlock_irq(&device->cache.lock); =20 @@ -363,14 +352,14 @@ static void ib_cache_setup_one(struct ib_device *devi= ce) =20 device->cache.pkey_cache =3D kmalloc(sizeof *device->cache.pkey_cache * - (end_port(device) - start_port(device) + 1), GFP_KERNEL); + (rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL); device->cache.gid_cache =3D kmalloc(sizeof *device->cache.gid_cache * - (end_port(device) - start_port(device) + 1), GFP_KERNEL); + (rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL); =20 device->cache.lmc_cache =3D kmalloc(sizeof *device->cache.lmc_cache * - (end_port(device) - - start_port(device) + 1), + (rdma_end_port(device) - + rdma_start_port(device) + 1), GFP_KERNEL); =20 if (!device->cache.pkey_cache || !device->cache.gid_cache || @@ -380,10 +369,10 @@ static void ib_cache_setup_one(struct ib_device *devi= ce) goto err; } =20 - for (p =3D 0; p <=3D end_port(device) - start_port(device); ++p) { + for (p =3D 0; p <=3D rdma_end_port(device) - rdma_start_port(device); ++p= ) { device->cache.pkey_cache[p] =3D NULL; device->cache.gid_cache [p] =3D NULL; - ib_cache_update(device, p + start_port(device)); + ib_cache_update(device, p + rdma_start_port(device)); } =20 INIT_IB_EVENT_HANDLER(&device->cache.event_handler, @@ -394,7 +383,7 @@ static void ib_cache_setup_one(struct ib_device *device) return; =20 err_cache: - for (p =3D 0; p <=3D end_port(device) - start_port(device); ++p) { + for (p =3D 0; p <=3D rdma_end_port(device) - rdma_start_port(device); ++p= ) { kfree(device->cache.pkey_cache[p]); kfree(device->cache.gid_cache[p]); } @@ -412,7 +401,7 @@ static void ib_cache_cleanup_one(struct ib_device *devi= ce) ib_unregister_event_handler(&device->cache.event_handler); flush_workqueue(ib_wq); =20 - for (p =3D 0; p <=3D end_port(device) - start_port(device); ++p) { + for (p =3D 0; p <=3D rdma_end_port(device) - rdma_start_port(device); ++p= ) { kfree(device->cache.pkey_cache[p]); kfree(device->cache.gid_cache[p]); } diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/dev= ice.c index 18c1ece765f2..1d07df37178f 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -151,18 +151,6 @@ static int alloc_name(char *name) return 0; } =20 -static int start_port(struct ib_device *device) -{ - return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? 0 : 1; -} - - -static int end_port(struct ib_device *device) -{ - return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? - 0 : device->phys_port_cnt; -} - /** * ib_alloc_device - allocate an IB device struct * @size:size of structure to allocate @@ -232,7 +220,7 @@ static int read_port_table_lengths(struct ib_device *de= vice) if (!tprops) goto out; =20 - num_ports =3D end_port(device) - start_port(device) + 1; + num_ports =3D rdma_end_port(device) - rdma_start_port(device) + 1; =20 device->pkey_tbl_len =3D kmalloc(sizeof *device->pkey_tbl_len * num_ports, GFP_KERNEL); @@ -242,7 +230,7 @@ static int read_port_table_lengths(struct ib_device *de= vice) goto err; =20 for (port_index =3D 0; port_index < num_ports; ++port_index) { - ret =3D ib_query_port(device, port_index + start_port(device), + ret =3D ib_query_port(device, port_index + rdma_start_port(device), tprops); if (ret) goto err; @@ -575,7 +563,7 @@ int ib_query_port(struct ib_device *device, u8 port_num, struct ib_port_attr *port_attr) { - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 return device->query_port(device, port_num, port_attr); @@ -653,7 +641,7 @@ int ib_modify_port(struct ib_device *device, if (!device->modify_port) return -ENOSYS; =20 - if (port_num < start_port(device) || port_num > end_port(device)) + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; =20 return device->modify_port(device, port_num, port_modify_mask, @@ -676,8 +664,8 @@ int ib_find_gid(struct ib_device *device, union ib_gid = *gid, union ib_gid tmp_gid; int ret, port, i; =20 - for (port =3D start_port(device); port <=3D end_port(device); ++port) { - for (i =3D 0; i < device->gid_tbl_len[port - start_port(device)]; ++i) { + for (port =3D rdma_start_port(device); port <=3D rdma_end_port(device); += +port) { + for (i =3D 0; i < device->gid_tbl_len[port - rdma_start_port(device)]; += +i) { ret =3D ib_query_gid(device, port, i, &tmp_gid); if (ret) return ret; @@ -709,7 +697,7 @@ int ib_find_pkey(struct ib_device *device, u16 tmp_pkey; int partial_ix =3D -1; =20 - for (i =3D 0; i < device->pkey_tbl_len[port_num - start_port(device)]; ++= i) { + for (i =3D 0; i < device->pkey_tbl_len[port_num - rdma_start_port(device)= ]; ++i) { ret =3D ib_query_pkey(device, port_num, i, &tmp_pkey); if (ret) return ret; diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core= /uverbs_cmd.c index 779067acd270..ab6326cdde23 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1915,6 +1915,11 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *f= ile, goto out; } =20 + if (!rdma_is_port_valid(qp->device, cmd.port_num)) { + ret =3D -EINVAL; + goto release_qp; + } + attr->qp_state =3D cmd.qp_state; attr->cur_qp_state =3D cmd.cur_qp_state; attr->path_mtu =3D cmd.path_mtu; @@ -2397,6 +2402,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *fi= le, const char __user *buf, int in_len, int out_len) { + struct ib_device *ib_dev =3D file->device->ib_dev; struct ib_uverbs_create_ah cmd; struct ib_uverbs_create_ah_resp resp; struct ib_uobject *uobj; @@ -2411,6 +2417,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *fi= le, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; =20 + if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num)) + return -EINVAL; + uobj =3D kmalloc(sizeof *uobj, GFP_KERNEL); if (!uobj) return -ENOMEM; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 9a0cc5b5561a..d3ff4c0082fe 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -397,8 +397,10 @@ static int i8042_start(struct serio *serio) { struct i8042_port *port =3D serio->port_data; =20 + spin_lock_irq(&i8042_lock); port->exists =3D true; - mb(); + spin_unlock_irq(&i8042_lock); + return 0; } =20 @@ -411,16 +413,20 @@ static void i8042_stop(struct serio *serio) { struct i8042_port *port =3D serio->port_data; =20 + spin_lock_irq(&i8042_lock); port->exists =3D false; + port->serio =3D NULL; + spin_unlock_irq(&i8042_lock); =20 /* + * We need to make sure that interrupt handler finishes using + * our serio port before we return from this function. * We synchronize with both AUX and KBD IRQs because there is * a (very unlikely) chance that AUX IRQ is raised for KBD port * and vice versa. */ synchronize_irq(I8042_AUX_IRQ); synchronize_irq(I8042_KBD_IRQ); - port->serio =3D NULL; } =20 /* @@ -537,7 +543,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_i= d) =20 spin_unlock_irqrestore(&i8042_lock, flags); =20 - if (likely(port->exists && !filtered)) + if (likely(serio && !filtered)) serio_interrupt(serio, data, dfl); =20 out: diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscree= n/ads7846.c index da201b8e37dc..f0ec124b8f6f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -668,18 +668,22 @@ static int ads7846_no_filter(void *ads, int data_idx,= int *val) =20 static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) { + int value; struct spi_transfer *t =3D list_entry(m->transfers.prev, struct spi_transfer, transfer_list); =20 if (ts->model =3D=3D 7845) { - return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; + value =3D be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1])); } else { /* * adjust: on-wire is a must-ignore bit, a BE12 value, then * padding; built from two 8 bit values written msb-first. */ - return be16_to_cpup((__be16 *)t->rx_buf) >> 3; + value =3D be16_to_cpup((__be16 *)t->rx_buf); } + + /* enforce ADC output is 12 bits width */ + return (value >> 3) & 0xfff; } =20 static void ads7846_update_value(struct spi_message *m, int val) diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm= _windtunnel.c index 3b4a157714b1..b40ed32379ec 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -408,6 +408,7 @@ static const struct i2c_device_id therm_windtunnel_id[]= =3D { { "therm_adm1030", adm1030 }, { } }; +MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); =20 static int do_probe(struct i2c_client *cl, const struct i2c_device_id *id) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d043e50ebea7..4f0773c8ad20 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1183,11 +1183,62 @@ void dm_accept_partial_bio(struct bio *bio, unsigne= d n_sectors) } EXPORT_SYMBOL_GPL(dm_accept_partial_bio); =20 +/* + * Flush current->bio_list when the target map method blocks. + * This fixes deadlocks in snapshot and possibly in other targets. + */ +struct dm_offload { + struct blk_plug plug; + struct blk_plug_cb cb; +}; + +static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_sched= ule) +{ + struct dm_offload *o =3D container_of(cb, struct dm_offload, cb); + struct bio_list list; + struct bio *bio; + + INIT_LIST_HEAD(&o->cb.list); + + if (unlikely(!current->bio_list)) + return; + + list =3D *current->bio_list; + bio_list_init(current->bio_list); + + while ((bio =3D bio_list_pop(&list))) { + struct bio_set *bs =3D bio->bi_pool; + if (unlikely(!bs) || bs =3D=3D fs_bio_set) { + bio_list_add(current->bio_list, bio); + continue; + } + + spin_lock(&bs->rescue_lock); + bio_list_add(&bs->rescue_list, bio); + queue_work(bs->rescue_workqueue, &bs->rescue_work); + spin_unlock(&bs->rescue_lock); + } +} + +static void dm_offload_start(struct dm_offload *o) +{ + blk_start_plug(&o->plug); + o->cb.callback =3D flush_current_bio_list; + list_add(&o->cb.list, ¤t->plug->cb_list); +} + +static void dm_offload_end(struct dm_offload *o) +{ + list_del(&o->cb.list); + blk_finish_plug(&o->plug); +} + static void __map_bio(struct dm_target_io *tio) { int r; sector_t sector; struct mapped_device *md; + struct dm_offload o; struct bio *clone =3D &tio->clone; struct dm_target *ti =3D tio->ti; =20 @@ -1200,7 +1251,11 @@ static void __map_bio(struct dm_target_io *tio) */ atomic_inc(&tio->io->io_count); sector =3D clone->bi_iter.bi_sector; + + dm_offload_start(&o); r =3D ti->type->map(ti, clone); + dm_offload_end(&o); + if (r =3D=3D DM_MAPIO_REMAPPED) { /* the bio has been remapped so dispatch it */ =20 diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 0d91644e80eb..41b1f7aa88d3 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1122,13 +1122,16 @@ static void make_request(struct mddev *mddev, struc= t bio * bio) */ DEFINE_WAIT(w); for (;;) { - flush_signals(current); + sigset_t full, old; prepare_to_wait(&conf->wait_barrier, &w, TASK_INTERRUPTIBLE); if (bio_end_sector(bio) <=3D mddev->suspend_lo || bio->bi_iter.bi_sector >=3D mddev->suspend_hi) break; + sigfillset(&full); + sigprocmask(SIG_BLOCK, &full, &old); schedule(); + sigprocmask(SIG_SETMASK, &old, NULL); } finish_wait(&conf->wait_barrier, &w); } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 63a094166138..16789320135f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4721,12 +4721,15 @@ static void make_request(struct mddev *mddev, struc= t bio * bi) * userspace, we want an interruptible * wait. */ - flush_signals(current); prepare_to_wait(&conf->wait_for_overlap, &w, TASK_INTERRUPTIBLE); if (logical_sector >=3D mddev->suspend_lo && logical_sector < mddev->suspend_hi) { + sigset_t full, old; + sigfillset(&full); + sigprocmask(SIG_BLOCK, &full, &old); schedule(); + sigprocmask(SIG_SETMASK, &old, NULL); do_prepare =3D true; } goto retry; diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci= /saa7164/saa7164-buffer.c index 66696fa8341d..9bd1f73f82da 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -130,9 +130,9 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7= 164_port *port, goto fail2; =20 /* init the buffers to a known pattern, easier during debugging */ - memset_io(buf->cpu, 0xff, buf->pci_size); + memset(buf->cpu, 0xff, buf->pci_size); buf->crc =3D crc32(0, buf->cpu, buf->actual_size); - memset_io(buf->pt_cpu, 0xff, buf->pt_size); + memset(buf->pt_cpu, 0xff, buf->pt_size); =20 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n", __func__, buf, params->numpagetables); diff --git a/drivers/media/pci/saa7164/saa7164-bus.c b/drivers/media/pci/sa= a7164/saa7164-bus.c index 5f6f3094c44e..1c779ea8b5ec 100644 --- a/drivers/media/pci/saa7164/saa7164-bus.c +++ b/drivers/media/pci/saa7164/saa7164-bus.c @@ -33,12 +33,12 @@ int saa7164_bus_setup(struct saa7164_dev *dev) b->Type =3D TYPE_BUS_PCIe; b->m_wMaxReqSize =3D SAA_DEVICE_MAXREQUESTSIZE; =20 - b->m_pdwSetRing =3D (u8 *)(dev->bmmio + + b->m_pdwSetRing =3D (u8 __iomem *)(dev->bmmio + ((u32)dev->busdesc.CommandRing)); =20 b->m_dwSizeSetRing =3D SAA_DEVICE_BUFFERBLOCKSIZE; =20 - b->m_pdwGetRing =3D (u8 *)(dev->bmmio + + b->m_pdwGetRing =3D (u8 __iomem *)(dev->bmmio + ((u32)dev->busdesc.ResponseRing)); =20 b->m_dwSizeGetRing =3D SAA_DEVICE_BUFFERBLOCKSIZE; @@ -138,6 +138,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmC= omResInfo* msg, u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; u32 new_swp, space_rem; int ret =3D SAA_ERR_BAD_PARAMETER; + u16 size; =20 if (!msg) { printk(KERN_ERR "%s() !msg\n", __func__); @@ -148,10 +149,6 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tm= ComResInfo* msg, =20 saa7164_bus_verify(dev); =20 - msg->size =3D cpu_to_le16(msg->size); - msg->command =3D cpu_to_le32(msg->command); - msg->controlselector =3D cpu_to_le16(msg->controlselector); - if (msg->size > dev->bus.m_wMaxReqSize) { printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n", __func__); @@ -169,8 +166,8 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmC= omResInfo* msg, bytes_to_write =3D sizeof(*msg) + msg->size; free_write_space =3D 0; timeout =3D SAA_BUS_TIMEOUT; - curr_srp =3D le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); - curr_swp =3D le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos)); + curr_srp =3D saa7164_readl(bus->m_dwSetReadPos); + curr_swp =3D saa7164_readl(bus->m_dwSetWritePos); =20 /* Deal with ring wrapping issues */ if (curr_srp > curr_swp) @@ -203,7 +200,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmC= omResInfo* msg, mdelay(1); =20 /* Check the space usage again */ - curr_srp =3D le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); + curr_srp =3D saa7164_readl(bus->m_dwSetReadPos); =20 /* Deal with ring wrapping issues */ if (curr_srp > curr_swp) @@ -223,6 +220,16 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tm= ComResInfo* msg, dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing =3D %x\n", __func__, bus->m_dwSizeSetRing); =20 + /* + * Make a copy of msg->size before it is converted to le16 since it is + * used in the code below. + */ + size =3D msg->size; + /* Convert to le16/le32 */ + msg->size =3D (__force u16)cpu_to_le16(msg->size); + msg->command =3D (__force u32)cpu_to_le32(msg->command); + msg->controlselector =3D (__force u16)cpu_to_le16(msg->controlselector); + /* Mental Note: line 462 tmmhComResBusPCIe.cpp */ =20 /* Check if we're going to wrap again */ @@ -243,28 +250,28 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct t= mComResInfo* msg, dprintk(DBGLVL_BUS, "%s() tr4\n", __func__); =20 /* Split the msg into pieces as the ring wraps */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem); - memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem, + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, space_rem); + memcpy_toio(bus->m_pdwSetRing, (u8 *)msg + space_rem, sizeof(*msg) - space_rem); =20 - memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem, - buf, msg->size); + memcpy_toio(bus->m_pdwSetRing + sizeof(*msg) - space_rem, + buf, size); =20 } else if (space_rem =3D=3D sizeof(*msg)) { dprintk(DBGLVL_BUS, "%s() tr5\n", __func__); =20 /* Additional data at the beginning of the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing, buf, msg->size); + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + memcpy_toio(bus->m_pdwSetRing, buf, size); =20 } else { /* Additional data wraps around the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - if (msg->size > 0) { - memcpy(bus->m_pdwSetRing + curr_swp + + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + if (size > 0) { + memcpy_toio(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, space_rem - sizeof(*msg)); - memcpy(bus->m_pdwSetRing, (u8 *)buf + + memcpy_toio(bus->m_pdwSetRing, (u8 *)buf + space_rem - sizeof(*msg), bytes_to_write - space_rem); } @@ -276,15 +283,20 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct t= mComResInfo* msg, dprintk(DBGLVL_BUS, "%s() tr6\n", __func__); =20 /* The ring buffer doesn't wrap, two simple copies */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, - msg->size); + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + memcpy_toio(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, + size); } =20 dprintk(DBGLVL_BUS, "%s() new_swp =3D %x\n", __func__, new_swp); =20 /* Update the bus write position */ - saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp)); + saa7164_writel(bus->m_dwSetWritePos, new_swp); + + /* Convert back to cpu after writing the msg to the ringbuffer. */ + msg->size =3D le16_to_cpu((__force __le16)msg->size); + msg->command =3D le32_to_cpu((__force __le32)msg->command); + msg->controlselector =3D le16_to_cpu((__force __le16)msg->controlselector= ); ret =3D SAA_OK; =20 out: @@ -336,8 +348,8 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmC= omResInfo* msg, /* Peek the bus to see if a msg exists, if it's not what we're expecting * then return cleanly else read the message from the bus. */ - curr_gwp =3D le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos)); - curr_grp =3D le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos)); + curr_gwp =3D saa7164_readl(bus->m_dwGetWritePos); + curr_grp =3D saa7164_readl(bus->m_dwGetReadPos); =20 if (curr_gwp =3D=3D curr_grp) { ret =3D SAA_ERR_EMPTY; @@ -369,19 +381,23 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct t= mComResInfo* msg, new_grp -=3D bus->m_dwSizeGetRing; space_rem =3D bus->m_dwSizeGetRing - curr_grp; =20 - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, + memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); + memcpy_fromio((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, bytes_to_read - space_rem); =20 } else { /* No wrapping */ - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); + memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); } + /* Convert from little endian to CPU */ + msg_tmp.size =3D le16_to_cpu((__force __le16)msg_tmp.size); + msg_tmp.command =3D le32_to_cpu((__force __le32)msg_tmp.command); + msg_tmp.controlselector =3D le16_to_cpu((__force __le16)msg_tmp.controlse= lector); + memcpy(msg, &msg_tmp, sizeof(*msg)); =20 /* No need to update the read positions, because this was a peek */ /* If the caller specifically want to peek, return */ if (peekonly) { - memcpy(msg, &msg_tmp, sizeof(*msg)); goto peekout; } =20 @@ -426,25 +442,19 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct t= mComResInfo* msg, space_rem =3D bus->m_dwSizeGetRing - curr_grp; =20 if (space_rem < sizeof(*msg)) { - /* msg wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing, - sizeof(*msg) - space_rem); if (buf) - memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) - + memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) - space_rem, buf_size); =20 } else if (space_rem =3D=3D sizeof(*msg)) { - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) - memcpy(buf, bus->m_pdwGetRing, buf_size); + memcpy_fromio(buf, bus->m_pdwGetRing, buf_size); } else { /* Additional data wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) { - memcpy(buf, bus->m_pdwGetRing + curr_grp + + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), space_rem - sizeof(*msg)); - memcpy(buf + space_rem - sizeof(*msg), + memcpy_fromio(buf + space_rem - sizeof(*msg), bus->m_pdwGetRing, bytes_to_read - space_rem); } @@ -453,19 +463,15 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct t= mComResInfo* msg, =20 } else { /* No wrapping */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) - memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), buf_size); } =20 /* Update the read positions, adjusting the ring */ - saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp)); + saa7164_writel(bus->m_dwGetReadPos, new_grp); =20 peekout: - msg->size =3D le16_to_cpu(msg->size); - msg->command =3D le32_to_cpu(msg->command); - msg->controlselector =3D le16_to_cpu(msg->controlselector); ret =3D SAA_OK; out: mutex_unlock(&bus->lock); diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/s= aa7164/saa7164-core.c index 1bf06970ca3e..009140b64bde 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -119,7 +119,7 @@ static void saa7164_ts_verifier(struct saa7164_buffer *= buf) u32 i; u8 cc, a; u16 pid; - u8 __iomem *bufcpu =3D (u8 *)buf->cpu; + u8 *bufcpu =3D (u8 *)buf->cpu; =20 port->sync_errors =3D 0; port->v_cc_errors =3D 0; @@ -260,7 +260,7 @@ static void saa7164_work_enchandler_helper(struct saa71= 64_port *port, int bufnr) struct saa7164_user_buffer *ubuf =3D NULL; struct list_head *c, *n; int i =3D 0; - u8 __iomem *p; + u8 *p; =20 mutex_lock(&port->dmaqueue_lock); list_for_each_safe(c, n, &port->dmaqueue.list) { @@ -318,8 +318,7 @@ static void saa7164_work_enchandler_helper(struct saa71= 64_port *port, int bufnr) =20 if (buf->actual_size <=3D ubuf->actual_size) { =20 - memcpy_fromio(ubuf->data, buf->cpu, - ubuf->actual_size); + memcpy(ubuf->data, buf->cpu, ubuf->actual_size); =20 if (crc_checking) { /* Throw a new checksum on the read buffer */ @@ -346,7 +345,7 @@ static void saa7164_work_enchandler_helper(struct saa71= 64_port *port, int bufnr) * with known bad data. We check for this data at a later point * in time. */ saa7164_buffer_zero_offsets(port, bufnr); - memset_io(buf->cpu, 0xff, buf->pci_size); + memset(buf->cpu, 0xff, buf->pci_size); if (crc_checking) { /* Throw yet aanother new checksum on the dma buffer */ buf->crc =3D crc32(0, buf->cpu, buf->actual_size); @@ -1096,7 +1095,7 @@ static int saa7164_proc_show(struct seq_file *m, void= *v) if (c =3D=3D 0) seq_printf(m, " %04x:", i); =20 - seq_printf(m, " %02x", *(b->m_pdwSetRing + i)); + seq_printf(m, " %02x", readb(b->m_pdwSetRing + i)); =20 if (++c =3D=3D 16) { seq_printf(m, "\n"); @@ -1111,7 +1110,7 @@ static int saa7164_proc_show(struct seq_file *m, void= *v) if (c =3D=3D 0) seq_printf(m, " %04x:", i); =20 - seq_printf(m, " %02x", *(b->m_pdwGetRing + i)); + seq_printf(m, " %02x", readb(b->m_pdwGetRing + i)); =20 if (++c =3D=3D 16) { seq_printf(m, "\n"); diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa= 7164/saa7164-fw.c index 86763203d61d..add06ab5124d 100644 --- a/drivers/media/pci/saa7164/saa7164-fw.c +++ b/drivers/media/pci/saa7164/saa7164-fw.c @@ -72,7 +72,7 @@ static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u= 32 reg) /* TODO: move dlflags into dev-> and change to write/readl/b */ /* TODO: Excessive levels of debug */ static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 src= size, - u32 dlflags, u8 *dst, u32 dstsize) + u32 dlflags, u8 __iomem *dst, u32 dstsize) { u32 reg, timeout, offset; u8 *srcbuf =3D NULL; @@ -136,7 +136,7 @@ static int saa7164_downloadimage(struct saa7164_dev *de= v, u8 *src, u32 srcsize, srcsize -=3D dstsize, offset +=3D dstsize) { =20 dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize); - memcpy(dst, srcbuf + offset, dstsize); + memcpy_toio(dst, srcbuf + offset, dstsize); =20 /* Flag the data as ready */ saa7164_writel(drflag, 1); @@ -154,7 +154,7 @@ static int saa7164_downloadimage(struct saa7164_dev *de= v, u8 *src, u32 srcsize, =20 dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize); /* Write last block to the device */ - memcpy(dst, srcbuf+offset, srcsize); + memcpy_toio(dst, srcbuf+offset, srcsize); =20 /* Flag the data as ready */ saa7164_writel(drflag, 1); diff --git a/drivers/media/pci/saa7164/saa7164-types.h b/drivers/media/pci/= saa7164/saa7164-types.h index 1d2140a3eb38..f48ba978f835 100644 --- a/drivers/media/pci/saa7164/saa7164-types.h +++ b/drivers/media/pci/saa7164/saa7164-types.h @@ -78,9 +78,9 @@ enum tmBusType { struct tmComResBusInfo { enum tmBusType Type; u16 m_wMaxReqSize; - u8 *m_pdwSetRing; + u8 __iomem *m_pdwSetRing; u32 m_dwSizeSetRing; - u8 *m_pdwGetRing; + u8 __iomem *m_pdwGetRing; u32 m_dwSizeGetRing; u32 m_dwSetWritePos; u32 m_dwSetReadPos; diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa716= 4/saa7164.h index 8b29e8990301..cd1a07ce27cb 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -313,13 +313,13 @@ struct saa7164_buffer { =20 /* A block of page align PCI memory */ u32 pci_size; /* PCI allocation size in bytes */ - u64 __iomem *cpu; /* Virtual address */ + u64 *cpu; /* Virtual address */ dma_addr_t dma; /* Physical address */ u32 crc; /* Checksum for the entire buffer data */ =20 /* A page table that splits the block into a number of entries */ u32 pt_size; /* PCI allocation size in bytes */ - u64 __iomem *pt_cpu; /* Virtual address */ + u64 *pt_cpu; /* Virtual address */ dma_addr_t pt_dma; /* Physical address */ =20 /* Encoder fops */ diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 6afe8a211b22..107984cd4825 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -765,6 +765,7 @@ static void mce_request_packet(struct mceusb_dev *ir, u= nsigned char *data, } else if (urb_type =3D=3D MCEUSB_RX) { /* standard request */ async_urb =3D ir->urb_in; + async_buf =3D NULL; ir->send_flags =3D RECV_FLAG_IN_PROGRESS; =20 } else { @@ -780,6 +781,10 @@ static void mce_request_packet(struct mceusb_dev *ir, = unsigned char *data, res =3D usb_submit_urb(async_urb, GFP_ATOMIC); if (res) { dev_err(dev, "receive request FAILED! (res=3D%d)", res); + if (urb_type =3D=3D MCEUSB_TX) { + kfree(async_buf); + usb_free_urb(async_urb); + } return; } dev_dbg(dev, "receive request complete (res=3D%d)", res); diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 46272b0ae2dd..6890e726b04f 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -457,7 +457,7 @@ static ssize_t sysfs_set_reg(struct device *dev, int err; =20 if (reg & DPOT_ADDR_OTP_EN) { - if (!strncmp(buf, "enabled", sizeof("enabled"))) + if (sysfs_streq(buf, "enabled")) set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask); else clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask); diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 2cf2bbc0b927..6cab9411b158 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -320,6 +320,7 @@ int enclosure_add_device(struct enclosure_device *edev,= int component, struct device *dev) { struct enclosure_component *cdev; + int err; =20 if (!edev || component >=3D edev->components) return -EINVAL; @@ -329,12 +330,17 @@ int enclosure_add_device(struct enclosure_device *ede= v, int component, if (cdev->dev =3D=3D dev) return -EEXIST; =20 - if (cdev->dev) + if (cdev->dev) { enclosure_remove_links(cdev); - - put_device(cdev->dev); + put_device(cdev->dev); + } cdev->dev =3D get_device(dev); - return enclosure_add_links(cdev); + err =3D enclosure_add_links(cdev); + if (err) { + put_device(cdev->dev); + cdev->dev =3D NULL; + } + return err; } EXPORT_SYMBOL_GPL(enclosure_add_device); =20 diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ether= net/intel/e1000e/netdev.c index fe03a752b84b..388902518dd8 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6031,6 +6031,28 @@ static int e1000_init_phy_wakeup(struct e1000_adapte= r *adapter, u32 wufc) return retval; } =20 +static void e1000e_flush_lpic(struct pci_dev *pdev) +{ + struct net_device *netdev =3D pci_get_drvdata(pdev); + struct e1000_adapter *adapter =3D netdev_priv(netdev); + struct e1000_hw *hw =3D &adapter->hw; + u32 ret_val; + + pm_runtime_get_sync(netdev->dev.parent); + + ret_val =3D hw->phy.ops.acquire(hw); + if (ret_val) + goto fl_out; + + pr_info("EEE TX LPI TIMER: %08X\n", + er32(LPIC) >> E1000_LPIC_LPIET_SHIFT); + + hw->phy.ops.release(hw); + +fl_out: + pm_runtime_put_sync(netdev->dev.parent); +} + static int e1000e_pm_freeze(struct device *dev) { struct net_device *netdev =3D pci_get_drvdata(to_pci_dev(dev)); @@ -6330,10 +6352,17 @@ static int e1000e_pm_thaw(struct device *dev) static int e1000e_pm_suspend(struct device *dev) { struct pci_dev *pdev =3D to_pci_dev(dev); + int rc; + + e1000e_flush_lpic(pdev); =20 e1000e_pm_freeze(dev); =20 - return __e1000_shutdown(pdev, false); + rc =3D __e1000_shutdown(pdev, false); + if (rc) + e1000e_pm_thaw(dev); + + return rc; } =20 static int e1000e_pm_resume(struct device *dev) @@ -6409,6 +6438,8 @@ static int e1000e_pm_runtime_suspend(struct device *d= ev) =20 static void e1000_shutdown(struct pci_dev *pdev) { + e1000e_flush_lpic(pdev); + e1000e_pm_freeze(&pdev->dev); =20 __e1000_shutdown(pdev, false); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_dr= v.c index ab68d940a2c7..ff0e464441d0 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -643,15 +643,18 @@ int netvsc_recv_callback(struct hv_device *device_obj, packet->total_data_buflen); =20 skb->protocol =3D eth_type_trans(skb, net); - if (csum_info) { - /* We only look at the IP checksum here. - * Should we be dropping the packet if checksum - * failed? How do we deal with other checksums - TCP/UDP? - */ - if (csum_info->receive.ip_checksum_succeeded) + + /* skb is already created with CHECKSUM_NONE */ + skb_checksum_none_assert(skb); + + /* + * In Linux, the IP checksum is always checked. + * Do L4 checksum offload if enabled and present. + */ + if (csum_info && (net->features & NETIF_F_RXCSUM)) { + if (csum_info->receive.tcp_checksum_succeeded || + csum_info->receive.udp_checksum_succeeded) skb->ip_summed =3D CHECKSUM_UNNECESSARY; - else - skb->ip_summed =3D CHECKSUM_NONE; } =20 if (packet->vlan_tci & VLAN_TAG_PRESENT) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 34f510f78d63..4bb359c79a32 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -991,7 +991,7 @@ static bool vxlan_snoop(struct net_device *dev, return false; =20 /* Don't migrate static entries, drop packets */ - if (f->state & NUD_NOARP) + if (f->state & (NUD_PERMANENT | NUD_NOARP)) return true; =20 if (net_ratelimit()) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wire= less/ath/ath9k/ar9003_phy.c index b81f885aa68c..341e3d0435ce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1688,8 +1688,6 @@ static void ar9003_hw_spectral_scan_wait(struct ath_h= w *ah) static void ar9003_hw_tx99_start(struct ath_hw *ah, u32 qnum) { REG_SET_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); - REG_SET_BIT(ah, 0x9864, 0x7f000); - REG_SET_BIT(ah, 0x9924, 0x7f00fe); REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); REG_WRITE(ah, AR_CR, AR_CR_RXD); REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/a= th/ath9k/tx99.c index a65cfb91adca..fa48dcf3fe03 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c @@ -184,22 +184,27 @@ static ssize_t write_file_tx99(struct file *file, con= st char __user *user_buf, if (strtobool(buf, &start)) return -EINVAL; =20 + mutex_lock(&sc->mutex); + if (start =3D=3D sc->tx99_state) { if (!start) - return count; + goto out; ath_dbg(common, XMIT, "Resetting TX99\n"); ath9k_tx99_deinit(sc); } =20 if (!start) { ath9k_tx99_deinit(sc); - return count; + goto out; } =20 r =3D ath9k_tx99_init(sc); - if (r) + if (r) { + mutex_unlock(&sc->mutex); return r; - + } +out: + mutex_unlock(&sc->mutex); return count; } =20 diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wire= less/iwlwifi/mvm/mac80211.c index b690f7a4ae2f..142e18ff0941 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1315,14 +1315,32 @@ static void iwl_mvm_bss_info_changed_station(struct= iwl_mvm *mvm, WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false), "Failed to update SF upon disassociation\n"); =20 - /* remove AP station now that the MAC is unassoc */ - ret =3D iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); - if (ret) - IWL_ERR(mvm, "failed to remove AP station\n"); + /* + * If we get an assert during the connection (after the + * station has been added, but before the vif is set + * to associated), mac80211 will re-add the station and + * then configure the vif. Since the vif is not + * associated, we would remove the station here and + * this would fail the recovery. + */ + if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, + &mvm->status)) { + /* + * Remove AP station now that + * the MAC is unassoc + */ + ret =3D iwl_mvm_rm_sta_id(mvm, vif, + mvmvif->ap_sta_id); + if (ret) + IWL_ERR(mvm, + "failed to remove AP station\n"); + + if (mvm->d0i3_ap_sta_id =3D=3D mvmvif->ap_sta_id) + mvm->d0i3_ap_sta_id =3D + IWL_MVM_STATION_COUNT; + mvmvif->ap_sta_id =3D IWL_MVM_STATION_COUNT; + } =20 - if (mvm->d0i3_ap_sta_id =3D=3D mvmvif->ap_sta_id) - mvm->d0i3_ap_sta_id =3D IWL_MVM_STATION_COUNT; - mvmvif->ap_sta_id =3D IWL_MVM_STATION_COUNT; /* remove quota for this interface */ ret =3D iwl_mvm_update_quotas(mvm, NULL); if (ret) diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/li= bertas/mesh.c index 6fef746345bc..99da58e99082 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -240,8 +240,9 @@ static ssize_t lbs_prb_rsp_limit_set(struct device *dev, memset(&mesh_access, 0, sizeof(mesh_access)); mesh_access.data[0] =3D cpu_to_le32(CMD_ACT_SET); =20 - if (!kstrtoul(buf, 10, &retry_limit)) - return -ENOTSUPP; + ret =3D kstrtoul(buf, 10, &retry_limit); + if (ret) + return ret; if (retry_limit > 15) return -ENOTSUPP; =20 diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless= /mwifiex/cfg80211.c index 4e674c16d091..ca688991c4c1 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2160,6 +2160,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct = wiphy *wiphy, struct net_device *dev; void *mdev_priv; struct wireless_dev *wdev; + int ret; =20 if (!adapter) return ERR_PTR(-EFAULT); @@ -2254,8 +2255,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct = wiphy *wiphy, priv->bss_num =3D 0; =20 if (mwifiex_cfg80211_init_p2p_client(priv)) { - wdev =3D ERR_PTR(-EFAULT); - goto done; + ret =3D -EFAULT; + goto err_set_bss_mode; } =20 break; @@ -2268,9 +2269,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct = wiphy *wiphy, ether_setup, IEEE80211_NUM_ACS, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); - priv->bss_mode =3D NL80211_IFTYPE_UNSPECIFIED; - wdev =3D ERR_PTR(-ENOMEM); - goto done; + ret =3D -ENOMEM; + goto err_alloc_netdev; } =20 mwifiex_init_priv_params(priv, dev); @@ -2305,31 +2305,32 @@ struct wireless_dev *mwifiex_add_virtual_intf(struc= t wiphy *wiphy, =20 SET_NETDEV_DEV(dev, adapter->dev); =20 + sema_init(&priv->async_sem, 1); + /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - free_netdev(dev); - priv->bss_mode =3D NL80211_IFTYPE_UNSPECIFIED; - priv->netdev =3D NULL; - wdev =3D ERR_PTR(-EFAULT); - goto done; + ret =3D -EFAULT; + goto err_reg_netdev; } =20 - sema_init(&priv->async_sem, 1); - dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); =20 #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_init(priv); #endif =20 -done: - if (IS_ERR(wdev)) { - kfree(priv->wdev); - priv->wdev =3D NULL; - } - return wdev; + +err_reg_netdev: + free_netdev(dev); + priv->netdev =3D NULL; +err_set_bss_mode: +err_alloc_netdev: + kfree(priv->wdev); + priv->wdev =3D NULL; + priv->bss_mode =3D NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); =20 diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifi= ex/fw.h index 3175dd04834b..f58c6f1fba0c 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -203,11 +203,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { =20 #define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR =20 -#define GET_RXSTBC(x) (x & IEEE80211_HT_CAP_RX_STBC) -#define MWIFIEX_RX_STBC1 0x0100 -#define MWIFIEX_RX_STBC12 0x0200 -#define MWIFIEX_RX_STBC123 0x0300 - /* dev_cap bitmap * BIT * 0-16 reserved diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/= mwifiex/uap_cmd.c index 32643555dd2a..a6a6a53cda40 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -159,7 +159,6 @@ mwifiex_set_ht_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { const u8 *ht_ie; - u16 cap_info; =20 if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info)) return; @@ -169,27 +168,6 @@ mwifiex_set_ht_params(struct mwifiex_private *priv, if (ht_ie) { memcpy(&bss_cfg->ht_cap, ht_ie + 2, sizeof(struct ieee80211_ht_cap)); - cap_info =3D le16_to_cpu(bss_cfg->ht_cap.cap_info); - memset(&bss_cfg->ht_cap.mcs, 0, - priv->adapter->number_of_antenna); - switch (GET_RXSTBC(cap_info)) { - case MWIFIEX_RX_STBC1: - /* HT_CAP 1X1 mode */ - bss_cfg->ht_cap.mcs.rx_mask[0] =3D 0xff; - break; - case MWIFIEX_RX_STBC12: /* fall through */ - case MWIFIEX_RX_STBC123: - /* HT_CAP 2X2 mode */ - bss_cfg->ht_cap.mcs.rx_mask[0] =3D 0xff; - bss_cfg->ht_cap.mcs.rx_mask[1] =3D 0xff; - break; - default: - dev_warn(priv->adapter->dev, - "Unsupported RX-STBC, default to 2x2\n"); - bss_cfg->ht_cap.mcs.rx_mask[0] =3D 0xff; - bss_cfg->ht_cap.mcs.rx_mask[1] =3D 0xff; - break; - } priv->ap_11n_enabled =3D 1; } else { memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti= /wlcore/spi.c index a460fe669443..a57ee3893c5d 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -30,6 +30,7 @@ #include #include #include +#include =20 #include "wlcore.h" #include "wl12xx_80211.h" @@ -71,7 +72,7 @@ * only support SPI for 12xx - this code should be reworked when 18xx * support is introduced */ -#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) +#define SPI_AGGR_BUFFER_SIZE (4 * SZ_4K) =20 /* Maximum number of SPI write chunks */ #define WSPI_MAX_NUM_OF_CHUNKS \ diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 8b490d77054f..0f2b2123d523 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -743,6 +743,8 @@ ccio_map_single(struct device *dev, void *addr, size_t = size, =20 BUG_ON(!dev); ioc =3D GET_IOC(dev); + if (!ioc) + return DMA_ERROR_CODE; =20 BUG_ON(size <=3D 0); =20 @@ -807,6 +809,10 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova,= size_t size, =09 BUG_ON(!dev); ioc =3D GET_IOC(dev); + if (!ioc) { + WARN_ON(!ioc); + return; + } =20 DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long)iova, size); @@ -910,6 +916,8 @@ ccio_map_sg(struct device *dev, struct scatterlist *sgl= ist, int nents, =09 BUG_ON(!dev); ioc =3D GET_IOC(dev); + if (!ioc) + return 0; =09 DBG_RUN_SG("%s() START %d entries\n", __func__, nents); =20 @@ -982,6 +990,10 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *= sglist, int nents, =20 BUG_ON(!dev); ioc =3D GET_IOC(dev); + if (!ioc) { + WARN_ON(!ioc); + return; + } =20 DBG_RUN_SG("%s() START %d entries, %08lx,%x\n", __func__, nents, sg_virt_addr(sglist), sglist->length); diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 9eae9834bcc7..cf77ab14b681 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -154,7 +154,10 @@ struct dino_device }; =20 /* Looks nice and keeps the compiler happy */ -#define DINO_DEV(d) ((struct dino_device *) d) +#define DINO_DEV(d) ({ \ + void *__pdata =3D d; \ + BUG_ON(!__pdata); \ + (struct dino_device *)__pdata; }) =20 =20 /* diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 37e71ff6408d..4590515a275c 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -111,8 +111,10 @@ static u32 lba_t32; =20 =20 /* Looks nice and keeps the compiler happy */ -#define LBA_DEV(d) ((struct lba_device *) (d)) - +#define LBA_DEV(d) ({ \ + void *__pdata =3D d; \ + BUG_ON(!__pdata); \ + (struct lba_device *)__pdata; }) =20 /* ** Only allow 8 subsidiary busses per LBA diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 1ff1b67e8b27..ad21a240f644 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -691,6 +691,8 @@ static int sba_dma_supported( struct device *dev, u64 m= ask) return 0; =20 ioc =3D GET_IOC(dev); + if (!ioc) + return 0; =20 /* * check if mask is >=3D than the current max IO Virt Address @@ -722,6 +724,8 @@ sba_map_single(struct device *dev, void *addr, size_t s= ize, int pide; =20 ioc =3D GET_IOC(dev); + if (!ioc) + return DMA_ERROR_CODE; =20 /* save offset bits */ offset =3D ((dma_addr_t) (long) addr) & ~IOVP_MASK; @@ -803,6 +807,10 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, = size_t size, DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size); =20 ioc =3D GET_IOC(dev); + if (!ioc) { + WARN_ON(!ioc); + return; + } offset =3D iova & ~IOVP_MASK; iova ^=3D offset; /* clear offset bits */ size +=3D offset; @@ -942,6 +950,8 @@ sba_map_sg(struct device *dev, struct scatterlist *sgli= st, int nents, DBG_RUN_SG("%s() START %d entries\n", __func__, nents); =20 ioc =3D GET_IOC(dev); + if (!ioc) + return 0; =20 /* Fast path single entry scatterlists. */ if (nents =3D=3D 1) { @@ -1028,6 +1038,10 @@ sba_unmap_sg(struct device *dev, struct scatterlist = *sglist, int nents, __func__, nents, sg_virt_addr(sglist), sglist->length); =20 ioc =3D GET_IOC(dev); + if (!ioc) { + WARN_ON(!ioc); + return; + } =20 #ifdef SBA_COLLECT_STATS ioc->usg_calls++; diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e2bab48f6446..51cdff7c2c01 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -922,6 +922,7 @@ static int pci_pm_thaw_noirq(struct device *dev) return pci_legacy_resume_early(dev); =20 pci_update_current_state(pci_dev, PCI_D0); + pci_restore_state(pci_dev); =20 if (drv && drv->pm && drv->pm->thaw_noirq) error =3D drv->pm->thaw_noirq(dev); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 7505fa72ea5d..0ca2961a56a2 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1367,10 +1367,10 @@ int __must_check pci_create_sysfs_dev_files(struct = pci_dev *pdev) if (!sysfs_initialized) return -EACCES; =20 - if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) - retval =3D sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); - else + if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) retval =3D sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); + else + retval =3D sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); if (retval) goto err; =20 @@ -1422,10 +1422,10 @@ int __must_check pci_create_sysfs_dev_files(struct = pci_dev *pdev) err_resource_files: pci_remove_resource_files(pdev); err_config_file: - if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) - sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); - else + if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); + else + sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); err: return retval; } @@ -1459,10 +1459,10 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pde= v) =20 pci_remove_capabilities_sysfs(pdev); =20 - if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) - sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); - else + if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); + else + sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); =20 pci_remove_resource_files(pdev); =20 diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 914c1cbe4d3e..bc4147bfe0ad 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -288,12 +288,24 @@ static void quirk_citrine(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, qui= rk_citrine); =20 +/* + * This chip can cause bus lockups if config addresses above 0x600 + * are read or written. + */ +static void quirk_nfp6000(struct pci_dev *dev) +{ + dev->cfg_size =3D 0x600; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_= NFP4000, quirk_nfp6000); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_= NFP6000, quirk_nfp6000); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_= NFP6000_VF, quirk_nfp6000); + /* On IBM Crocodile ipr SAS adapters, expand BAR to system page size */ static void quirk_extend_bar_to_page(struct pci_dev *dev) { int i; =20 - for (i =3D 0; i < PCI_STD_RESOURCE_END; i++) { + for (i =3D 0; i <=3D PCI_STD_RESOURCE_END; i++) { struct resource *r =3D &dev->resource[i]; =20 if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) { diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 6cd65e6987e4..1c489e179149 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -216,11 +216,13 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev= , unsigned selector, reg &=3D ~(0x7 << 20); reg |=3D (pin->mux_mode << 20); writel(reg, ipctl->base + pin_reg->mux_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", + pin_reg->mux_reg, reg); } else { writel(pin->mux_mode, ipctl->base + pin_reg->mux_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", + pin_reg->mux_reg, pin->mux_mode); } - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", - pin_reg->mux_reg, pin->mux_mode); =20 /* * If the select input value begins with 0xff, it's a quirky @@ -347,11 +349,13 @@ static int imx_pinconf_set(struct pinctrl_dev *pctlde= v, reg &=3D ~0xffff; reg |=3D configs[i]; writel(reg, ipctl->base + pin_reg->conf_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", + pin_reg->conf_reg, reg); } else { writel(configs[i], ipctl->base + pin_reg->conf_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", + pin_reg->conf_reg, configs[i]); } - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", - pin_reg->conf_reg, configs[i]); } /* for each config */ =20 return 0; diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index a53da0958e95..2c87abef1baa 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -93,7 +93,7 @@ static int *check_rtc_access_enable(struct nuc900_rtc *nu= c900_rtc) __raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER); =20 while (!(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB) - && timeout--) + && --timeout) mdelay(1); =20 if (!timeout) diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_is= csi.c index 166543f7ef55..0bf408ac5b7a 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -1906,7 +1906,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct= Scsi_Host *shost, =20 bnx2i_ep_active_list_add(hba, bnx2i_ep); =20 - if (bnx2i_map_ep_dbell_regs(bnx2i_ep)) + rc =3D bnx2i_map_ep_dbell_regs(bnx2i_ep); + if (rc) goto del_active_ep; =20 mutex_unlock(&hba->net_dev_lock); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 81d4151179d8..c31e1cb009af 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -387,11 +387,12 @@ static void scsi_target_reap_ref_release(struct kref = *kref) =3D container_of(kref, struct scsi_target, reap_ref); =20 /* - * if we get here and the target is still in the CREATED state that + * if we get here and the target is still in a CREATED state that * means it was allocated but never made visible (because a scan * turned up no LUNs), so don't call device_del() on it. */ - if (starget->state !=3D STARGET_CREATED) { + if ((starget->state !=3D STARGET_CREATED) && + (starget->state !=3D STARGET_CREATED_REMOVE)) { transport_remove_device(&starget->dev); device_del(&starget->dev); } diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ae280e7d3831..5c35a9578dd7 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1151,11 +1151,15 @@ void scsi_remove_target(struct device *dev) spin_lock_irqsave(shost->host_lock, flags); list_for_each_entry(starget, &shost->__targets, siblings) { if (starget->state =3D=3D STARGET_DEL || - starget->state =3D=3D STARGET_REMOVE) + starget->state =3D=3D STARGET_REMOVE || + starget->state =3D=3D STARGET_CREATED_REMOVE) continue; if (starget->dev.parent =3D=3D dev || &starget->dev =3D=3D dev) { kref_get(&starget->reap_ref); - starget->state =3D STARGET_REMOVE; + if (starget->state =3D=3D STARGET_CREATED) + starget->state =3D STARGET_CREATED_REMOVE; + else + starget->state =3D STARGET_REMOVE; spin_unlock_irqrestore(shost->host_lock, flags); __scsi_remove_target(starget); scsi_target_reap(starget); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transp= ort_iscsi.c index 0102a2d70dd8..858085beb902 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -3689,7 +3689,7 @@ iscsi_if_rx(struct sk_buff *skb) uint32_t group; =20 nlh =3D nlmsg_hdr(skb); - if (nlh->nlmsg_len < sizeof(*nlh) || + if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) || skb->len < nlh->nlmsg_len) { break; } diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index f2e68459f7ea..6585d75bf732 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -566,6 +566,7 @@ static int esp_sbus_probe(struct platform_device *op) struct device_node *dp =3D op->dev.of_node; struct platform_device *dma_of =3D NULL; int hme =3D 0; + int ret; =20 if (dp->parent && (!strcmp(dp->parent->name, "espdma") || @@ -580,7 +581,11 @@ static int esp_sbus_probe(struct platform_device *op) if (!dma_of) return -ENODEV; =20 - return esp_sbus_probe_one(op, dma_of, hme); + ret =3D esp_sbus_probe_one(op, dma_of, hme); + if (ret) + put_device(&dma_of->dev); + + return ret; } =20 static int esp_sbus_remove(struct platform_device *op) @@ -613,6 +618,8 @@ static int esp_sbus_remove(struct platform_device *op) =20 dev_set_drvdata(&op->dev, NULL); =20 + put_device(&dma_of->dev); + return 0; } =20 diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 308256b5e4cb..42ecf4c18e2e 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -686,6 +686,16 @@ static void virtscsi_target_destroy(struct scsi_target= *starget) kfree(tgt); } =20 +/* + * The host guarantees to respond to each command, although I/O + * latencies might be higher than on bare metal. Reset the timer + * unconditionally to give the host a chance to perform EH. + */ +static enum blk_eh_timer_return virtscsi_eh_timed_out(struct scsi_cmnd *sc= mnd) +{ + return BLK_EH_RESET_TIMER; +} + static struct scsi_host_template virtscsi_host_template_single =3D { .module =3D THIS_MODULE, .name =3D "Virtio SCSI HBA", @@ -695,6 +705,7 @@ static struct scsi_host_template virtscsi_host_template= _single =3D { .queuecommand =3D virtscsi_queuecommand_single, .eh_abort_handler =3D virtscsi_abort, .eh_device_reset_handler =3D virtscsi_device_reset, + .eh_timed_out =3D virtscsi_eh_timed_out, =20 .can_queue =3D 1024, .dma_boundary =3D UINT_MAX, @@ -712,6 +723,7 @@ static struct scsi_host_template virtscsi_host_template= _multi =3D { .queuecommand =3D virtscsi_queuecommand_multi, .eh_abort_handler =3D virtscsi_abort, .eh_device_reset_handler =3D virtscsi_device_reset, + .eh_timed_out =3D virtscsi_eh_timed_out, =20 .can_queue =3D 1024, .dma_boundary =3D UINT_MAX, diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index bbf7c5e79b95..7bfd64f7d76b 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -206,6 +206,7 @@ struct atmel_spi_caps { bool is_spi2; bool has_wdrbt; bool has_dma_support; + bool has_pdc_support; }; =20 /* @@ -1278,7 +1279,28 @@ static void atmel_get_caps(struct atmel_spi *as) =20 as->caps.is_spi2 =3D version > 0x121; as->caps.has_wdrbt =3D version >=3D 0x210; +#ifdef CONFIG_SOC_SAM_V4_V5 + /* + * Atmel SoCs based on ARM9 (SAM9x) cores should not use spi_map_buf() + * since this later function tries to map buffers with dma_map_sg() + * even if they have not been allocated inside DMA-safe areas. + * On SoCs based on Cortex A5 (SAMA5Dx), it works anyway because for + * those ARM cores, the data cache follows the PIPT model. + * Also the L2 cache controller of SAMA5D2 uses the PIPT model too. + * In case of PIPT caches, there cannot be cache aliases. + * However on ARM9 cores, the data cache follows the VIVT model, hence + * the cache aliases issue can occur when buffers are allocated from + * DMA-unsafe areas, by vmalloc() for instance, where cache coherency is + * not taken into account or at least not handled completely (cache + * lines of aliases are not invalidated). + * This is not a theorical issue: it was reproduced when trying to mount + * a UBI file-system on a at91sam9g35ek board. + */ + as->caps.has_dma_support =3D false; +#else as->caps.has_dma_support =3D version >=3D 0x212; +#endif + as->caps.has_pdc_support =3D version < 0x212; } =20 /*------------------------------------------------------------------------= -*/ @@ -1356,7 +1378,7 @@ static int atmel_spi_probe(struct platform_device *pd= ev) if (as->caps.has_dma_support) { if (atmel_spi_configure_dma(as) =3D=3D 0) as->use_dma =3D true; - } else { + } else if (as->caps.has_pdc_support) { as->use_pdc =3D true; } =20 diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/= comedi_fops.c index 47a9a5cf3447..f3fb3d95dfd0 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2626,6 +2626,7 @@ static int __init comedi_init(void) dev =3D comedi_alloc_board_minor(NULL); if (IS_ERR(dev)) { comedi_cleanup_board_minors(); + class_destroy(comedi_class); cdev_del(&comedi_cdev); unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub= _main.c index 9c5832abbdf1..7c08d6e47221 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -266,7 +266,11 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) kmem_cache_free(stub_priv_cache, priv); =20 kfree(urb->transfer_buffer); + urb->transfer_buffer =3D NULL; + kfree(urb->setup_packet); + urb->setup_packet =3D NULL; + usb_free_urb(urb); } } diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_t= x.c index dbcabc9dbe0d..021003c4de53 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -28,7 +28,11 @@ static void stub_free_priv_and_urb(struct stub_priv *pri= v) struct urb *urb =3D priv->urb; =20 kfree(urb->setup_packet); + urb->setup_packet =3D NULL; + kfree(urb->transfer_buffer); + urb->transfer_buffer =3D NULL; + list_del(&priv->list); kmem_cache_free(stub_priv_cache, priv); usb_free_urb(urb); diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/= iscsi/iscsi_target_configfs.c index e7785e29a858..425e4c7969e9 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1057,6 +1057,8 @@ TPG_ATTR(default_erl, S_IRUGO | S_IWUSR); */ DEF_TPG_ATTRIB(t10_pi); TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR); +DEF_TPG_ATTRIB(login_keys_workaround); +TPG_ATTR(login_keys_workaround, S_IRUGO | S_IWUSR); =20 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] =3D { &iscsi_tpg_attrib_authentication.attr, @@ -1070,6 +1072,7 @@ static struct configfs_attribute *lio_target_tpg_attr= ib_attrs[] =3D { &iscsi_tpg_attrib_demo_mode_discovery.attr, &iscsi_tpg_attrib_default_erl.attr, &iscsi_tpg_attrib_t10_pi.attr, + &iscsi_tpg_attrib_login_keys_workaround.attr, NULL, }; =20 diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscs= i/iscsi_target_core.h index 1863de28ce46..f8e14dda29f6 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -60,6 +60,14 @@ #define TA_CACHE_CORE_NPS 0 /* T10 protection information disabled by default */ #define TA_DEFAULT_T10_PI 0 +/* + * Used to control the sending of keys with optional to respond state bit, + * as a workaround for non RFC compliant initiators,that do not propose, + * nor respond to specific keys required for login to complete. + * + * See iscsi_check_proposer_for_optional_reply() for more details. + */ +#define TA_DEFAULT_LOGIN_KEYS_WORKAROUND 1 =20 #define ISCSI_IOV_DATA_BUFFER 5 =20 @@ -774,6 +782,7 @@ struct iscsi_tpg_attrib { u32 demo_mode_discovery; u32 default_erl; u8 t10_pi; + u32 login_keys_workaround; struct iscsi_portal_group *tpg; }; =20 diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscs= i/iscsi_target_nego.c index c15cfcb3fcc9..d2d4b5010447 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -887,7 +887,8 @@ static int iscsi_target_handle_csg_zero( SENDER_TARGET, login->rsp_buf, &login->rsp_length, - conn->param_list); + conn->param_list, + conn->tpg->tpg_attrib.login_keys_workaround); if (ret < 0) return -1; =20 @@ -957,7 +958,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_con= n *conn, struct iscsi_log SENDER_TARGET, login->rsp_buf, &login->rsp_length, - conn->param_list); + conn->param_list, + conn->tpg->tpg_attrib.login_keys_workaround); if (ret < 0) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, ISCSI_LOGIN_STATUS_INIT_ERR); diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/targe= t/iscsi/iscsi_target_parameters.c index 578f5d03d84e..070dc042d250 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -787,7 +787,8 @@ static int iscsi_check_for_auth_key(char *key) return 0; } =20 -static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *pa= ram) +static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *pa= ram, + bool keys_workaround) { if (IS_TYPE_BOOL_AND(param)) { if (!strcmp(param->value, NO)) @@ -795,19 +796,31 @@ static void iscsi_check_proposer_for_optional_reply(s= truct iscsi_param *param) } else if (IS_TYPE_BOOL_OR(param)) { if (!strcmp(param->value, YES)) SET_PSTATE_REPLY_OPTIONAL(param); - /* - * Required for gPXE iSCSI boot client - */ - if (!strcmp(param->name, IMMEDIATEDATA)) - SET_PSTATE_REPLY_OPTIONAL(param); + + if (keys_workaround) { + /* + * Required for gPXE iSCSI boot client + */ + if (!strcmp(param->name, IMMEDIATEDATA)) + SET_PSTATE_REPLY_OPTIONAL(param); + } } else if (IS_TYPE_NUMBER(param)) { if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) SET_PSTATE_REPLY_OPTIONAL(param); - /* - * Required for gPXE iSCSI boot client - */ - if (!strcmp(param->name, MAXCONNECTIONS)) - SET_PSTATE_REPLY_OPTIONAL(param); + + if (keys_workaround) { + /* + * Required for Mellanox Flexboot PXE boot ROM + */ + if (!strcmp(param->name, FIRSTBURSTLENGTH)) + SET_PSTATE_REPLY_OPTIONAL(param); + + /* + * Required for gPXE iSCSI boot client + */ + if (!strcmp(param->name, MAXCONNECTIONS)) + SET_PSTATE_REPLY_OPTIONAL(param); + } } else if (IS_PHASE_DECLARATIVE(param)) SET_PSTATE_REPLY_OPTIONAL(param); } @@ -1657,7 +1670,8 @@ int iscsi_encode_text_output( u8 sender, char *textbuf, u32 *length, - struct iscsi_param_list *param_list) + struct iscsi_param_list *param_list, + bool keys_workaround) { char *output_buf =3D NULL; struct iscsi_extra_response *er; @@ -1693,7 +1707,8 @@ int iscsi_encode_text_output( *length +=3D 1; output_buf =3D textbuf + *length; SET_PSTATE_PROPOSER(param); - iscsi_check_proposer_for_optional_reply(param); + iscsi_check_proposer_for_optional_reply(param, + keys_workaround); pr_debug("Sending key: %s=3D%s\n", param->name, param->value); } diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/targe= t/iscsi/iscsi_target_parameters.h index a47046a752aa..f430a0eba0f8 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h @@ -40,7 +40,7 @@ extern int iscsi_extract_key_value(char *, char **, char = **); extern int iscsi_update_param_value(struct iscsi_param *, char *); extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn = *); extern int iscsi_encode_text_output(u8, u8, char *, u32 *, - struct iscsi_param_list *); + struct iscsi_param_list *, bool); extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *, struct iscsi_param_list *); diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi= /iscsi_target_tpg.c index 48cd3cf741df..79ca361078b8 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -228,6 +228,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi= _portal_group *tpg) a->demo_mode_discovery =3D TA_DEMO_MODE_DISCOVERY; a->default_erl =3D TA_DEFAULT_ERL; a->t10_pi =3D TA_DEFAULT_T10_PI; + a->login_keys_workaround =3D TA_DEFAULT_LOGIN_KEYS_WORKAROUND; } =20 int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_port= al_group *tpg) @@ -878,3 +879,21 @@ int iscsit_ta_t10_pi( =20 return 0; } + +int iscsit_ta_login_keys_workaround( + struct iscsi_portal_group *tpg, + u32 flag) +{ + struct iscsi_tpg_attrib *a =3D &tpg->tpg_attrib; + + if ((flag !=3D 0) && (flag !=3D 1)) { + pr_err("Illegal value %d\n", flag); + return -EINVAL; + } + + a->login_keys_workaround =3D flag; + pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s = ", + tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF"); + + return 0; +} diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi= /iscsi_target_tpg.h index e7265337bc43..49b869fab102 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.h +++ b/drivers/target/iscsi/iscsi_target_tpg.h @@ -39,5 +39,6 @@ extern int iscsit_ta_prod_mode_write_protect(struct iscsi= _portal_group *, u32); extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32); extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); +extern int iscsit_ta_login_keys_workaround(struct iscsi_portal_group *, u3= 2); =20 #endif /* ISCSI_TARGET_TPG_H */ diff --git a/drivers/target/target_core_transport.c b/drivers/target/target= _core_transport.c index 6c3b00ca4d20..da00938c6dfa 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -689,6 +689,15 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_s= tatus) if (cmd->transport_state & CMD_T_ABORTED || cmd->transport_state & CMD_T_STOP) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); + /* + * If COMPARE_AND_WRITE was stopped by __transport_wait_for_tasks(), + * release se_device->caw_sem obtained by sbc_compare_and_write() + * since target_complete_ok_work() or target_complete_failure_work() + * won't be called to invoke the normal CAW completion callbacks. + */ + if (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) { + up(&dev->caw_sem); + } complete_all(&cmd->t_transport_stop_comp); return; } else if (!success) { diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 91f29f2975c1..5d1bfbe14f27 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -757,6 +757,8 @@ static void s3c24xx_serial_set_termios(struct uart_port= *port, /* check to see if we need to change clock source */ =20 if (ourport->baudclk !=3D clk) { + clk_prepare_enable(clk); + s3c24xx_serial_setsource(port, clk_sel); =20 if (!IS_ERR(ourport->baudclk)) { @@ -764,8 +766,6 @@ static void s3c24xx_serial_set_termios(struct uart_port= *port, ourport->baudclk =3D ERR_PTR(-EINVAL); } =20 - clk_prepare_enable(clk); - ourport->baudclk =3D clk; ourport->baudclk_rate =3D clk ? clk_get_rate(clk) : 0; } diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index e84b6a3bdd18..89677b9f82b9 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -890,14 +890,19 @@ static int sccnxp_probe(struct platform_device *pdev) =20 clk =3D devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { - if (PTR_ERR(clk) =3D=3D -EPROBE_DEFER) { - ret =3D -EPROBE_DEFER; + ret =3D PTR_ERR(clk); + if (ret =3D=3D -EPROBE_DEFER) goto err_out; - } + uartclk =3D 0; + } else { + clk_prepare_enable(clk); + uartclk =3D clk_get_rate(clk); + } + + if (!uartclk) { dev_notice(&pdev->dev, "Using default clock frequency\n"); uartclk =3D s->chip->freq_std; - } else - uartclk =3D clk_get_rate(clk); + } =20 /* Check input frequency */ if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) { diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index a57f3761ab47..322c4818dd0c 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2687,13 +2687,13 @@ int tioclinux(struct tty_struct *tty, unsigned long= arg) * related to the kernel should not use this. */ data =3D vt_get_shift_state(); - ret =3D __put_user(data, p); + ret =3D put_user(data, p); break; case TIOCL_GETMOUSEREPORTING: console_lock(); /* May be overkill */ data =3D mouse_reporting(); console_unlock(); - ret =3D __put_user(data, p); + ret =3D put_user(data, p); break; case TIOCL_SETVESABLANK: console_lock(); @@ -2702,7 +2702,7 @@ int tioclinux(struct tty_struct *tty, unsigned long a= rg) break; case TIOCL_GETKMSGREDIRECT: data =3D vt_get_kmsg_redirect(); - ret =3D __put_user(data, p); + ret =3D put_user(data, p); break; case TIOCL_SETKMSGREDIRECT: if (!capable(CAP_SYS_ADMIN)) { diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 3a5a4f49e894..59106b01dc20 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -220,6 +220,10 @@ static const struct usb_device_id usb_quirk_list[] =3D= { /* Blackmagic Design UltraStudio SDI */ { USB_DEVICE(0x1edb, 0xbd4f), .driver_info =3D USB_QUIRK_NO_LPM }, =20 + /* Hauppauge HVR-950q */ + { USB_DEVICE(0x2040, 0x7200), .driver_info =3D + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info =3D USB_QUIRK_RESET_RESUME }, =20 diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 56188f231de0..48562be0f07f 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1209,6 +1209,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t2 |=3D PORT_WKOC_E | PORT_WKCONN_E; t2 &=3D ~PORT_WKDISC_E; } + if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && + (hcd->speed < HCD_USB3)) + t2 &=3D ~PORT_WAKE_BITS; } else t2 &=3D ~PORT_WAKE_BITS; =20 diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 6e48fd8d673e..60edc9668935 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -47,6 +47,11 @@ #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 =20 +#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 +#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba +#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb +#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc + static const char hcd_name[] =3D "xhci_hcd"; =20 /* called after powerup, by probe or system-pm "wakeup" */ @@ -120,6 +125,13 @@ static void xhci_pci_quirks(struct device *dev, struct= xhci_hcd *xhci) if (pdev->vendor =3D=3D PCI_VENDOR_ID_AMD) xhci->quirks |=3D XHCI_TRUST_TX_LENGTH; =20 + if ((pdev->vendor =3D=3D PCI_VENDOR_ID_AMD) && + ((pdev->device =3D=3D PCI_DEVICE_ID_AMD_PROMONTORYA_4) || + (pdev->device =3D=3D PCI_DEVICE_ID_AMD_PROMONTORYA_3) || + (pdev->device =3D=3D PCI_DEVICE_ID_AMD_PROMONTORYA_2) || + (pdev->device =3D=3D PCI_DEVICE_ID_AMD_PROMONTORYA_1))) + xhci->quirks |=3D XHCI_U2_DISABLE_WAKE; + if (pdev->vendor =3D=3D PCI_VENDOR_ID_INTEL) { xhci->quirks |=3D XHCI_LPM_SUPPORT; xhci->quirks |=3D XHCI_INTEL_HOST; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f117bacec41c..92e852cc3944 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1569,6 +1569,7 @@ struct xhci_hcd { #define XHCI_BROKEN_STREAMS (1 << 19) #define XHCI_PME_STUCK_QUIRK (1 << 20) #define XHCI_MISSING_CAS (1 << 24) +#define XHCI_U2_DISABLE_WAKE (1 << 27) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 36f029b0d357..d8315638e825 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -9,9 +9,9 @@ =20 #define RNDIS_REG(x) (0x80 + ((x - 1) * 4)) =20 -#define EP_MODE_AUTOREG_NONE 0 -#define EP_MODE_AUTOREG_ALL_NEOP 1 -#define EP_MODE_AUTOREG_ALWAYS 3 +#define EP_MODE_AUTOREQ_NONE 0 +#define EP_MODE_AUTOREQ_ALL_NEOP 1 +#define EP_MODE_AUTOREQ_ALWAYS 3 =20 #define EP_MODE_DMA_TRANSPARENT 0 #define EP_MODE_DMA_RNDIS 1 @@ -426,19 +426,19 @@ static bool cppi41_configure_channel(struct dma_chann= el *channel, =20 /* auto req */ cppi41_set_autoreq_mode(cppi41_channel, - EP_MODE_AUTOREG_ALL_NEOP); + EP_MODE_AUTOREQ_ALL_NEOP); } else { musb_writel(musb->ctrl_base, RNDIS_REG(cppi41_channel->port_num), 0); cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); cppi41_set_autoreq_mode(cppi41_channel, - EP_MODE_AUTOREG_NONE); + EP_MODE_AUTOREQ_NONE); } } else { /* fallback mode */ cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); - cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREG_NONE); + cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); len =3D min_t(u32, packet_sz, len); } cppi41_channel->prog_len =3D len; @@ -570,10 +570,15 @@ static int cppi41_dma_channel_abort(struct dma_channe= l *channel) csr &=3D ~MUSB_TXCSR_DMAENAB; musb_writew(epio, MUSB_TXCSR, csr); } else { + cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); + csr =3D musb_readw(epio, MUSB_RXCSR); csr &=3D ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB); musb_writew(epio, MUSB_RXCSR, csr); =20 + /* wait to drain cppi dma pipe line */ + udelay(50); + csr =3D musb_readw(epio, MUSB_RXCSR); if (csr & MUSB_RXCSR_RXPKTRDY) { csr |=3D MUSB_RXCSR_FLUSHFIFO; @@ -587,13 +592,14 @@ static int cppi41_dma_channel_abort(struct dma_channe= l *channel) tdbit <<=3D 16; =20 do { - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + if (is_tx) + musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); ret =3D dmaengine_terminate_all(cppi41_channel->dc); } while (ret =3D=3D -EAGAIN); =20 - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); - if (is_tx) { + musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + csr =3D musb_readw(epio, MUSB_TXCSR); if (csr & MUSB_TXCSR_TXPKTRDY) { csr |=3D MUSB_TXCSR_FLUSHFIFO; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 6b72aacdd779..0786281108f6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -134,6 +134,7 @@ static const struct usb_device_id id_table[] =3D { { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ + { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range= */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 58b13a537a7d..475104bb3395 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1888,6 +1888,10 @@ static const struct usb_device_id option_ids[] =3D { .driver_info =3D (kernel_ulong_t)&four_g_w100_blacklist }, { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800,= 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff), + .driver_info =3D (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), + .driver_info =3D (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 4f91868736a5..23c303b2a3a2 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -156,6 +156,7 @@ static const struct usb_device_id id_table[] =3D { {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ + {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */ {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */ {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */ {DEVICE_SWI(0x1199, 0x9078)}, /* Sierra Wireless EM74xx */ diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index f018d8d0f975..7b2f32726c1a 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -278,6 +278,34 @@ static void vfio_group_put(struct vfio_group *group) kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock); } =20 +struct vfio_group_put_work { + struct work_struct work; + struct vfio_group *group; +}; + +static void vfio_group_put_bg(struct work_struct *work) +{ + struct vfio_group_put_work *do_work; + + do_work =3D container_of(work, struct vfio_group_put_work, work); + + vfio_group_put(do_work->group); + kfree(do_work); +} + +static void vfio_group_schedule_put(struct vfio_group *group) +{ + struct vfio_group_put_work *do_work; + + do_work =3D kmalloc(sizeof(*do_work), GFP_KERNEL); + if (WARN_ON(!do_work)) + return; + + INIT_WORK(&do_work->work, vfio_group_put_bg); + do_work->group =3D group; + schedule_work(&do_work->work); +} + /* Assume group_lock or group reference is held */ static void vfio_group_get(struct vfio_group *group) { @@ -553,7 +581,14 @@ static int vfio_iommu_group_notifier(struct notifier_b= lock *nb, break; } =20 - vfio_group_put(group); + /* + * If we're the last reference to the group, the group will be + * released, which includes unregistering the iommu group notifier. + * We hold a read-lock on that notifier list, unregistering needs + * a write-lock... deadlock. Release our reference asynchronously + * to avoid that situation. + */ + vfio_group_schedule_put(group); return NOTIFY_OK; } =20 @@ -1401,6 +1436,15 @@ void vfio_group_put_external_user(struct vfio_group = *group) } EXPORT_SYMBOL_GPL(vfio_group_put_external_user); =20 +bool vfio_external_group_match_file(struct vfio_group *test_group, + struct file *filep) +{ + struct vfio_group *group =3D filep->private_data; + + return (filep->f_op =3D=3D &vfio_group_fops) && (group =3D=3D test_group); +} +EXPORT_SYMBOL_GPL(vfio_external_group_match_file); + int vfio_external_user_iommu_id(struct vfio_group *group) { return iommu_group_id(group->iommu_group); diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty= /atyfb_base.c index c3d0074a32db..fba5736acfd6 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -1852,7 +1852,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cm= d, u_long arg) #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) case ATYIO_CLKR: if (M64_HAS(INTEGRATED)) { - struct atyclk clk; + struct atyclk clk =3D { 0 }; union aty_pll *pll =3D &par->pll; u32 dsp_config =3D pll->ct.dsp_config; u32 dsp_on_off =3D pll->ct.dsp_on_off; diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index fb3e64d37cb4..6b16b8653d98 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -82,12 +82,6 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *tr= ans, switch (type) { case ACL_TYPE_ACCESS: name =3D POSIX_ACL_XATTR_ACCESS; - if (acl) { - ret =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (ret) - return ret; - } - ret =3D 0; break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) @@ -123,7 +117,18 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *= trans, =20 int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { - return __btrfs_set_acl(NULL, inode, acl, type); + int ret; + umode_t old_mode =3D inode->i_mode; + + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + ret =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); + if (ret) + return ret; + } + ret =3D __btrfs_set_acl(NULL, inode, acl, type); + if (ret) + inode->i_mode =3D old_mode; + return ret; } =20 /* diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1f20c8e75e19..f55eee900557 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4230,7 +4230,7 @@ static int may_commit_transaction(struct btrfs_root *= root, =20 spin_lock(&delayed_rsv->lock); if (percpu_counter_compare(&space_info->total_bytes_pinned, - bytes - delayed_rsv->size) >=3D 0) { + bytes - delayed_rsv->size) < 0) { spin_unlock(&delayed_rsv->lock); return -ENOSPC; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 085a90d0d2e4..e1553eb5ef61 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2177,10 +2177,13 @@ static int fill_holes(struct btrfs_trans_handle *tr= ans, struct inode *inode, */ static int find_first_non_hole(struct inode *inode, u64 *start, u64 *len) { + struct btrfs_root *root =3D BTRFS_I(inode)->root; struct extent_map *em; int ret =3D 0; =20 - em =3D btrfs_get_extent(inode, NULL, 0, *start, *len, 0); + em =3D btrfs_get_extent(inode, NULL, 0, + round_down(*start, root->sectorsize), + round_up(*len, root->sectorsize), 0); if (IS_ERR_OR_NULL(em)) { if (!em) ret =3D -ENOMEM; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index cde876a98fb8..04972508c98b 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1681,7 +1681,7 @@ static noinline int btrfs_ioctl_snap_create_transid(s= truct file *file, =20 src_inode =3D file_inode(src.file); if (src_inode->i_sb !=3D file_inode(file)->i_sb) { - btrfs_info(BTRFS_I(src_inode)->root->fs_info, + btrfs_info(BTRFS_I(file_inode(file))->root->fs_info, "Snapshot src from another FS"); ret =3D -EXDEV; } else if (!inode_owner_or_capable(src_inode)) { diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 9409fa10bd5c..4893d86047a6 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -45,6 +45,9 @@ #define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_= flags */ #define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user= */ #define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a grou= p */ +#define CIFS_MOUNT_USE_PREFIX_PATH 0x1000000 /* make subpath with unaccess= ible + * root mountable + */ =20 struct cifs_sb_info { struct rb_root tlink_tree; @@ -66,5 +69,6 @@ struct cifs_sb_info { struct backing_dev_info bdi; struct delayed_work prune_tlinks; struct rcu_head rcu; + char *prepath; }; #endif /* _CIFS_FS_SB_H */ diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f16839ccf1eb..281358942b64 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -584,6 +584,9 @@ cifs_get_root(struct smb_vol *vol, struct super_block *= sb) char *s, *p; char sep; =20 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + return dget(sb->s_root); + full_path =3D cifs_build_path_to_root(vol, cifs_sb, cifs_sb_master_tcon(cifs_sb)); if (full_path =3D=3D NULL) @@ -663,10 +666,14 @@ cifs_do_mount(struct file_system_type *fs_type, cifs_sb->mountdata =3D kstrndup(data, PAGE_SIZE, GFP_KERNEL); if (cifs_sb->mountdata =3D=3D NULL) { root =3D ERR_PTR(-ENOMEM); - goto out_cifs_sb; + goto out_free; } =20 - cifs_setup_cifs_sb(volume_info, cifs_sb); + rc =3D cifs_setup_cifs_sb(volume_info, cifs_sb); + if (rc) { + root =3D ERR_PTR(rc); + goto out_free; + } =20 rc =3D cifs_mount(cifs_sb, volume_info); if (rc) { @@ -674,7 +681,7 @@ cifs_do_mount(struct file_system_type *fs_type, cifs_dbg(VFS, "cifs_mount failed w/return code =3D %d\n", rc); root =3D ERR_PTR(rc); - goto out_mountdata; + goto out_free; } =20 mnt_data.vol =3D volume_info; @@ -717,9 +724,9 @@ cifs_do_mount(struct file_system_type *fs_type, cifs_cleanup_volume_info(volume_info); return root; =20 -out_mountdata: +out_free: + kfree(cifs_sb->prepath); kfree(cifs_sb->mountdata); -out_cifs_sb: kfree(cifs_sb); out_nls: unload_nls(volume_info->local_nls); diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ea1cbff2932f..6e2d4581ceb2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -183,7 +183,7 @@ extern int cifs_read_from_socket(struct TCP_Server_Info= *server, char *buf, extern int cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, unsigned int nr_segs, unsigned int to_read); -extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, +extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, struct cifs_sb_info *cifs_sb); extern int cifs_match_super(struct super_block *, void *); extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 95a9573f49e9..2959522238c5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2751,6 +2751,22 @@ compare_mount_options(struct super_block *sb, struct= cifs_mnt_data *mnt_data) return 1; } =20 +static int +match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data) +{ + struct cifs_sb_info *old =3D CIFS_SB(sb); + struct cifs_sb_info *new =3D mnt_data->cifs_sb; + bool old_set =3D old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH; + bool new_set =3D new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH; + + if (old_set && new_set && !strcmp(new->prepath, old->prepath)) + return 1; + else if (!old_set && !new_set) + return 1; + + return 0; +} + int cifs_match_super(struct super_block *sb, void *data) { @@ -2778,7 +2794,8 @@ cifs_match_super(struct super_block *sb, void *data) =20 if (!match_server(tcp_srv, volume_info) || !match_session(ses, volume_info) || - !match_tcon(tcon, volume_info->UNC)) { + !match_tcon(tcon, volume_info->UNC) || + !match_prepath(sb, mnt_data)) { rc =3D 0; goto out; } @@ -3194,7 +3211,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct ci= fs_tcon *tcon, } } =20 -void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, +int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, struct cifs_sb_info *cifs_sb) { INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); @@ -3276,6 +3293,14 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, =20 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supp= orted\n"); + + if (pvolume_info->prepath) { + cifs_sb->prepath =3D kstrdup(pvolume_info->prepath, GFP_KERNEL); + if (cifs_sb->prepath =3D=3D NULL) + return -ENOMEM; + } + + return 0; } =20 static void @@ -3446,6 +3471,44 @@ cifs_get_volume_info(char *mount_data, const char *d= evname) return volume_info; } =20 +static int +cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, + unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + char *full_path) +{ + int rc; + char *s; + char sep, tmp; + + sep =3D CIFS_DIR_SEP(cifs_sb); + s =3D full_path; + + rc =3D server->ops->is_path_accessible(xid, tcon, cifs_sb, ""); + while (rc =3D=3D 0) { + /* skip separators */ + while (*s =3D=3D sep) + s++; + if (!*s) + break; + /* next separator */ + while (*s && *s !=3D sep) + s++; + + /* + * temporarily null-terminate the path at the end of + * the current component + */ + tmp =3D *s; + *s =3D 0; + rc =3D server->ops->is_path_accessible(xid, tcon, cifs_sb, + full_path); + *s =3D tmp; + } + return rc; +} + int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) { @@ -3572,6 +3635,18 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_= vol *volume_info) kfree(full_path); goto mount_fail_check; } + + if (rc !=3D -EREMOTE) { + rc =3D cifs_are_all_path_components_accessible(server, + xid, tcon, cifs_sb, + full_path); + if (rc !=3D 0) { + cifs_dbg(VFS, "cannot query dirs between root and final path, " + "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); + cifs_sb->mnt_cifs_flags |=3D CIFS_MOUNT_USE_PREFIX_PATH; + rc =3D 0; + } + } kfree(full_path); } =20 @@ -3835,6 +3910,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb) =20 bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb->mountdata); + kfree(cifs_sb->prepath); call_rcu(&cifs_sb->rcu, delayed_free); } =20 diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3f2dd87b899a..619e30f103d0 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -84,6 +84,7 @@ build_path_from_dentry(struct dentry *direntry) struct dentry *temp; int namelen; int dfsplen; + int pplen =3D 0; char *full_path; char dirsep; struct cifs_sb_info *cifs_sb =3D CIFS_SB(direntry->d_sb); @@ -95,8 +96,12 @@ build_path_from_dentry(struct dentry *direntry) dfsplen =3D strnlen(tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen =3D 0; + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + pplen =3D cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0; + cifs_bp_rename_retry: - namelen =3D dfsplen; + namelen =3D dfsplen + pplen; seq =3D read_seqbegin(&rename_lock); rcu_read_lock(); for (temp =3D direntry; !IS_ROOT(temp);) { @@ -137,7 +142,7 @@ build_path_from_dentry(struct dentry *direntry) } } rcu_read_unlock(); - if (namelen !=3D dfsplen || read_seqretry(&rename_lock, seq)) { + if (namelen !=3D dfsplen + pplen || read_seqretry(&rename_lock, seq)) { cifs_dbg(FYI, "did not end path lookup where expected. namelen=3D%ddfspl= en=3D%d\n", namelen, dfsplen); /* presumably this is only possible if racing with a rename @@ -153,6 +158,17 @@ build_path_from_dentry(struct dentry *direntry) those safely to '/' if any are found in the middle of the prepath */ /* BB test paths to Windows with '/' in the midst of prepath */ =20 + if (pplen) { + int i; + + cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath); + memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1); + full_path[dfsplen] =3D '\\'; + for (i =3D 0; i < pplen-1; i++) + if (full_path[dfsplen+1+i] =3D=3D '/') + full_path[dfsplen+1+i] =3D CIFS_DIR_SEP(cifs_sb); + } + if (dfsplen) { strncpy(full_path, tcon->treeName, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f82e4905752..0ae3f55290e9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2593,18 +2593,19 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *fr= om) ssize_t rc =3D -EACCES; loff_t lock_pos =3D iocb->ki_pos; =20 + mutex_lock(&inode->i_mutex); /* * We need to hold the sem to be sure nobody modifies lock list * with a brlock that prevents writing. */ down_read(&cinode->lock_sem); - mutex_lock(&inode->i_mutex); if (file->f_flags & O_APPEND) lock_pos =3D i_size_read(inode); if (!cifs_find_lock_conflict(cfile, lock_pos, iov_iter_count(from), server->vals->exclusive_lock_type, NULL, CIFS_WRITE_OP)) { rc =3D __generic_file_write_iter(iocb, from); + up_read(&cinode->lock_sem); mutex_unlock(&inode->i_mutex); =20 if (rc > 0) { @@ -2615,9 +2616,9 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) rc =3D err; } } else { + up_read(&cinode->lock_sem); mutex_unlock(&inode->i_mutex); } - up_read(&cinode->lock_sem); return rc; } =20 diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 6a5ca969c301..a9a5bee1890e 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -950,12 +950,29 @@ struct inode *cifs_root_iget(struct super_block *sb) struct inode *inode =3D NULL; long rc; struct cifs_tcon *tcon =3D cifs_sb_master_tcon(cifs_sb); + char *path =3D NULL; + int len; + + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + && cifs_sb->prepath) { + len =3D strlen(cifs_sb->prepath); + path =3D kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL); + if (path =3D=3D NULL) + return ERR_PTR(-ENOMEM); + path[0] =3D '/'; + memcpy(path+1, cifs_sb->prepath, len); + } else { + path =3D kstrdup("", GFP_KERNEL); + if (path =3D=3D NULL) + return ERR_PTR(-ENOMEM); + } =20 xid =3D get_xid(); + convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); if (tcon->unix_ext) - rc =3D cifs_get_inode_info_unix(&inode, "", sb, xid); + rc =3D cifs_get_inode_info_unix(&inode, path, sb, xid); else - rc =3D cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL); + rc =3D cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); =20 if (!inode) { inode =3D ERR_PTR(rc); @@ -983,6 +1000,7 @@ struct inode *cifs_root_iget(struct super_block *sb) } =20 out: + kfree(path); /* can not call macro free_xid here since in a void func * TODO: This is no longer true */ diff --git a/fs/dcache.c b/fs/dcache.c index c35d0ee1a7da..8a84b99ea8d4 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1066,11 +1066,12 @@ void shrink_dcache_sb(struct super_block *sb) LIST_HEAD(dispose); =20 freed =3D list_lru_walk(&sb->s_dentry_lru, - dentry_lru_isolate_shrink, &dispose, UINT_MAX); + dentry_lru_isolate_shrink, &dispose, 1024); =20 this_cpu_sub(nr_dentry_unused, freed); shrink_dentry_list(&dispose); - } while (freed > 0); + cond_resched(); + } while (list_lru_count(&sb->s_dentry_lru) > 0); } EXPORT_SYMBOL(shrink_dcache_sb); =20 diff --git a/fs/exec.c b/fs/exec.c index b5af6a256cf7..fa3604731bae 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1269,7 +1269,7 @@ static void check_unsafe_exec(struct linux_binprm *bp= rm) * This isn't strictly necessary, but it makes it harder for LSMs to * mess up. */ - if (current->no_new_privs) + if (task_no_new_privs(current)) bprm->unsafe |=3D LSM_UNSAFE_NO_NEW_PRIVS; =20 t =3D p; @@ -1303,7 +1303,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm) if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) return; =20 - if (current->no_new_privs) + if (task_no_new_privs(current)) return; =20 inode =3D file_inode(bprm->file); diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index d6aeb84e90b6..57f367e75838 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -178,11 +178,8 @@ ext2_get_acl(struct inode *inode, int type) return acl; } =20 -/* - * inode->i_mutex: down - */ -int -ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +static int +__ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int name_index; void *value =3D NULL; @@ -192,13 +189,6 @@ ext2_set_acl(struct inode *inode, struct posix_acl *ac= l, int type) switch(type) { case ACL_TYPE_ACCESS: name_index =3D EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - error =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - inode->i_ctime =3D CURRENT_TIME_SEC; - mark_inode_dirty(inode); - } break; =20 case ACL_TYPE_DEFAULT: @@ -224,6 +214,31 @@ ext2_set_acl(struct inode *inode, struct posix_acl *ac= l, int type) return error; } =20 +/* + * inode->i_mutex: down + */ +int +ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + int error; + int update_mode =3D 0; + umode_t mode =3D inode->i_mode; + + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + error =3D posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; + update_mode =3D 1; + } + error =3D __ext2_set_acl(inode, acl, type); + if (!error && update_mode) { + inode->i_mode =3D mode; + inode->i_ctime =3D CURRENT_TIME_SEC; + mark_inode_dirty(inode); + } + return error; +} + /* * Initialize the ACLs of a new inode. Called from ext2_new_inode. * @@ -241,12 +256,12 @@ ext2_init_acl(struct inode *inode, struct inode *dir) return error; =20 if (default_acl) { - error =3D ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + error =3D __ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!error) - error =3D ext2_set_acl(inode, acl, ACL_TYPE_ACCESS); + error =3D __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); } return error; diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index c4509495a104..72e13c25e62a 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -194,13 +194,6 @@ __ext3_set_acl(handle_t *handle, struct inode *inode, = int type, switch(type) { case ACL_TYPE_ACCESS: name_index =3D EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - error =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - inode->i_ctime =3D CURRENT_TIME_SEC; - ext3_mark_inode_dirty(handle, inode); - } break; =20 case ACL_TYPE_DEFAULT: @@ -234,12 +227,26 @@ ext3_set_acl(struct inode *inode, struct posix_acl *a= cl, int type) { handle_t *handle; int error, retries =3D 0; + int update_mode =3D 0; + umode_t mode =3D inode->i_mode; =20 retry: handle =3D ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + error =3D posix_acl_update_mode(inode, &mode, &acl); + if (error) + goto journal_stop; + update_mode =3D 1; + } error =3D __ext3_set_acl(handle, inode, type, acl); + if (!error && update_mode) { + inode->i_mode =3D mode; + inode->i_ctime =3D CURRENT_TIME_SEC; + ext3_mark_inode_dirty(handle, inode); + } +journal_stop: ext3_journal_stop(handle); if (error =3D=3D -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries= )) goto retry; diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 87d9bbf6a53f..a3d322487a86 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -200,13 +200,6 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, = int type, switch (type) { case ACL_TYPE_ACCESS: name_index =3D EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - error =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - inode->i_ctime =3D ext4_current_time(inode); - ext4_mark_inode_dirty(handle, inode); - } break; =20 case ACL_TYPE_DEFAULT: @@ -228,8 +221,9 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, i= nt type, value, size, 0); =20 kfree(value); - if (!error) + if (!error) { set_cached_acl(inode, type, acl); + } =20 return error; } @@ -239,6 +233,8 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl= , int type) { handle_t *handle; int error, retries =3D 0; + umode_t mode =3D inode->i_mode; + int update_mode =3D 0; =20 retry: handle =3D ext4_journal_start(inode, EXT4_HT_XATTR, @@ -246,7 +242,20 @@ ext4_set_acl(struct inode *inode, struct posix_acl *ac= l, int type) if (IS_ERR(handle)) return PTR_ERR(handle); =20 + if ((type =3D=3D ACL_TYPE_ACCESS) && acl) { + error =3D posix_acl_update_mode(inode, &mode, &acl); + if (error) + goto out_stop; + update_mode =3D 1; + } + error =3D __ext4_set_acl(handle, inode, type, acl); + if (!error && update_mode) { + inode->i_mode =3D mode; + inode->i_ctime =3D ext4_current_time(inode); + ext4_mark_inode_dirty(handle, inode); + } +out_stop: ext4_journal_stop(handle); if (error =3D=3D -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries= )) goto retry; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index ff4737033823..e6e2dd4779f0 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -202,6 +202,7 @@ static int __f2fs_set_acl(struct inode *inode, int type, void *value =3D NULL; size_t size =3D 0; int error; + umode_t mode =3D inode->i_mode; =20 if (acl) { error =3D posix_acl_valid(acl); @@ -212,11 +213,11 @@ static int __f2fs_set_acl(struct inode *inode, int ty= pe, switch (type) { case ACL_TYPE_ACCESS: name_index =3D F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - error =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); + if (acl && !ipage) { + error =3D posix_acl_update_mode(inode, &mode, &acl); if (error) return error; - set_acl_inode(fi, inode->i_mode); + set_acl_inode(fi, mode); } break; =20 diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 6267817dfe87..b3524f06fd82 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -35,13 +35,14 @@ static int gc_thread_func(void *data) =20 wait_ms =3D gc_th->min_sleep_time; =20 + set_freezable(); do { + wait_event_interruptible_timeout(*wq, + kthread_should_stop() || freezing(current), + msecs_to_jiffies(wait_ms)); + if (try_to_freeze()) continue; - else - wait_event_interruptible_timeout(*wq, - kthread_should_stop(), - msecs_to_jiffies(wait_ms)); if (kthread_should_stop()) break; =20 diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 2cf6962f6cc8..4d333b643cc8 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -168,6 +168,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigne= d long ino) ret =3D -EIO; goto bad_inode; } + f2fs_set_inode_flags(inode); unlock_new_inode(inode); trace_f2fs_iget(inode); return inode; diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c index 71b3087b7e32..c3173d480636 100644 --- a/fs/hfsplus/posix_acl.c +++ b/fs/hfsplus/posix_acl.c @@ -54,8 +54,8 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *ino= de, int type) return acl; } =20 -int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, - int type) +static int __hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *= acl, + int type) { int err; char *xattr_name; @@ -67,12 +67,6 @@ int hfsplus_set_posix_acl(struct inode *inode, struct po= six_acl *acl, switch (type) { case ACL_TYPE_ACCESS: xattr_name =3D POSIX_ACL_XATTR_ACCESS; - if (acl) { - err =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (err) - return err; - } - err =3D 0; break; =20 case ACL_TYPE_DEFAULT: @@ -108,6 +102,18 @@ int hfsplus_set_posix_acl(struct inode *inode, struct = posix_acl *acl, return err; } =20 +int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, int = type) +{ + int err; + + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + err =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); + if (err) + return err; + } + return __hfsplus_set_posix_acl(inode, acl, type); +} + int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) { int err =3D 0; @@ -125,15 +131,15 @@ int hfsplus_init_posix_acl(struct inode *inode, struc= t inode *dir) return err; =20 if (default_acl) { - err =3D hfsplus_set_posix_acl(inode, default_acl, - ACL_TYPE_DEFAULT); + err =3D __hfsplus_set_posix_acl(inode, default_acl, + ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } =20 if (acl) { if (!err) - err =3D hfsplus_set_posix_acl(inode, acl, - ACL_TYPE_ACCESS); + err =3D __hfsplus_set_posix_acl(inode, acl, + ACL_TYPE_ACCESS); posix_acl_release(acl); } return err; diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 9fad9f4fe883..30b70ad9fc1a 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -83,13 +83,6 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode,= int type, switch (type) { case ACL_TYPE_ACCESS: ea_name =3D POSIX_ACL_XATTR_ACCESS; - if (acl) { - rc =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (rc) - return rc; - inode->i_ctime =3D CURRENT_TIME; - mark_inode_dirty(inode); - } break; case ACL_TYPE_DEFAULT: ea_name =3D POSIX_ACL_XATTR_DEFAULT; @@ -121,12 +114,27 @@ int jfs_set_acl(struct inode *inode, struct posix_acl= *acl, int type) { int rc; tid_t tid; + int update_mode =3D 0; + umode_t mode =3D inode->i_mode; =20 tid =3D txBegin(inode->i_sb, 0); mutex_lock(&JFS_IP(inode)->commit_mutex); + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + rc =3D posix_acl_update_mode(inode, &mode, &acl); + if (rc) + goto end_tx; + update_mode =3D 1; + } rc =3D __jfs_set_acl(tid, inode, type, acl); - if (!rc) + if (!rc) { + if (update_mode) { + inode->i_mode =3D mode; + inode->i_ctime =3D CURRENT_TIME; + mark_inode_dirty(inode); + } rc =3D txCommit(tid, 1, &inode, 0); + } +end_tx: txEnd(tid); mutex_unlock(&JFS_IP(inode)->commit_mutex); return rc; diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 2475585f034b..75a00557cfea 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1030,7 +1030,7 @@ static int sysctl_check_table(const char *path, struc= t ctl_table *table) int err =3D 0; for (; table->procname; table++) { if (table->child) - err =3D sysctl_err(path, table, "Not a file"); + err |=3D sysctl_err(path, table, "Not a file"); =20 if ((table->proc_handler =3D=3D proc_dostring) || (table->proc_handler =3D=3D proc_dointvec) || @@ -1041,15 +1041,15 @@ static int sysctl_check_table(const char *path, str= uct ctl_table *table) (table->proc_handler =3D=3D proc_doulongvec_minmax) || (table->proc_handler =3D=3D proc_doulongvec_ms_jiffies_minmax)) { if (!table->data) - err =3D sysctl_err(path, table, "No data"); + err |=3D sysctl_err(path, table, "No data"); if (!table->maxlen) - err =3D sysctl_err(path, table, "No maxlen"); + err |=3D sysctl_err(path, table, "No maxlen"); } if (!table->proc_handler) - err =3D sysctl_err(path, table, "No proc_handler"); + err |=3D sysctl_err(path, table, "No proc_handler"); =20 if ((table->mode & (S_IRUGO|S_IWUGO)) !=3D table->mode) - err =3D sysctl_err(path, table, "bogus .mode 0%o", + err |=3D sysctl_err(path, table, "bogus .mode 0%o", table->mode); } return err; diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 7071c2230a92..095d0a52e5a6 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -23,7 +23,8 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *a= cl, int type) struct reiserfs_transaction_handle th; size_t jcreate_blocks; int size =3D acl ? posix_acl_xattr_size(acl->a_count) : 0; - + int update_mode =3D 0; + umode_t mode =3D inode->i_mode; =20 /* * Pessimism: We can't assume that anything from the xattr root up @@ -37,7 +38,16 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *= acl, int type) error =3D journal_begin(&th, inode->i_sb, jcreate_blocks); reiserfs_write_unlock(inode->i_sb); if (error =3D=3D 0) { + if (type =3D=3D ACL_TYPE_ACCESS && acl) { + error =3D posix_acl_update_mode(inode, &mode, &acl); + if (error) + goto unlock; + update_mode =3D 1; + } error =3D __reiserfs_set_acl(&th, inode, type, acl); + if (!error && update_mode) + inode->i_mode =3D mode; +unlock: reiserfs_write_lock(inode->i_sb); error2 =3D journal_end(&th); reiserfs_write_unlock(inode->i_sb); @@ -245,11 +255,6 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle = *th, struct inode *inode, switch (type) { case ACL_TYPE_ACCESS: name =3D POSIX_ACL_XATTR_ACCESS; - if (acl) { - error =3D posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - } break; case ACL_TYPE_DEFAULT: name =3D POSIX_ACL_XATTR_DEFAULT; diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 0e045e75abd8..2e93c33b1048 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -573,7 +573,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct= inode *dir, aligned_dlen =3D ALIGN(dlen, 8); aligned_ilen =3D ALIGN(ilen, 8); len =3D aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; - dent =3D kmalloc(len, GFP_NOFS); + dent =3D kzalloc(len, GFP_NOFS); if (!dent) return -ENOMEM; =20 @@ -956,7 +956,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct= inode *old_dir, len =3D aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); if (old_dir !=3D new_dir) len +=3D plen; - dent =3D kmalloc(len, GFP_NOFS); + dent =3D kzalloc(len, GFP_NOFS); if (!dent) return -ENOMEM; =20 @@ -1303,7 +1303,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, cons= t struct inode *host, hlen =3D host_ui->data_len + UBIFS_INO_NODE_SZ; len =3D aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); =20 - xent =3D kmalloc(len, GFP_NOFS); + xent =3D kzalloc(len, GFP_NOFS); if (!xent) return -ENOMEM; =20 @@ -1410,7 +1410,7 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, cons= t struct inode *inode, aligned_len1 =3D ALIGN(len1, 8); aligned_len =3D aligned_len1 + ALIGN(len2, 8); =20 - ino =3D kmalloc(aligned_len, GFP_NOFS); + ino =3D kzalloc(aligned_len, GFP_NOFS); if (!ino) return -ENOMEM; =20 diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index f07596463cde..cc2186990dbc 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -2712,6 +2712,8 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t = inum) dbg_tnc("xent '%s', ino %lu", xent->name, (unsigned long)xattr_inum); =20 + ubifs_evict_xattr_inode(c, xattr_inum); + nm.name =3D xent->name; nm.len =3D le16_to_cpu(xent->nlen); err =3D ubifs_tnc_remove_nm(c, &key1, &nm); diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 2a18270b02c0..8e764ac28f53 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1756,6 +1756,7 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const c= har *name, void *buf, size_t size); ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); int ubifs_removexattr(struct dentry *dentry, const char *name); +void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); =20 /* super.c */ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index ce6c0d4aa48d..4b6e09615ed5 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -481,6 +481,28 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *b= uffer, size_t size) return written; } =20 +/** + * ubifs_evict_xattr_inode - Evict an xattr inode. + * @c: UBIFS file-system description object + * @xattr_inum: xattr inode number + * + * When an inode that hosts xattrs is being removed we have to make sure + * that cached inodes of the xattrs also get removed from the inode cache + * otherwise we'd waste memory. This function looks up an inode from the + * inode cache and clears the link counter such that iput() will evict + * the inode. + */ +void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum) +{ + struct inode *inode; + + inode =3D ilookup(c->vfs_sb, xattr_inum); + if (inode) { + clear_nlink(inode); + iput(inode); + } +} + static int remove_xattr(struct ubifs_info *c, struct inode *host, struct inode *inode, const struct qstr *nm) { diff --git a/fs/udf/file.c b/fs/udf/file.c index 1aaf63a5f32f..8fc4135e514c 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -44,10 +44,15 @@ static void __udf_adinicb_readpage(struct page *page) struct inode *inode =3D page->mapping->host; char *kaddr; struct udf_inode_info *iinfo =3D UDF_I(inode); + loff_t isize =3D i_size_read(inode); =20 + /* + * We have to be careful here as truncate can change i_size under us. + * So just sample it once and use the same value everywhere. + */ kaddr =3D kmap(page); - memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); - memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size); + memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize); + memset(kaddr + isize, 0, PAGE_CACHE_SIZE - isize); flush_dcache_page(page); SetPageUptodate(page); kunmap(page); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index c2b1e6aa8dbd..28b5d30a7181 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1238,8 +1238,8 @@ int udf_setsize(struct inode *inode, loff_t newsize) return err; } set_size: - truncate_setsize(inode, newsize); up_write(&iinfo->i_data_sem); + truncate_setsize(inode, newsize); } else { if (iinfo->i_alloc_type =3D=3D ICBTAG_FLAG_AD_IN_ICB) { down_write(&iinfo->i_data_sem); @@ -1256,9 +1256,9 @@ int udf_setsize(struct inode *inode, loff_t newsize) udf_get_block); if (err) return err; + truncate_setsize(inode, newsize); down_write(&iinfo->i_data_sem); udf_clear_extent_cache(inode); - truncate_setsize(inode, newsize); udf_truncate_extents(inode); up_write(&iinfo->i_data_sem); } diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 7d65e25eccc5..0ca1a03da0b3 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -176,8 +176,8 @@ xfs_get_acl(struct inode *inode, int type) return acl; } =20 -STATIC int -__xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) +int +__xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { struct xfs_inode *ip =3D XFS_I(inode); unsigned char *ea_name; @@ -297,5 +297,5 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl,= int type) } =20 set_acl: - return __xfs_set_acl(inode, type, acl); + return __xfs_set_acl(inode, acl, type); } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 5dc163744511..19628001094d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -61,6 +61,7 @@ struct xfs_acl { #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int typ= e); +extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int t= ype); extern int posix_acl_access_exists(struct inode *inode); extern int posix_acl_default_exists(struct inode *inode); #else diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index 623bbe8fd921..a62b36731775 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h @@ -228,7 +228,14 @@ static inline void xfs_dinode_put_rdev(struct xfs_dino= de *dip, xfs_dev_t rdev) #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) =20 #ifdef CONFIG_XFS_RT -#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIM= E) + +/* + * make sure we ignore the inode flag if the filesystem doesn't have a + * configured realtime device. + */ +#define XFS_IS_REALTIME_INODE(ip) \ + (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) && \ + (ip)->i_mount->m_rtdev_targp) #else #define XFS_IS_REALTIME_INODE(ip) (0) #endif diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 37f6884ae39a..ea5628fe1ff2 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -173,12 +173,12 @@ xfs_generic_create( =20 #ifdef CONFIG_XFS_POSIX_ACL if (default_acl) { - error =3D -xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + error =3D -__xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); if (error) goto out_cleanup_inode; } if (acl) { - error =3D -xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); + error =3D -__xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); if (error) goto out_cleanup_inode; } diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 2997af6d2ccd..0e0f3a4e8844 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -225,6 +225,23 @@ int cpumask_set_cpu_local_first(int i, int numa_node, = cpumask_t *dstp); (cpu) =3D cpumask_next_zero((cpu), (mask)), \ (cpu) < nr_cpu_ids;) =20 +extern int cpumask_next_wrap(int n, const struct cpumask *mask, int start,= bool wrap); + +/** + * for_each_cpu_wrap - iterate over every cpu in a mask, starting at a spe= cified location + * @cpu: the (optionally unsigned) integer iterator + * @mask: the cpumask poiter + * @start: the start location + * + * The implementation does not assume any bit in @mask is set (including @= start). + * + * After the loop, cpu is >=3D nr_cpu_ids. + */ +#define for_each_cpu_wrap(cpu, mask, start) \ + for ((cpu) =3D cpumask_next_wrap((start)-1, (mask), (start), false); \ + (cpu) < nr_cpumask_bits; \ + (cpu) =3D cpumask_next_wrap((cpu), (mask), (start), true)) + /** * for_each_cpu_and - iterate over every cpu in both masks * @cpu: the (optionally unsigned) integer iterator diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index ade2390ffe92..6e39c9bb0dae 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -93,12 +93,12 @@ extern int cpuset_slab_spread_node(void); =20 static inline int cpuset_do_page_mem_spread(void) { - return current->flags & PF_SPREAD_PAGE; + return task_spread_page(current); } =20 static inline int cpuset_do_slab_mem_spread(void) { - return current->flags & PF_SPREAD_SLAB; + return task_spread_slab(current); } =20 extern int current_cpuset_is_being_rebound(void); diff --git a/include/linux/net.h b/include/linux/net.h index 17d83393afcc..8751fe4e8038 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -242,8 +242,25 @@ do { \ net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) #define net_info_ratelimited(fmt, ...) \ net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) +#if defined(CONFIG_DYNAMIC_DEBUG) +#define net_dbg_ratelimited(fmt, ...) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ + net_ratelimit()) \ + __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ + ##__VA_ARGS__); \ +} while (0) +#elif defined(DEBUG) #define net_dbg_ratelimited(fmt, ...) \ net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) +#else +#define net_dbg_ratelimited(fmt, ...) \ + do { \ + if (0) \ + no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ + } while (0) +#endif =20 bool __net_get_random_once(void *buf, int nbytes, bool *done, struct static_key *done_key); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 83a76633c03e..cf1846de8196 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2474,6 +2474,13 @@ #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff =20 +#define PCI_VENDOR_ID_NETRONOME 0x19ee +#define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200 +#define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240 +#define PCI_DEVICE_ID_NETRONOME_NFP4000 0x4000 +#define PCI_DEVICE_ID_NETRONOME_NFP6000 0x6000 +#define PCI_DEVICE_ID_NETRONOME_NFP6000_VF 0x6003 + #define PCI_VENDOR_ID_QMI 0x1a32 =20 #define PCI_VENDOR_ID_AZWAVE 0x1a3b diff --git a/include/linux/sched.h b/include/linux/sched.h index 504f5599463e..25ad8f0bbdcb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1317,13 +1317,12 @@ struct task_struct { * execve */ unsigned in_iowait:1; =20 - /* task may not gain privileges */ - unsigned no_new_privs:1; - /* Revert to default priority/policy when forking */ unsigned sched_reset_on_fork:1; unsigned sched_contributes_to_load:1; =20 + unsigned long atomic_flags; /* Flags needing atomic access. */ + pid_t pid; pid_t tgid; =20 @@ -1924,8 +1923,6 @@ extern void thread_group_cputime_adjusted(struct task= _struct *p, cputime_t *ut, #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ -#define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ -#define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ #define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle = with cpus_allowed */ #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process poli= cy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex teste= r */ @@ -1979,6 +1976,33 @@ static inline void memalloc_noio_restore(unsigned in= t flags) current->flags =3D (current->flags & ~PF_MEMALLOC_NOIO) | flags; } =20 +/* Per-process atomic flags. */ +#define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ +#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ +#define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ + + +#define TASK_PFA_TEST(name, func) \ + static inline bool task_##func(struct task_struct *p) \ + { return test_bit(PFA_##name, &p->atomic_flags); } +#define TASK_PFA_SET(name, func) \ + static inline void task_set_##func(struct task_struct *p) \ + { set_bit(PFA_##name, &p->atomic_flags); } +#define TASK_PFA_CLEAR(name, func) \ + static inline void task_clear_##func(struct task_struct *p) \ + { clear_bit(PFA_##name, &p->atomic_flags); } + +TASK_PFA_TEST(NO_NEW_PRIVS, no_new_privs) +TASK_PFA_SET(NO_NEW_PRIVS, no_new_privs) + +TASK_PFA_TEST(SPREAD_PAGE, spread_page) +TASK_PFA_SET(SPREAD_PAGE, spread_page) +TASK_PFA_CLEAR(SPREAD_PAGE, spread_page) + +TASK_PFA_TEST(SPREAD_SLAB, spread_slab) +TASK_PFA_SET(SPREAD_SLAB, spread_slab) +TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) + /* * task->jobctl flags */ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 6e98f62ea70d..5369c77607e5 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -542,9 +542,9 @@ extern void usb_ep0_reinit(struct usb_device *); ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) =20 #define EndpointRequest \ - ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) #define EndpointOutRequest \ - ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) =20 /* class requests from the USB 2.0 hub spec, table 11-15 */ /* GetBusState and SetHubDescriptor are optional, omitted */ diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 8ec980b5e3af..e0074a2ed593 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -94,6 +94,8 @@ extern void vfio_unregister_iommu_driver( */ extern struct vfio_group *vfio_group_get_external_user(struct file *filep); extern void vfio_group_put_external_user(struct vfio_group *group); +extern bool vfio_external_group_match_file(struct vfio_group *group, + struct file *filep); extern int vfio_external_user_iommu_id(struct vfio_group *group); extern long vfio_external_check_extension(struct vfio_group *group, unsigned long arg); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 7ccef342f724..7367f8c9aeeb 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1694,6 +1694,40 @@ int ib_query_port(struct ib_device *device, enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num); =20 +/** + * rdma_start_port - Return the first valid port number for the device + * specified + * + * @device: Device to be checked + * + * Return start port number + */ +static inline u8 rdma_start_port(const struct ib_device *device) +{ + return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? 0 : 1; +} + +/** + * rdma_end_port - Return the last valid port number for the device + * specified + * + * @device: Device to be checked + * + * Return last port number + */ +static inline u8 rdma_end_port(const struct ib_device *device) +{ + return (device->node_type =3D=3D RDMA_NODE_IB_SWITCH) ? + 0 : device->phys_port_cnt; +} + +static inline int rdma_is_port_valid(const struct ib_device *device, + unsigned int port) +{ + return (port >=3D rdma_start_port(device) && + port <=3D rdma_end_port(device)); +} + int ib_query_gid(struct ib_device *device, u8 port_num, int index, union ib_gid *gid); =20 diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 72a1b3aba1a0..6868a5ca183c 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -265,6 +265,7 @@ enum scsi_target_state { STARGET_CREATED =3D 1, STARGET_RUNNING, STARGET_REMOVE, + STARGET_CREATED_REMOVE, STARGET_DEL, }; =20 diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2= -dv-timings.h index 6c8f159e416e..63467ce7c3eb 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -175,70 +175,80 @@ =20 #define V4L2_DV_BT_CEA_3840X2160P24 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } =20 #define V4L2_DV_BT_CEA_3840X2160P25 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, 0) \ } =20 #define V4L2_DV_BT_CEA_3840X2160P30 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } =20 #define V4L2_DV_BT_CEA_3840X2160P50 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, 0) \ } =20 #define V4L2_DV_BT_CEA_3840X2160P60 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } =20 #define V4L2_DV_BT_CEA_4096X2160P24 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } =20 #define V4L2_DV_BT_CEA_4096X2160P25 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, 0) \ } =20 #define V4L2_DV_BT_CEA_4096X2160P30 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } =20 #define V4L2_DV_BT_CEA_4096X2160P50 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, 0) \ } =20 #define V4L2_DV_BT_CEA_4096X2160P60 { \ .type =3D V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ } diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 533494236c12..6dbc4bd416ec 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -339,13 +339,14 @@ static void cpuset_update_task_spread_flag(struct cpu= set *cs, struct task_struct *tsk) { if (is_spread_page(cs)) - tsk->flags |=3D PF_SPREAD_PAGE; + task_set_spread_page(tsk); else - tsk->flags &=3D ~PF_SPREAD_PAGE; + task_clear_spread_page(tsk); + if (is_spread_slab(cs)) - tsk->flags |=3D PF_SPREAD_SLAB; + task_set_spread_slab(tsk); else - tsk->flags &=3D ~PF_SPREAD_SLAB; + task_clear_spread_slab(tsk); } =20 /* diff --git a/kernel/events/core.c b/kernel/events/core.c index 847cf0d7428e..c1c6d24b5275 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4755,9 +4755,6 @@ static void perf_output_read_one(struct perf_output_h= andle *handle, __output_copy(handle, values, n * sizeof(u64)); } =20 -/* - * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. - */ static void perf_output_read_group(struct perf_output_handle *handle, struct perf_event *event, u64 enabled, u64 running) @@ -4802,6 +4799,13 @@ static void perf_output_read_group(struct perf_outpu= t_handle *handle, #define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ PERF_FORMAT_TOTAL_TIME_RUNNING) =20 +/* + * XXX PERF_SAMPLE_READ vs inherited events seems difficult. + * + * The problem is that its both hard and excessively expensive to iterate = the + * child list, not to mention that its impossible to IPI the children runn= ing + * on another CPU, from interrupt/NMI context. + */ static void perf_output_read(struct perf_output_handle *handle, struct perf_event *event) { @@ -7088,9 +7092,10 @@ perf_event_alloc(struct perf_event_attr *attr, int c= pu, local64_set(&hwc->period_left, hwc->sample_period); =20 /* - * we currently do not support PERF_FORMAT_GROUP on inherited events + * We currently do not support PERF_SAMPLE_READ on inherited events. + * See perf_output_read(). */ - if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) + if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ)) goto err_ns; =20 pmu =3D perf_init_event(event); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2fc44b2466f3..d6d34bbf921a 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5298,6 +5298,7 @@ early_initcall(migration_init); #ifdef CONFIG_SMP =20 static cpumask_var_t sched_domains_tmpmask; /* sched_domains_mutex */ +cpumask_var_t sched_domains_tmpmask2; =20 #ifdef CONFIG_SCHED_DEBUG =20 @@ -5775,21 +5776,39 @@ enum s_alloc { * and our sibling sd spans will be empty. Domains should always include t= he * cpu they're built on, so check that. * + * Only CPUs that can arrive at this group should be considered to continue + * balancing. */ -static void build_group_mask(struct sched_domain *sd, struct sched_group *= sg) +static void +build_group_mask(struct sched_domain *sd, struct sched_group *sg, struct c= pumask *mask) { const struct cpumask *span =3D sched_domain_span(sd); struct sd_data *sdd =3D sd->private; struct sched_domain *sibling; int i; =20 + cpumask_clear(mask); + for_each_cpu(i, span) { sibling =3D *per_cpu_ptr(sdd->sd, i); - if (!cpumask_test_cpu(i, sched_domain_span(sibling))) + + /* + * Can happen in the asymmetric case, where these siblings are + * unused. The mask will not be empty because those CPUs that + * do have the top domain _should_ span the domain. + */ + if (!sibling->child) + continue; + + /* If we would not end up here, we can't continue from here */ + if (!cpumask_equal(span, sched_domain_span(sibling->child))) continue; =20 - cpumask_set_cpu(i, sched_group_mask(sg)); + cpumask_set_cpu(i, mask); } + + /* We must not have empty masks here */ + WARN_ON_ONCE(cpumask_empty(mask)); } =20 /* @@ -5801,6 +5820,52 @@ int group_balance_cpu(struct sched_group *sg) return cpumask_first_and(sched_group_cpus(sg), sched_group_mask(sg)); } =20 +static struct sched_group * +build_group_from_child_sched_domain(struct sched_domain *sd, int cpu) +{ + struct sched_group *sg; + struct cpumask *sg_span; + + sg =3D kzalloc_node(sizeof(struct sched_group) + cpumask_size(), + GFP_KERNEL, cpu_to_node(cpu)); + + if (!sg) + return NULL; + + sg_span =3D sched_group_cpus(sg); + if (sd->child) + cpumask_copy(sg_span, sched_domain_span(sd->child)); + else + cpumask_copy(sg_span, sched_domain_span(sd)); + + return sg; +} + +static void init_overlap_sched_group(struct sched_domain *sd, + struct sched_group *sg) +{ + struct cpumask *mask =3D sched_domains_tmpmask2; + struct sd_data *sdd =3D sd->private; + struct cpumask *sg_span; + int cpu; + + build_group_mask(sd, sg, mask); + cpu =3D cpumask_first_and(sched_group_cpus(sg), mask); + + sg->sgc =3D *per_cpu_ptr(sdd->sgc, cpu); + if (atomic_inc_return(&sg->sgc->ref) =3D=3D 1) + cpumask_copy(sched_group_mask(sg), mask); + + /* + * Initialize sgc->capacity such that even if we mess up the + * domains and no possible iteration will get us here, we won't + * die on a /0 trap. + */ + sg_span =3D sched_group_cpus(sg); + sg->sgc->capacity =3D SCHED_CAPACITY_SCALE * cpumask_weight(sg_span); + sg->sgc->capacity_orig =3D sg->sgc->capacity; +} + static int build_overlap_sched_groups(struct sched_domain *sd, int cpu) { @@ -5808,49 +5873,31 @@ build_overlap_sched_groups(struct sched_domain *sd,= int cpu) const struct cpumask *span =3D sched_domain_span(sd); struct cpumask *covered =3D sched_domains_tmpmask; struct sd_data *sdd =3D sd->private; - struct sched_domain *child; + struct sched_domain *sibling; int i; =20 cpumask_clear(covered); =20 - for_each_cpu(i, span) { + for_each_cpu_wrap(i, span, cpu) { struct cpumask *sg_span; =20 if (cpumask_test_cpu(i, covered)) continue; =20 - child =3D *per_cpu_ptr(sdd->sd, i); + sibling =3D *per_cpu_ptr(sdd->sd, i); =20 /* See the comment near build_group_mask(). */ - if (!cpumask_test_cpu(i, sched_domain_span(child))) + if (!cpumask_test_cpu(i, sched_domain_span(sibling))) continue; =20 - sg =3D kzalloc_node(sizeof(struct sched_group) + cpumask_size(), - GFP_KERNEL, cpu_to_node(cpu)); - + sg =3D build_group_from_child_sched_domain(sibling, cpu); if (!sg) goto fail; =20 sg_span =3D sched_group_cpus(sg); - if (child->child) { - child =3D child->child; - cpumask_copy(sg_span, sched_domain_span(child)); - } else - cpumask_set_cpu(i, sg_span); - cpumask_or(covered, covered, sg_span); =20 - sg->sgc =3D *per_cpu_ptr(sdd->sgc, i); - if (atomic_inc_return(&sg->sgc->ref) =3D=3D 1) - build_group_mask(sd, sg); - - /* - * Initialize sgc->capacity such that even if we mess up the - * domains and no possible iteration will get us here, we won't - * die on a /0 trap. - */ - sg->sgc->capacity =3D SCHED_CAPACITY_SCALE * cpumask_weight(sg_span); - sg->sgc->capacity_orig =3D sg->sgc->capacity; + init_overlap_sched_group(sd, sg); =20 /* * Make sure the first group of this domain contains the @@ -7109,6 +7156,7 @@ void __init sched_init(void) =20 #ifdef CONFIG_SMP zalloc_cpumask_var(&sched_domains_tmpmask, GFP_NOWAIT); + zalloc_cpumask_var(&sched_domains_tmpmask2, GFP_NOWAIT); /* May be allocated at isolcpus cmdline parse time */ if (cpu_isolated_map =3D=3D NULL) zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 301bbc24739c..e2eb71b1e970 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -224,7 +224,7 @@ static long seccomp_attach_filter(struct sock_fprog *fp= rog) * This avoids scenarios where unprivileged tasks can affect the * behavior of privileged children. */ - if (!current->no_new_privs && + if (!task_no_new_privs(current) && security_capable_noaudit(current_cred(), current_user_ns(), CAP_SYS_ADMIN) !=3D 0) return -EACCES; diff --git a/kernel/sys.c b/kernel/sys.c index 6fe6c5986c59..0cb192dc4a93 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1989,12 +1989,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, = arg2, unsigned long, arg3, if (arg2 !=3D 1 || arg3 || arg4 || arg5) return -EINVAL; =20 - current->no_new_privs =3D 1; + task_set_no_new_privs(current); break; case PR_GET_NO_NEW_PRIVS: if (arg2 || arg3 || arg4 || arg5) return -EINVAL; - return current->no_new_privs ? 1 : 0; + return task_no_new_privs(current) ? 1 : 0; case PR_GET_THP_DISABLE: if (arg2 || arg3 || arg4 || arg5) return -EINVAL; diff --git a/lib/cpumask.c b/lib/cpumask.c index b6513a9f2892..78c13985a0a3 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -63,6 +63,38 @@ int cpumask_any_but(const struct cpumask *mask, unsigned= int cpu) return i; } =20 +/** + * cpumask_next_wrap - helper to implement for_each_cpu_wrap + * @n: the cpu prior to the place to search + * @mask: the cpumask pointer + * @start: the start point of the iteration + * @wrap: assume @n crossing @start terminates the iteration + * + * Returns >=3D nr_cpu_ids on completion + * + * Note: the @wrap argument is required for the start condition when + * we cannot assume @start is set in @mask. + */ +int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool w= rap) +{ + int next; + +again: + next =3D cpumask_next(n, mask); + + if (wrap && n < start && next >=3D start) { + return nr_cpumask_bits; + + } else if (next >=3D nr_cpumask_bits) { + wrap =3D true; + n =3D -1; + goto again; + } + + return next; +} +EXPORT_SYMBOL(cpumask_next_wrap); + /* These are not inline because of header tangles. */ #ifdef CONFIG_CPUMASK_OFFSTACK /** diff --git a/mm/memory.c b/mm/memory.c index ea9698d1b865..e1bde862d6d3 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3274,8 +3274,18 @@ static int __handle_mm_fault(struct mm_struct *mm, s= truct vm_area_struct *vma, if (unlikely(pmd_none(*pmd)) && unlikely(__pte_alloc(mm, vma, pmd, address))) return VM_FAULT_OOM; - /* if an huge pmd materialized from under us just retry later */ - if (unlikely(pmd_trans_huge(*pmd))) + /* + * If a huge pmd materialized under us just retry later. Use + * pmd_trans_unstable() instead of pmd_trans_huge() to ensure the pmd + * didn't become pmd_trans_huge under us and then back to pmd_none, as + * a result of MADV_DONTNEED running immediately after a huge pmd fault + * in a different thread of this mm, in turn leading to a misleading + * pmd_trans_huge() retval. All we have to ensure is that it is a + * regular pmd that we can walk with pte_offset_map() and we can do that + * through an atomic read in C, which is what pmd_trans_unstable() + * provides. + */ + if (unlikely(pmd_trans_unstable(pmd))) return 0; /* * A regular pmd is established and it can't morph into a huge pmd diff --git a/mm/mmap.c b/mm/mmap.c index 03b34261aa08..44134131b8f1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2141,7 +2141,7 @@ int expand_upwards(struct vm_area_struct *vma, unsign= ed long address) =20 /* Guard against exceeding limits of the address space. */ address &=3D PAGE_MASK; - if (address >=3D TASK_SIZE) + if (address >=3D (TASK_SIZE & PAGE_MASK)) return -ENOMEM; address +=3D PAGE_SIZE; =20 @@ -2153,7 +2153,8 @@ int expand_upwards(struct vm_area_struct *vma, unsign= ed long address) gap_addr =3D TASK_SIZE; =20 next =3D vma->vm_next; - if (next && next->vm_start < gap_addr) { + if (next && next->vm_start < gap_addr && + (next->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) { if (!(next->vm_flags & VM_GROWSUP)) return -ENOMEM; /* Check that both stack segments have the same anon_vma? */ @@ -2233,7 +2234,8 @@ int expand_downwards(struct vm_area_struct *vma, if (gap_addr > address) return -ENOMEM; prev =3D vma->vm_prev; - if (prev && prev->vm_end > gap_addr) { + if (prev && prev->vm_end > gap_addr && + (prev->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) { if (!(prev->vm_flags & VM_GROWSDOWN)) return -ENOMEM; /* Check that both stack segments have the same anon_vma? */ diff --git a/mm/slab.c b/mm/slab.c index 084985404fec..a36735ae2366 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -3112,7 +3112,7 @@ static inline void *____cache_alloc(struct kmem_cache= *cachep, gfp_t flags) =20 #ifdef CONFIG_NUMA /* - * Try allocating on another node if PF_SPREAD_SLAB is a mempolicy is set. + * Try allocating on another node if PFA_SPREAD_SLAB is a mempolicy is set. * * If we are in_interrupt, then process context, including cpusets and * mempolicy, may not apply and should not be used for allocation policy. @@ -3344,7 +3344,7 @@ __do_cache_alloc(struct kmem_cache *cache, gfp_t flag= s) { void *objp; =20 - if (current->mempolicy || unlikely(current->flags & PF_SPREAD_SLAB)) { + if (current->mempolicy || cpuset_do_slab_mem_spread()) { objp =3D alternate_node_alloc(cache, flags); if (objp) goto out; diff --git a/mm/swap.c b/mm/swap.c index 9e8e3472248b..a4d58b5fc4be 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -474,7 +474,7 @@ void rotate_reclaimable_page(struct page *page) page_cache_get(page); local_irq_save(flags); pvec =3D this_cpu_ptr(&lru_rotate_pvecs); - if (!pagevec_add(pvec, page)) + if (!pagevec_add(pvec, page) || PageCompound(page)) pagevec_move_tail(pvec); local_irq_restore(flags); } @@ -530,7 +530,7 @@ void activate_page(struct page *page) struct pagevec *pvec =3D &get_cpu_var(activate_page_pvecs); =20 page_cache_get(page); - if (!pagevec_add(pvec, page)) + if (!pagevec_add(pvec, page) || PageCompound(page)) pagevec_lru_move_fn(pvec, __activate_page, NULL); put_cpu_var(activate_page_pvecs); } @@ -630,9 +630,8 @@ static void __lru_cache_add(struct page *page) struct pagevec *pvec =3D &get_cpu_var(lru_add_pvec); =20 page_cache_get(page); - if (!pagevec_space(pvec)) + if (!pagevec_add(pvec, page) || PageCompound(page)) __pagevec_lru_add(pvec); - pagevec_add(pvec, page); put_cpu_var(lru_add_pvec); } =20 @@ -811,7 +810,7 @@ void deactivate_page(struct page *page) if (likely(get_page_unless_zero(page))) { struct pagevec *pvec =3D &get_cpu_var(lru_deactivate_pvecs); =20 - if (!pagevec_add(pvec, page)) + if (!pagevec_add(pvec, page) || PageCompound(page)) pagevec_lru_move_fn(pvec, lru_deactivate_fn, NULL); put_cpu_var(lru_deactivate_pvecs); } diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 84c0a21c1cda..0dbc437958ec 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -59,7 +59,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn = *conn, u8 code, u8 ident, u16 dlen, void *data); static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16= len, void *data); -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_= t data_size); static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); =20 static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, @@ -1401,7 +1401,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) =20 set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } =20 @@ -2978,12 +2978,15 @@ static inline int l2cap_get_conf_opt(void **ptr, in= t *type, int *olen, return len; } =20 -static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long = val) +static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long = val, size_t size) { struct l2cap_conf_opt *opt =3D *ptr; =20 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val); =20 + if (size < L2CAP_CONF_OPT_SIZE + len) + return; + opt->type =3D type; opt->len =3D len; =20 @@ -3008,7 +3011,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u= 8 len, unsigned long val) *ptr +=3D L2CAP_CONF_OPT_SIZE + len; } =20 -static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) +static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t = size) { struct l2cap_conf_efs efs; =20 @@ -3036,7 +3039,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2ca= p_chan *chan) } =20 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, size); } =20 static void l2cap_ack_timeout(struct work_struct *work) @@ -3180,11 +3183,12 @@ static inline void l2cap_txwin_setup(struct l2cap_c= han *chan) chan->ack_win =3D chan->tx_win; } =20 -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_= t data_size) { struct l2cap_conf_req *req =3D data; struct l2cap_conf_rfc rfc =3D { .mode =3D chan->mode }; void *ptr =3D req->data; + void *endptr =3D data + data_size; u16 size; =20 BT_DBG("chan %p", chan); @@ -3209,7 +3213,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *ch= an, void *data) =20 done: if (chan->imtu !=3D L2CAP_DEFAULT_MTU) - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); =20 switch (chan->mode) { case L2CAP_MODE_BASIC: @@ -3225,7 +3229,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *ch= an, void *data) rfc.max_pdu_size =3D 0; =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); break; =20 case L2CAP_MODE_ERTM: @@ -3245,21 +3249,21 @@ static int l2cap_build_conf_req(struct l2cap_chan *= chan, void *data) L2CAP_DEFAULT_TX_WINDOW); =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); =20 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) - l2cap_add_opt_efs(&ptr, chan); + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); =20 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, - chan->tx_win); + chan->tx_win, endptr - ptr); =20 if (chan->conn->feat_mask & L2CAP_FEAT_FCS) if (chan->fcs =3D=3D L2CAP_FCS_NONE || test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { chan->fcs =3D L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); + chan->fcs, endptr - ptr); } break; =20 @@ -3277,17 +3281,17 @@ static int l2cap_build_conf_req(struct l2cap_chan *= chan, void *data) rfc.max_pdu_size =3D cpu_to_le16(size); =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); =20 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) - l2cap_add_opt_efs(&ptr, chan); + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); =20 if (chan->conn->feat_mask & L2CAP_FEAT_FCS) if (chan->fcs =3D=3D L2CAP_FCS_NONE || test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { chan->fcs =3D L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); + chan->fcs, endptr - ptr); } break; } @@ -3298,10 +3302,11 @@ static int l2cap_build_conf_req(struct l2cap_chan *= chan, void *data) return ptr - data; } =20 -static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) +static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_= t data_size) { struct l2cap_conf_rsp *rsp =3D data; void *ptr =3D rsp->data; + void *endptr =3D data + data_size; void *req =3D chan->conf_req; int len =3D chan->conf_len; int type, hint, olen; @@ -3403,7 +3408,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) return -ECONNREFUSED; =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); } =20 if (result =3D=3D L2CAP_CONF_SUCCESS) { @@ -3416,7 +3421,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) chan->omtu =3D mtu; set_bit(CONF_MTU_DONE, &chan->conf_state); } - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); =20 if (remote_efs) { if (chan->local_stype !=3D L2CAP_SERV_NOTRAFIC && @@ -3430,7 +3435,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); } else { /* Send PENDING Conf Rsp */ result =3D L2CAP_CONF_PENDING; @@ -3463,7 +3468,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) set_bit(CONF_MODE_DONE, &chan->conf_state); =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); =20 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->remote_id =3D efs.id; @@ -3477,7 +3482,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) le32_to_cpu(efs.sdu_itime); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); } break; =20 @@ -3491,7 +3496,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *ch= an, void *data) set_bit(CONF_MODE_DONE, &chan->conf_state); =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); =20 break; =20 @@ -3513,10 +3518,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *= chan, void *data) } =20 static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int le= n, - void *data, u16 *result) + void *data, size_t size, u16 *result) { struct l2cap_conf_req *req =3D data; void *ptr =3D req->data; + void *endptr =3D data + size; int type, olen; unsigned long val; struct l2cap_conf_rfc rfc =3D { .mode =3D L2CAP_MODE_BASIC }; @@ -3534,13 +3540,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *= chan, void *rsp, int len, chan->imtu =3D L2CAP_DEFAULT_MIN_MTU; } else chan->imtu =3D val; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); break; =20 case L2CAP_CONF_FLUSH_TO: chan->flush_to =3D val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, - 2, chan->flush_to); + 2, chan->flush_to, endptr - ptr); break; =20 case L2CAP_CONF_RFC: @@ -3554,13 +3560,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *= chan, void *rsp, int len, chan->fcs =3D 0; =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); break; =20 case L2CAP_CONF_EWS: chan->ack_win =3D min_t(u16, val, chan->ack_win); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, - chan->tx_win); + chan->tx_win, endptr - ptr); break; =20 case L2CAP_CONF_EFS: @@ -3573,7 +3579,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *ch= an, void *rsp, int len, return -ECONNREFUSED; =20 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); break; =20 case L2CAP_CONF_FCS: @@ -3678,7 +3684,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *cha= n) return; =20 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } =20 @@ -3885,7 +3891,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_= conn *conn, u8 buf[128]; set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } =20 @@ -3965,7 +3971,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn= *conn, break; =20 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, req), req); + l2cap_build_conf_req(chan, req, sizeof(req)), req); chan->num_conf_req++; break; =20 @@ -4077,7 +4083,7 @@ static inline int l2cap_config_req(struct l2cap_conn = *conn, } =20 /* Complete config. */ - len =3D l2cap_parse_conf_req(chan, rsp); + len =3D l2cap_parse_conf_req(chan, rsp, sizeof(rsp)); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto unlock; @@ -4111,7 +4117,7 @@ static inline int l2cap_config_req(struct l2cap_conn = *conn, if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { u8 buf[64]; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } =20 @@ -4171,7 +4177,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn = *conn, char buf[64]; =20 len =3D l2cap_parse_conf_rsp(chan, rsp->data, len, - buf, &result); + buf, sizeof(buf), &result); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto done; @@ -4201,7 +4207,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn = *conn, /* throw out any old stored conf requests */ result =3D L2CAP_CONF_SUCCESS; len =3D l2cap_parse_conf_rsp(chan, rsp->data, len, - req, &result); + req, sizeof(req), &result); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto done; @@ -4782,7 +4788,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, = int result, set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } } @@ -7361,7 +7367,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 stat= us, u8 encrypt) set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 7b7f3de79db9..b7b6d387ef5d 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -22,6 +22,7 @@ =20 #include #include +#include #include =20 #include @@ -153,7 +154,7 @@ bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 i= rk[16], if (err) return false; =20 - return !memcmp(bdaddr->b, hash, 3); + return !crypto_memneq(bdaddr->b, hash, 3); } =20 int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *r= pa) @@ -533,7 +534,7 @@ static u8 smp_random(struct smp_chan *smp) if (ret) return SMP_UNSPECIFIED; =20 - if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) !=3D 0) { + if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) { BT_ERR("Pairing failed (confirmation values mismatch)"); return SMP_CONFIRM_FAILED; } diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 7d736cd3ee91..c232ededeaa2 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -797,7 +797,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_i= faddr *iprim) if (ifa->ifa_flags & IFA_F_SECONDARY) { prim =3D inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); if (prim =3D=3D NULL) { - pr_warn("%s: bug: prim =3D=3D NULL\n", __func__); + /* if the device has been deleted, we don't perform + * address promotion + */ + if (!in_dev->dead) + pr_warn("%s: bug: prim =3D=3D NULL\n", __func__); return; } if (iprim && iprim !=3D prim) { diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 4a74ea85518f..b77a181cd450 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -862,6 +862,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) val =3D 65535 - 40; if (type =3D=3D RTAX_MTU && val > 65535 - 15) val =3D 65535 - 15; + if (type =3D=3D RTAX_HOPLIMIT && val > 255) + val =3D 255; fi->fib_metrics[type - 1] =3D val; } } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3cb23fb85a4a..6561c103e216 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -158,7 +158,8 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct s= ock *sk, } =20 skb->priority =3D sk->sk_priority; - skb->mark =3D sk->sk_mark; + if (!skb->mark) + skb->mark =3D sk->sk_mark; =20 /* Send it out. */ return ip_local_out(skb); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f8ee2fc404cd..6ad29aa904bf 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2863,6 +2863,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, stru= ct dst_entry *dst, TCP_ECN_make_synack(req, th); th->source =3D htons(ireq->ir_num); th->dest =3D ireq->ir_rmt_port; + skb->mark =3D ireq->ir_mark; /* Setting of flags are superfluous here for callers (and ECE is * not even correctly set) */ diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d5fe33752ca6..9f48905cac9c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1610,17 +1610,10 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *ne= t, const struct in6_addr *add =20 static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) { - if (ifp->flags&IFA_F_PERMANENT) { - spin_lock_bh(&ifp->lock); - addrconf_del_dad_work(ifp); - ifp->flags |=3D IFA_F_TENTATIVE; - if (dad_failed) - ifp->flags |=3D IFA_F_DADFAILED; - spin_unlock_bh(&ifp->lock); - if (dad_failed) - ipv6_ifa_notify(0, ifp); - in6_ifa_put(ifp); - } else if (ifp->flags&IFA_F_TEMPORARY) { + if (dad_failed) + ifp->flags |=3D IFA_F_DADFAILED; + + if (ifp->flags&IFA_F_TEMPORARY) { struct inet6_ifaddr *ifpub; spin_lock_bh(&ifp->lock); ifpub =3D ifp->ifpub; @@ -1633,6 +1626,14 @@ static void addrconf_dad_stop(struct inet6_ifaddr *i= fp, int dad_failed) spin_unlock_bh(&ifp->lock); } ipv6_del_addr(ifp); + } else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) { + spin_lock_bh(&ifp->lock); + addrconf_del_dad_work(ifp); + ifp->flags |=3D IFA_F_TENTATIVE; + spin_unlock_bh(&ifp->lock); + if (dad_failed) + ipv6_ifa_notify(0, ifp); + in6_ifa_put(ifp); } else { ipv6_del_addr(ifp); } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f5e99a85bf92..36aadaeb7f44 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -653,10 +653,14 @@ static int fib6_commit_metrics(struct dst_entry *dst, int type =3D nla_type(nla); =20 if (type) { + u32 val =3D nla_get_u32(nla); + if (type > RTAX_MAX) return -EINVAL; =20 - mp[type - 1] =3D nla_get_u32(nla); + if (type =3D=3D RTAX_HOPLIMIT && val > 255) + val =3D 255; + mp[type - 1] =3D val; } } return 0; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index f521848e26c7..086049f5abd3 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -706,10 +706,8 @@ static int iucv_sock_bind(struct socket *sock, struct = sockaddr *addr, char uid[9]; =20 /* Verify the input sockaddr */ - if (!addr || addr->sa_family !=3D AF_IUCV) - return -EINVAL; - - if (addr_len < sizeof(struct sockaddr_iucv)) + if (addr_len < sizeof(struct sockaddr_iucv) || + addr->sa_family !=3D AF_IUCV) return -EINVAL; =20 lock_sock(sk); @@ -853,7 +851,7 @@ static int iucv_sock_connect(struct socket *sock, struc= t sockaddr *addr, struct iucv_sock *iucv =3D iucv_sk(sk); int err; =20 - if (addr->sa_family !=3D AF_IUCV || alen < sizeof(struct sockaddr_iucv)) + if (alen < sizeof(struct sockaddr_iucv) || addr->sa_family !=3D AF_IUCV) return -EINVAL; =20 if (sk->sk_state !=3D IUCV_OPEN && sk->sk_state !=3D IUCV_BOUND) diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 1ecc71ce8cae..d30f5c03d72f 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -390,7 +390,7 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct= sk_buff *skb) drop: IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); kfree_skb(skb); - return -1; + return 0; } =20 /* Userspace will call sendmsg() on the tunnel socket to send L2TP diff --git a/net/nfc/core.c b/net/nfc/core.c index 819b87702b70..2ff3c924b64f 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -950,6 +950,8 @@ static void nfc_release(struct device *d) kfree(se); } =20 + ida_simple_remove(&nfc_index_ida, dev->idx); + kfree(dev); } =20 @@ -1024,6 +1026,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *o= ps, int tx_headroom, int tx_tailroom) { struct nfc_dev *dev; + int rc; =20 if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || !ops->deactivate_target || !ops->im_transceive) @@ -1036,6 +1039,15 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *= ops, if (!dev) return NULL; =20 + rc =3D ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); + if (rc < 0) + goto err_free_dev; + dev->idx =3D rc; + + dev->dev.class =3D &nfc_class; + dev_set_name(&dev->dev, "nfc%d", dev->idx); + device_initialize(&dev->dev); + dev->ops =3D ops; dev->supported_protocols =3D supported_protocols; dev->tx_headroom =3D tx_headroom; @@ -1058,6 +1070,11 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *= ops, } =20 return dev; + +err_free_dev: + kfree(dev); + + return ERR_PTR(rc); } EXPORT_SYMBOL(nfc_allocate_device); =20 @@ -1072,14 +1089,6 @@ int nfc_register_device(struct nfc_dev *dev) =20 pr_debug("dev_name=3D%s\n", dev_name(&dev->dev)); =20 - dev->idx =3D ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); - if (dev->idx < 0) - return dev->idx; - - dev->dev.class =3D &nfc_class; - dev_set_name(&dev->dev, "nfc%d", dev->idx); - device_initialize(&dev->dev); - mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; rc =3D device_add(&dev->dev); @@ -1117,12 +1126,10 @@ EXPORT_SYMBOL(nfc_register_device); */ void nfc_unregister_device(struct nfc_dev *dev) { - int rc, id; + int rc; =20 pr_debug("dev_name=3D%s\n", dev_name(&dev->dev)); =20 - id =3D dev->idx; - if (dev->rfkill) { rfkill_unregister(dev->rfkill); rfkill_destroy(dev->rfkill); @@ -1147,8 +1154,6 @@ void nfc_unregister_device(struct nfc_dev *dev) nfc_devlist_generation++; device_del(&dev->dev); mutex_unlock(&nfc_devlist_mutex); - - ida_simple_remove(&nfc_index_ida, id); } EXPORT_SYMBOL(nfc_unregister_device); =20 diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 7e4e15075c81..4878016ecc9c 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -309,7 +309,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct n= lmsghdr *n) case RTM_DELTFILTER: err =3D tp->ops->delete(tp, fh); if (err =3D=3D 0) - tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); + tfilter_notify(net, skb, n, tp, + t->tcm_handle, RTM_DELTFILTER); goto errout; case RTM_GETTFILTER: err =3D tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER); diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gs= s_krb5_crypto.c index 0f43e894bc0a..4ff1a3486937 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -34,6 +34,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ =20 +#include #include #include #include @@ -838,7 +839,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset,= struct xdr_buf *buf, if (ret) goto out_err; =20 - if (memcmp(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) !=3D 0) { + if (crypto_memneq(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) !=3D 0) { ret =3D GSS_S_BAD_SIG; goto out_err; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ec05ad8ade21..6fd21cab5ada 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -299,8 +299,7 @@ static const struct nla_policy nl80211_policy[NL80211_A= TTR_MAX+1] =3D { [NL80211_ATTR_WPA_VERSIONS] =3D { .type =3D NLA_U32 }, [NL80211_ATTR_PID] =3D { .type =3D NLA_U32 }, [NL80211_ATTR_4ADDR] =3D { .type =3D NLA_U8 }, - [NL80211_ATTR_PMKID] =3D { .type =3D NLA_BINARY, - .len =3D WLAN_PMKID_LEN }, + [NL80211_ATTR_PMKID] =3D { .len =3D WLAN_PMKID_LEN }, [NL80211_ATTR_DURATION] =3D { .type =3D NLA_U32 }, [NL80211_ATTR_COOKIE] =3D { .type =3D NLA_U64 }, [NL80211_ATTR_TX_RATES] =3D { .type =3D NLA_NESTED }, @@ -355,6 +354,7 @@ static const struct nla_policy nl80211_policy[NL80211_A= TTR_MAX+1] =3D { [NL80211_ATTR_SCAN_FLAGS] =3D { .type =3D NLA_U32 }, [NL80211_ATTR_P2P_CTWINDOW] =3D { .type =3D NLA_U8 }, [NL80211_ATTR_P2P_OPPPS] =3D { .type =3D NLA_U8 }, + [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =3D {. type =3D NLA_U32 }, [NL80211_ATTR_ACL_POLICY] =3D {. type =3D NLA_U32 }, [NL80211_ATTR_MAC_ADDRS] =3D { .type =3D NLA_NESTED }, [NL80211_ATTR_STA_CAPABILITY] =3D { .type =3D NLA_U16 }, @@ -5288,6 +5288,10 @@ static int validate_scan_freqs(struct nlattr *freqs) struct nlattr *attr1, *attr2; int n_channels =3D 0, tmp1, tmp2; =20 + nla_for_each_nested(attr1, freqs, tmp1) + if (nla_len(attr1) !=3D sizeof(u32)) + return 0; + nla_for_each_nested(attr1, freqs, tmp1) { n_channels++; /* @@ -8923,6 +8927,9 @@ static int nl80211_set_rekey_data(struct sk_buff *skb= , struct genl_info *info) if (err) return err; =20 + if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] || + !tb[NL80211_REKEY_DATA_KCK]) + return -EINVAL; if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) !=3D NL80211_REPLAY_CTR_LE= N) return -ERANGE; if (nla_len(tb[NL80211_REKEY_DATA_KEK]) !=3D NL80211_KEK_LEN) diff --git a/scripts/tags.sh b/scripts/tags.sh index 140e5fad867d..c652a245aa18 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -197,6 +197,9 @@ exuberant() --regex-c++=3D'/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ --regex-c++=3D'/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ --regex-c++=3D'/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex-c++=3D'/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \ + --regex-c++=3D'/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \ + --regex-c++=3D'/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/'\ --regex-c=3D'/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \ --regex-c=3D'/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \ --regex-c=3D'/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \ @@ -259,6 +262,9 @@ emacs() --regex=3D'/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ --regex=3D'/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ --regex=3D'/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex=3D'/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \ + --regex=3D'/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \ + --regex=3D'/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/' \ --regex=3D'/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ --regex=3D'/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ --regex=3D'/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/= '\ diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index c0ee04da93e6..24a21cd72b4c 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -621,7 +621,7 @@ int aa_change_hat(const char *hats[], int count, u64 to= ken, bool permtest) * There is no exception for unconfined as change_hat is not * available. */ - if (current->no_new_privs) + if (task_no_new_privs(current)) return -EPERM; =20 /* released below */ @@ -778,7 +778,7 @@ int aa_change_profile(const char *ns_name, const char *= hname, bool onexec, * no_new_privs is set because this aways results in a reduction * of permissions. */ - if (current->no_new_privs && !unconfined(profile)) { + if (task_no_new_privs(current) && !unconfined(profile)) { put_cred(cred); return -EPERM; } diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixe= r.c index 5988e044c519..259bf54a9df0 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -88,7 +88,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl, int changed; =20 mutex_lock(&chip->mutex); - changed =3D !value->value.integer.value[0] !=3D chip->dac_mute; + changed =3D (!value->value.integer.value[0]) !=3D chip->dac_mute; if (changed) { chip->dac_mute =3D !value->value.integer.value[0]; chip->model.update_dac_mute(chip); diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 9ffd6009d0ec..31fa7cc3d462 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -67,7 +67,8 @@ static int soc_compr_open(struct snd_compr_stream *cstrea= m) static int soc_compr_open_fe(struct snd_compr_stream *cstream) { struct snd_soc_pcm_runtime *fe =3D cstream->private_data; - struct snd_pcm_substream *fe_substream =3D fe->pcm->streams[0].substream; + struct snd_pcm_substream *fe_substream =3D + fe->pcm->streams[cstream->direction].substream; struct snd_soc_platform *platform =3D fe->platform; struct snd_soc_dpcm *dpcm; struct snd_soc_dapm_widget_list *list; @@ -411,7 +412,8 @@ static int soc_compr_set_params_fe(struct snd_compr_str= eam *cstream, struct snd_compr_params *params) { struct snd_soc_pcm_runtime *fe =3D cstream->private_data; - struct snd_pcm_substream *fe_substream =3D fe->pcm->streams[0].substream; + struct snd_pcm_substream *fe_substream =3D + fe->pcm->streams[cstream->direction].substream; struct snd_soc_platform *platform =3D fe->platform; int ret =3D 0, stream; =20 diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep= /uinclude/linux/lockdep.h index c1552c28507e..908a9c6fecf0 100644 --- a/tools/lib/lockdep/uinclude/linux/lockdep.h +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h @@ -8,7 +8,7 @@ #include =20 =20 -#define MAX_LOCK_DEPTH 2000UL +#define MAX_LOCK_DEPTH 255UL =20 #define asmlinkage #define __visible diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c index ba1a93f935c7..4884708fa0b4 100644 --- a/virt/kvm/vfio.c +++ b/virt/kvm/vfio.c @@ -46,6 +46,22 @@ static struct vfio_group *kvm_vfio_group_get_external_us= er(struct file *filep) return vfio_group; } =20 +static bool kvm_vfio_external_group_match_file(struct vfio_group *group, + struct file *filep) +{ + bool ret, (*fn)(struct vfio_group *, struct file *); + + fn =3D symbol_get(vfio_external_group_match_file); + if (!fn) + return false; + + ret =3D fn(group, filep); + + symbol_put(vfio_external_group_match_file); + + return ret; +} + static void kvm_vfio_group_put_external_user(struct vfio_group *vfio_group) { void (*fn)(struct vfio_group *); @@ -168,18 +184,13 @@ static int kvm_vfio_set_group(struct kvm_device *dev,= long attr, u64 arg) if (!f.file) return -EBADF; =20 - vfio_group =3D kvm_vfio_group_get_external_user(f.file); - fdput(f); - - if (IS_ERR(vfio_group)) - return PTR_ERR(vfio_group); - ret =3D -ENOENT; =20 mutex_lock(&kv->lock); =20 list_for_each_entry(kvg, &kv->group_list, node) { - if (kvg->vfio_group !=3D vfio_group) + if (!kvm_vfio_external_group_match_file(kvg->vfio_group, + f.file)) continue; =20 list_del(&kvg->node); @@ -191,7 +202,7 @@ static int kvm_vfio_set_group(struct kvm_device *dev, l= ong attr, u64 arg) =20 mutex_unlock(&kv->lock); =20 - kvm_vfio_group_put_external_user(vfio_group); + fdput(f); =20 kvm_vfio_update_coherency(dev); =20 --Ah40dssYA/cDqAW1-- --Mit9XoPEfICDqq/V Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBWd+2See/yOyVhhEJAQpV6A/+LxVTZwukTGjHTTizbdOIXT5uRYBfP767 JFk3WtApqzRvJOdfYVYq/9cLbyMVheKJ4fK5arSRudj9Bf8r8NuO8oN12caVCsa4 1gdQMMS894RqjkziTZ7uM/nwHYmzyEvwT3GGMuUODO2zIPOSav/LGDCpcYN7pI8L qgBzb5dg8Umf39KBEYlP8eTYY0CEf89LNSsv6wrnyLwPmr+L33xnVHCFYtmMhQLw 4SIe2jxBVDyoml0LeE2aWDjLFOolInGbz+cb8YG37LUE2zJjQt5BVKawCwCXmkKY REPC+JpieTP+N/qHb8I+sU4uSR0Ly2Uc9RSgK0b9OrBOwDI3/8YNCRrvKnvej+yg YhkbxLDJWAzktDxOAv9ylVDrWEwz/8vju0p5yML60aLjOK2Su+9W5j2KjlGf7h7f P5VaT0wGvejg3qF+WyAfbi8rZhtipUyfFAuEeTQRyylqB94YRrjd6jEc81SBTNO9 fuLtTM7SXRoQxfb19PTDIcczSPpws45mMcvwmEW62+xWxqJwxzufBlj2rQhqhRJr AhqftHs0zwqe4NJHjjjDbfUrgULLnK8D3O5e+QxeIAlZEnmPp9SqfNzByPdHcnCz AA0b3u60aOVnzIBpDeP8b/uB7jfOZXCv43nfxFDYC8Zsn7wOKRMWiiOecSHFFTfr 8M/NEjj9wy4= =upJY -----END PGP SIGNATURE----- --Mit9XoPEfICDqq/V--