This is the start of the stable review cycle for the 3.16.54 release. There are 136 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Feb 13 12:00:00 UTC 2018. Anything received after that time might be too late.
All the patches have also been committed to the linux-3.16.y-rc branch of https://git.kernel.org/pub/scm/linux/kernel/git/bwh/linux-stable-rc.git . A shortlog and diffstat can be found below.
Ben.
-------------
Alan Stern (1): USB: usbfs: compute urb->actual_length for isochronous [2ef47001b3ee3ded579b7532ebdcf8680e4d8c54]
Alex Chen (1): ocfs2: should wait dio before inode lock in ocfs2_setattr() [28f5a8a7c033cbf3e32277f4cc9c6afd74f05300]
Alexander Popov (1): usbip: fix NULL pointer dereference on errors [8c7003a3b4b4afd3734cdcc39217ef22d78a4a16]
Alexander Potapenko (1): sctp: fully initialize the IPv6 address in sctp_v6_to_addr() [15339e441ec46fbc3bf3486bb1ae4845b0f1bb8d]
Alexander Steffen (1): tpm-dev-common: Reject too short writes [ee70bc1e7b63ac8023c9ff9475d8741e397316e7]
Alexandre Belloni (1): rtc: set the alarm to the next expiring timer [74717b28cb32e1ad3c1042cafd76b264c8c0f68d]
Andreas Rohner (1): nilfs2: fix race condition that causes file system corruption [31ccb1f7ba3cfe29631587d451cf5bb8ab593550]
Andrew F. Davis (1): ASoC: cs42l56: Fix reset GPIO name in example DT binding [8adc430603d67e76a0f8491df21654f691acda62]
Andrey Konovalov (1): p54: don't unregister leds when they are not initialized [fc09785de0a364427a5df63d703bae9a306ed116]
Andy Lutomirski (4): x86, vdso, pvclock: Simplify and speed up the vdso pvclock reader [6b078f5de7fc0851af4102493c7b5bb07e49c4cb] x86, vdso: Move the vvar area before the vdso text [e6577a7ce99a506b587bcd1d2cd803cb45119557] x86/vdso: Get pvclock data from the vvar VMA instead of the fixmap [dac16fba6fc590fa7239676b35ed75dae4c4cd2b] x86/vdso: Remove pvclock fixmap machinery [cc1e24fdb064d3126a494716f22ad4fc39306742]
Anna Schumaker (1): NFS: Avoid RCU usage in tracepoints [3944369db701f075092357b511fd9f5755771585]
Arnd Bergmann (4): Input: adxl34x - do not treat FIFO_MODE() as boolean [1dbc080c9ef6bcfba652ef0d6ae919b8c7c85a1d] drm: gma500: fix logic error [67a3b63a54cbe18944191f43d644686731cf30c7] elf_fdpic: fix unused variable warning [11e3e8d6d9274bf630859b4c47bc4e4d76f289db] isofs: fix timestamps beyond 2027 [34be4dbf87fc3e474a842305394534216d428f5d]
Bart Van Assche (3): IB/srp: Avoid that a cable pull can trigger a kernel crash [8a0d18c62121d3c554a83eb96e2752861d84d937] IB/srpt: Do not accept invalid initiator port names [c70ca38960399a63d5c048b7b700612ea321d17e] target/iscsi: Fix iSCSI task reassignment handling [59b6986dbfcdab96a971f9663221849de79a7556]
Ben Hutchings (1): usbip: tools: Install all headers needed for libusbip development [c15562c0dcb2c7f26e891923b784cf1926b8c833]
Ben Seri (1): Bluetooth: Prevent stack info leak from the EFS element. [06e7e776ca4d36547e503279aeff996cbb292c16]
Bernhard Rosenkraenzer (1): USB: Add delay-init quirk for Corsair K70 LUX keyboards [a0fea6027f19c62727315aba1a7fae75a9caa842]
Boshi Wang (1): ima: fix hash algorithm initialization [ebe7c0a7be92bbd34c6ff5b55810546a0ee05bee]
Brent Taylor (1): mtd: nand: Fix writing mtdoops to nand flash. [30863e38ebeb500a31cecee8096fb5002677dd9b]
Brian King (6): i40e: Use smp_rmb rather than read_barrier_depends [52c6912fde0133981ee50ba08808f257829c4c93] i40evf: Use smp_rmb rather than read_barrier_depends [f72271e2a0ae4277d53c4053f5eed8bb346ba38a] igb: Use smp_rmb rather than read_barrier_depends [c4cb99185b4cc96c0a1c70104dc21ae14d7e7f28] igbvf: Use smp_rmb rather than read_barrier_depends [1e1f9ca546556e508d021545861f6b5fc75a95fe] ixgbe: Fix skb list corruption on Power systems [0a9a17e3bb4564caf4bfe2a6783ae1287667d188] ixgbevf: Use smp_rmb rather than read_barrier_depends [ae0c585d93dfaf923d2c7eb44b2c3ab92854ea9b]
Christian König (1): drm/ttm: once more fix ttm_buffer_object_transfer [4d98e5ee6084f6d7bc578c5d5f86de7156aaa4cb]
Chuck Lever (1): nfs: Fix ugly referral attributes [c05cefcc72416a37eba5a2b35f0704ed758a9145]
Colin Ian King (3): btrfs: avoid null pointer dereference on fs_info when calling btrfs_crit [3993b112dac968612b0b213ed59cb30f50b0015b] rtc: interface: ignore expired timers when enqueuing new timers [2b2f5ff00f63847d95adad6289bd8b05f5983dd5] staging: rtl8188eu: avoid a null dereference on pmlmepriv [123c0aab0050cd0e07ce18e453389fbbb0a5a425]
Coly Li (2): bcache: check ca->alloc_thread initialized before wake up it [91af8300d9c1d7c6b6a2fd754109e08d4798b8d8] bcache: only permit to recovery read error when cache device is clean [d59b23795933678c9638fd20c942d2b4f3cd6185]
Corey Minyard (1): ipmi: fix unsigned long underflow [392a17b10ec4320d3c0e96e2a23ebaad1123b989]
Dan Carpenter (2): eCryptfs: use after free in ecryptfs_release_messaging() [db86be3a12d0b6e5c5b51c2ab2a48f06329cb590] scsi: bfa: integer overflow in debugfs [3e351275655d3c84dc28abf170def9786db5176d]
Dongho Sim (1): f2fs: remove redundant lines in allocate_data_block [33be828ada7274ebcade2001f16e5b4e33a4636e]
Doug Berger (1): net: bcmgenet: enable loopback during UniMAC sw_reset [28c2d1a7a0bfdf3617800d2beae1c67983c03d15]
Douglas Fischer (1): USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update [771394a54148f18926ca86414e51c69eda27d0cd]
Eric Biggers (1): dm bufio: fix integer overflow when limiting maximum cache size [74d4108d9e681dbbe4a2940ed8fdff1f6868184c]
Eric Dumazet (1): netfilter: xt_TCPMSS: add more sanity tests on tcph->doff [2638fd0f92d4397884fd991d8f4925cb3f081901]
Eric W. Biederman (1): net/sctp: Always set scope_id in sctp_inet6_skb_msgname [7c8a61d9ee1df0fb4747879fa67a99614eb62fec]
Gabriele Paoloni (1): PCI/AER: Report non-fatal errors only to the affected endpoint [86acc790717fb60fb51ea3095084e331d8711c74]
Guenter Roeck (1): kaiser: Set _PAGE_NX only if supported [61e9b3671007a5da8127955a1a3bda7e0d5f42e8]
Guillaume Nault (5): l2tp: don't register sessions in l2tp_session_create() [3953ae7b218df4d1e544b98a393666f9ae58a78c] l2tp: ensure sessions are freed after their PPPOL2TP socket [cdd10c9627496ad25c87ce6394e29752253c69d3] l2tp: initialise PPP sessions before registering them [f98be6c6359e7e4a61aaefb9964c1db31cb9ec0c] l2tp: initialise l2tp_eth sessions before registering them [ee28de6bbd78c2e18111a0aef43ea746f28d2073] l2tp: protect sock pointer of struct pppol2tp_session with RCU [ee40fb2e1eb5bc0ddd3f2f83c6e39a454ef5a741]
Heiko Carstens (2): s390/runtime instrumention: fix possible memory corruption [d6e646ad7cfa7034d280459b2b2546288f247144] s390: fix transactional execution control register handling [a1c5befc1c24eb9c1ee83f711e0f21ee79cbb556]
Hou Tao (1): dm: fix race between dm_get_from_kobject() and __dm_destroy() [b9a41d21dceadf8104812626ef85dc56ee8a60ed]
Ingo Molnar (1): x86/platform/uv: Include clocksource.h for clocksource_touch_watchdog() [d51953b0873358d13b189996e6976dfa12a9b59d]
Jaegeuk Kim (1): f2fs: expose some sectors to user in inline data or dentry case [5b4267d195dd887c4412e34b5a7365baa741b679]
James Morse (2): ACPI / APEI: Remove ghes_ioremap_area [520e18a5080d2c444a03280d99c8a35cb667d321] ACPI / APEI: Replace ioremap_page_range() with fixmap [4f89fa286f6729312e227e7c2d764e8e7b9d340e]
Jan Harkes (1): coda: fix 'kernel memory exposure attempt' in fsync [d337b66a4c52c7b04eec661d86c2ef6e168965a2]
Jani Nikula (1): drm/i915/bios: parse DDI ports also for CHV for HDMI DDC pin and DP AUX channel [348e4058ebf53904e817eec7a1b25327143c2ed2]
Jason Gunthorpe (1): sctp: Fixup v4mapped behaviour to comply with Sock API [299ee123e19889d511092347f5fc14db0f10e3a6]
Jens Axboe (1): blktrace: fix unlocked access to init/start-stop/teardown [1f2cac107c591c24b60b115d6050adc213d10fc0]
Joerg Roedel (1): iommu/vt-d: Don't register bus-notifier under dmar_global_lock [ec154bf56b276a0bb36079a5d22a267b5f417801]
Johan Hovold (5): NFC: fix device-allocation error return [c45e3e4c5b134b081e8af362109905427967eb19] USB: serial: garmin_gps: fix I/O after failed probe and remove [19a565d9af6e0d828bd0d521d3bafd5017f4ce52] USB: serial: garmin_gps: fix memory leak on probe errors [74d471b598444b7f2d964930f7234779c80960a0] USB: serial: metro-usb: stop I/O after failed open [2339536d229df25c71c0900fc619289229bfecf6] clk: ti: dra7-atl-clock: fix child-node lookups [33ec6dbc5a02677509d97fe36cd2105753f0f0ea]
Johannes Berg (1): nl80211: don't expose wdev->ssid for most interfaces [44905265bc155e0237c76c25bf5ddf740d85a8f2]
John David Anglin (1): parisc: Fix validity check of pointer size argument in new CAS implementation [05f016d2ca7a4fab99d5d5472168506ddf95e74f]
John Johansen (1): apparmor: ensure that undecidable profile attachments fail [844b8292b6311ecd30ae63db1471edb26e01d895]
Joshua Watt (1): NFS: Fix typo in nomigration mount option [f02fee227e5f21981152850744a6084ff3fa94ee]
Juerg Haefliger (1): Revert "x86: kvmclock: Disable use from vDSO if KPTI is enabled" [not upstream; reverts 3.16-specific change]
Ladi Prosek (1): KVM: nVMX: set IDTR and GDTR limits when loading L1 host state [21f2d551183847bc7fbe8d866151d00cdad18752]
Ladislav Michl (1): video: udlfb: Fix read EDID timeout [c98769475575c8a585f5b3952f4b5f90266f699b]
Lepton Wu (1): kaiser: Set _PAGE_NX only if supported [not upstream; specific to KAISER backport]
Maciej W. Rozycki (1): MIPS: Fix an n32 core file generation regset support regression [547da673173de51f73887377eb275304775064ad]
Majd Dibbiny (1): IB/mlx5: Assign send CQ and recv CQ of UMR QP [31fde034a8bd964a5c7c1a5663fc87a913158db2]
Manasi Navare (1): drm/i915/edp: Get the Panel Power Off timestamp after panel is off [cbacf02e7796fea02e5c6e46c90ed7cbe9e6f2c0]
Mark Bloch (1): IB/mlx4: Increase maximal message size under UD QP [5f22a1d87c5315a98981ecf93cd8de226cffe6ca]
Mark Rutland (1): arm64: vdso: fix clock_getres for 4GiB-aligned res [c80ed088a519da53f27b798a69748eaabc66aadf]
Markus Elfring (2): media: omap_vout: Fix a possible null pointer dereference in omap_vout_open() [bfba2b3e21b9426c0f9aca00f3cad8631b2da170] platform/x86: sony-laptop: Fix error handling in sony_nc_setup_rfkill() [f6c8a317ab208aee223776327c06f23342492d54]
Masami Hiramatsu (1): x86/decoder: Add new TEST instruction pattern [12a78d43de767eaf8fb272facb7a7b6f2dc6a9df]
Mauro Carvalho Chehab (1): [media] cx231xx: Fix the max number of interfaces [139d28826b8e2bc7a9232fde0d2f14812914f501]
Michał Mirosław (1): clk: tegra: Fix cclk_lp divisor register [54eff2264d3e9fd7e3987de1d7eba1d3581c631e]
Mike Snitzer (1): dm: discard support requires all targets in a table support discards [8a74d29d541cd86569139c6f3f44b2d210458071]
Mohamed Ghannam (2): RDS: Heap OOB write in rds_message_alloc_sgs() [c095508770aebf1b9218e77026e48345d719b17c] RDS: null pointer dereference in rds_atomic_free_op [7d11f77f84b27cef452cee332f4e469503084737]
Nadav Amit (2): KVM: vmx: Inject #GP on invalid PAT CR [4566654bb9be9e8864df417bb72ceee5136b6a6a] staging: lustre: ptlrpc: kfree used instead of kvfree [c3eec59659cf25916647d2178c541302bb4822ad]
Nathan Lynch (1): arm64: vdso: minor ABI fix for clock_getres [e1b6b6ce55a0a25c8aa8af019095253b2133a41a]
NeilBrown (2): autofs: don't fail mount for transient error [ecc0c469f27765ed1e2b967be0aa17cee1a60b76] autofs: fix careless error in recent commit [302ec300ef8a545a7fc7f667e5fd743b091c2eeb]
Nicholas Bellinger (3): iscsi-target: Fix non-immediate TMR reference leak [3fc9fb13a4b2576aeab86c62fd64eb29ab68659c] iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref [ae072726f6109bb1c94841d6fb3a82dde298ea85] target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK [1c21a48055a67ceb693e9c2587824a8de60a217c]
Paolo Bonzini (2): KVM: SVM: obey guest PAT [15038e14724799b8c205beb5f20f9e54896013c3] x86: pvclock: Really remove the sched notifier for cross-cpu migrations [73459e2a1ada09a68c02cc5b73f3116fc8194b3d]
Peter Ujfalusi (1): clk: ti: dra7-atl-clock: Fix of_node reference counting [660e1551939931657808d47838a3f443c0e83fd0]
Peter Zijlstra (1): lib/int_sqrt: optimize small argument [3f3295709edea6268ff1609855f498035286af73]
Philip Derrin (1): ARM: 8721/1: mm: dump: check hardware RO bit for LPAE [3b0c0c922ff4be275a8beb87ce5657d16f355b54]
Radu Alexe (1): crypto: caam - fix incorrect define [cc2f8ab5334a736fa0e775cfccf06c1e268667f0]
Roger Quadros (1): mtd: nand: omap2: Fix subpage write [739c64414f01748a36e7d82c8e0611dea94412bd]
Roman Kapl (1): drm/radeon: fix atombios on big endian [4f626a4ac8f57ddabf06d03870adab91e463217f]
Sean Young (1): media: rc: check for integer overflow [3e45067f94bbd61dec0619b1c32744eb0de480c8]
Shriya (1): powerpc/powernv/cpufreq: Fix the frequency read by /proc/cpuinfo [cd77b5ce208c153260ed7882d8910f2395bfaabd]
Shuah Khan (4): usbip: fix stub_rx: get_pipe() to validate endpoint number [635f545a7e8be7596b9b2b6a43cab6bbd5a88e43] usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input [c6688ef9f29762e65bce325ef4acd6c675806366] usbip: fix stub_send_ret_submit() vulnerability to null transfer_buffer [be6123df1ea8f01ee2f896a16c2b7be3e4557a5a] usbip: prevent vhci_hcd driver from leaking a socket pointer address [2f2d0088eb93db5c649d2a5e34a3800a8a935fc5]
Stanislaw Gruszka (1): rt2x00usb: mark device removed when get ENOENT usb error [bfa62a52cad93686bb8d8171ea5288813248a7c6]
Takashi Iwai (6): ALSA: seq: Make ioctls race-free [b3defb791b26ea0683a93a4f49c77ec45ec96f10] ALSA: timer: Remove kernel warning at compat ioctl error paths [3d4e8303f2c747c8540a0a0126d0151514f6468b] ALSA: usb-audio: Add sanity checks in v2 clock parsers [0a62d6c966956d77397c32836a5bbfe3af786fc1] ALSA: usb-audio: Add sanity checks to FE parser [d937cd6790a2bef2d07b500487646bd794c039bb] ALSA: usb-audio: Fix potential out-of-bound access at parsing SU [f658f17b5e0e339935dca23e77e0f3cad591926b] ALSA: usb-audio: Fix potential zero-division at parsing FU [8428a8ebde2db1e988e41a58497a28beb7ce1705]
Theodore Ts'o (1): ext4: fix interaction between i_size, fallocate, and delalloc after a crash [51e3ae81ec58e95f10a98ef3dd6d7bce5d8e35a2]
Tuomas Tynkkynen (2): fs/9p: Compare qid.path in v9fs_test_inode [8ee031631546cf2f7859cc69593bd60bbdd70b46] net/9p: Switch to wait_event_killable() [9523feac272ccad2ad8186ba4fcc89103754de52]
Tyrel Datwyler (1): powerpc/pseries/vio: Dispose of virq mapping on vdevice unregister [b8f89fea599d91e674497aad572613eb63181f31]
Vasily Gorbik (1): s390/disassembler: increase show_code buffer size [b192571d1ae375e0bbe0aa3ccfa1a3c3704454b9]
Vijendar Mukunda (1): ALSA: hda: Add Raven PCI ID [9ceace3c9c18c67676e75141032a65a8e01f9a7a]
Viktor Slavkovic (1): staging: android: ashmem: fix a race condition in ASHMEM_SET_SIZE ioctl [443064cb0b1fb4569fe0a71209da7625129fb760]
Ville Syrjälä (1): drm/i915: Read timings from the correct transcoder in intel_crtc_mode_get() [e30a154b5262b967b133b06ac40777e651045898]
Waiman Long (1): blktrace: Fix potential deadlock between delete & sysfs ops [5acb3cc2c2e9d3020a4fee43763c6463767f1572]
William A. Kennington III (1): powerpc/opal: Fix EBUSY bug in acquiring tokens [71e24d7731a2903b1ae2bba2b2971c654d9c2aa6]
Xin Long (2): route: also update fnhe_genid when updating a route cache [cebe84c6190d741045a322f5343f717139993c08] route: update fnhe_expires for redirect when the fnhe exists [e39d5246111399dbc6e11cd39fd8580191b86c47]
Yunlong Song (1): Revert "f2fs: handle dirty segments inside refresh_sit_entry" [65f1b80b33378501ea552ef085e9c31739af356c]
Zhou Chengming (1): kprobes, x86/alternatives: Use text_mutex to protect smp_alt_modules [e846d13958066828a9483d862cc8370a72fadbb6]
.../devicetree/bindings/sound/cs42l56.txt | 2 +- Makefile | 4 +- arch/arm/mm/dump.c | 4 +- arch/arm64/kernel/vdso/gettimeofday.S | 3 +- arch/mips/kernel/ptrace.c | 17 ++ arch/parisc/kernel/syscall.S | 6 +- arch/powerpc/kernel/vio.c | 2 + arch/powerpc/platforms/powernv/opal-async.c | 6 +- arch/powerpc/platforms/powernv/setup.c | 2 +- arch/s390/include/asm/switch_to.h | 2 +- arch/s390/kernel/dis.c | 4 +- arch/s390/kernel/early.c | 4 +- arch/s390/kernel/process.c | 1 + arch/s390/kernel/runtime_instr.c | 4 +- arch/x86/include/asm/fixmap.h | 11 +- arch/x86/include/asm/pvclock.h | 15 +- arch/x86/include/asm/vdso.h | 19 +- arch/x86/kernel/alternative.c | 26 +- arch/x86/kernel/kvmclock.c | 16 +- arch/x86/kernel/pvclock.c | 68 ----- arch/x86/kvm/svm.c | 7 + arch/x86/kvm/vmx.c | 4 + arch/x86/kvm/x86.c | 5 +- arch/x86/kvm/x86.h | 2 + arch/x86/lib/x86-opcode-map.txt | 2 +- arch/x86/mm/kaiser.c | 7 +- arch/x86/platform/uv/uv_nmi.c | 1 + arch/x86/vdso/vclock_gettime.c | 103 ++++--- arch/x86/vdso/vdso-layout.lds.S | 45 ++- arch/x86/vdso/vdso2c.c | 15 +- arch/x86/vdso/vdso2c.h | 25 +- arch/x86/vdso/vma.c | 34 ++- block/blk-core.c | 3 + drivers/acpi/apei/ghes.c | 85 +----- drivers/char/ipmi/ipmi_msghandler.c | 10 +- drivers/char/tpm/tpm-dev.c | 6 + drivers/clk/tegra/clk-tegra30.c | 2 +- drivers/clk/ti/clk-dra7-atl.c | 3 +- drivers/crypto/caam/desc.h | 2 +- drivers/gpu/drm/gma500/mdfld_intel_display.c | 2 +- drivers/gpu/drm/i915/intel_bios.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 14 +- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/radeon/atombios_dp.c | 38 ++- drivers/gpu/drm/ttm/ttm_bo_util.c | 1 + drivers/infiniband/hw/mlx4/qp.c | 2 +- drivers/infiniband/hw/mlx5/main.c | 2 + drivers/infiniband/ulp/srp/ib_srp.c | 23 +- drivers/infiniband/ulp/srpt/ib_srpt.c | 9 +- drivers/input/misc/adxl34x.c | 2 +- drivers/iommu/dmar.c | 7 +- drivers/iommu/intel-iommu.c | 10 + drivers/md/bcache/alloc.c | 3 +- drivers/md/bcache/request.c | 10 +- drivers/md/dm-bufio.c | 15 +- drivers/md/dm-table.c | 32 +- drivers/md/dm.c | 12 +- drivers/media/platform/omap/omap_vout.c | 3 +- drivers/media/rc/ir-lirc-codec.c | 9 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 3 +- drivers/mtd/nand/nand_base.c | 9 +- drivers/mtd/nand/omap2.c | 340 ++++++++++++++------- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 56 +--- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- drivers/net/ethernet/intel/igbvf/netdev.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/wireless/p54/main.c | 7 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +- drivers/pci/pcie/aer/aerdrv_core.c | 9 +- drivers/platform/x86/sony-laptop.c | 14 +- drivers/rtc/interface.c | 16 +- drivers/scsi/bfa/bfad_debugfs.c | 5 +- drivers/staging/android/ashmem.c | 2 + drivers/staging/lustre/lustre/ptlrpc/sec.c | 2 +- drivers/staging/rtl8188eu/core/rtw_mlme.c | 3 +- drivers/staging/usbip/stub.h | 1 - drivers/staging/usbip/stub_dev.c | 4 +- drivers/staging/usbip/stub_rx.c | 66 ++-- drivers/staging/usbip/stub_tx.c | 13 +- drivers/staging/usbip/usbip_common.h | 1 + drivers/staging/usbip/userspace/Makefile.am | 3 +- .../staging/usbip/userspace/libsrc/vhci_driver.c | 8 +- drivers/staging/usbip/vhci_sysfs.c | 20 +- drivers/target/iscsi/iscsi_target.c | 49 ++- drivers/target/target_core_tmr.c | 10 + drivers/target/target_core_transport.c | 2 + drivers/usb/core/devio.c | 14 + drivers/usb/core/quirks.c | 3 + drivers/usb/serial/garmin_gps.c | 22 +- drivers/usb/serial/metro-usb.c | 11 +- drivers/usb/serial/qcserial.c | 1 + drivers/video/fbdev/udlfb.c | 10 +- fs/9p/vfs_inode.c | 3 + fs/9p/vfs_inode_dotl.c | 3 + fs/autofs4/waitq.c | 16 +- fs/binfmt_elf_fdpic.c | 2 + fs/btrfs/super.c | 4 +- fs/coda/upcall.c | 3 +- fs/ecryptfs/messaging.c | 7 +- fs/ext4/extents.c | 6 +- fs/f2fs/file.c | 5 + fs/f2fs/segment.c | 20 +- fs/isofs/isofs.h | 2 +- fs/isofs/rock.h | 2 +- fs/isofs/util.c | 2 +- fs/nfs/nfs4proc.c | 18 +- fs/nfs/nfs4trace.h | 8 +- fs/nfs/super.c | 2 +- fs/nilfs2/segment.c | 6 +- fs/ocfs2/file.c | 9 +- include/linux/blkdev.h | 1 + include/linux/dmar.h | 1 + include/linux/sched.h | 8 - include/net/sctp/sctp.h | 2 + include/net/sctp/structs.h | 8 +- include/target/target_core_base.h | 2 + kernel/extable.c | 2 + kernel/sched/core.c | 15 - kernel/trace/blktrace.c | 76 ++++- lib/int_sqrt.c | 3 + net/9p/client.c | 3 +- net/9p/trans_virtio.c | 13 +- net/bluetooth/l2cap_core.c | 20 +- net/ipv4/route.c | 14 +- net/l2tp/l2tp_core.c | 21 +- net/l2tp/l2tp_core.h | 3 + net/l2tp/l2tp_eth.c | 101 ++++-- net/l2tp/l2tp_ppp.c | 236 ++++++++------ net/netfilter/xt_TCPMSS.c | 6 +- net/nfc/core.c | 2 +- net/rds/rdma.c | 4 + net/sctp/ipv6.c | 160 +++++----- net/sctp/protocol.c | 12 +- net/sctp/socket.c | 33 +- net/sctp/transport.c | 4 +- net/sctp/ulpevent.c | 2 +- net/wireless/nl80211.c | 26 +- security/apparmor/domain.c | 53 +++- security/integrity/ima/ima_main.c | 4 + sound/core/seq/seq_clientmgr.c | 10 +- sound/core/seq/seq_clientmgr.h | 1 + sound/core/timer_compat.c | 12 +- sound/pci/hda/hda_intel.c | 3 + sound/usb/clock.c | 9 +- sound/usb/mixer.c | 19 +- 149 files changed, 1480 insertions(+), 1026 deletions(-)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros rogerq@ti.com
commit 739c64414f01748a36e7d82c8e0611dea94412bd upstream.
Since v4.12, NAND subpage writes were causing a NULL pointer dereference on OMAP platforms (omap2-nand) using OMAP_ECC_BCH4_CODE_HW, OMAP_ECC_BCH8_CODE_HW and OMAP_ECC_BCH16_CODE_HW.
This is because for those ECC modes, omap_calculate_ecc_bch() generates ECC bytes for the entire (multi-sector) page and this can overflow the ECC buffer provided by nand_write_subpage_hwecc() as it expects ecc.calculate() to return ECC bytes for just one sector.
However, the root cause of the problem is present since v3.9 but was not seen then as NAND buffers were being allocated as one big chunk prior to commit 3deb9979c731 ("mtd: nand: allocate aligned buffers if NAND_OWN_BUFFERS is unset").
Fix the issue by providing a OMAP optimized write_subpage() implementation.
Fixes: 62116e5171e0 ("mtd: nand: omap2: Support for hardware BCH error correction.") Signed-off-by: Roger Quadros rogerq@ti.com Signed-off-by: Boris Brezillon boris.brezillon@free-electrons.com [bwh: Backported to 3.16: - Open-code mtd_to_omap() - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1163,130 +1163,174 @@ static u8 bch8_polynomial[] = {0xef, 0x 0x97, 0x79, 0xe5, 0x24, 0xb5};
/** - * omap_calculate_ecc_bch - Generate bytes of ECC bytes + * _omap_calculate_ecc_bch - Generate ECC bytes for one sector * @mtd: MTD device structure * @dat: The pointer to data on which ecc is computed * @ecc_code: The ecc_code buffer + * @i: The sector number (for a multi sector page) * - * Support calculating of BCH4/8 ecc vectors for the page + * Support calculating of BCH4/8/16 ECC vectors for one sector + * within a page. Sector number is in @i. */ -static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, - const u_char *dat, u_char *ecc_calc) +static int _omap_calculate_ecc_bch(struct mtd_info *mtd, + const u_char *dat, u_char *ecc_calc, int i) { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); int eccbytes = info->nand.ecc.bytes; struct gpmc_nand_regs *gpmc_regs = &info->reg; u8 *ecc_code; - unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; + unsigned long bch_val1, bch_val2, bch_val3, bch_val4; u32 val; - int i, j; + int j; + + ecc_code = ecc_calc; + switch (info->ecc_opt) { + case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: + case OMAP_ECC_BCH8_CODE_HW: + bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); + bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); + bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]); + bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]); + *ecc_code++ = (bch_val4 & 0xFF); + *ecc_code++ = ((bch_val3 >> 24) & 0xFF); + *ecc_code++ = ((bch_val3 >> 16) & 0xFF); + *ecc_code++ = ((bch_val3 >> 8) & 0xFF); + *ecc_code++ = (bch_val3 & 0xFF); + *ecc_code++ = ((bch_val2 >> 24) & 0xFF); + *ecc_code++ = ((bch_val2 >> 16) & 0xFF); + *ecc_code++ = ((bch_val2 >> 8) & 0xFF); + *ecc_code++ = (bch_val2 & 0xFF); + *ecc_code++ = ((bch_val1 >> 24) & 0xFF); + *ecc_code++ = ((bch_val1 >> 16) & 0xFF); + *ecc_code++ = ((bch_val1 >> 8) & 0xFF); + *ecc_code++ = (bch_val1 & 0xFF); + break; + case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: + case OMAP_ECC_BCH4_CODE_HW: + bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); + bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); + *ecc_code++ = ((bch_val2 >> 12) & 0xFF); + *ecc_code++ = ((bch_val2 >> 4) & 0xFF); + *ecc_code++ = ((bch_val2 & 0xF) << 4) | + ((bch_val1 >> 28) & 0xF); + *ecc_code++ = ((bch_val1 >> 20) & 0xFF); + *ecc_code++ = ((bch_val1 >> 12) & 0xFF); + *ecc_code++ = ((bch_val1 >> 4) & 0xFF); + *ecc_code++ = ((bch_val1 & 0xF) << 4); + break; + case OMAP_ECC_BCH16_CODE_HW: + val = readl(gpmc_regs->gpmc_bch_result6[i]); + ecc_code[0] = ((val >> 8) & 0xFF); + ecc_code[1] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result5[i]); + ecc_code[2] = ((val >> 24) & 0xFF); + ecc_code[3] = ((val >> 16) & 0xFF); + ecc_code[4] = ((val >> 8) & 0xFF); + ecc_code[5] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result4[i]); + ecc_code[6] = ((val >> 24) & 0xFF); + ecc_code[7] = ((val >> 16) & 0xFF); + ecc_code[8] = ((val >> 8) & 0xFF); + ecc_code[9] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result3[i]); + ecc_code[10] = ((val >> 24) & 0xFF); + ecc_code[11] = ((val >> 16) & 0xFF); + ecc_code[12] = ((val >> 8) & 0xFF); + ecc_code[13] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result2[i]); + ecc_code[14] = ((val >> 24) & 0xFF); + ecc_code[15] = ((val >> 16) & 0xFF); + ecc_code[16] = ((val >> 8) & 0xFF); + ecc_code[17] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result1[i]); + ecc_code[18] = ((val >> 24) & 0xFF); + ecc_code[19] = ((val >> 16) & 0xFF); + ecc_code[20] = ((val >> 8) & 0xFF); + ecc_code[21] = ((val >> 0) & 0xFF); + val = readl(gpmc_regs->gpmc_bch_result0[i]); + ecc_code[22] = ((val >> 24) & 0xFF); + ecc_code[23] = ((val >> 16) & 0xFF); + ecc_code[24] = ((val >> 8) & 0xFF); + ecc_code[25] = ((val >> 0) & 0xFF); + break; + default: + return -EINVAL; + } + + /* ECC scheme specific syndrome customizations */ + switch (info->ecc_opt) { + case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: + /* Add constant polynomial to remainder, so that + * ECC of blank pages results in 0x0 on reading back + */ + for (j = 0; j < eccbytes; j++) + ecc_calc[j] ^= bch4_polynomial[j]; + break; + case OMAP_ECC_BCH4_CODE_HW: + /* Set 8th ECC byte as 0x0 for ROM compatibility */ + ecc_calc[eccbytes - 1] = 0x0; + break; + case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: + /* Add constant polynomial to remainder, so that + * ECC of blank pages results in 0x0 on reading back + */ + for (j = 0; j < eccbytes; j++) + ecc_calc[j] ^= bch8_polynomial[j]; + break; + case OMAP_ECC_BCH8_CODE_HW: + /* Set 14th ECC byte as 0x0 for ROM compatibility */ + ecc_calc[eccbytes - 1] = 0x0; + break; + case OMAP_ECC_BCH16_CODE_HW: + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction + * @mtd: MTD device structure + * @dat: The pointer to data on which ecc is computed + * @ecc_code: The ecc_code buffer + * + * Support calculating of BCH4/8/16 ECC vectors for one sector. This is used + * when SW based correction is required as ECC is required for one sector + * at a time. + */ +static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd, + const u_char *dat, u_char *ecc_calc) +{ + return _omap_calculate_ecc_bch(mtd, dat, ecc_calc, 0); +} + +/** + * omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors + * @mtd: MTD device structure + * @dat: The pointer to data on which ecc is computed + * @ecc_code: The ecc_code buffer + * + * Support calculating of BCH4/8/16 ecc vectors for the entire page in one go. + */ +static int omap_calculate_ecc_bch_multi(struct mtd_info *mtd, + const u_char *dat, u_char *ecc_calc) +{ + struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, + mtd); + int eccbytes = info->nand.ecc.bytes; + unsigned long nsectors; + int i, ret;
nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; for (i = 0; i < nsectors; i++) { - ecc_code = ecc_calc; - switch (info->ecc_opt) { - case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: - case OMAP_ECC_BCH8_CODE_HW: - bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); - bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); - bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]); - bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]); - *ecc_code++ = (bch_val4 & 0xFF); - *ecc_code++ = ((bch_val3 >> 24) & 0xFF); - *ecc_code++ = ((bch_val3 >> 16) & 0xFF); - *ecc_code++ = ((bch_val3 >> 8) & 0xFF); - *ecc_code++ = (bch_val3 & 0xFF); - *ecc_code++ = ((bch_val2 >> 24) & 0xFF); - *ecc_code++ = ((bch_val2 >> 16) & 0xFF); - *ecc_code++ = ((bch_val2 >> 8) & 0xFF); - *ecc_code++ = (bch_val2 & 0xFF); - *ecc_code++ = ((bch_val1 >> 24) & 0xFF); - *ecc_code++ = ((bch_val1 >> 16) & 0xFF); - *ecc_code++ = ((bch_val1 >> 8) & 0xFF); - *ecc_code++ = (bch_val1 & 0xFF); - break; - case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: - case OMAP_ECC_BCH4_CODE_HW: - bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); - bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); - *ecc_code++ = ((bch_val2 >> 12) & 0xFF); - *ecc_code++ = ((bch_val2 >> 4) & 0xFF); - *ecc_code++ = ((bch_val2 & 0xF) << 4) | - ((bch_val1 >> 28) & 0xF); - *ecc_code++ = ((bch_val1 >> 20) & 0xFF); - *ecc_code++ = ((bch_val1 >> 12) & 0xFF); - *ecc_code++ = ((bch_val1 >> 4) & 0xFF); - *ecc_code++ = ((bch_val1 & 0xF) << 4); - break; - case OMAP_ECC_BCH16_CODE_HW: - val = readl(gpmc_regs->gpmc_bch_result6[i]); - ecc_code[0] = ((val >> 8) & 0xFF); - ecc_code[1] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result5[i]); - ecc_code[2] = ((val >> 24) & 0xFF); - ecc_code[3] = ((val >> 16) & 0xFF); - ecc_code[4] = ((val >> 8) & 0xFF); - ecc_code[5] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result4[i]); - ecc_code[6] = ((val >> 24) & 0xFF); - ecc_code[7] = ((val >> 16) & 0xFF); - ecc_code[8] = ((val >> 8) & 0xFF); - ecc_code[9] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result3[i]); - ecc_code[10] = ((val >> 24) & 0xFF); - ecc_code[11] = ((val >> 16) & 0xFF); - ecc_code[12] = ((val >> 8) & 0xFF); - ecc_code[13] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result2[i]); - ecc_code[14] = ((val >> 24) & 0xFF); - ecc_code[15] = ((val >> 16) & 0xFF); - ecc_code[16] = ((val >> 8) & 0xFF); - ecc_code[17] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result1[i]); - ecc_code[18] = ((val >> 24) & 0xFF); - ecc_code[19] = ((val >> 16) & 0xFF); - ecc_code[20] = ((val >> 8) & 0xFF); - ecc_code[21] = ((val >> 0) & 0xFF); - val = readl(gpmc_regs->gpmc_bch_result0[i]); - ecc_code[22] = ((val >> 24) & 0xFF); - ecc_code[23] = ((val >> 16) & 0xFF); - ecc_code[24] = ((val >> 8) & 0xFF); - ecc_code[25] = ((val >> 0) & 0xFF); - break; - default: - return -EINVAL; - } - - /* ECC scheme specific syndrome customizations */ - switch (info->ecc_opt) { - case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: - /* Add constant polynomial to remainder, so that - * ECC of blank pages results in 0x0 on reading back */ - for (j = 0; j < eccbytes; j++) - ecc_calc[j] ^= bch4_polynomial[j]; - break; - case OMAP_ECC_BCH4_CODE_HW: - /* Set 8th ECC byte as 0x0 for ROM compatibility */ - ecc_calc[eccbytes - 1] = 0x0; - break; - case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: - /* Add constant polynomial to remainder, so that - * ECC of blank pages results in 0x0 on reading back */ - for (j = 0; j < eccbytes; j++) - ecc_calc[j] ^= bch8_polynomial[j]; - break; - case OMAP_ECC_BCH8_CODE_HW: - /* Set 14th ECC byte as 0x0 for ROM compatibility */ - ecc_calc[eccbytes - 1] = 0x0; - break; - case OMAP_ECC_BCH16_CODE_HW: - break; - default: - return -EINVAL; - } + ret = _omap_calculate_ecc_bch(mtd, dat, ecc_calc, i); + if (ret) + return ret;
- ecc_calc += eccbytes; + ecc_calc += eccbytes; }
return 0; @@ -1527,7 +1571,7 @@ static int omap_write_page_bch(struct mt chip->write_buf(mtd, buf, mtd->writesize);
/* Update ecc vector from GPMC result registers */ - chip->ecc.calculate(mtd, buf, &ecc_calc[0]); + omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
for (i = 0; i < chip->ecc.total; i++) chip->oob_poi[eccpos[i]] = ecc_calc[i]; @@ -1538,6 +1582,72 @@ static int omap_write_page_bch(struct mt }
/** + * omap_write_subpage_bch - BCH hardware ECC based subpage write + * @mtd: mtd info structure + * @chip: nand chip info structure + * @offset: column address of subpage within the page + * @data_len: data length + * @buf: data buffer + * @oob_required: must write chip->oob_poi to OOB + * @page: page number to write + * + * OMAP optimized subpage write method. + */ +static int omap_write_subpage_bch(struct mtd_info *mtd, + struct nand_chip *chip, u32 offset, + u32 data_len, const u8 *buf, + int oob_required, int page) +{ + u8 *ecc_calc = chip->buffers->ecccalc; + int ecc_size = chip->ecc.size; + int ecc_bytes = chip->ecc.bytes; + int ecc_steps = chip->ecc.steps; + u32 start_step = offset / ecc_size; + u32 end_step = (offset + data_len - 1) / ecc_size; + int step, ret = 0; + + /* + * Write entire page at one go as it would be optimal + * as ECC is calculated by hardware. + * ECC is calculated for all subpages but we choose + * only what we want. + */ + + /* Enable GPMC ECC engine */ + chip->ecc.hwctl(mtd, NAND_ECC_WRITE); + + /* Write data */ + chip->write_buf(mtd, buf, mtd->writesize); + + for (step = 0; step < ecc_steps; step++) { + /* mask ECC of un-touched subpages by padding 0xFF */ + if (step < start_step || step > end_step) + memset(ecc_calc, 0xff, ecc_bytes); + else + ret = _omap_calculate_ecc_bch(mtd, buf, ecc_calc, step); + + if (ret) + return ret; + + buf += ecc_size; + ecc_calc += ecc_bytes; + } + + /* copy calculated ECC for whole page to chip->buffer->oob */ + /* this include masked-value(0xFF) for unwritten subpages */ + ecc_calc = chip->buffers->ecccalc; + ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0, + chip->ecc.total); + if (ret) + return ret; + + /* write OOB buffer to NAND device */ + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); + + return 0; +} + +/** * omap_read_page_bch - BCH ecc based page read function for entire page * @mtd: mtd info structure * @chip: nand chip info structure @@ -1574,7 +1684,7 @@ static int omap_read_page_bch(struct mtd chip->read_buf(mtd, oob, chip->ecc.total);
/* Calculate ecc bytes */ - chip->ecc.calculate(mtd, buf, ecc_calc); + omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
@@ -1823,7 +1933,7 @@ static int omap_nand_probe(struct platfo nand_chip->ecc.strength = 4; nand_chip->ecc.hwctl = omap_enable_hwecc_bch; nand_chip->ecc.correct = nand_bch_correct_data; - nand_chip->ecc.calculate = omap_calculate_ecc_bch; + nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw; /* define ECC layout */ ecclayout->eccbytes = nand_chip->ecc.bytes * (mtd->writesize / @@ -1863,9 +1973,9 @@ static int omap_nand_probe(struct platfo nand_chip->ecc.strength = 4; nand_chip->ecc.hwctl = omap_enable_hwecc_bch; nand_chip->ecc.correct = omap_elm_correct_data; - nand_chip->ecc.calculate = omap_calculate_ecc_bch; nand_chip->ecc.read_page = omap_read_page_bch; nand_chip->ecc.write_page = omap_write_page_bch; + nand_chip->ecc.write_subpage = omap_write_subpage_bch; /* define ECC layout */ ecclayout->eccbytes = nand_chip->ecc.bytes * (mtd->writesize / @@ -1898,7 +2008,7 @@ static int omap_nand_probe(struct platfo nand_chip->ecc.strength = 8; nand_chip->ecc.hwctl = omap_enable_hwecc_bch; nand_chip->ecc.correct = nand_bch_correct_data; - nand_chip->ecc.calculate = omap_calculate_ecc_bch; + nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw; /* define ECC layout */ ecclayout->eccbytes = nand_chip->ecc.bytes * (mtd->writesize / @@ -1939,9 +2049,9 @@ static int omap_nand_probe(struct platfo nand_chip->ecc.strength = 8; nand_chip->ecc.hwctl = omap_enable_hwecc_bch; nand_chip->ecc.correct = omap_elm_correct_data; - nand_chip->ecc.calculate = omap_calculate_ecc_bch; nand_chip->ecc.read_page = omap_read_page_bch; nand_chip->ecc.write_page = omap_write_page_bch; + nand_chip->ecc.write_subpage = omap_write_subpage_bch; /* This ECC scheme requires ELM H/W block */ err = is_elm_present(info, pdata->elm_of_node, BCH8_ECC); if (err < 0) { @@ -1974,9 +2084,9 @@ static int omap_nand_probe(struct platfo nand_chip->ecc.strength = 16; nand_chip->ecc.hwctl = omap_enable_hwecc_bch; nand_chip->ecc.correct = omap_elm_correct_data; - nand_chip->ecc.calculate = omap_calculate_ecc_bch; nand_chip->ecc.read_page = omap_read_page_bch; nand_chip->ecc.write_page = omap_write_page_bch; + nand_chip->ecc.write_subpage = omap_write_subpage_bch; /* This ECC scheme requires ELM H/W block */ err = is_elm_present(info, pdata->elm_of_node, BCH16_ECC); if (err < 0) {
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Potapenko glider@google.com
commit 15339e441ec46fbc3bf3486bb1ae4845b0f1bb8d upstream.
KMSAN reported use of uninitialized sctp_addr->v4.sin_addr.s_addr and sctp_addr->v6.sin6_scope_id in sctp_v6_cmp_addr() (see below). Make sure all fields of an IPv6 address are initialized, which guarantees that the IPv4 fields are also initialized.
================================================================== BUG: KMSAN: use of uninitialized memory in sctp_v6_cmp_addr+0x8d4/0x9f0 net/sctp/ipv6.c:517 CPU: 2 PID: 31056 Comm: syz-executor1 Not tainted 4.11.0-rc5+ #2944 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: dump_stack+0x172/0x1c0 lib/dump_stack.c:42 is_logbuf_locked mm/kmsan/kmsan.c:59 [inline] kmsan_report+0x12a/0x180 mm/kmsan/kmsan.c:938 native_save_fl arch/x86/include/asm/irqflags.h:18 [inline] arch_local_save_flags arch/x86/include/asm/irqflags.h:72 [inline] arch_local_irq_save arch/x86/include/asm/irqflags.h:113 [inline] __msan_warning_32+0x61/0xb0 mm/kmsan/kmsan_instr.c:467 sctp_v6_cmp_addr+0x8d4/0x9f0 net/sctp/ipv6.c:517 sctp_v6_get_dst+0x8c7/0x1630 net/sctp/ipv6.c:290 sctp_transport_route+0x101/0x570 net/sctp/transport.c:292 sctp_assoc_add_peer+0x66d/0x16f0 net/sctp/associola.c:651 sctp_sendmsg+0x35a5/0x4f90 net/sctp/socket.c:1871 inet_sendmsg+0x498/0x670 net/ipv4/af_inet.c:762 sock_sendmsg_nosec net/socket.c:633 [inline] sock_sendmsg net/socket.c:643 [inline] SYSC_sendto+0x608/0x710 net/socket.c:1696 SyS_sendto+0x8a/0xb0 net/socket.c:1664 entry_SYSCALL_64_fastpath+0x13/0x94 RIP: 0033:0x44b479 RSP: 002b:00007f6213f21c08 EFLAGS: 00000286 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000020000000 RCX: 000000000044b479 RDX: 0000000000000041 RSI: 0000000020edd000 RDI: 0000000000000006 RBP: 00000000007080a8 R08: 0000000020b85fe4 R09: 000000000000001c R10: 0000000000040005 R11: 0000000000000286 R12: 00000000ffffffff R13: 0000000000003760 R14: 00000000006e5820 R15: 0000000000ff8000 origin description: ----dst_saddr@sctp_v6_get_dst local variable created at: sk_fullsock include/net/sock.h:2321 [inline] inet6_sk include/linux/ipv6.h:309 [inline] sctp_v6_get_dst+0x91/0x1630 net/sctp/ipv6.c:241 sctp_transport_route+0x101/0x570 net/sctp/transport.c:292 ================================================================== BUG: KMSAN: use of uninitialized memory in sctp_v6_cmp_addr+0x8d4/0x9f0 net/sctp/ipv6.c:517 CPU: 2 PID: 31056 Comm: syz-executor1 Not tainted 4.11.0-rc5+ #2944 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: dump_stack+0x172/0x1c0 lib/dump_stack.c:42 is_logbuf_locked mm/kmsan/kmsan.c:59 [inline] kmsan_report+0x12a/0x180 mm/kmsan/kmsan.c:938 native_save_fl arch/x86/include/asm/irqflags.h:18 [inline] arch_local_save_flags arch/x86/include/asm/irqflags.h:72 [inline] arch_local_irq_save arch/x86/include/asm/irqflags.h:113 [inline] __msan_warning_32+0x61/0xb0 mm/kmsan/kmsan_instr.c:467 sctp_v6_cmp_addr+0x8d4/0x9f0 net/sctp/ipv6.c:517 sctp_v6_get_dst+0x8c7/0x1630 net/sctp/ipv6.c:290 sctp_transport_route+0x101/0x570 net/sctp/transport.c:292 sctp_assoc_add_peer+0x66d/0x16f0 net/sctp/associola.c:651 sctp_sendmsg+0x35a5/0x4f90 net/sctp/socket.c:1871 inet_sendmsg+0x498/0x670 net/ipv4/af_inet.c:762 sock_sendmsg_nosec net/socket.c:633 [inline] sock_sendmsg net/socket.c:643 [inline] SYSC_sendto+0x608/0x710 net/socket.c:1696 SyS_sendto+0x8a/0xb0 net/socket.c:1664 entry_SYSCALL_64_fastpath+0x13/0x94 RIP: 0033:0x44b479 RSP: 002b:00007f6213f21c08 EFLAGS: 00000286 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000020000000 RCX: 000000000044b479 RDX: 0000000000000041 RSI: 0000000020edd000 RDI: 0000000000000006 RBP: 00000000007080a8 R08: 0000000020b85fe4 R09: 000000000000001c R10: 0000000000040005 R11: 0000000000000286 R12: 00000000ffffffff R13: 0000000000003760 R14: 00000000006e5820 R15: 0000000000ff8000 origin description: ----dst_saddr@sctp_v6_get_dst local variable created at: sk_fullsock include/net/sock.h:2321 [inline] inet6_sk include/linux/ipv6.h:309 [inline] sctp_v6_get_dst+0x91/0x1630 net/sctp/ipv6.c:241 sctp_transport_route+0x101/0x570 net/sctp/transport.c:292 ==================================================================
Signed-off-by: Alexander Potapenko glider@google.com Reviewed-by: Xin Long lucien.xin@gmail.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/sctp/ipv6.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -491,7 +491,9 @@ static void sctp_v6_to_addr(union sctp_a { addr->sa.sa_family = AF_INET6; addr->v6.sin6_port = port; + addr->v6.sin6_flowinfo = 0; addr->v6.sin6_addr = *saddr; + addr->v6.sin6_scope_id = 0; }
/* Compare addresses exactly.
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Konovalov andreyknvl@google.com
commit fc09785de0a364427a5df63d703bae9a306ed116 upstream.
ieee80211_register_hw() in p54_register_common() may fail and leds won't get initialized. Currently p54_unregister_common() doesn't check that and always calls p54_unregister_leds(). The fix is to check priv->registered flag before calling p54_unregister_leds().
Found by syzkaller.
INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 1 PID: 1404 Comm: kworker/1:1 Not tainted 4.14.0-rc1-42251-gebb2c2437d80-dirty #205 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:16 dump_stack+0x292/0x395 lib/dump_stack.c:52 register_lock_class+0x6c4/0x1a00 kernel/locking/lockdep.c:769 __lock_acquire+0x27e/0x4550 kernel/locking/lockdep.c:3385 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 flush_work+0xf0/0x8c0 kernel/workqueue.c:2886 __cancel_work_timer+0x51d/0x870 kernel/workqueue.c:2961 cancel_delayed_work_sync+0x1f/0x30 kernel/workqueue.c:3081 p54_unregister_leds+0x6c/0xc0 drivers/net/wireless/intersil/p54/led.c:160 p54_unregister_common+0x3d/0xb0 drivers/net/wireless/intersil/p54/main.c:856 p54u_disconnect+0x86/0x120 drivers/net/wireless/intersil/p54/p54usb.c:1073 usb_unbind_interface+0x21c/0xa90 drivers/usb/core/driver.c:423 __device_release_driver drivers/base/dd.c:861 device_release_driver_internal+0x4f4/0x5c0 drivers/base/dd.c:893 device_release_driver+0x1e/0x30 drivers/base/dd.c:918 bus_remove_device+0x2f4/0x4b0 drivers/base/bus.c:565 device_del+0x5c4/0xab0 drivers/base/core.c:1985 usb_disable_device+0x1e9/0x680 drivers/usb/core/message.c:1170 usb_disconnect+0x260/0x7a0 drivers/usb/core/hub.c:2124 hub_port_connect drivers/usb/core/hub.c:4754 hub_port_connect_change drivers/usb/core/hub.c:5009 port_event drivers/usb/core/hub.c:5115 hub_event+0x1318/0x3740 drivers/usb/core/hub.c:5195 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119 process_scheduled_works kernel/workqueue.c:2179 worker_thread+0xb2b/0x1850 kernel/workqueue.c:2255 kthread+0x3a1/0x470 kernel/kthread.c:231 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
Signed-off-by: Andrey Konovalov andreyknvl@google.com Acked-by: Christian Lamparter chunkeey@googlemail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org [bwh: Backported to 3.16: adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/wireless/p54/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -851,12 +851,11 @@ void p54_unregister_common(struct ieee80 { struct p54_common *priv = dev->priv;
-#ifdef CONFIG_P54_LEDS - p54_unregister_leds(priv); -#endif /* CONFIG_P54_LEDS */ - if (priv->registered) { priv->registered = false; +#ifdef CONFIG_P54_LEDS + p54_unregister_leds(priv); +#endif /* CONFIG_P54_LEDS */ ieee80211_unregister_hw(dev); }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long longman@redhat.com
commit 5acb3cc2c2e9d3020a4fee43763c6463767f1572 upstream.
The lockdep code had reported the following unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(s_active#228); lock(&bdev->bd_mutex/1); lock(s_active#228); lock(&bdev->bd_mutex);
*** DEADLOCK ***
The deadlock may happen when one task (CPU1) is trying to delete a partition in a block device and another task (CPU0) is accessing tracing sysfs file (e.g. /sys/block/dm-1/trace/act_mask) in that partition.
The s_active isn't an actual lock. It is a reference count (kn->count) on the sysfs (kernfs) file. Removal of a sysfs file, however, require a wait until all the references are gone. The reference count is treated like a rwsem using lockdep instrumentation code.
The fact that a thread is in the sysfs callback method or in the ioctl call means there is a reference to the opended sysfs or device file. That should prevent the underlying block structure from being removed.
Instead of using bd_mutex in the block_device structure, a new blk_trace_mutex is now added to the request_queue structure to protect access to the blk_trace structure.
Suggested-by: Christoph Hellwig hch@infradead.org Signed-off-by: Waiman Long longman@redhat.com Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org
Fix typo in patch subject line, and prune a comment detailing how the code used to work.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- block/blk-core.c | 3 +++ include/linux/blkdev.h | 1 + kernel/trace/blktrace.c | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-)
--- a/block/blk-core.c +++ b/block/blk-core.c @@ -611,6 +611,9 @@ struct request_queue *blk_alloc_queue_no
kobject_init(&q->kobj, &blk_queue_ktype);
+#ifdef CONFIG_BLK_DEV_IO_TRACE + mutex_init(&q->blk_trace_mutex); +#endif mutex_init(&q->sysfs_lock); spin_lock_init(&q->__queue_lock);
--- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -448,6 +448,7 @@ struct request_queue { int node; #ifdef CONFIG_BLK_DEV_IO_TRACE struct blk_trace *blk_trace; + struct mutex blk_trace_mutex; #endif /* * for flush operations --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -634,6 +634,12 @@ int blk_trace_startstop(struct request_q } EXPORT_SYMBOL_GPL(blk_trace_startstop);
+/* + * When reading or writing the blktrace sysfs files, the references to the + * opened sysfs or device files should prevent the underlying block device + * from being removed. So no further delete protection is really needed. + */ + /** * blk_trace_ioctl: - handle the ioctls associated with tracing * @bdev: the block device @@ -651,7 +657,7 @@ int blk_trace_ioctl(struct block_device if (!q) return -ENXIO;
- mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex);
switch (cmd) { case BLKTRACESETUP: @@ -677,7 +683,7 @@ int blk_trace_ioctl(struct block_device break; }
- mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); return ret; }
@@ -1670,7 +1676,7 @@ static ssize_t sysfs_blk_trace_attr_show if (q == NULL) goto out_bdput;
- mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex);
if (attr == &dev_attr_enable) { ret = sprintf(buf, "%u\n", !!q->blk_trace); @@ -1689,7 +1695,7 @@ static ssize_t sysfs_blk_trace_attr_show ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba);
out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out: @@ -1731,7 +1737,7 @@ static ssize_t sysfs_blk_trace_attr_stor if (q == NULL) goto out_bdput;
- mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex);
if (attr == &dev_attr_enable) { if (value) @@ -1757,7 +1763,7 @@ static ssize_t sysfs_blk_trace_attr_stor }
out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out:
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mark Bloch markb@mellanox.com
commit 5f22a1d87c5315a98981ecf93cd8de226cffe6ca upstream.
Maximal message should be used as a limit to the max message payload allowed, without the headers. The ConnectX-3 check is done against this value includes the headers. When the payload is 4K this will cause the NIC to drop packets.
Increase maximal message to 8K as workaround, this shouldn't change current behaviour because we continue to set the MTU to 4k.
To reproduce; set MTU to 4296 on the corresponding interface, for example: ifconfig eth0 mtu 4296 (both server and client)
On server: ib_send_bw -c UD -d mlx4_0 -s 4096 -n 1000000 -i1 -m 4096
On client: ib_send_bw -d mlx4_0 -c UD <server_ip> -s 4096 -n 1000000 -i 1 -m 4096
Fixes: 6e0d733d9215 ("IB/mlx4: Allow 4K messages for UD QPs") Signed-off-by: Mark Bloch markb@mellanox.com Reviewed-by: Majd Dibbiny majd@mellanox.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/infiniband/hw/mlx4/qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1468,7 +1468,7 @@ static int __mlx4_ib_modify_qp(struct ib context->mtu_msgmax = (IB_MTU_4096 << 5) | ilog2(dev->dev->caps.max_gso_sz); else - context->mtu_msgmax = (IB_MTU_4096 << 5) | 12; + context->mtu_msgmax = (IB_MTU_4096 << 5) | 13; } else if (attr_mask & IB_QP_PATH_MTU) { if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { pr_err("path MTU (%u) is invalid\n",
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer snitzer@redhat.com
commit 8a74d29d541cd86569139c6f3f44b2d210458071 upstream.
A DM device with a mix of discard capabilities (due to some underlying devices not having discard support) _should_ just return -EOPNOTSUPP for the region of the device that doesn't support discards (even if only by way of the underlying driver formally not supporting discards). BUT, that does ask the underlying driver to handle something that it never advertised support for. In doing so we're exposing users to the potential for a underlying disk driver hanging if/when a discard is issued a the device that is incapable and never claimed to support discards.
Fix this by requiring that each DM target in a DM table provide discard support as a prereq for a DM device to advertise support for discards.
This may cause some configurations that were happily supporting discards (even in the face of a mix of discard support) to stop supporting discards -- but the risk of users hitting driver hangs, and forced reboots, outweighs supporting those fringe mixed discard configurations.
Signed-off-by: Mike Snitzer snitzer@redhat.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/md/dm-table.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-)
--- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1643,12 +1643,12 @@ void dm_table_run_md_queue_async(struct } EXPORT_SYMBOL(dm_table_run_md_queue_async);
-static int device_discard_capable(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_not_discard_capable(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { struct request_queue *q = bdev_get_queue(dev->bdev);
- return q && blk_queue_discard(q); + return q && !blk_queue_discard(q); }
bool dm_table_supports_discards(struct dm_table *t) @@ -1656,26 +1656,22 @@ bool dm_table_supports_discards(struct d struct dm_target *ti; unsigned i = 0;
- /* - * Unless any target used by the table set discards_supported, - * require at least one underlying device to support discards. - * t->devices includes internal dm devices such as mirror logs - * so we need to use iterate_devices here, which targets - * supporting discard selectively must provide. - */ while (i < dm_table_get_num_targets(t)) { ti = dm_table_get_target(t, i++);
if (!ti->num_discard_bios) - continue; + return false;
- if (ti->discards_supported) - return 1; - - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, device_discard_capable, NULL)) - return 1; + /* + * Either the target provides discard support (as implied by setting + * 'discards_supported') or it relies on _all_ data devices having + * discard support. + */ + if (!ti->discards_supported && + (!ti->type->iterate_devices || + ti->type->iterate_devices(ti, device_not_discard_capable, NULL))) + return false; }
- return 0; + return true; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Philip Derrin philip@cog.systems
commit 3b0c0c922ff4be275a8beb87ce5657d16f355b54 upstream.
When CONFIG_ARM_LPAE is set, the PMD dump relies on the software read-only bit to determine whether a page is writable. This concealed a bug which left the kernel text section writable (AP2=0) while marked read-only in the software bit.
In a kernel with the AP2 bug, the dump looks like this:
---[ Kernel Mapping ]--- 0xc0000000-0xc0200000 2M RW NX SHD 0xc0200000-0xc0600000 4M ro x SHD 0xc0600000-0xc0800000 2M ro NX SHD 0xc0800000-0xc4800000 64M RW NX SHD
The fix is to check that the software and hardware bits are both set before displaying "ro". The dump then shows the true perms:
---[ Kernel Mapping ]--- 0xc0000000-0xc0200000 2M RW NX SHD 0xc0200000-0xc0600000 4M RW x SHD 0xc0600000-0xc0800000 2M RW NX SHD 0xc0800000-0xc4800000 64M RW NX SHD
Fixes: ded947798469 ("ARM: 8109/1: mm: Modify pte_write and pmd_write logic for LPAE") Signed-off-by: Philip Derrin philip@cog.systems Tested-by: Neil Dick neil@cog.systems Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/arm/mm/dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -126,8 +126,8 @@ static const struct prot_bits section_bi .val = PMD_SECT_USER, .set = "USR", }, { - .mask = L_PMD_SECT_RDONLY, - .val = L_PMD_SECT_RDONLY, + .mask = L_PMD_SECT_RDONLY | PMD_SECT_AP2, + .val = L_PMD_SECT_RDONLY | PMD_SECT_AP2, .set = "ro", .clear = "RW", #elif __LINUX_ARM_ARCH__ >= 6
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Radu Alexe radu.alexe@nxp.com
commit cc2f8ab5334a736fa0e775cfccf06c1e268667f0 upstream.
Fixes: 3ebfa92f49a6 ("crypto: caam - Add new macros for building extended SEC descriptors (> 64 words)") Signed-off-by: Radu Alexe radu.alexe@nxp.com Signed-off-by: Horia Geantă horia.geanta@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/crypto/caam/desc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -1434,7 +1434,7 @@ struct sec4_sg_entry { #define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT) #define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT) #define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT) -#define MATH_SRC1_DPOVRD (0x07 << MATH_SRC0_SHIFT) +#define MATH_SRC1_DPOVRD (0x07 << MATH_SRC1_SHIFT) #define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT) #define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT) #define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck groeck@chromium.org
This resolves a crash if loaded under qemu + haxm under windows. See https://www.spinics.net/lists/kernel/msg2689835.html for details. Here is a boot log (the log is from chromeos-4.4, but Tao Wu says that the same log is also seen with vanilla v4.4.110-rc1).
[ 0.712750] Freeing unused kernel memory: 552K [ 0.721821] init: Corrupted page table at address 57b029b332e0 [ 0.722761] PGD 80000000bb238067 PUD bc36a067 PMD bc369067 PTE 45d2067 [ 0.722761] Bad pagetable: 000b [#1] PREEMPT SMP [ 0.722761] Modules linked in: [ 0.722761] CPU: 1 PID: 1 Comm: init Not tainted 4.4.96 #31 [ 0.722761] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org 04/01/2014 [ 0.722761] task: ffff8800bc290000 ti: ffff8800bc28c000 task.ti: ffff8800bc28c000 [ 0.722761] RIP: 0010:[<ffffffff83f4129e>] [<ffffffff83f4129e>] __clear_user+0x42/0x67 [ 0.722761] RSP: 0000:ffff8800bc28fcf8 EFLAGS: 00010202 [ 0.722761] RAX: 0000000000000000 RBX: 00000000000001a4 RCX: 00000000000001a4 [ 0.722761] RDX: 0000000000000000 RSI: 0000000000000008 RDI: 000057b029b332e0 [ 0.722761] RBP: ffff8800bc28fd08 R08: ffff8800bc290000 R09: ffff8800bb2f4000 [ 0.722761] R10: ffff8800bc290000 R11: ffff8800bb2f4000 R12: 000057b029b332e0 [ 0.722761] R13: 0000000000000000 R14: 000057b029b33340 R15: ffff8800bb1e2a00 [ 0.722761] FS: 0000000000000000(0000) GS:ffff8800bfb00000(0000) knlGS:0000000000000000 [ 0.722761] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 0.722761] CR2: 000057b029b332e0 CR3: 00000000bb2f8000 CR4: 00000000000006e0 [ 0.722761] Stack: [ 0.722761] 000057b029b332e0 ffff8800bb95fa80 ffff8800bc28fd18 ffffffff83f4120c [ 0.722761] ffff8800bc28fe18 ffffffff83e9e7a1 ffff8800bc28fd68 0000000000000000 [ 0.722761] ffff8800bc290000 ffff8800bc290000 ffff8800bc290000 ffff8800bc290000 [ 0.722761] Call Trace: [ 0.722761] [<ffffffff83f4120c>] clear_user+0x2e/0x30 [ 0.722761] [<ffffffff83e9e7a1>] load_elf_binary+0xa7f/0x18f7 [ 0.722761] [<ffffffff83de2088>] search_binary_handler+0x86/0x19c [ 0.722761] [<ffffffff83de389e>] do_execveat_common.isra.26+0x909/0xf98 [ 0.722761] [<ffffffff844febe0>] ? rest_init+0x87/0x87 [ 0.722761] [<ffffffff83de40be>] do_execve+0x23/0x25 [ 0.722761] [<ffffffff83c002e3>] run_init_process+0x2b/0x2d [ 0.722761] [<ffffffff844fec4d>] kernel_init+0x6d/0xda [ 0.722761] [<ffffffff84505b2f>] ret_from_fork+0x3f/0x70 [ 0.722761] [<ffffffff844febe0>] ? rest_init+0x87/0x87 [ 0.722761] Code: 86 84 be 12 00 00 00 e8 87 0d e8 ff 66 66 90 48 89 d8 48 c1 eb 03 4c 89 e7 83 e0 07 48 89 d9 be 08 00 00 00 31 d2 48 85 c9 74 0a <48> 89 17 48 01 f7 ff c9 75 f6 48 89 c1 85 c9 74 09 88 17 48 ff [ 0.722761] RIP [<ffffffff83f4129e>] __clear_user+0x42/0x67 [ 0.722761] RSP <ffff8800bc28fcf8> [ 0.722761] ---[ end trace def703879b4ff090 ]--- [ 0.722761] BUG: sleeping function called from invalid context at /mnt/host/source/src/third_party/kernel/v4.4/kernel/locking/rwsem.c:21 [ 0.722761] in_atomic(): 0, irqs_disabled(): 1, pid: 1, name: init [ 0.722761] CPU: 1 PID: 1 Comm: init Tainted: G D 4.4.96 #31 [ 0.722761] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org 04/01/2014 [ 0.722761] 0000000000000086 dcb5d76098c89836 ffff8800bc28fa30 ffffffff83f34004 [ 0.722761] ffffffff84839dc2 0000000000000015 ffff8800bc28fa40 ffffffff83d57dc9 [ 0.722761] ffff8800bc28fa68 ffffffff83d57e6a ffffffff84a53640 0000000000000000 [ 0.722761] Call Trace: [ 0.722761] [<ffffffff83f34004>] dump_stack+0x4d/0x63 [ 0.722761] [<ffffffff83d57dc9>] ___might_sleep+0x13a/0x13c [ 0.722761] [<ffffffff83d57e6a>] __might_sleep+0x9f/0xa6 [ 0.722761] [<ffffffff84502788>] down_read+0x20/0x31 [ 0.722761] [<ffffffff83cc5d9b>] __blocking_notifier_call_chain+0x35/0x63 [ 0.722761] [<ffffffff83cc5ddd>] blocking_notifier_call_chain+0x14/0x16 [ 0.800374] usb 1-1: new full-speed USB device number 2 using uhci_hcd [ 0.722761] [<ffffffff83cefe97>] profile_task_exit+0x1a/0x1c [ 0.802309] [<ffffffff83cac84e>] do_exit+0x39/0xe7f [ 0.802309] [<ffffffff83ce5938>] ? vprintk_default+0x1d/0x1f [ 0.802309] [<ffffffff83d7bb95>] ? printk+0x57/0x73 [ 0.802309] [<ffffffff83c46e25>] oops_end+0x80/0x85 [ 0.802309] [<ffffffff83c7b747>] pgtable_bad+0x8a/0x95 [ 0.802309] [<ffffffff83ca7f4a>] __do_page_fault+0x8c/0x352 [ 0.802309] [<ffffffff83eefba5>] ? file_has_perm+0xc4/0xe5 [ 0.802309] [<ffffffff83ca821c>] do_page_fault+0xc/0xe [ 0.802309] [<ffffffff84507682>] page_fault+0x22/0x30 [ 0.802309] [<ffffffff83f4129e>] ? __clear_user+0x42/0x67 [ 0.802309] [<ffffffff83f4127f>] ? __clear_user+0x23/0x67 [ 0.802309] [<ffffffff83f4120c>] clear_user+0x2e/0x30 [ 0.802309] [<ffffffff83e9e7a1>] load_elf_binary+0xa7f/0x18f7 [ 0.802309] [<ffffffff83de2088>] search_binary_handler+0x86/0x19c [ 0.802309] [<ffffffff83de389e>] do_execveat_common.isra.26+0x909/0xf98 [ 0.802309] [<ffffffff844febe0>] ? rest_init+0x87/0x87 [ 0.802309] [<ffffffff83de40be>] do_execve+0x23/0x25 [ 0.802309] [<ffffffff83c002e3>] run_init_process+0x2b/0x2d [ 0.802309] [<ffffffff844fec4d>] kernel_init+0x6d/0xda [ 0.802309] [<ffffffff84505b2f>] ret_from_fork+0x3f/0x70 [ 0.802309] [<ffffffff844febe0>] ? rest_init+0x87/0x87 [ 0.830559] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009 [ 0.830559] [ 0.831305] Kernel Offset: 0x2c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 0.831305] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
The crash part of this problem may be solved with the following patch (thanks to Hugh for the hint). There is still another problem, though - with this patch applied, the qemu session aborts with "VCPU Shutdown request", whatever that means.
Cc: lepton ytht.net@gmail.com Signed-off-by: Guenter Roeck groeck@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org (cherry picked from commit b33c3c64c4786cd724ccde6fa97c87ada49f6a73 linux-4.4.y) Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/mm/kaiser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index 8d1019d176e2..2d5ac54dbcee 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -428,7 +428,8 @@ pgd_t kaiser_set_shadow_pgd(pgd_t *pgdp, pgd_t pgd) * get out to userspace running on the kernel CR3, * userspace will crash instead of running. */ - pgd.pgd |= _PAGE_NX; + if (__supported_pte_mask & _PAGE_NX) + pgd.pgd |= _PAGE_NX; } } else if (!pgd.pgd) { /*
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen john.johansen@canonical.com
commit 844b8292b6311ecd30ae63db1471edb26e01d895 upstream.
Profiles that have an undecidable overlap in their attachments are being incorrectly handled. Instead of failing to attach the first one encountered is being used.
eg. profile A /** { .. } profile B /*foo { .. }
have an unresolvable longest left attachment, they both have an exact match on / and then have an overlapping expression that has no clear winner.
Currently the winner will be the profile that is loaded first which can result in non-deterministic behavior. Instead in this situation the exec should fail.
Fixes: 898127c34ec0 ("AppArmor: functions for domain transitions") Signed-off-by: John Johansen john.johansen@canonical.com [bwh: Backported to 3.16: - Add 'info' parameter to x_to_profile(), done upstream in commit 93c98a484c49 "apparmor: move exec domain mediation to using labels" - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- security/apparmor/domain.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-)
--- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -126,6 +126,7 @@ static struct file_perms change_profile_ * __attach_match_ - find an attachment match * @name - to match against (NOT NULL) * @head - profile list to walk (NOT NULL) + * @info - info message if there was an error (NOT NULL) * * Do a linear search on the profiles in the list. There is a matching * preference where an exact match is preferred over a name which uses @@ -137,28 +138,44 @@ static struct file_perms change_profile_ * Returns: profile or NULL if no match found */ static struct aa_profile *__attach_match(const char *name, - struct list_head *head) + struct list_head *head, + const char **info) { int len = 0; + bool conflict = false; struct aa_profile *profile, *candidate = NULL;
list_for_each_entry_rcu(profile, head, base.list) { if (profile->flags & PFLAG_NULL) continue; - if (profile->xmatch && profile->xmatch_len > len) { - unsigned int state = aa_dfa_match(profile->xmatch, - DFA_START, name); - u32 perm = dfa_user_allow(profile->xmatch, state); - /* any accepting state means a valid match. */ - if (perm & MAY_EXEC) { - candidate = profile; - len = profile->xmatch_len; + if (profile->xmatch) { + if (profile->xmatch_len == len) { + conflict = true; + continue; + } else if (profile->xmatch_len > len) { + unsigned int state; + u32 perm; + + state = aa_dfa_match(profile->xmatch, + DFA_START, name); + perm = dfa_user_allow(profile->xmatch, state); + /* any accepting state means a valid match. */ + if (perm & MAY_EXEC) { + candidate = profile; + len = profile->xmatch_len; + conflict = false; + } } } else if (!strcmp(profile->base.name, name)) /* exact non-re match, no more searching required */ return profile; }
+ if (conflict) { + *info = "conflicting profile attachments"; + return NULL; + } + return candidate; }
@@ -167,16 +184,18 @@ static struct aa_profile *__attach_match * @ns: the current namespace (NOT NULL) * @list: list to search (NOT NULL) * @name: the executable name to match against (NOT NULL) + * @info: info message if there was an error * * Returns: profile or NULL if no match found */ static struct aa_profile *find_attach(struct aa_namespace *ns, - struct list_head *list, const char *name) + struct list_head *list, const char *name, + const char **info) { struct aa_profile *profile;
rcu_read_lock(); - profile = aa_get_profile(__attach_match(name, list)); + profile = aa_get_profile(__attach_match(name, list, info)); rcu_read_unlock();
return profile; @@ -298,7 +317,8 @@ static struct aa_profile *x_table_lookup * Returns: refcounted profile or NULL if not found available */ static struct aa_profile *x_to_profile(struct aa_profile *profile, - const char *name, u32 xindex) + const char *name, u32 xindex, + const char **info) { struct aa_profile *new_profile = NULL; struct aa_namespace *ns = profile->ns; @@ -312,11 +332,11 @@ static struct aa_profile *x_to_profile(s if (xindex & AA_X_CHILD) /* released by caller */ new_profile = find_attach(ns, &profile->base.profiles, - name); + name, info); else /* released by caller */ new_profile = find_attach(ns, &ns->base.profiles, - name); + name, info); break; case AA_X_TABLE: /* released by caller */ @@ -385,7 +405,8 @@ int apparmor_bprm_set_creds(struct linux /* change_profile on exec already been granted */ new_profile = aa_get_profile(cxt->onexec); else - new_profile = find_attach(ns, &ns->base.profiles, name); + new_profile = find_attach(ns, &ns->base.profiles, name, + &info); if (!new_profile) goto cleanup; /* @@ -421,7 +442,7 @@ int apparmor_bprm_set_creds(struct linux
if (perms.allow & MAY_EXEC) { /* exec permission determine how to transition */ - new_profile = x_to_profile(profile, name, perms.xindex); + new_profile = x_to_profile(profile, name, perms.xindex, &info); if (!new_profile) { if (perms.xindex & AA_X_INHERIT) { /* (p|c|n)ix - don't change profile but do
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik gor@linux.vnet.ibm.com
commit b192571d1ae375e0bbe0aa3ccfa1a3c3704454b9 upstream.
Current buffer size of 64 is too small. objdump shows that there are instructions which would require up to 75 bytes buffer (with current formating). 128 bytes "ought to be enough for anybody".
Also replaces 8 spaces with a single tab to reduce the memory footprint.
Fixes the following KASAN finding:
BUG: KASAN: stack-out-of-bounds in number+0x3fe/0x538 Write of size 1 at addr 000000005a4a75a0 by task bash/1282
CPU: 1 PID: 1282 Comm: bash Not tainted 4.14.0+ #215 Hardware name: IBM 2964 N96 702 (z/VM 6.4.0) Call Trace: ([<000000000011eeb6>] show_stack+0x56/0x88) [<0000000000e1ce1a>] dump_stack+0x15a/0x1b0 [<00000000004e2994>] print_address_description+0xf4/0x288 [<00000000004e2cf2>] kasan_report+0x13a/0x230 [<0000000000e38ae6>] number+0x3fe/0x538 [<0000000000e3dfe4>] vsnprintf+0x194/0x948 [<0000000000e3ea42>] sprintf+0xa2/0xb8 [<00000000001198dc>] print_insn+0x374/0x500 [<0000000000119346>] show_code+0x4ee/0x538 [<000000000011f234>] show_registers+0x34c/0x388 [<000000000011f2ae>] show_regs+0x3e/0xa8 [<000000000011f502>] die+0x1ea/0x2e8 [<0000000000138f0e>] do_no_context+0x106/0x168 [<0000000000139a1a>] do_protection_exception+0x4da/0x7d0 [<0000000000e55914>] pgm_check_handler+0x16c/0x1c0 [<000000000090639e>] sysrq_handle_crash+0x46/0x58 ([<0000000000000007>] 0x7) [<00000000009073fa>] __handle_sysrq+0x102/0x218 [<0000000000907c06>] write_sysrq_trigger+0xd6/0x100 [<000000000061d67a>] proc_reg_write+0xb2/0x128 [<0000000000520be6>] __vfs_write+0xee/0x368 [<0000000000521222>] vfs_write+0x21a/0x278 [<000000000052156a>] SyS_write+0xda/0x178 [<0000000000e555cc>] system_call+0xc4/0x270
The buggy address belongs to the page: page:000003d1016929c0 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() raw: 0000000000000000 0000000000000000 0000000000000000 ffffffff00000000 raw: 0000000000000100 0000000000000200 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: 000000005a4a7480: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 000000005a4a7500: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 00
000000005a4a7580: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
^ 000000005a4a7600: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 000000005a4a7680: f2 f2 f2 f2 f2 f2 f8 f8 f2 f2 f3 f3 f3 f3 00 00 ==================================================================
Signed-off-by: Vasily Gorbik gor@linux.vnet.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/s390/kernel/dis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -1765,7 +1765,7 @@ void show_code(struct pt_regs *regs) { char *mode = user_mode(regs) ? "User" : "Krnl"; unsigned char code[64]; - char buffer[64], *ptr; + char buffer[128], *ptr; mm_segment_t old_fs; unsigned long addr; int start, end, opsize, hops, i; @@ -1828,7 +1828,7 @@ void show_code(struct pt_regs *regs) start += opsize; printk(buffer); ptr = buffer; - ptr += sprintf(ptr, "\n "); + ptr += sprintf(ptr, "\n\t "); hops++; } printk("\n");
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit 19a565d9af6e0d828bd0d521d3bafd5017f4ce52 upstream.
Make sure to stop any submitted interrupt and bulk-out URBs before returning after failed probe and when the port is being unbound to avoid later NULL-pointer dereferences in the completion callbacks.
Also fix up the related and broken I/O cancellation on failed open and on close. (Note that port->write_urb was never submitted.)
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/serial/garmin_gps.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
--- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -138,6 +138,7 @@ struct garmin_data { __u8 privpkt[4*6]; spinlock_t lock; struct list_head pktlist; + struct usb_anchor write_urbs; };
@@ -906,7 +907,7 @@ static int garmin_init_session(struct us sizeof(GARMIN_START_SESSION_REQ), 0);
if (status < 0) - break; + goto err_kill_urbs; }
if (status > 0) @@ -914,6 +915,12 @@ static int garmin_init_session(struct us }
return status; + +err_kill_urbs: + usb_kill_anchored_urbs(&garmin_data_p->write_urbs); + usb_kill_urb(port->interrupt_in_urb); + + return status; }
@@ -931,7 +938,6 @@ static int garmin_open(struct tty_struct spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */ - usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb);
if (garmin_data_p->state == STATE_RESET) @@ -954,7 +960,7 @@ static void garmin_close(struct usb_seri
/* shutdown our urbs */ usb_kill_urb(port->read_urb); - usb_kill_urb(port->write_urb); + usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
/* keep reset state so we know that we must start a new session */ if (garmin_data_p->state != STATE_RESET) @@ -1038,12 +1044,14 @@ static int garmin_write_bulk(struct usb_ }
/* send it down the pipe */ + usb_anchor_urb(urb, &garmin_data_p->write_urbs); status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); count = status; + usb_unanchor_urb(urb); kfree(buffer); }
@@ -1402,6 +1410,7 @@ static int garmin_port_probe(struct usb_ garmin_data_p->state = 0; garmin_data_p->flags = 0; garmin_data_p->count = 0; + init_usb_anchor(&garmin_data_p->write_urbs); usb_set_serial_port_data(port, garmin_data_p);
status = garmin_init_session(port); @@ -1414,6 +1423,7 @@ static int garmin_port_remove(struct usb { struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
+ usb_kill_anchored_urbs(&garmin_data_p->write_urbs); usb_kill_urb(port->interrupt_in_urb); del_timer_sync(&garmin_data_p->timer); kfree(garmin_data_p);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski luto@amacapital.net
commit e6577a7ce99a506b587bcd1d2cd803cb45119557 upstream.
Putting the vvar area after the vdso text is rather complicated: it only works of the total length of the vdso text mapping is known at vdso link time, and the linker doesn't allow symbol addresses to depend on the sizes of non-allocatable data after the PT_LOAD segment.
Moving the vvar area before the vdso text will allow is to safely map non-allocatable data after the vdso text, which is a nice simplification.
Signed-off-by: Andy Lutomirski luto@amacapital.net Link: http://lkml.kernel.org/r/156c78c0d93144ff1055a66493783b9e56813983.1405040914... Signed-off-by: H. Peter Anvin hpa@linux.intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/include/asm/vdso.h | 18 ++++++++--------- arch/x86/vdso/vdso-layout.lds.S | 44 ++++++++++++++++++----------------------- arch/x86/vdso/vdso2c.c | 12 ++++++----- arch/x86/vdso/vdso2c.h | 25 ++++++++++++++--------- arch/x86/vdso/vma.c | 20 ++++++++++--------- 5 files changed, 62 insertions(+), 57 deletions(-)
--- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h @@ -18,15 +18,15 @@ struct vdso_image {
unsigned long alt, alt_len;
- unsigned long sym_end_mapping; /* Total size of the mapping */ + long sym_vvar_start; /* Negative offset to the vvar area */
- unsigned long sym_vvar_page; - unsigned long sym_hpet_page; - unsigned long sym_VDSO32_NOTE_MASK; - unsigned long sym___kernel_sigreturn; - unsigned long sym___kernel_rt_sigreturn; - unsigned long sym___kernel_vsyscall; - unsigned long sym_VDSO32_SYSENTER_RETURN; + long sym_vvar_page; + long sym_hpet_page; + long sym_VDSO32_NOTE_MASK; + long sym___kernel_sigreturn; + long sym___kernel_rt_sigreturn; + long sym___kernel_vsyscall; + long sym_VDSO32_SYSENTER_RETURN; };
#ifdef CONFIG_X86_64 --- a/arch/x86/vdso/vdso-layout.lds.S +++ b/arch/x86/vdso/vdso-layout.lds.S @@ -18,6 +18,25 @@
SECTIONS { + /* + * User/kernel shared data is before the vDSO. This may be a little + * uglier than putting it after the vDSO, but it avoids issues with + * non-allocatable things that dangle past the end of the PT_LOAD + * segment. + */ + + vvar_start = . - 2 * PAGE_SIZE; + vvar_page = vvar_start; + + /* Place all vvars at the offsets in asm/vvar.h. */ +#define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset; +#define __VVAR_KERNEL_LDS +#include <asm/vvar.h> +#undef __VVAR_KERNEL_LDS +#undef EMIT_VVAR + + hpet_page = vvar_start + PAGE_SIZE; + . = SIZEOF_HEADERS;
.hash : { *(.hash) } :text @@ -74,31 +93,6 @@ SECTIONS .altinstructions : { *(.altinstructions) } :text .altinstr_replacement : { *(.altinstr_replacement) } :text
- /* - * The remainder of the vDSO consists of special pages that are - * shared between the kernel and userspace. It needs to be at the - * end so that it doesn't overlap the mapping of the actual - * vDSO image. - */ - - . = ALIGN(PAGE_SIZE); - vvar_page = .; - - /* Place all vvars at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset; -#define __VVAR_KERNEL_LDS -#include <asm/vvar.h> -#undef __VVAR_KERNEL_LDS -#undef EMIT_VVAR - - . = vvar_page + PAGE_SIZE; - - hpet_page = .; - . = . + PAGE_SIZE; - - . = ALIGN(PAGE_SIZE); - end_mapping = .; - /DISCARD/ : { *(.discard) *(.discard.*) --- a/arch/x86/vdso/vdso2c.c +++ b/arch/x86/vdso/vdso2c.c @@ -20,9 +20,9 @@ const char *outfilename;
/* Symbols that we need in vdso2c. */ enum { + sym_vvar_start, sym_vvar_page, sym_hpet_page, - sym_end_mapping, sym_VDSO_FAKE_SECTION_TABLE_START, sym_VDSO_FAKE_SECTION_TABLE_END, }; @@ -38,9 +38,9 @@ struct vdso_sym { };
struct vdso_sym required_syms[] = { + [sym_vvar_start] = {"vvar_start", true}, [sym_vvar_page] = {"vvar_page", true}, [sym_hpet_page] = {"hpet_page", true}, - [sym_end_mapping] = {"end_mapping", true}, [sym_VDSO_FAKE_SECTION_TABLE_START] = { "VDSO_FAKE_SECTION_TABLE_START", false }, @@ -96,9 +96,11 @@ extern void bad_put_le(void);
#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
-#define BITSFUNC3(name, bits) name##bits -#define BITSFUNC2(name, bits) BITSFUNC3(name, bits) -#define BITSFUNC(name) BITSFUNC2(name, ELF_BITS) +#define BITSFUNC3(name, bits, suffix) name##bits##suffix +#define BITSFUNC2(name, bits, suffix) BITSFUNC3(name, bits, suffix) +#define BITSFUNC(name) BITSFUNC2(name, ELF_BITS, ) + +#define INT_BITS BITSFUNC2(int, ELF_BITS, _t)
#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x #define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x) --- a/arch/x86/vdso/vdso2c.h +++ b/arch/x86/vdso/vdso2c.h @@ -132,7 +132,7 @@ static void BITSFUNC(go)(void *addr, siz *alt_sec = NULL; ELF(Dyn) *dyn = 0, *dyn_end = 0; const char *secstrings; - uint64_t syms[NSYMS] = {}; + INT_BITS syms[NSYMS] = {};
struct BITSFUNC(fake_sections) fake_sections = {};
@@ -209,6 +209,13 @@ static void BITSFUNC(go)(void *addr, siz fail("duplicate symbol %s\n", required_syms[k].name); } + + /* + * Careful: we use negative addresses, but + * st_value is unsigned, so we rely + * on syms[k] being a signed type of the + * correct width. + */ syms[k] = GET_LE(&sym->st_value); } } @@ -263,15 +270,15 @@ static void BITSFUNC(go)(void *addr, siz if (syms[i] % 4096) fail("%s must be a multiple of 4096\n", required_syms[i].name); - if (syms[i] < data_size) - fail("%s must be after the text mapping\n", + if (syms[sym_vvar_start] > syms[i] + 4096) + fail("%s underruns begin_vvar\n", required_syms[i].name); - if (syms[sym_end_mapping] < syms[i] + 4096) - fail("%s overruns end_mapping\n", + if (syms[i] + 4096 > 0) + fail("%s is on the wrong side of the vdso text\n", required_syms[i].name); } - if (syms[sym_end_mapping] % 4096) - fail("end_mapping must be a multiple of 4096\n"); + if (syms[sym_vvar_start] % 4096) + fail("vvar_begin must be a multiple of 4096\n");
if (!name) { fwrite(addr, load_size, 1, outfile); @@ -311,8 +318,8 @@ static void BITSFUNC(go)(void *addr, siz } for (i = 0; i < NSYMS; i++) { if (required_syms[i].export && syms[i]) - fprintf(outfile, "\t.sym_%s = 0x%" PRIx64 ",\n", - required_syms[i].name, syms[i]); + fprintf(outfile, "\t.sym_%s = %" PRIi64 ",\n", + required_syms[i].name, (int64_t)syms[i]); } fprintf(outfile, "};\n"); } --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c @@ -106,7 +106,7 @@ static int map_vdso(const struct vdso_im { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - unsigned long addr; + unsigned long addr, text_start; int ret = 0; static struct page *no_pages[] = {NULL}; static struct vm_special_mapping vvar_mapping = { @@ -116,26 +116,28 @@ static int map_vdso(const struct vdso_im
if (calculate_addr) { addr = vdso_addr(current->mm->start_stack, - image->sym_end_mapping); + image->size - image->sym_vvar_start); } else { addr = 0; }
down_write(&mm->mmap_sem);
- addr = get_unmapped_area(NULL, addr, image->sym_end_mapping, 0, 0); + addr = get_unmapped_area(NULL, addr, + image->size - image->sym_vvar_start, 0, 0); if (IS_ERR_VALUE(addr)) { ret = addr; goto up_fail; }
- current->mm->context.vdso = (void __user *)addr; + text_start = addr - image->sym_vvar_start; + current->mm->context.vdso = (void __user *)text_start;
/* * MAYWRITE to allow gdb to COW and set breakpoints */ vma = _install_special_mapping(mm, - addr, + text_start, image->size, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, @@ -147,8 +149,8 @@ static int map_vdso(const struct vdso_im }
vma = _install_special_mapping(mm, - addr + image->size, - image->sym_end_mapping - image->size, + addr, + -image->sym_vvar_start, VM_READ, &vvar_mapping);
@@ -159,7 +161,7 @@ static int map_vdso(const struct vdso_im
if (image->sym_vvar_page) ret = remap_pfn_range(vma, - addr + image->sym_vvar_page, + text_start + image->sym_vvar_page, __pa_symbol(&__vvar_page) >> PAGE_SHIFT, PAGE_SIZE, PAGE_READONLY); @@ -170,7 +172,7 @@ static int map_vdso(const struct vdso_im #ifdef CONFIG_HPET_TIMER if (hpet_address && image->sym_hpet_page) { ret = io_remap_pfn_range(vma, - addr + image->sym_hpet_page, + text_start + image->sym_hpet_page, hpet_address >> PAGE_SHIFT, PAGE_SIZE, pgprot_noncached(PAGE_READONLY));
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens heiko.carstens@de.ibm.com
commit a1c5befc1c24eb9c1ee83f711e0f21ee79cbb556 upstream.
Dan Horák reported the following crash related to transactional execution:
User process fault: interruption code 0013 ilc:3 in libpthread-2.26.so[3ff93c00000+1b000] CPU: 2 PID: 1 Comm: /init Not tainted 4.13.4-300.fc27.s390x #1 Hardware name: IBM 2827 H43 400 (z/VM 6.4.0) task: 00000000fafc8000 task.stack: 00000000fafc4000 User PSW : 0705200180000000 000003ff93c14e70 R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:2 PM:0 RI:0 EA:3 User GPRS: 0000000000000077 000003ff00000000 000003ff93144d48 000003ff93144d5e 0000000000000000 0000000000000002 0000000000000000 000003ff00000000 0000000000000000 0000000000000418 0000000000000000 000003ffcc9fe770 000003ff93d28f50 000003ff9310acf0 000003ff92b0319a 000003ffcc9fe6d0 User Code: 000003ff93c14e62: 60e0b030 std %f14,48(%r11) 000003ff93c14e66: 60f0b038 std %f15,56(%r11) #000003ff93c14e6a: e5600000ff0e tbegin 0,65294 >000003ff93c14e70: a7740006 brc 7,3ff93c14e7c 000003ff93c14e74: a7080000 lhi %r0,0 000003ff93c14e78: a7f40023 brc 15,3ff93c14ebe 000003ff93c14e7c: b2220000 ipm %r0 000003ff93c14e80: 8800001c srl %r0,28
There are several bugs with control register handling with respect to transactional execution:
- on task switch update_per_regs() is only called if the next task has an mm (is not a kernel thread). This however is incorrect. This breaks e.g. for user mode helper handling, where the kernel creates a kernel thread and then execve's a user space program. Control register contents related to transactional execution won't be updated on execve. If the previous task ran with transactional execution disabled then the new task will also run with transactional execution disabled, which is incorrect. Therefore call update_per_regs() unconditionally within switch_to().
- on startup the transactional execution facility is not enabled for the idle thread. This is not really a bug, but an inconsistency to other facilities. Therefore enable the facility if it is available.
- on fork the new thread's per_flags field is not cleared. This means that a child process inherits the PER_FLAG_NO_TE flag. This flag can be set with a ptrace request to disable transactional execution for the current process. It should not be inherited by new child processes in order to be consistent with the handling of all other PER related debugging options. Therefore clear the per_flags field in copy_thread_tls().
Reported-and-tested-by: Dan Horák dan@danny.cz Fixes: d35339a42dd1 ("s390: add support for transactional memory") Cc: Martin Schwidefsky schwidefsky@de.ibm.com Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Reviewed-by: Hendrik Brueckner brueckner@linux.vnet.ibm.com Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/s390/include/asm/switch_to.h | 2 +- arch/s390/kernel/early.c | 4 +++- arch/s390/kernel/process.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-)
--- a/arch/s390/include/asm/switch_to.h +++ b/arch/s390/include/asm/switch_to.h @@ -124,12 +124,12 @@ static inline void restore_access_regs(u save_access_regs(&prev->thread.acrs[0]); \ save_ri_cb(prev->thread.ri_cb); \ } \ + update_cr_regs(next); \ if (next->mm) { \ restore_fp_ctl(&next->thread.fp_regs.fpc); \ restore_fp_regs(next->thread.fp_regs.fprs); \ restore_access_regs(&next->thread.acrs[0]); \ restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \ - update_cr_regs(next); \ } \ prev = __switch_to(prev,next); \ } while (0) --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -388,8 +388,10 @@ static __init void detect_machine_facili S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; if (test_facility(40)) S390_lowcore.machine_flags |= MACHINE_FLAG_LPP; - if (test_facility(50) && test_facility(73)) + if (test_facility(50) && test_facility(73)) { S390_lowcore.machine_flags |= MACHINE_FLAG_TE; + __ctl_set_bit(0, 55); + } if (test_facility(66)) S390_lowcore.machine_flags |= MACHINE_FLAG_RRBM; if (test_facility(51)) --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -123,6 +123,7 @@ int copy_thread(unsigned long clone_flag memset(&p->thread.per_user, 0, sizeof(p->thread.per_user)); memset(&p->thread.per_event, 0, sizeof(p->thread.per_event)); clear_tsk_thread_flag(p, TIF_SINGLE_STEP); + p->thread.per_flags = 0; /* Initialize per thread user and system timer values */ ti = task_thread_info(p); ti->user_timer = 0;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski luto@kernel.org
commit cc1e24fdb064d3126a494716f22ad4fc39306742 upstream.
Signed-off-by: Andy Lutomirski luto@kernel.org Reviewed-by: Paolo Bonzini pbonzini@redhat.com Cc: Andy Lutomirski luto@amacapital.net Cc: Borislav Petkov bp@alien8.de Cc: Brian Gerst brgerst@gmail.com Cc: Denys Vlasenko dvlasenk@redhat.com Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/4933029991103ae44672c82b97a20035f5c1fe4f.1449702533... Signed-off-by: Ingo Molnar mingo@kernel.org [bwh: Backported to 3.16: adjust filenames, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/include/asm/fixmap.h | 5 ----- arch/x86/include/asm/pvclock.h | 5 ----- arch/x86/kernel/kvmclock.c | 6 ------ arch/x86/kernel/pvclock.c | 24 ------------------------ arch/x86/vdso/vclock_gettime.c | 1 - arch/x86/vdso/vma.c | 1 + 6 files changed, 1 insertion(+), 41 deletions(-)
--- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -19,7 +19,6 @@ #include <asm/acpi.h> #include <asm/apicdef.h> #include <asm/page.h> -#include <asm/pvclock.h> #ifdef CONFIG_X86_32 #include <linux/threads.h> #include <asm/kmap_types.h> @@ -70,10 +69,6 @@ enum fixed_addresses { FIX_HOLE, #else VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT, -#ifdef CONFIG_PARAVIRT_CLOCK - PVCLOCK_FIXMAP_BEGIN, - PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1, -#endif #endif FIX_DBGP_BASE, FIX_EARLYCON_MEM_BASE, --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -107,10 +107,5 @@ struct pvclock_vsyscall_time_info { } __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) -#define PVCLOCK_VSYSCALL_NR_PAGES (((NR_CPUS-1)/(PAGE_SIZE/PVTI_SIZE))+1) - -int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i, - int size); -struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu);
#endif /* _ASM_X86_PVCLOCK_H */ --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -278,7 +278,6 @@ int __init kvm_setup_vsyscall_timeinfo(v { #ifdef CONFIG_X86_64 int cpu; - int ret; u8 flags; struct pvclock_vcpu_time_info *vcpu_time; unsigned int size; @@ -299,11 +298,6 @@ int __init kvm_setup_vsyscall_timeinfo(v return 1; }
- if ((ret = pvclock_init_vsyscall(hv_clock, size))) { - preempt_enable(); - return ret; - } - preempt_enable();
kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK; --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -140,27 +140,3 @@ void pvclock_read_wallclock(struct pvclo
set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); } - -#ifdef CONFIG_X86_64 -/* - * Initialize the generic pvclock vsyscall state. This will allocate - * a/some page(s) for the per-vcpu pvclock information, set up a - * fixmap mapping for the page(s) - */ - -int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i, - int size) -{ - int idx; - - WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE); - - for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { - __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, - __pa(i) + (idx*PAGE_SIZE), - PAGE_KERNEL_VVAR); - } - - return 0; -} -#endif --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -45,7 +45,6 @@ extern u8 pvclock_page
#include <linux/kernel.h> #include <asm/vsyscall.h> -#include <asm/fixmap.h> #include <asm/pvclock.h>
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c @@ -11,6 +11,7 @@ #include <linux/random.h> #include <linux/elf.h> #include <asm/vsyscall.h> +#include <asm/pvclock.h> #include <asm/vgtod.h> #include <asm/proto.h> #include <asm/vdso.h>
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab m.chehab@samsung.com
commit 139d28826b8e2bc7a9232fde0d2f14812914f501 upstream.
The max number of interfaces was read from the wrong descriptor.
Signed-off-by: Mauro Carvalho Chehab m.chehab@samsung.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/media/usb/cx231xx/cx231xx-cards.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1185,8 +1185,7 @@ static int cx231xx_usb_probe(struct usb_ dev->vbi_or_sliced_cc_mode = 0;
/* get maximum no.of IAD interfaces */ - assoc_desc = udev->actconfig->intf_assoc[0]; - dev->max_iad_interface_count = assoc_desc->bInterfaceCount; + dev->max_iad_interface_count = udev->config->desc.bNumInterfaces;
/* init CIR module TBD */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault g.nault@alphalink.fr
commit f98be6c6359e7e4a61aaefb9964c1db31cb9ec0c upstream.
pppol2tp_connect() initialises L2TP sessions after they've been exposed to the rest of the system by l2tp_session_register(). This puts sessions into transient states that are the source of several races, in particular with session's deletion path.
This patch centralises the initialisation code into pppol2tp_session_init(), which is called before the registration phase. The only field that can't be set before session registration is the pppol2tp socket pointer, which has already been converted to RCU. So pppol2tp_connect() should now be race-free.
The session's .session_close() callback is now set before registration. Therefore, it's always called when l2tp_core deletes the session, even if it was created by pppol2tp_session_create() and hasn't been plugged to a pppol2tp socket yet. That'd prevent session free because the extra reference taken by pppol2tp_session_close() wouldn't be dropped by the socket's ->sk_destruct() callback (pppol2tp_session_destruct()). We could set .session_close() only while connecting a session to its pppol2tp socket, or teach pppol2tp_session_close() to avoid grabbing a reference when the session isn't connected, but that'd require adding some form of synchronisation to be race free.
Instead of that, we can just let the pppol2tp socket hold a reference on the session as soon as it starts depending on it (that is, in pppol2tp_connect()). Then we don't need to utilise pppol2tp_session_close() to hold a reference at the last moment to prevent l2tp_core from dropping it.
When releasing the socket, pppol2tp_release() now deletes the session using the standard l2tp_session_delete() function, instead of merely removing it from hash tables. l2tp_session_delete() drops the reference the sessions holds on itself, but also makes sure it doesn't remove a session twice. So it can safely be called, even if l2tp_core already tried, or is concurrently trying, to remove the session. Finally, pppol2tp_session_destruct() drops the reference held by the socket.
Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/l2tp/l2tp_ppp.c | 69 +++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 31 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -468,9 +468,6 @@ static void pppol2tp_session_close(struc inet_shutdown(sk->sk_socket, SEND_SHUTDOWN); sock_put(sk); } - - /* Don't let the session go away before our socket does */ - l2tp_session_inc_refcount(session); }
/* Really kill the session socket. (Called from sock_put() if @@ -526,8 +523,7 @@ static int pppol2tp_release(struct socke if (session != NULL) { struct pppol2tp_session *ps;
- __l2tp_session_unhash(session); - l2tp_session_queue_purge(session); + l2tp_session_delete(session);
ps = l2tp_session_priv(session); mutex_lock(&ps->sk_lock); @@ -619,6 +615,35 @@ static void pppol2tp_show(struct seq_fil } #endif
+static void pppol2tp_session_init(struct l2tp_session *session) +{ + struct pppol2tp_session *ps; + struct dst_entry *dst; + + session->recv_skb = pppol2tp_recv; + session->session_close = pppol2tp_session_close; +#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) + session->show = pppol2tp_show; +#endif + + ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); + ps->tunnel_sock = session->tunnel->sock; + ps->owner = current->pid; + + /* If PMTU discovery was enabled, use the MTU that was discovered */ + dst = sk_dst_get(session->tunnel->sock); + if (dst) { + u32 pmtu = dst_mtu(dst); + + if (pmtu) { + session->mtu = pmtu - PPPOL2TP_HEADER_OVERHEAD; + session->mru = pmtu - PPPOL2TP_HEADER_OVERHEAD; + } + dst_release(dst); + } +} + /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket */ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, @@ -630,7 +655,6 @@ static int pppol2tp_connect(struct socke struct l2tp_session *session = NULL; struct l2tp_tunnel *tunnel; struct pppol2tp_session *ps; - struct dst_entry *dst; struct l2tp_session_cfg cfg = { 0, }; int error = 0; u32 tunnel_id, peer_tunnel_id; @@ -775,8 +799,8 @@ static int pppol2tp_connect(struct socke goto end; }
+ pppol2tp_session_init(session); ps = l2tp_session_priv(session); - mutex_init(&ps->sk_lock); l2tp_session_inc_refcount(session);
mutex_lock(&ps->sk_lock); @@ -789,26 +813,6 @@ static int pppol2tp_connect(struct socke drop_refcnt = true; }
- ps->owner = current->pid; - ps->tunnel_sock = tunnel->sock; - - session->recv_skb = pppol2tp_recv; - session->session_close = pppol2tp_session_close; -#if defined(CONFIG_L2TP_DEBUGFS) || defined(CONFIG_L2TP_DEBUGFS_MODULE) - session->show = pppol2tp_show; -#endif - - /* If PMTU discovery was enabled, use the MTU that was discovered */ - dst = sk_dst_get(tunnel->sock); - if (dst != NULL) { - u32 pmtu = dst_mtu(dst); - - if (pmtu != 0) - session->mtu = session->mru = pmtu - - PPPOL2TP_HEADER_OVERHEAD; - dst_release(dst); - } - /* Special case: if source & dest session_id == 0x0000, this * socket is being created to manage the tunnel. Just set up * the internal context for use by ioctl() and sockopt() @@ -842,6 +846,12 @@ out_no_ppp: rcu_assign_pointer(ps->sk, sk); mutex_unlock(&ps->sk_lock);
+ /* Keep the reference we've grabbed on the session: sk doesn't expect + * the session to disappear. pppol2tp_session_destruct() is responsible + * for dropping it. + */ + drop_refcnt = false; + sk->sk_state = PPPOX_CONNECTED; l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", session->name); @@ -865,7 +875,6 @@ static int pppol2tp_session_create(struc { int error; struct l2tp_session *session; - struct pppol2tp_session *ps;
/* Error if tunnel socket is not prepped */ if (!tunnel->sock) { @@ -888,9 +897,7 @@ static int pppol2tp_session_create(struc goto err; }
- ps = l2tp_session_priv(session); - mutex_init(&ps->sk_lock); - ps->tunnel_sock = tunnel->sock; + pppol2tp_session_init(session);
error = l2tp_session_register(session, tunnel); if (error < 0)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shuah Khan shuahkh@osg.samsung.com
commit c6688ef9f29762e65bce325ef4acd6c675806366 upstream.
Harden CMD_SUBMIT path to handle malicious input that could trigger large memory allocations. Add checks to validate transfer_buffer_length and number_of_packets to protect against bad input requesting for unbounded memory allocations. Validate early in get_pipe() and return failure.
Reported-by: Secunia Research vuln@secunia.com Signed-off-by: Shuah Khan shuahkh@osg.samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/usbip/stub_rx.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-)
--- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -336,11 +336,13 @@ static struct stub_priv *stub_priv_alloc return priv; }
-static int get_pipe(struct stub_device *sdev, int epnum, int dir) +static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) { struct usb_device *udev = sdev->udev; struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL; + int epnum = pdu->base.ep; + int dir = pdu->base.direction;
if (epnum < 0 || epnum > 15) goto err_ret; @@ -353,6 +355,15 @@ static int get_pipe(struct stub_device * goto err_ret;
epd = &ep->desc; + + /* validate transfer_buffer_length */ + if (pdu->u.cmd_submit.transfer_buffer_length > INT_MAX) { + dev_err(&sdev->udev->dev, + "CMD_SUBMIT: -EMSGSIZE transfer_buffer_length %d\n", + pdu->u.cmd_submit.transfer_buffer_length); + return -1; + } + if (usb_endpoint_xfer_control(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, epnum); @@ -375,6 +386,21 @@ static int get_pipe(struct stub_device * }
if (usb_endpoint_xfer_isoc(epd)) { + /* validate packet size and number of packets */ + unsigned int maxp, packets, bytes; + + maxp = usb_endpoint_maxp(epd); + maxp *= usb_endpoint_maxp_mult(epd); + bytes = pdu->u.cmd_submit.transfer_buffer_length; + packets = DIV_ROUND_UP(bytes, maxp); + + if (pdu->u.cmd_submit.number_of_packets < 0 || + pdu->u.cmd_submit.number_of_packets > packets) { + dev_err(&sdev->udev->dev, + "CMD_SUBMIT: isoc invalid num packets %d\n", + pdu->u.cmd_submit.number_of_packets); + return -1; + } if (dir == USBIP_DIR_OUT) return usb_sndisocpipe(udev, epnum); else @@ -383,7 +409,7 @@ static int get_pipe(struct stub_device *
err_ret: /* NOT REACHED */ - dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum); + dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); return -1; }
@@ -448,7 +474,7 @@ static void stub_recv_cmd_submit(struct struct stub_priv *priv; struct usbip_device *ud = &sdev->ud; struct usb_device *udev = sdev->udev; - int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); + int pipe = get_pipe(sdev, pdu);
if (pipe == -1) return; @@ -471,7 +497,8 @@ static void stub_recv_cmd_submit(struct }
/* allocate urb transfer buffer, if needed */ - if (pdu->u.cmd_submit.transfer_buffer_length > 0) { + if (pdu->u.cmd_submit.transfer_buffer_length > 0 && + pdu->u.cmd_submit.transfer_buffer_length <= INT_MAX) { priv->urb->transfer_buffer = kzalloc(pdu->u.cmd_submit.transfer_buffer_length, GFP_KERNEL);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Coly Li colyli@suse.de
commit d59b23795933678c9638fd20c942d2b4f3cd6185 upstream.
When bcache does read I/Os, for example in writeback or writethrough mode, if a read request on cache device is failed, bcache will try to recovery the request by reading from cached device. If the data on cached device is not synced with cache device, then requester will get a stale data.
For critical storage system like database, providing stale data from recovery may result an application level data corruption, which is unacceptible.
With this patch, for a failed read request in writeback or writethrough mode, recovery a recoverable read request only happens when cache device is clean. That is to say, all data on cached device is up to update.
For other cache modes in bcache, read request will never hit cached_dev_read_error(), they don't need this patch.
Please note, because cache mode can be switched arbitrarily in run time, a writethrough mode might be switched from a writeback mode. Therefore checking dc->has_data in writethrough mode still makes sense.
Changelog: V4: Fix parens error pointed by Michael Lyle. v3: By response from Kent Oversteet, he thinks recovering stale data is a bug to fix, and option to permit it is unnecessary. So this version the sysfs file is removed. v2: rename sysfs entry from allow_stale_data_on_failure to allow_stale_data_on_failure, and fix the confusing commit log. v1: initial patch posted.
[small change to patch comment spelling by mlyle]
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Michael Lyle mlyle@lyle.org Reported-by: Arne Wolf awolf@lenovo.com Reviewed-by: Michael Lyle mlyle@lyle.org Cc: Kent Overstreet kent.overstreet@gmail.com Cc: Nix nix@esperi.org.uk Cc: Kai Krakow hurikhan77@gmail.com Cc: Eric Wheeler bcache@lists.ewheeler.net Cc: Junhui Tang tang.junhui@zte.com.cn Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/md/bcache/request.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -698,8 +698,16 @@ static void cached_dev_read_error(struct { struct search *s = container_of(cl, struct search, cl); struct bio *bio = &s->bio.bio; + struct cached_dev *dc = container_of(s->d, struct cached_dev, disk);
- if (s->recoverable) { + /* + * If cache device is dirty (dc->has_dirty is non-zero), then + * recovery a failed read request from cached device may get a + * stale data back. So read failure recovery is only permitted + * when cache device is clean. + */ + if (s->recoverable && + (dc && !atomic_read(&dc->has_dirty))) { /* Retry from the backing device: */ trace_bcache_read_retry(s->orig_bio);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shuah Khan shuahkh@osg.samsung.com
commit 2f2d0088eb93db5c649d2a5e34a3800a8a935fc5 upstream.
When a client has a USB device attached over IP, the vhci_hcd driver is locally leaking a socket pointer address via the
/sys/devices/platform/vhci_hcd/status file (world-readable) and in debug output when "usbip --debug port" is run.
Fix it to not leak. The socket pointer address is not used at the moment and it was made visible as a convenient way to find IP address from socket pointer address by looking up /proc/net/{tcp,tcp6}.
As this opens a security hole, the fix replaces socket pointer address with sockfd.
Reported-by: Secunia Research vuln@secunia.com Signed-off-by: Shuah Khan shuahkh@osg.samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: - usbip port status does not include hub type - Adjust filenames, context, indentation] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/usbip/usbip_common.h | 1 + drivers/staging/usbip/vhci_sysfs.c | 25 ++++++++++++++++--------- drivers/staging/usbip/userspace/libsrc/vhci_driver.c | 8 ++++---- 3 files changed, 21 insertions(+), 13 deletions(-)
--- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -261,6 +261,7 @@ struct usbip_device { /* lock for status */ spinlock_t lock;
+ int sockfd; struct socket *tcp_socket;
struct task_struct *tcp_rx; --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -39,13 +39,18 @@ static ssize_t status_show(struct device
/* * output example: - * prt sta spd dev socket local_busid - * 000 004 000 000 c5a7bb80 1-2.3 - * 001 004 000 000 d8cee980 2-3.4 + * prt sta spd dev sockfd local_busid + * 000 004 000 000 3 1-2.3 + * 001 004 000 000 4 2-3.4 + * + * Output includes socket fd instead of socket pointer address to avoid + * leaking kernel memory address in: + * /sys/devices/platform/vhci_hcd.0/status and in debug output. + * The socket pointer address is not used at the moment and it was made + * visible as a convenient way to find IP address from socket pointer + * address by looking up /proc/net/{tcp,tcp6}. As this opens a security + * hole, the change is made to use sockfd instead. * - * IP address can be retrieved from a socket pointer address by looking - * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a - * port number and its peer IP address. */ out += sprintf(out, "prt sta spd bus dev socket local_busid\n"); @@ -59,7 +64,7 @@ static ssize_t status_show(struct device if (vdev->ud.status == VDEV_ST_USED) { out += sprintf(out, "%03u %08x ", vdev->speed, vdev->devid); - out += sprintf(out, "%16p ", vdev->ud.tcp_socket); + out += sprintf(out, "%u", vdev->ud.sockfd); out += sprintf(out, "%s", dev_name(&vdev->udev->dev));
} else { @@ -223,6 +228,7 @@ static ssize_t store_attach(struct devic
vdev->devid = devid; vdev->speed = speed; + vdev->ud.sockfd = sockfd; vdev->ud.tcp_socket = socket; vdev->ud.status = VDEV_ST_NOTASSIGNED;
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -55,12 +55,12 @@ static int parse_status(const char *valu
while (*c != '\0') { int port, status, speed, devid; - unsigned long socket; + int sockfd; char lbusid[SYSFS_BUS_ID_SIZE];
- ret = sscanf(c, "%d %d %d %x %lx %31s\n", + ret = sscanf(c, "%d %d %d %x %u %31s\n", &port, &status, &speed, - &devid, &socket, lbusid); + &devid, &sockfd, lbusid);
if (ret < 5) { dbg("sscanf failed: %d", ret); @@ -69,7 +69,7 @@ static int parse_status(const char *valu
dbg("port %d status %d speed %d devid %x", port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + dbg("sockfd %u lbusid %s", sockfd, lbusid);
/* if a device is connected, look at it */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault g.nault@alphalink.fr
commit 3953ae7b218df4d1e544b98a393666f9ae58a78c upstream.
Sessions created by l2tp_session_create() aren't fully initialised: some pseudo-wire specific operations need to be done before making the session usable. Therefore the PPP and Ethernet pseudo-wires continue working on the returned l2tp session while it's already been exposed to the rest of the system. This can lead to various issues. In particular, the session may enter the deletion process before having been fully initialised, which will confuse the session removal code.
This patch moves session registration out of l2tp_session_create(), so that callers can control when the session is exposed to the rest of the system. This is done by the new l2tp_session_register() function.
Only pppol2tp_session_create() can be easily converted to avoid modifying its session after registration (the debug message is dropped in order to avoid the need for holding a reference on the session).
For pppol2tp_connect() and l2tp_eth_create()), more work is needed. That'll be done in followup patches. For now, let's just register the session right after its creation, like it was done before. The only difference is that we can easily take a reference on the session before registering it, so, at least, we're sure it's not going to be freed while we're working on it.
Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/l2tp/l2tp_core.c | 21 +++++++-------------- net/l2tp/l2tp_core.h | 3 +++ net/l2tp/l2tp_eth.c | 9 +++++++++ net/l2tp/l2tp_ppp.c | 23 +++++++++++++++++------ 4 files changed, 36 insertions(+), 20 deletions(-)
--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -370,8 +370,8 @@ struct l2tp_session *l2tp_session_get_by } EXPORT_SYMBOL_GPL(l2tp_session_get_by_ifname);
-static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, - struct l2tp_session *session) +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel) { struct l2tp_session *session_walk; struct hlist_head *g_head; @@ -419,6 +419,10 @@ static int l2tp_session_add_to_tunnel(st hlist_add_head(&session->hlist, head); write_unlock_bh(&tunnel->hlist_lock);
+ /* Ignore management session in session count value */ + if (session->session_id != 0) + atomic_inc(&l2tp_session_count); + return 0;
err_tlock_pnlock: @@ -428,6 +432,7 @@ err_tlock:
return err; } +EXPORT_SYMBOL_GPL(l2tp_session_register);
/* Lookup a tunnel by id */ @@ -1868,7 +1873,6 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_heade struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct l2tp_session *session; - int err;
session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL); if (session != NULL) { @@ -1926,17 +1930,6 @@ struct l2tp_session *l2tp_session_create
l2tp_session_inc_refcount(session);
- err = l2tp_session_add_to_tunnel(tunnel, session); - if (err) { - kfree(session); - - return ERR_PTR(err); - } - - /* Ignore management session in session count value */ - if (session->session_id != 0) - atomic_inc(&l2tp_session_count); - return session; }
--- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -274,6 +274,9 @@ struct l2tp_session *l2tp_session_create struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel); + void __l2tp_session_unhash(struct l2tp_session *session); int l2tp_session_delete(struct l2tp_session *session); void l2tp_session_free(struct l2tp_session *session); --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -217,6 +217,13 @@ static int l2tp_eth_create(struct net *n goto out; }
+ l2tp_session_inc_refcount(session); + rc = l2tp_session_register(session, tunnel); + if (rc < 0) { + kfree(session); + goto out; + } + dev = alloc_netdev(sizeof(*priv), name, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; @@ -250,6 +257,7 @@ static int l2tp_eth_create(struct net *n __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); + l2tp_session_dec_refcount(session);
dev_hold(dev);
@@ -260,6 +268,7 @@ out_del_dev: spriv->dev = NULL; out_del_session: l2tp_session_delete(session); + l2tp_session_dec_refcount(session); out: return rc; } --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -737,6 +737,14 @@ static int pppol2tp_connect(struct socke error = PTR_ERR(session); goto end; } + + l2tp_session_inc_refcount(session); + error = l2tp_session_register(session, tunnel); + if (error < 0) { + kfree(session); + goto end; + } + drop_refcnt = true; }
/* Associate session with its PPPoL2TP socket */ @@ -824,7 +832,7 @@ static int pppol2tp_session_create(struc /* Error if tunnel socket is not prepped */ if (!tunnel->sock) { error = -ENOENT; - goto out; + goto err; }
/* Default MTU values. */ @@ -839,18 +847,21 @@ static int pppol2tp_session_create(struc peer_session_id, cfg); if (IS_ERR(session)) { error = PTR_ERR(session); - goto out; + goto err; }
ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock;
- l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", - session->name); - - error = 0; - -out: + error = l2tp_session_register(session, tunnel); + if (error < 0) + goto err_sess; + + return 0; + +err_sess: + kfree(session); +err: return error; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Viktor Slavkovic viktors@google.com
commit 443064cb0b1fb4569fe0a71209da7625129fb760 upstream.
A lock-unlock is missing in ASHMEM_SET_SIZE ioctl which can result in a race condition when mmap is called. After the !asma->file check, before setting asma->size, asma->file can be set in mmap. That would result in having different asma->size than the mapped memory size. Combined with ASHMEM_UNPIN ioctl and shrinker invocation, this can result in memory corruption.
Signed-off-by: Viktor Slavkovic viktors@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/android/ashmem.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -758,10 +758,12 @@ static long ashmem_ioctl(struct file *fi break; case ASHMEM_SET_SIZE: ret = -EINVAL; + mutex_lock(&ashmem_mutex); if (!asma->file) { ret = 0; asma->size = (size_t) arg; } + mutex_unlock(&ashmem_mutex); break; case ASHMEM_GET_SIZE: ret = asma->size;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ladi Prosek lprosek@redhat.com
commit 21f2d551183847bc7fbe8d866151d00cdad18752 upstream.
Intel SDM 27.5.2 Loading Host Segment and Descriptor-Table Registers:
"The GDTR and IDTR limits are each set to FFFFH."
Signed-off-by: Ladi Prosek lprosek@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/vmx.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8695,6 +8695,8 @@ static void load_vmcs12_host_state(struc vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->host_ia32_sysenter_eip); vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base); vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base); + vmcs_write32(GUEST_IDTR_LIMIT, 0xFFFF); + vmcs_write32(GUEST_GDTR_LIMIT, 0xFFFF);
/* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski luto@kernel.org
commit dac16fba6fc590fa7239676b35ed75dae4c4cd2b upstream.
Signed-off-by: Andy Lutomirski luto@kernel.org Reviewed-by: Paolo Bonzini pbonzini@redhat.com Cc: Andy Lutomirski luto@amacapital.net Cc: Borislav Petkov bp@alien8.de Cc: Brian Gerst brgerst@gmail.com Cc: Denys Vlasenko dvlasenk@redhat.com Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/9d37826fdc7e2d2809efe31d5345f97186859284.1449702533... Signed-off-by: Ingo Molnar mingo@kernel.org [bwh: Backported to 3.16: adjust filenames] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/vdso/vclock_gettime.c | 20 ++++++++------------ arch/x86/vdso/vdso-layout.lds.S | 3 ++- arch/x86/vdso/vdso2c.c | 3 +++ arch/x86/vdso/vma.c | 13 +++++++++++++ arch/x86/include/asm/pvclock.h | 9 +++++++++ arch/x86/include/asm/vdso.h | 1 + arch/x86/kernel/kvmclock.c | 5 +++++ 7 files changed, 41 insertions(+), 13 deletions(-)
--- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -36,6 +36,11 @@ static notrace cycle_t vread_hpet(void) } #endif
+#ifdef CONFIG_PARAVIRT_CLOCK +extern u8 pvclock_page + __attribute__((visibility("hidden"))); +#endif + #ifndef BUILD_VDSO32
#include <linux/kernel.h> @@ -62,23 +67,14 @@ notrace static long vdso_fallback_gtod(s
#ifdef CONFIG_PARAVIRT_CLOCK
-static notrace const struct pvclock_vsyscall_time_info *get_pvti(int cpu) +static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void) { - const struct pvclock_vsyscall_time_info *pvti_base; - int idx = cpu / (PAGE_SIZE/PVTI_SIZE); - int offset = cpu % (PAGE_SIZE/PVTI_SIZE); - - BUG_ON(PVCLOCK_FIXMAP_BEGIN + idx > PVCLOCK_FIXMAP_END); - - pvti_base = (struct pvclock_vsyscall_time_info *) - __fix_to_virt(PVCLOCK_FIXMAP_BEGIN+idx); - - return &pvti_base[offset]; + return (const struct pvclock_vsyscall_time_info *)&pvclock_page; }
static notrace cycle_t vread_pvclock(int *mode) { - const struct pvclock_vcpu_time_info *pvti = &get_pvti(0)->pvti; + const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; cycle_t ret; u64 tsc, pvti_tsc; u64 last, delta, pvti_system_time; --- a/arch/x86/vdso/vdso-layout.lds.S +++ b/arch/x86/vdso/vdso-layout.lds.S @@ -25,7 +25,7 @@ SECTIONS * segment. */
- vvar_start = . - 2 * PAGE_SIZE; + vvar_start = . - 3 * PAGE_SIZE; vvar_page = vvar_start;
/* Place all vvars at the offsets in asm/vvar.h. */ @@ -36,6 +36,7 @@ SECTIONS #undef EMIT_VVAR
hpet_page = vvar_start + PAGE_SIZE; + pvclock_page = vvar_start + 2 * PAGE_SIZE;
. = SIZEOF_HEADERS;
--- a/arch/x86/vdso/vdso2c.c +++ b/arch/x86/vdso/vdso2c.c @@ -23,6 +23,7 @@ enum { sym_vvar_start, sym_vvar_page, sym_hpet_page, + sym_pvclock_page, sym_VDSO_FAKE_SECTION_TABLE_START, sym_VDSO_FAKE_SECTION_TABLE_END, }; @@ -30,6 +31,7 @@ enum { const int special_pages[] = { sym_vvar_page, sym_hpet_page, + sym_pvclock_page, };
struct vdso_sym { @@ -41,6 +43,7 @@ struct vdso_sym required_syms[] = { [sym_vvar_start] = {"vvar_start", true}, [sym_vvar_page] = {"vvar_page", true}, [sym_hpet_page] = {"hpet_page", true}, + [sym_pvclock_page] = {"pvclock_page", true}, [sym_VDSO_FAKE_SECTION_TABLE_START] = { "VDSO_FAKE_SECTION_TABLE_START", false }, --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c @@ -113,6 +113,7 @@ static int map_vdso(const struct vdso_im .name = "[vvar]", .pages = no_pages, }; + struct pvclock_vsyscall_time_info *pvti;
if (calculate_addr) { addr = vdso_addr(current->mm->start_stack, @@ -182,6 +183,18 @@ static int map_vdso(const struct vdso_im } #endif
+ pvti = pvclock_pvti_cpu0_va(); + if (pvti && image->sym_pvclock_page) { + ret = remap_pfn_range(vma, + text_start + image->sym_pvclock_page, + __pa(pvti) >> PAGE_SHIFT, + PAGE_SIZE, + PAGE_READONLY); + + if (ret) + goto up_fail; + } + up_fail: if (ret) current->mm->context.vdso = NULL; --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -4,6 +4,15 @@ #include <linux/clocksource.h> #include <asm/pvclock-abi.h>
+#ifdef CONFIG_PARAVIRT_CLOCK +extern struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void); +#else +static inline struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void) +{ + return NULL; +} +#endif + /* some helper functions for xen and kvm pv clock sources */ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src); --- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h @@ -22,6 +22,7 @@ struct vdso_image {
long sym_vvar_page; long sym_hpet_page; + long sym_pvclock_page; long sym_VDSO32_NOTE_MASK; long sym___kernel_sigreturn; long sym___kernel_rt_sigreturn; --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -44,6 +44,11 @@ early_param("no-kvmclock", parse_no_kvmc static struct pvclock_vsyscall_time_info *hv_clock; static struct pvclock_wall_clock wall_clock;
+struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void) +{ + return hv_clock; +} + /* * The wallclock is the time of day when we booted. Since then, some time may * have elapsed since the hypervisor wrote the data. So we try to account for
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: James Morse james.morse@arm.com
commit 520e18a5080d2c444a03280d99c8a35cb667d321 upstream.
Now that nothing is using the ghes_ioremap_area pages, rip them out.
Signed-off-by: James Morse james.morse@arm.com Reviewed-by: Borislav Petkov bp@suse.de Tested-by: Tyler Baicar tbaicar@codeaurora.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com [bwh: Backported to 3.16: - Delete additional call to ghes_ioremap_exit() from ghes_exit() - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/acpi/apei/ghes.c | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-)
--- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -112,19 +112,7 @@ static DEFINE_RAW_SPINLOCK(ghes_nmi_lock * from BIOS to Linux can be determined only in NMI, IRQ or timer * handler, but general ioremap can not be used in atomic context, so * the fixmap is used instead. - */ - -/* - * Two virtual pages are used, one for NMI context, the other for - * IRQ/PROCESS context - */ -#define GHES_IOREMAP_PAGES 2 -#define GHES_IOREMAP_NMI_PAGE(base) (base) -#define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE) - -/* virtual memory area for atomic ioremap */ -static struct vm_struct *ghes_ioremap_area; -/* + * * These 2 spinlocks are used to prevent the fixmap entries from being used * simultaneously. */ @@ -147,23 +135,6 @@ static struct irq_work ghes_proc_irq_wor struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; static atomic_t ghes_estatus_cache_alloced;
-static int ghes_ioremap_init(void) -{ - ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, - VM_IOREMAP, VMALLOC_START, VMALLOC_END); - if (!ghes_ioremap_area) { - pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n"); - return -ENOMEM; - } - - return 0; -} - -static void ghes_ioremap_exit(void) -{ - free_vm_area(ghes_ioremap_area); -} - static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) { __set_fixmap(FIX_APEI_GHES_NMI, pfn << PAGE_SHIFT, PAGE_KERNEL); @@ -1063,13 +1034,9 @@ static int __init ghes_init(void)
init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq);
- rc = ghes_ioremap_init(); - if (rc) - goto err; - rc = ghes_estatus_pool_init(); if (rc) - goto err_ioremap_exit; + goto err;
rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX); @@ -1093,8 +1060,6 @@ static int __init ghes_init(void) return 0; err_pool_exit: ghes_estatus_pool_exit(); -err_ioremap_exit: - ghes_ioremap_exit(); err: return rc; } @@ -1103,7 +1068,6 @@ static void __exit ghes_exit(void) { platform_driver_unregister(&ghes_platform_driver); ghes_estatus_pool_exit(); - ghes_ioremap_exit(); }
module_init(ghes_init);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Zhou Chengming zhouchengming1@huawei.com
commit e846d13958066828a9483d862cc8370a72fadbb6 upstream.
We use alternatives_text_reserved() to check if the address is in the fixed pieces of alternative reserved, but the problem is that we don't hold the smp_alt mutex when call this function. So the list traversal may encounter a deleted list_head if another path is doing alternatives_smp_module_del().
One solution is that we can hold smp_alt mutex before call this function, but the difficult point is that the callers of this functions, arch_prepare_kprobe() and arch_prepare_optimized_kprobe(), are called inside the text_mutex. So we must hold smp_alt mutex before we go into these arch dependent code. But we can't now, the smp_alt mutex is the arch dependent part, only x86 has it. Maybe we can export another arch dependent callback to solve this.
But there is a simpler way to handle this problem. We can reuse the text_mutex to protect smp_alt_modules instead of using another mutex. And all the arch dependent checks of kprobes are inside the text_mutex, so it's safe now.
Signed-off-by: Zhou Chengming zhouchengming1@huawei.com Reviewed-by: Masami Hiramatsu mhiramat@kernel.org Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org Cc: Andy Lutomirski luto@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Brian Gerst brgerst@gmail.com Cc: Denys Vlasenko dvlasenk@redhat.com Cc: H. Peter Anvin hpa@zytor.com Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: bp@suse.de Fixes: 2cfa197 "ftrace/alternatives: Introducing *_text_reserved functions" Link: http://lkml.kernel.org/r/1509585501-79466-1-git-send-email-zhouchengming1@hu... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kernel/alternative.c | 26 +++++++++++++------------- kernel/extable.c | 2 ++ 2 files changed, 15 insertions(+), 13 deletions(-)
--- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -409,7 +409,6 @@ static void alternatives_smp_lock(const { const s32 *poff;
- mutex_lock(&text_mutex); for (poff = start; poff < end; poff++) { u8 *ptr = (u8 *)poff + *poff;
@@ -419,7 +418,6 @@ static void alternatives_smp_lock(const if (*ptr == 0x3e) text_poke(ptr, ((unsigned char []){0xf0}), 1); } - mutex_unlock(&text_mutex); }
static void alternatives_smp_unlock(const s32 *start, const s32 *end, @@ -427,7 +425,6 @@ static void alternatives_smp_unlock(cons { const s32 *poff;
- mutex_lock(&text_mutex); for (poff = start; poff < end; poff++) { u8 *ptr = (u8 *)poff + *poff;
@@ -437,7 +434,6 @@ static void alternatives_smp_unlock(cons if (*ptr == 0xf0) text_poke(ptr, ((unsigned char []){0x3E}), 1); } - mutex_unlock(&text_mutex); }
struct smp_alt_module { @@ -456,8 +452,7 @@ struct smp_alt_module { struct list_head next; }; static LIST_HEAD(smp_alt_modules); -static DEFINE_MUTEX(smp_alt); -static bool uniproc_patched = false; /* protected by smp_alt */ +static bool uniproc_patched = false; /* protected by text_mutex */
void __init_or_module alternatives_smp_module_add(struct module *mod, char *name, @@ -466,7 +461,7 @@ void __init_or_module alternatives_smp_m { struct smp_alt_module *smp;
- mutex_lock(&smp_alt); + mutex_lock(&text_mutex); if (!uniproc_patched) goto unlock;
@@ -493,14 +488,14 @@ void __init_or_module alternatives_smp_m smp_unlock: alternatives_smp_unlock(locks, locks_end, text, text_end); unlock: - mutex_unlock(&smp_alt); + mutex_unlock(&text_mutex); }
void __init_or_module alternatives_smp_module_del(struct module *mod) { struct smp_alt_module *item;
- mutex_lock(&smp_alt); + mutex_lock(&text_mutex); list_for_each_entry(item, &smp_alt_modules, next) { if (mod != item->mod) continue; @@ -508,7 +503,7 @@ void __init_or_module alternatives_smp_m kfree(item); break; } - mutex_unlock(&smp_alt); + mutex_unlock(&text_mutex); }
void alternatives_enable_smp(void) @@ -518,7 +513,7 @@ void alternatives_enable_smp(void) /* Why bother if there are no other CPUs? */ BUG_ON(num_possible_cpus() == 1);
- mutex_lock(&smp_alt); + mutex_lock(&text_mutex);
if (uniproc_patched) { pr_info("switching to SMP code\n"); @@ -530,10 +525,13 @@ void alternatives_enable_smp(void) mod->text, mod->text_end); uniproc_patched = false; } - mutex_unlock(&smp_alt); + mutex_unlock(&text_mutex); }
-/* Return 1 if the address range is reserved for smp-alternatives */ +/* + * Return 1 if the address range is reserved for SMP-alternatives. + * Must hold text_mutex. + */ int alternatives_text_reserved(void *start, void *end) { struct smp_alt_module *mod; @@ -541,6 +539,8 @@ int alternatives_text_reserved(void *sta u8 *text_start = start; u8 *text_end = end;
+ lockdep_assert_held(&text_mutex); + list_for_each_entry(mod, &smp_alt_modules, next) { if (mod->text > text_end || mod->text_end < text_start) continue; --- a/kernel/extable.c +++ b/kernel/extable.c @@ -28,6 +28,8 @@ * mutex protecting text section modification (dynamic code patching). * some users need to sleep (allocating memory...) while they hold this lock. * + * Note: Also protects SMP-alternatives modification on x86. + * * NOT exported to modules - patching kernel text is a really delicate matter. */ DEFINE_MUTEX(text_mutex);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Doug Berger opendmb@gmail.com
commit 28c2d1a7a0bfdf3617800d2beae1c67983c03d15 upstream.
It is necessary for the UniMAC to be clocked at least 5 cycles while the sw_reset is asserted to ensure a clean reset.
It was discovered that this condition was not being met when connected to an external RGMII PHY that disabled the Rx clock in the Power Save state.
This commit modifies the reset_umac function to place the (RG)MII interface into a local loopback mode where the Rx clock comes from the GENET sourced Tx clk during the sw_reset to ensure the presence and stability of the clock.
In addition, it turns out that the sw_reset of the UniMAC is not self clearing, but this was masked by a bug in the timeout code.
The sw_reset is now explicitly cleared by zeroing the UMAC_CMD register before returning from reset_umac which makes it no longer necessary to do so in init_umac and makes the clearing of CMD_TX_EN and CMD_RX_EN by umac_enable_set redundant. The timeout code (and its associated bug) are removed so reset_umac no longer needs to return a result, and that means init_umac that calls reset_umac does not need to as well.
Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") Signed-off-by: Doug Berger opendmb@gmail.com Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: - Update call to init_umac() in bcmgenet_wol_resume() - Drop changes in bcmgenet_resume() - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1509,12 +1509,8 @@ static void bcmgenet_free_rx_buffers(str } }
-static int reset_umac(struct bcmgenet_priv *priv) +static void reset_umac(struct bcmgenet_priv *priv) { - struct device *kdev = &priv->pdev->dev; - unsigned int timeout = 0; - u32 reg; - /* 7358a0/7552a0: bad default in RBUF_FLUSH_CTRL.umac_sw_rst */ bcmgenet_rbuf_ctrl_set(priv, 0); udelay(10); @@ -1522,38 +1518,21 @@ static int reset_umac(struct bcmgenet_pr /* disable MAC while updating its registers */ bcmgenet_umac_writel(priv, 0, UMAC_CMD);
- /* issue soft reset, wait for it to complete */ - bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); - while (timeout++ < 1000) { - reg = bcmgenet_umac_readl(priv, UMAC_CMD); - if (!(reg & CMD_SW_RESET)) - return 0; - - udelay(1); - } - - if (timeout == 1000) { - dev_err(kdev, - "timeout waiting for MAC to come out of resetn\n"); - return -ETIMEDOUT; - } - - return 0; + /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */ + bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD); + udelay(2); + bcmgenet_umac_writel(priv, 0, UMAC_CMD); }
-static int init_umac(struct bcmgenet_priv *priv) +static void init_umac(struct bcmgenet_priv *priv) { struct device *kdev = &priv->pdev->dev; - int ret; u32 reg, cpu_mask_clear;
dev_dbg(&priv->pdev->dev, "bcmgenet: init_umac\n");
- ret = reset_umac(priv); - if (ret) - return ret; + reset_umac(priv);
- bcmgenet_umac_writel(priv, 0, UMAC_CMD); /* clear tx/rx counter */ bcmgenet_umac_writel(priv, MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT, UMAC_MIB_CTRL); @@ -1604,8 +1583,6 @@ static int init_umac(struct bcmgenet_pri
/* Enable rx/tx engine.*/ dev_dbg(kdev, "done init umac\n"); - - return 0; }
/* Initialize all house-keeping variables for a TX ring, along @@ -1994,14 +1971,10 @@ static void bcmgenet_set_hw_addr(struct
static int bcmgenet_wol_resume(struct bcmgenet_priv *priv) { - int ret; - /* From WOL-enabled suspend, switch to regular clock */ clk_disable(priv->clk_wol); /* init umac registers to synchronize s/w with h/w */ - ret = init_umac(priv); - if (ret) - return ret; + init_umac(priv);
phy_init_hw(priv->phydev); /* Speed settings must be restored */ @@ -2062,14 +2035,7 @@ static int bcmgenet_open(struct net_devi /* take MAC out of reset */ bcmgenet_umac_reset(priv);
- ret = init_umac(priv); - if (ret) - goto err_clk_disable; - - /* disable ethernet MAC while updating its registers */ - reg = bcmgenet_umac_readl(priv, UMAC_CMD); - reg &= ~(CMD_TX_EN | CMD_RX_EN); - bcmgenet_umac_writel(priv, reg, UMAC_CMD); + init_umac(priv);
bcmgenet_set_hw_addr(priv, dev->dev_addr);
@@ -2603,9 +2569,7 @@ static int bcmgenet_probe(struct platfor !strcasecmp(phy_mode_str, "internal")) bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
- err = reset_umac(priv); - if (err) - goto err_clk_disable; + reset_umac(priv);
err = bcmgenet_mii_init(dev); if (err)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown neilb@suse.com
commit ecc0c469f27765ed1e2b967be0aa17cee1a60b76 upstream.
Currently if the autofs kernel module gets an error when writing to the pipe which links to the daemon, then it marks the whole moutpoint as catatonic, and it will stop working.
It is possible that the error is transient. This can happen if the daemon is slow and more than 16 requests queue up. If a subsequent process tries to queue a request, and is then signalled, the write to the pipe will return -ERESTARTSYS and autofs will take that as total failure.
So change the code to assess -ERESTARTSYS and -ENOMEM as transient failures which only abort the current request, not the whole mountpoint.
It isn't a crash or a data corruption, but having autofs mountpoints suddenly stop working is rather inconvenient.
Ian said:
: And given the problems with a half dozen (or so) user space applications : consuming large amounts of CPU under heavy mount and umount activity this : could happen more easily than we expect.
Link: http://lkml.kernel.org/r/87y3norvgp.fsf@notabene.neil.brown.name Signed-off-by: NeilBrown neilb@suse.com Acked-by: Ian Kent raven@themaw.net Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/autofs4/waitq.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
--- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -87,7 +87,8 @@ static int autofs4_write(struct autofs_s spin_unlock_irqrestore(¤t->sighand->siglock, flags); }
- return (bytes > 0); + /* if 'wr' returned 0 (impossible) we assume -EIO (safe) */ + return bytes == 0 ? 0 : wr < 0 ? wr : -EIO; } static void autofs4_notify_daemon(struct autofs_sb_info *sbi, @@ -101,6 +102,7 @@ static void autofs4_notify_daemon(struct } pkt; struct file *pipe = NULL; size_t pktsz; + int ret;
DPRINTK("wait id = 0x%08lx, name = %.*s, type=%d", (unsigned long) wq->wait_queue_token, wq->name.len, wq->name.name, type); @@ -173,7 +175,18 @@ static void autofs4_notify_daemon(struct mutex_unlock(&sbi->wq_mutex);
if (autofs4_write(sbi, pipe, &pkt, pktsz)) + switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { + case 0: + break; + case -ENOMEM: + case -ERESTARTSYS: + /* Just fail this one */ + autofs4_wait_release(sbi, wq->wait_queue_token, ret); + break; + default: autofs4_catatonic_mode(sbi); + break; + } fput(pipe); }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger nab@linux-iscsi.org
commit ae072726f6109bb1c94841d6fb3a82dde298ea85 upstream.
Since commit 59b6986dbf fixed a potential NULL pointer dereference by allocating a se_tmr_req for ISCSI_TM_FUNC_TASK_REASSIGN, the se_tmr_req is currently leaked by iscsit_free_cmd() because no iscsi_cmd->se_cmd.se_tfo was associated.
To address this, treat ISCSI_TM_FUNC_TASK_REASSIGN like any other TMR and call transport_init_se_cmd() + target_get_sess_cmd() to setup iscsi_cmd->se_cmd.se_tfo with se_cmd->cmd_kref of 2.
This will ensure normal release operation once se_cmd->cmd_kref reaches zero and target_release_cmd_kref() is invoked, se_tmr_req will be released via existing target_free_cmd_mem() and core_tmr_release_req() code.
Reported-by: Donald White dew@datera.io Cc: Donald White dew@datera.io Cc: Mike Christie mchristi@redhat.com Cc: Hannes Reinecke hare@suse.com Signed-off-by: Nicholas Bellinger nab@linux-iscsi.org [bwh: Backported to 3.16: Arguments passed to transport_init_se_cmd() and target_{get,put}_sess_cmd() are different] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/target/iscsi/iscsi_target.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
--- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1753,7 +1753,6 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ struct iscsi_tmr_req *tmr_req; struct iscsi_tm *hdr; int out_of_order_cmdsn = 0, ret; - bool sess_ref = false; u8 function, tcm_function = TMR_UNKNOWN;
hdr = (struct iscsi_tm *) buf; @@ -1795,19 +1794,18 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ buf); }
+ transport_init_se_cmd(&cmd->se_cmd, + &lio_target_fabric_configfs->tf_ops, + conn->sess->se_sess, 0, DMA_NONE, + MSG_SIMPLE_TAG, cmd->sense_buffer + 2); + + target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); + /* * TASK_REASSIGN for ERL=2 / connection stays inside of * LIO-Target $FABRIC_MOD */ if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { - transport_init_se_cmd(&cmd->se_cmd, - &lio_target_fabric_configfs->tf_ops, - conn->sess->se_sess, 0, DMA_NONE, - MSG_SIMPLE_TAG, cmd->sense_buffer + 2); - - target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); - sess_ref = true; - switch (function) { case ISCSI_TM_FUNC_ABORT_TASK: tcm_function = TMR_ABORT_TASK; @@ -1944,12 +1942,8 @@ attach: * For connection recovery, this is also the default action for * TMR TASK_REASSIGN. */ - if (sess_ref) { - pr_debug("Handle TMR, using sess_ref=true check\n"); - target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); - } - iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); + target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); return 0; } EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger nab@linux-iscsi.org
commit 1c21a48055a67ceb693e9c2587824a8de60a217c upstream.
This patch fixes bug where early se_cmd exceptions that occur before backend execution can result in use-after-free if/when a subsequent ABORT_TASK occurs for the same tag.
Since an early se_cmd exception will have had se_cmd added to se_session->sess_cmd_list via target_get_sess_cmd(), it will not have CMD_T_COMPLETE set by the usual target_complete_cmd() backend completion path.
This causes a subsequent ABORT_TASK + __target_check_io_state() to signal ABORT_TASK should proceed. As core_tmr_abort_task() executes, it will bring the outstanding se_cmd->cmd_kref count down to zero releasing se_cmd, after se_cmd has already been queued with error status into fabric driver response path code.
To address this bug, introduce a CMD_T_PRE_EXECUTE bit that is set at target_get_sess_cmd() time, and cleared immediately before backend driver dispatch in target_execute_cmd() once CMD_T_ACTIVE is set.
Then, check CMD_T_PRE_EXECUTE within __target_check_io_state() to determine when an early exception has occured, and avoid aborting this se_cmd since it will have already been queued into fabric driver response path code.
Reported-by: Donald White dew@datera.io Cc: Donald White dew@datera.io Cc: Mike Christie mchristi@redhat.com Cc: Hannes Reinecke hare@suse.com Signed-off-by: Nicholas Bellinger nab@linux-iscsi.org [bwh: Backported to 3.16: - Use target_core_fabric_ops::get_task_tag to get the tag and %u to format it - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/target/target_core_tmr.c | 9 +++++++++ drivers/target/target_core_transport.c | 2 ++ include/target/target_core_base.h | 1 + 3 files changed, 12 insertions(+)
--- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -141,6 +141,16 @@ static bool __target_check_io_state(stru spin_unlock(&se_cmd->t_state_lock); return false; } + if (se_cmd->transport_state & CMD_T_PRE_EXECUTE) { + if (se_cmd->scsi_status) { + pr_debug("Attempted to abort io tag: %u early failure" + " status: 0x%02x\n", + se_cmd->se_tfo->get_task_tag(se_cmd), + se_cmd->scsi_status); + spin_unlock(&se_cmd->t_state_lock); + return false; + } + } if (sess->sess_tearing_down || se_cmd->cmd_wait_set) { pr_debug("Attempted to abort io tag: %u already shutdown," " skipping\n", se_cmd->se_tfo->get_task_tag(se_cmd)); --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1797,6 +1797,7 @@ void target_execute_cmd(struct se_cmd *c }
cmd->t_state = TRANSPORT_PROCESSING; + cmd->transport_state &= ~CMD_T_PRE_EXECUTE; cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT; spin_unlock_irq(&cmd->t_state_lock); /* @@ -2441,6 +2442,7 @@ int target_get_sess_cmd(struct se_sessio ret = -ESHUTDOWN; goto out; } + se_cmd->transport_state |= CMD_T_PRE_EXECUTE; list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); out: spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -536,6 +536,7 @@ struct se_cmd { #define CMD_T_BUSY (1 << 9) #define CMD_T_TAS (1 << 10) #define CMD_T_FABRIC_STOP (1 << 11) +#define CMD_T_PRE_EXECUTE (1 << 12) spinlock_t t_state_lock; struct completion t_transport_stop_comp;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Gabriele Paoloni gabriele.paoloni@huawei.com
commit 86acc790717fb60fb51ea3095084e331d8711c74 upstream.
Previously, if an non-fatal error was reported by an endpoint, we called report_error_detected() for the endpoint, every sibling on the bus, and their descendents. If any of them did not implement the .error_detected() method, do_recovery() failed, leaving all these devices unrecovered.
For example, the system described in the bugzilla below has two devices:
0000:74:02.0 [19e5:a230] SAS controller, driver has .error_detected() 0000:74:03.0 [19e5:a235] SATA controller, driver lacks .error_detected()
When a device such as 74:02.0 reported a non-fatal error, do_recovery() failed because 74:03.0 lacked an .error_detected() method. But per PCIe r3.1, sec 6.2.2.2.2, such an error does not compromise the Link and does not affect 74:03.0:
Non-fatal errors are uncorrectable errors which cause a particular transaction to be unreliable but the Link is otherwise fully functional. Isolating Non-fatal from Fatal errors provides Requester/Receiver logic in a device or system management software the opportunity to recover from the error without resetting the components on the Link and disturbing other transactions in progress. Devices not associated with the transaction in error are not impacted by the error.
Report non-fatal errors only to the endpoint that reported them. We really want to check for AER_NONFATAL here, but the current code structure doesn't allow that. Looking for pci_channel_io_normal is the best we can do now.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=197055 Fixes: 6c2b374d7485 ("PCI-Express AER implemetation: AER core and aerdriver") Signed-off-by: Gabriele Paoloni gabriele.paoloni@huawei.com Signed-off-by: Dongdong Liu liudongdong3@huawei.com [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/pci/pcie/aer/aerdrv_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -360,7 +360,14 @@ static pci_ers_result_t broadcast_error_ * If the error is reported by an end point, we think this * error is related to the upstream link of the end point. */ - pci_walk_bus(dev->bus, cb, &result_data); + if (state == pci_channel_io_normal) + /* + * the error is non fatal so the bus is ok, just invoke + * the callback for the function that logged the error. + */ + cb(dev, &result_data); + else + pci_walk_bus(dev->bus, cb, &result_data); }
return result_data.result;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Popov alpopov@ptsecurity.com
commit 8c7003a3b4b4afd3734cdcc39217ef22d78a4a16 upstream.
Fix NULL pointer dereference and obsolete comments forgotten when usbip server was converted from an interface driver to a device driver.
Signed-off-by: Alexander Popov alpopov@ptsecurity.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust filenames] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/usbip/stub.h | 1 - drivers/staging/usbip/stub_dev.c | 4 ++-- drivers/staging/usbip/stub_rx.c | 19 +++++++------------ drivers/staging/usbip/stub_tx.c | 6 +++--- 4 files changed, 12 insertions(+), 18 deletions(-)
--- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h @@ -33,7 +33,6 @@ #define STUB_BUSID_ALLOC 3
struct stub_device { - struct usb_interface *interface; struct usb_device *udev;
struct usbip_device ud; --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -246,7 +246,7 @@ static void stub_device_reset(struct usb
dev_dbg(&udev->dev, "device reset");
- ret = usb_lock_device_for_reset(udev, sdev->interface); + ret = usb_lock_device_for_reset(udev, NULL); if (ret < 0) { dev_err(&udev->dev, "lock for reset\n"); spin_lock_irq(&ud->lock); @@ -279,7 +279,7 @@ static void stub_device_unusable(struct
/** * stub_device_alloc - allocate a new stub_device struct - * @interface: usb_interface of a new device + * @udev: usb_device of a new device * * Allocates and initializes a new stub_device struct. */ --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -165,12 +165,7 @@ static int tweak_reset_device_cmd(struct
dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
- /* - * With the implementation of pre_reset and post_reset the driver no - * longer unbinds. This allows the use of synchronous reset. - */ - - if (usb_lock_device_for_reset(sdev->udev, sdev->interface) < 0) { + if (usb_lock_device_for_reset(sdev->udev, NULL) < 0) { dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); return 0; } @@ -321,7 +316,7 @@ static struct stub_priv *stub_priv_alloc
priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC); if (!priv) { - dev_err(&sdev->interface->dev, "alloc stub_priv\n"); + dev_err(&sdev->udev->dev, "alloc stub_priv\n"); spin_unlock_irqrestore(&sdev->priv_lock, flags); usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); return NULL; @@ -352,7 +347,7 @@ static int get_pipe(struct stub_device * else ep = udev->ep_out[epnum & 0x7f]; if (!ep) { - dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", + dev_err(&sdev->udev->dev, "no such endpoint?, %d\n", epnum); BUG(); } @@ -387,7 +382,7 @@ static int get_pipe(struct stub_device * }
/* NOT REACHED */ - dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum); + dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum); return 0; }
@@ -466,7 +461,7 @@ static void stub_recv_cmd_submit(struct priv->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!priv->urb) { - dev_err(&sdev->interface->dev, "malloc urb\n"); + dev_err(&udev->dev, "malloc urb\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); return; } @@ -486,7 +481,7 @@ static void stub_recv_cmd_submit(struct priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, GFP_KERNEL); if (!priv->urb->setup_packet) { - dev_err(&sdev->interface->dev, "allocate setup_packet\n"); + dev_err(&udev->dev, "allocate setup_packet\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); return; } @@ -517,7 +512,7 @@ static void stub_recv_cmd_submit(struct usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum); else { - dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret); + dev_err(&udev->dev, "submit_urb error, %d\n", ret); usbip_dump_header(pdu); usbip_dump_urb(priv->urb);
--- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -233,7 +233,7 @@ static int stub_send_ret_submit(struct s }
if (txsize != sizeof(pdu_header) + urb->actual_length) { - dev_err(&sdev->interface->dev, + dev_err(&sdev->udev->dev, "actual length of urb %d does not match iso packet sizes %zu\n", urb->actual_length, txsize-sizeof(pdu_header)); @@ -265,7 +265,7 @@ static int stub_send_ret_submit(struct s ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, iovnum, txsize); if (ret != txsize) { - dev_err(&sdev->interface->dev, + dev_err(&sdev->udev->dev, "sendmsg failed!, retval %d for %zd\n", ret, txsize); kfree(iov); @@ -340,7 +340,7 @@ static int stub_send_ret_unlink(struct s ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 1, txsize); if (ret != txsize) { - dev_err(&sdev->interface->dev, + dev_err(&sdev->udev->dev, "sendmsg failed!, retval %d for %zd\n", ret, txsize); usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault g.nault@alphalink.fr
commit ee28de6bbd78c2e18111a0aef43ea746f28d2073 upstream.
Sessions must be initialised before being made externally visible by l2tp_session_register(). Otherwise the session may be concurrently deleted before being initialised, which can confuse the deletion path and eventually lead to kernel oops.
Therefore, we need to move l2tp_session_register() down in l2tp_eth_create(), but also handle the intermediate step where only the session or the netdevice has been registered.
We can't just call l2tp_session_register() in ->ndo_init() because we'd have no way to properly undo this operation in ->ndo_uninit(). Instead, let's register the session and the netdevice in two different steps and protect the session's device pointer with RCU.
And now that we allow the session's .dev field to be NULL, we don't need to prevent the netdevice from being removed anymore. So we can drop the dev_hold() and dev_put() calls in l2tp_eth_create() and l2tp_eth_dev_uninit().
Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: - Update another 'goto out' in l2tp_eth_create() - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -51,7 +51,7 @@ struct l2tp_eth {
/* via l2tp_session_priv() */ struct l2tp_eth_sess { - struct net_device *dev; + struct net_device __rcu *dev; };
@@ -69,7 +69,14 @@ static int l2tp_eth_dev_init(struct net_
static void l2tp_eth_dev_uninit(struct net_device *dev) { - dev_put(dev); + struct l2tp_eth *priv = netdev_priv(dev); + struct l2tp_eth_sess *spriv; + + spriv = l2tp_session_priv(priv->session); + RCU_INIT_POINTER(spriv->dev, NULL); + /* No need for synchronize_net() here. We're called by + * unregister_netdev*(), which does the synchronisation for us. + */ }
static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) @@ -123,8 +130,8 @@ static void l2tp_eth_dev_setup(struct ne static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) { struct l2tp_eth_sess *spriv = l2tp_session_priv(session); - struct net_device *dev = spriv->dev; - struct l2tp_eth *priv = netdev_priv(dev); + struct net_device *dev; + struct l2tp_eth *priv;
if (session->debug & L2TP_MSG_DATA) { unsigned int length; @@ -148,16 +155,25 @@ static void l2tp_eth_dev_recv(struct l2t skb_dst_drop(skb); nf_reset(skb);
+ rcu_read_lock(); + dev = rcu_dereference(spriv->dev); + if (!dev) + goto error_rcu; + + priv = netdev_priv(dev); if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { atomic_long_inc(&priv->rx_packets); atomic_long_add(data_len, &priv->rx_bytes); } else { atomic_long_inc(&priv->rx_errors); } + rcu_read_unlock(); + return;
+error_rcu: + rcu_read_unlock(); error: - atomic_long_inc(&priv->rx_errors); kfree_skb(skb); }
@@ -168,11 +184,15 @@ static void l2tp_eth_delete(struct l2tp_
if (session) { spriv = l2tp_session_priv(session); - dev = spriv->dev; + + rtnl_lock(); + dev = rtnl_dereference(spriv->dev); if (dev) { - unregister_netdev(dev); - spriv->dev = NULL; + unregister_netdevice(dev); + rtnl_unlock(); module_put(THIS_MODULE); + } else { + rtnl_unlock(); } } } @@ -182,9 +202,20 @@ static void l2tp_eth_show(struct seq_fil { struct l2tp_session *session = arg; struct l2tp_eth_sess *spriv = l2tp_session_priv(session); - struct net_device *dev = spriv->dev; + struct net_device *dev; + + rcu_read_lock(); + dev = rcu_dereference(spriv->dev); + if (!dev) { + rcu_read_unlock(); + return; + } + dev_hold(dev); + rcu_read_unlock();
seq_printf(m, " interface %s\n", dev->name); + + dev_put(dev); } #endif
@@ -204,7 +235,7 @@ static int l2tp_eth_create(struct net *n if (dev) { dev_put(dev); rc = -EEXIST; - goto out; + goto err; } strlcpy(name, cfg->ifname, IFNAMSIZ); } else @@ -214,20 +245,13 @@ static int l2tp_eth_create(struct net *n peer_session_id, cfg); if (IS_ERR(session)) { rc = PTR_ERR(session); - goto out; - } - - l2tp_session_inc_refcount(session); - rc = l2tp_session_register(session, tunnel); - if (rc < 0) { - kfree(session); - goto out; + goto err; }
dev = alloc_netdev(sizeof(*priv), name, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; - goto out_del_session; + goto err_sess; }
dev_net_set(dev, net); @@ -248,28 +272,48 @@ static int l2tp_eth_create(struct net *n #endif
spriv = l2tp_session_priv(session); - spriv->dev = dev;
- rc = register_netdev(dev); - if (rc < 0) - goto out_del_dev; + l2tp_session_inc_refcount(session); + + rtnl_lock(); + + /* Register both device and session while holding the rtnl lock. This + * ensures that l2tp_eth_delete() will see that there's a device to + * unregister, even if it happened to run before we assign spriv->dev. + */ + rc = l2tp_session_register(session, tunnel); + if (rc < 0) { + rtnl_unlock(); + goto err_sess_dev; + } + + rc = register_netdevice(dev); + if (rc < 0) { + rtnl_unlock(); + l2tp_session_delete(session); + l2tp_session_dec_refcount(session); + free_netdev(dev); + + return rc; + }
- __module_get(THIS_MODULE); - /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); + rcu_assign_pointer(spriv->dev, dev); + + rtnl_unlock(); + l2tp_session_dec_refcount(session);
- dev_hold(dev); + __module_get(THIS_MODULE);
return 0;
-out_del_dev: - free_netdev(dev); - spriv->dev = NULL; -out_del_session: - l2tp_session_delete(session); +err_sess_dev: l2tp_session_dec_refcount(session); -out: + free_netdev(dev); +err_sess: + kfree(session); +err: return rc; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault g.nault@alphalink.fr
commit ee40fb2e1eb5bc0ddd3f2f83c6e39a454ef5a741 upstream.
pppol2tp_session_create() registers sessions that can't have their corresponding socket initialised. This socket has to be created by userspace, then connected to the session by pppol2tp_connect(). Therefore, we need to protect the pppol2tp socket pointer of L2TP sessions, so that it can safely be updated when userspace is connecting or closing the socket. This will eventually allow pppol2tp_connect() to avoid generating transient states while initialising its parts of the session.
To this end, this patch protects the pppol2tp socket pointer using RCU.
The pppol2tp socket pointer is still set in pppol2tp_connect(), but only once we know the function isn't going to fail. It's eventually reset by pppol2tp_release(), which now has to wait for a grace period to elapse before it can drop the last reference on the socket. This ensures that pppol2tp_session_get_sock() can safely grab a reference on the socket, even after ps->sk is reset to NULL but before this operation actually gets visible from pppol2tp_session_get_sock().
The rest is standard RCU conversion: pppol2tp_recv(), which already runs in atomic context, is simply enclosed by rcu_read_lock() and rcu_read_unlock(), while other functions are converted to use pppol2tp_session_get_sock() followed by sock_put(). pppol2tp_session_setsockopt() is a special case. It used to retrieve the pppol2tp socket from the L2TP session, which itself was retrieved from the pppol2tp socket. Therefore we can just avoid dereferencing ps->sk and directly use the original socket pointer instead.
With all users of ps->sk now handling NULL and concurrent updates, the L2TP ->ref() and ->deref() callbacks aren't needed anymore. Therefore, rather than converting pppol2tp_session_sock_hold() and pppol2tp_session_sock_put(), we can just drop them.
Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/l2tp/l2tp_ppp.c | 154 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 53 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -122,8 +122,11 @@ struct pppol2tp_session { int owner; /* pid that opened the socket */
- struct sock *sock; /* Pointer to the session + struct mutex sk_lock; /* Protects .sk */ + struct sock __rcu *sk; /* Pointer to the session * PPPoX socket */ + struct sock *__sk; /* Copy of .sk, for cleanup */ + struct rcu_head rcu; /* For asynchronous release */ struct sock *tunnel_sock; /* Pointer to the tunnel UDP * socket */ int flags; /* accessed by PPPIOCGFLAGS. @@ -138,6 +141,24 @@ static const struct ppp_channel_ops pppo
static const struct proto_ops pppol2tp_ops;
+/* Retrieves the pppol2tp socket associated to a session. + * A reference is held on the returned socket, so this function must be paired + * with sock_put(). + */ +static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session) +{ + struct pppol2tp_session *ps = l2tp_session_priv(session); + struct sock *sk; + + rcu_read_lock(); + sk = rcu_dereference(ps->sk); + if (sk) + sock_hold(sk); + rcu_read_unlock(); + + return sk; +} + /* Helpers to obtain tunnel/session contexts from sockets. */ static inline struct l2tp_session *pppol2tp_sock_to_session(struct sock *sk) @@ -225,7 +246,8 @@ static void pppol2tp_recv(struct l2tp_se /* If the socket is bound, send it in to PPP's input queue. Otherwise * queue it on the session socket. */ - sk = ps->sock; + rcu_read_lock(); + sk = rcu_dereference(ps->sk); if (sk == NULL) goto no_sock;
@@ -263,30 +285,16 @@ static void pppol2tp_recv(struct l2tp_se kfree_skb(skb); } } + rcu_read_unlock();
return;
no_sock: + rcu_read_unlock(); l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: no socket\n", session->name); kfree_skb(skb); }
-static void pppol2tp_session_sock_hold(struct l2tp_session *session) -{ - struct pppol2tp_session *ps = l2tp_session_priv(session); - - if (ps->sock) - sock_hold(ps->sock); -} - -static void pppol2tp_session_sock_put(struct l2tp_session *session) -{ - struct pppol2tp_session *ps = l2tp_session_priv(session); - - if (ps->sock) - sock_put(ps->sock); -} - /************************************************************************ * Transmit handling ***********************************************************************/ @@ -450,14 +458,16 @@ abort: */ static void pppol2tp_session_close(struct l2tp_session *session) { - struct pppol2tp_session *ps = l2tp_session_priv(session); - struct sock *sk = ps->sock; - struct socket *sock = sk->sk_socket; + struct sock *sk;
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
- if (sock) - inet_shutdown(sock, 2); + sk = pppol2tp_session_get_sock(session); + if (sk) { + if (sk->sk_socket) + inet_shutdown(sk->sk_socket, SEND_SHUTDOWN); + sock_put(sk); + }
/* Don't let the session go away before our socket does */ l2tp_session_inc_refcount(session); @@ -480,6 +490,14 @@ static void pppol2tp_session_destruct(st } }
+static void pppol2tp_put_sk(struct rcu_head *head) +{ + struct pppol2tp_session *ps; + + ps = container_of(head, typeof(*ps), rcu); + sock_put(ps->__sk); +} + /* Called when the PPPoX socket (session) is closed. */ static int pppol2tp_release(struct socket *sock) @@ -505,11 +523,24 @@ static int pppol2tp_release(struct socke
session = pppol2tp_sock_to_session(sk);
- /* Purge any queued data */ if (session != NULL) { + struct pppol2tp_session *ps; + __l2tp_session_unhash(session); l2tp_session_queue_purge(session); - sock_put(sk); + + ps = l2tp_session_priv(session); + mutex_lock(&ps->sk_lock); + ps->__sk = rcu_dereference_protected(ps->sk, + lockdep_is_held(&ps->sk_lock)); + RCU_INIT_POINTER(ps->sk, NULL); + mutex_unlock(&ps->sk_lock); + call_rcu(&ps->rcu, pppol2tp_put_sk); + + /* Rely on the sock_put() call at the end of the function for + * dropping the reference held by pppol2tp_sock_to_session(). + * The last reference will be dropped by pppol2tp_put_sk(). + */ } release_sock(sk);
@@ -576,12 +607,14 @@ out: static void pppol2tp_show(struct seq_file *m, void *arg) { struct l2tp_session *session = arg; - struct pppol2tp_session *ps = l2tp_session_priv(session); + struct sock *sk; + + sk = pppol2tp_session_get_sock(session); + if (sk) { + struct pppox_sock *po = pppox_sk(sk);
- if (ps) { - struct pppox_sock *po = pppox_sk(ps->sock); - if (po) - seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + sock_put(sk); } } #endif @@ -715,13 +748,17 @@ static int pppol2tp_connect(struct socke /* Using a pre-existing session is fine as long as it hasn't * been connected yet. */ - if (ps->sock) { + mutex_lock(&ps->sk_lock); + if (rcu_dereference_protected(ps->sk, + lockdep_is_held(&ps->sk_lock))) { + mutex_unlock(&ps->sk_lock); error = -EEXIST; goto end; }
/* consistency checks */ if (ps->tunnel_sock != tunnel->sock) { + mutex_unlock(&ps->sk_lock); error = -EEXIST; goto end; } @@ -738,19 +775,21 @@ static int pppol2tp_connect(struct socke goto end; }
+ ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); l2tp_session_inc_refcount(session); + + mutex_lock(&ps->sk_lock); error = l2tp_session_register(session, tunnel); if (error < 0) { + mutex_unlock(&ps->sk_lock); kfree(session); goto end; } drop_refcnt = true; }
- /* Associate session with its PPPoL2TP socket */ - ps = l2tp_session_priv(session); ps->owner = current->pid; - ps->sock = sk; ps->tunnel_sock = tunnel->sock;
session->recv_skb = pppol2tp_recv; @@ -759,12 +798,6 @@ static int pppol2tp_connect(struct socke session->show = pppol2tp_show; #endif
- /* We need to know each time a skb is dropped from the reorder - * queue. - */ - session->ref = pppol2tp_session_sock_hold; - session->deref = pppol2tp_session_sock_put; - /* If PMTU discovery was enabled, use the MTU that was discovered */ dst = sk_dst_get(tunnel->sock); if (dst != NULL) { @@ -798,12 +831,17 @@ static int pppol2tp_connect(struct socke po->chan.mtu = session->mtu;
error = ppp_register_net_channel(sock_net(sk), &po->chan); - if (error) + if (error) { + mutex_unlock(&ps->sk_lock); goto end; + }
out_no_ppp: /* This is how we get the session context from the socket. */ sk->sk_user_data = session; + rcu_assign_pointer(ps->sk, sk); + mutex_unlock(&ps->sk_lock); + sk->sk_state = PPPOX_CONNECTED; l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", session->name); @@ -851,6 +889,7 @@ static int pppol2tp_session_create(struc }
ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); ps->tunnel_sock = tunnel->sock;
error = l2tp_session_register(session, tunnel); @@ -1022,12 +1061,10 @@ static int pppol2tp_session_ioctl(struct "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", session->name, cmd, arg);
- sk = ps->sock; + sk = pppol2tp_session_get_sock(session); if (!sk) return -EBADR;
- sock_hold(sk); - switch (cmd) { case SIOCGIFMTU: err = -ENXIO; @@ -1303,7 +1340,6 @@ static int pppol2tp_session_setsockopt(s int optname, int val) { int err = 0; - struct pppol2tp_session *ps = l2tp_session_priv(session);
switch (optname) { case PPPOL2TP_SO_RECVSEQ: @@ -1324,8 +1360,8 @@ static int pppol2tp_session_setsockopt(s } session->send_seq = val ? -1 : 0; { - struct sock *ssk = ps->sock; - struct pppox_sock *po = pppox_sk(ssk); + struct pppox_sock *po = pppox_sk(sk); + po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; } @@ -1664,8 +1700,9 @@ static void pppol2tp_seq_session_show(st { struct l2tp_session *session = v; struct l2tp_tunnel *tunnel = session->tunnel; - struct pppol2tp_session *ps = l2tp_session_priv(session); - struct pppox_sock *po = pppox_sk(ps->sock); + unsigned char state; + char user_data_ok; + struct sock *sk; u32 ip = 0; u16 port = 0;
@@ -1675,6 +1712,15 @@ static void pppol2tp_seq_session_show(st port = ntohs(inet->inet_sport); }
+ sk = pppol2tp_session_get_sock(session); + if (sk) { + state = sk->sk_state; + user_data_ok = (session == sk->sk_user_data) ? 'Y' : 'N'; + } else { + state = 0; + user_data_ok = 'N'; + } + seq_printf(m, " SESSION '%s' %08X/%d %04X/%04X -> " "%04X/%04X %d %c\n", session->name, ip, port, @@ -1682,9 +1728,7 @@ static void pppol2tp_seq_session_show(st session->session_id, tunnel->peer_tunnel_id, session->peer_session_id, - ps->sock->sk_state, - (session == ps->sock->sk_user_data) ? - 'Y' : 'N'); + state, user_data_ok); seq_printf(m, " %d/%d/%c/%c/%s %08x %u\n", session->mtu, session->mru, session->recv_seq ? 'R' : '-', @@ -1701,8 +1745,12 @@ static void pppol2tp_seq_session_show(st atomic_long_read(&session->stats.rx_bytes), atomic_long_read(&session->stats.rx_errors));
- if (po) + if (sk) { + struct pppox_sock *po = pppox_sk(sk); + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + sock_put(sk); + } }
static int pppol2tp_seq_show(struct seq_file *m, void *v)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Manasi Navare manasi.d.navare@intel.com
commit cbacf02e7796fea02e5c6e46c90ed7cbe9e6f2c0 upstream.
Kernel stores the time in jiffies at which the eDP panel is turned off. This should be obtained after the panel is off (after the wait_panel_off). When we next attempt to turn the panel on, we use the difference between the timestamp at which we want to turn the panel on and timestamp at which panel was turned off to ensure that this is equal to panel power cycle delay and if not we wait for the remaining time. Not waiting for the panel power cycle delay can cause the panel to not turn on giving rise to AUX timeouts for the attempted AUX transactions.
v2: * Separate lines for bugzilla (Jani Nikula) * Suggested by tag (Daniel Vetter)
Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Jani Nikula jani.nikula@linux.intel.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101518 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101144 Suggested-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Manasi Navare manasi.d.navare@intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Jani Nikula jani.nikula@linux.intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/1507135706-17147-1-git-send-em... [bwh: Backported to 3.16: We really do use jiffies here, and the field in struct intel_dp has a different name] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1365,8 +1365,8 @@ void intel_edp_panel_off(struct intel_dp I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg);
- intel_dp->last_power_cycle = jiffies; wait_panel_off(intel_dp); + intel_dp->last_power_cycle = jiffies;
/* We got a reference when we enabled the VDD. */ power_domain = intel_display_port_power_domain(intel_encoder);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit c45e3e4c5b134b081e8af362109905427967eb19 upstream.
A recent change fixing NFC device allocation itself introduced an error-handling bug by returning an error pointer in case device-id allocation failed. This is clearly broken as the callers still expected NULL to be returned on errors as detected by Dan's static checker.
Fix this up by returning NULL in the event that we've run out of memory when allocating a new device id.
Note that the offending commit is marked for stable (3.8) so this fix needs to be backported along with it.
Fixes: 20777bc57c34 ("NFC: fix broken device allocation") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Samuel Ortiz sameo@linux.intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/nfc/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -1074,7 +1074,7 @@ struct nfc_dev *nfc_allocate_device(stru err_free_dev: kfree(dev);
- return ERR_PTR(rc); + return NULL; } EXPORT_SYMBOL(nfc_allocate_device);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long lucien.xin@gmail.com
commit cebe84c6190d741045a322f5343f717139993c08 upstream.
Now when ip route flush cache and it turn out all fnhe_genid != genid. If a redirect/pmtu icmp packet comes and the old fnhe is found and all it's members but fnhe_genid will be updated.
Then next time when it looks up route and tries to rebind this fnhe to the new dst, the fnhe will be flushed due to fnhe_genid != genid. It causes this redirect/pmtu icmp packet acutally not to be applied.
This patch is to also reset fnhe_genid when updating a route cache.
Fixes: 5aad1de5ea2c ("ipv4: use separate genid for next hop exceptions") Acked-by: Hannes Frederic Sowa hannes@stressinduktion.org Signed-off-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/ipv4/route.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -623,9 +623,12 @@ static void update_or_create_fnhe(struct struct fnhe_hash_bucket *hash; struct fib_nh_exception *fnhe; struct rtable *rt; + u32 genid, hval; unsigned int i; int depth; - u32 hval = fnhe_hashfun(daddr); + + genid = fnhe_genid(dev_net(nh->nh_dev)); + hval = fnhe_hashfun(daddr);
spin_lock_bh(&fnhe_lock);
@@ -648,6 +651,8 @@ static void update_or_create_fnhe(struct }
if (fnhe) { + if (fnhe->fnhe_genid != genid) + fnhe->fnhe_genid = genid; if (gw) fnhe->fnhe_gw = gw; if (pmtu) @@ -671,7 +676,7 @@ static void update_or_create_fnhe(struct fnhe->fnhe_next = hash->chain; rcu_assign_pointer(hash->chain, fnhe); } - fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev)); + fnhe->fnhe_genid = genid; fnhe->fnhe_daddr = daddr; fnhe->fnhe_gw = gw; fnhe->fnhe_pmtu = pmtu;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tyrel Datwyler tyreld@linux.vnet.ibm.com
commit b8f89fea599d91e674497aad572613eb63181f31 upstream.
When a vdevice is DLPAR removed from the system the vio subsystem doesn't bother unmapping the virq from the irq_domain. As a result we have a virq mapped to a hardware irq that is no longer valid for the irq_domain. A side effect is that we are left with /proc/irq/<irq#> affinity entries, and attempts to modify the smp_affinity of the irq will fail.
In the following observed example the kernel log is spammed by ics_rtas_set_affinity errors after the removal of a VSCSI adapter. This is a result of irqbalance trying to adjust the affinity every 10 seconds.
rpadlpar_io: slot U8408.E8E.10A7ACV-V5-C25 removed ics_rtas_set_affinity: ibm,set-xive irq=655385 returns -3 ics_rtas_set_affinity: ibm,set-xive irq=655385 returns -3
This patch fixes the issue by calling irq_dispose_mapping() on the virq of the viodev on unregister.
Fixes: f2ab6219969f ("powerpc/pseries: Add PFO support to the VIO bus") Signed-off-by: Tyrel Datwyler tyreld@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au [bwh: Backported to 3.16: adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/powerpc/kernel/vio.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1572,6 +1572,8 @@ static struct device_attribute vio_dev_a void vio_unregister_device(struct vio_dev *viodev) { device_unregister(&viodev->dev); + if (viodev->family == VDEVICE) + irq_dispose_mapping(viodev->irq); } EXPORT_SYMBOL(vio_unregister_device);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Ghannam simo.ghannam@gmail.com
commit c095508770aebf1b9218e77026e48345d719b17c upstream.
When args->nr_local is 0, nr_pages gets also 0 due some size calculation via rds_rm_size(), which is later used to allocate pages for DMA, this bug produces a heap Out-Of-Bound write access to a specific memory region.
Signed-off-by: Mohamed Ghannam simo.ghannam@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/rds/rdma.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -516,6 +516,9 @@ int rds_rdma_extra_size(struct rds_rdma_
local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
+ if (args->nr_local == 0) + return -EINVAL; + /* figure out the number of pages in the vector */ for (i = 0; i < args->nr_local; i++) { if (copy_from_user(&vec, &local_vec[i],
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King colin.king@canonical.com
commit 123c0aab0050cd0e07ce18e453389fbbb0a5a425 upstream.
There is a check on pmlmepriv before dereferencing it when vfree'ing pmlmepriv->free_bss_buf however the previous call to rtw_free_mlme_priv_ie_data deferences pmlmepriv causing a null pointer deference if it is null. Avoid this by also calling rtw_free_mlme_priv_ie_data if the pointer is non-null.
Detected by CoverityScan, CID#1230262 ("Dereference before null check") Fixes: 7b464c9fa5cc ("staging: r8188eu: Add files for new driver - part 4") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -120,9 +120,8 @@ void rtw_free_mlme_priv_ie_data(struct m
void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) { - rtw_free_mlme_priv_ie_data(pmlmepriv); - if (pmlmepriv) { + rtw_free_mlme_priv_ie_data(pmlmepriv); if (pmlmepriv->free_bss_buf) vfree(pmlmepriv->free_bss_buf); }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä ville.syrjala@linux.intel.com
commit e30a154b5262b967b133b06ac40777e651045898 upstream.
intel_crtc->config->cpu_transcoder isn't yet filled out when intel_crtc_mode_get() gets called during output probing, so we should not use it there. Instead intel_crtc_mode_get() figures out the correct transcoder on its own, and that's what we should use.
If the BIOS boots LVDS on pipe B, intel_crtc_mode_get() would actually end up reading the timings from pipe A instead (since PIPE_A==0), which clearly isn't what we want.
It looks to me like this may have been broken by commit eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") as that one removed the early initialization of cpu_transcoder from intel_crtc_init().
Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer rob@solution-space.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Reported-by: Rob Kramer rob@solution-space.com Fixes: eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") References: https://lists.freedesktop.org/archives/dri-devel/2016-April/104142.html Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson chris@chris-wilson.co.uk Link: https://patchwork.freedesktop.org/patch/msgid/1459525046-19425-1-git-send-em... [bwh: Backported to 3.16: pipe_config is a struct not a pointer] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8662,13 +8662,10 @@ struct drm_display_mode *intel_crtc_mode { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_config pipe_config; - int htot = I915_READ(HTOTAL(cpu_transcoder)); - int hsync = I915_READ(HSYNC(cpu_transcoder)); - int vtot = I915_READ(VTOTAL(cpu_transcoder)); - int vsync = I915_READ(VSYNC(cpu_transcoder)); + u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -8690,6 +8687,13 @@ struct drm_display_mode *intel_crtc_mode i9xx_crtc_clock_get(intel_crtc, &pipe_config);
mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier; + + cpu_transcoder = pipe_config.cpu_transcoder; + htot = I915_READ(HTOTAL(cpu_transcoder)); + hsync = I915_READ(HSYNC(cpu_transcoder)); + vtot = I915_READ(VTOTAL(cpu_transcoder)); + vsync = I915_READ(VSYNC(cpu_transcoder)); + mode->hdisplay = (htot & 0xffff) + 1; mode->htotal = ((htot & 0xffff0000) >> 16) + 1; mode->hsync_start = (hsync & 0xffff) + 1;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers ebiggers@google.com
commit 74d4108d9e681dbbe4a2940ed8fdff1f6868184c upstream.
The default max_cache_size_bytes for dm-bufio is meant to be the lesser of 25% of the size of the vmalloc area and 2% of the size of lowmem. However, on 32-bit systems the intermediate result in the expression
(VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100
overflows, causing the wrong result to be computed. For example, on a 32-bit system where the vmalloc area is 520093696 bytes, the result is 1174405 rather than the expected 130023424, which makes the maximum cache size much too small (far less than 2% of lowmem). This causes severe performance problems for dm-verity users on affected systems.
Fix this by using mult_frac() to correctly multiply by a percentage. Do this for all places in dm-bufio that multiply by a percentage. Also replace (VMALLOC_END - VMALLOC_START) with VMALLOC_TOTAL, which contrary to the comment is now defined in include/linux/vmalloc.h.
Depends-on: 9993bc635 ("sched/x86: Fix overflow in cyc2ns_offset") Fixes: 95d402f057f2 ("dm: add bufio") Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/md/dm-bufio.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
--- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -888,7 +888,8 @@ static void __get_memory_limit(struct dm buffers = c->minimum_buffers;
*limit_buffers = buffers; - *threshold_buffers = buffers * DM_BUFIO_WRITEBACK_PERCENT / 100; + *threshold_buffers = mult_frac(buffers, + DM_BUFIO_WRITEBACK_PERCENT, 100); }
/* @@ -1778,19 +1779,15 @@ static int __init dm_bufio_init(void) memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches); memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
- mem = (__u64)((totalram_pages - totalhigh_pages) * - DM_BUFIO_MEMORY_PERCENT / 100) << PAGE_SHIFT; + mem = (__u64)mult_frac(totalram_pages - totalhigh_pages, + DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT;
if (mem > ULONG_MAX) mem = ULONG_MAX;
#ifdef CONFIG_MMU - /* - * Get the size of vmalloc space the same way as VMALLOC_TOTAL - * in fs/proc/internal.h - */ - if (mem > (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100) - mem = (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100; + if (mem > mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100)) + mem = mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100); #endif
dm_bufio_default_cache_size = mem;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini pbonzini@redhat.com
commit 73459e2a1ada09a68c02cc5b73f3116fc8194b3d upstream.
This reverts commits 0a4e6be9ca17c54817cf814b4b5aa60478c6df27 and 80f7fdb1c7f0f9266421f823964fd1962681f6ce.
The task migration notifier was originally introduced in order to support the pvclock vsyscall with non-synchronized TSC, but KVM only supports it with synchronized TSC. Hence, on KVM the race condition is only needed due to a bad implementation on the host side, and even then it's so rare that it's mostly theoretical.
As far as KVM is concerned it's possible to fix the host, avoiding the additional complexity in the vDSO and the (re)introduction of the task migration notifier.
Xen, on the other hand, hasn't yet implemented vsyscall support at all, so we do not care about its plans for non-synchronized TSC.
Reported-by: Peter Zijlstra peterz@infradead.org Suggested-by: Marcelo Tosatti mtosatti@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/include/asm/pvclock.h | 1 - arch/x86/kernel/pvclock.c | 44 ------------------------------------------ arch/x86/vdso/vclock_gettime.c | 34 ++++++++++++++------------------ include/linux/sched.h | 8 -------- kernel/sched/core.c | 15 -------------- 5 files changed, 15 insertions(+), 87 deletions(-)
--- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -95,7 +95,6 @@ unsigned __pvclock_read_cycles(const str
struct pvclock_vsyscall_time_info { struct pvclock_vcpu_time_info pvti; - u32 migrate_count; } __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -141,46 +141,7 @@ void pvclock_read_wallclock(struct pvclo set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); }
-static struct pvclock_vsyscall_time_info *pvclock_vdso_info; - -static struct pvclock_vsyscall_time_info * -pvclock_get_vsyscall_user_time_info(int cpu) -{ - if (!pvclock_vdso_info) { - BUG(); - return NULL; - } - - return &pvclock_vdso_info[cpu]; -} - -struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu) -{ - return &pvclock_get_vsyscall_user_time_info(cpu)->pvti; -} - #ifdef CONFIG_X86_64 -static int pvclock_task_migrate(struct notifier_block *nb, unsigned long l, - void *v) -{ - struct task_migration_notifier *mn = v; - struct pvclock_vsyscall_time_info *pvti; - - pvti = pvclock_get_vsyscall_user_time_info(mn->from_cpu); - - /* this is NULL when pvclock vsyscall is not initialized */ - if (unlikely(pvti == NULL)) - return NOTIFY_DONE; - - pvti->migrate_count++; - - return NOTIFY_DONE; -} - -static struct notifier_block pvclock_migrate = { - .notifier_call = pvclock_task_migrate, -}; - /* * Initialize the generic pvclock vsyscall state. This will allocate * a/some page(s) for the per-vcpu pvclock information, set up a @@ -194,17 +155,12 @@ int __init pvclock_init_vsyscall(struct
WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE);
- pvclock_vdso_info = i; - for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, __pa(i) + (idx*PAGE_SIZE), PAGE_KERNEL_VVAR); }
- - register_task_migration_notifier(&pvclock_migrate); - return 0; } #endif --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -82,15 +82,18 @@ static notrace cycle_t vread_pvclock(int cycle_t ret; u64 last; u32 version; - u32 migrate_count; u8 flags; unsigned cpu, cpu1;
/* - * When looping to get a consistent (time-info, tsc) pair, we - * also need to deal with the possibility we can switch vcpus, - * so make sure we always re-fetch time-info for the current vcpu. + * Note: hypervisor must guarantee that: + * 1. cpu ID number maps 1:1 to per-CPU pvclock time info. + * 2. that per-CPU pvclock time info is updated if the + * underlying CPU changes. + * 3. that version is increased whenever underlying CPU + * changes. + * */ do { cpu = __getcpu() & VGETCPU_CPU_MASK; @@ -99,27 +102,20 @@ static notrace cycle_t vread_pvclock(int * __getcpu() calls (Gleb). */
- /* Make sure migrate_count will change if we leave the VCPU. */ - do { - pvti = get_pvti(cpu); - migrate_count = pvti->migrate_count; - - cpu1 = cpu; - cpu = __getcpu() & VGETCPU_CPU_MASK; - } while (unlikely(cpu != cpu1)); + pvti = get_pvti(cpu);
version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags);
/* * Test we're still on the cpu as well as the version. - * - We must read TSC of pvti's VCPU. - * - KVM doesn't follow the versioning protocol, so data could - * change before version if we left the VCPU. + * We could have been migrated just after the first + * vgetcpu but before fetching the version, so we + * wouldn't notice a version change. */ - smp_rmb(); - } while (unlikely((pvti->pvti.version & 1) || - pvti->pvti.version != version || - pvti->migrate_count != migrate_count)); + cpu1 = __getcpu() & VGETCPU_CPU_MASK; + } while (unlikely(cpu != cpu1 || + (pvti->pvti.version & 1) || + pvti->pvti.version != version));
if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) *mode = VCLOCK_NONE; --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -174,14 +174,6 @@ extern unsigned long this_cpu_load(void) extern void calc_global_load(unsigned long ticks); extern void update_cpu_load_nohz(void);
-/* Notifier for when a task gets migrated to a new CPU */ -struct task_migration_notifier { - struct task_struct *task; - int from_cpu; - int to_cpu; -}; -extern void register_task_migration_notifier(struct notifier_block *n); - extern unsigned long get_parent_ip(unsigned long addr);
extern void dump_cpu_task(int cpu); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1041,13 +1041,6 @@ void check_preempt_curr(struct rq *rq, s rq->skip_clock_update = 1; }
-static ATOMIC_NOTIFIER_HEAD(task_migration_notifier); - -void register_task_migration_notifier(struct notifier_block *n) -{ - atomic_notifier_chain_register(&task_migration_notifier, n); -} - #ifdef CONFIG_SMP void set_task_cpu(struct task_struct *p, unsigned int new_cpu) { @@ -1078,18 +1071,10 @@ void set_task_cpu(struct task_struct *p, trace_sched_migrate_task(p, new_cpu);
if (task_cpu(p) != new_cpu) { - struct task_migration_notifier tmn; - if (p->sched_class->migrate_task_rq) p->sched_class->migrate_task_rq(p, new_cpu); p->se.nr_migrations++; perf_sw_event_sched(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 0); - - tmn.task = p; - tmn.from_cpu = task_cpu(p); - tmn.to_cpu = new_cpu; - - atomic_notifier_call_chain(&task_migration_notifier, 0, &tmn); }
__set_task_cpu(p, new_cpu);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda Vijendar.Mukunda@amd.com
commit 9ceace3c9c18c67676e75141032a65a8e01f9a7a upstream.
This commit adds PCI ID for Raven platform
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1914,6 +1914,9 @@ static const struct pci_device_id azx_id /* AMD Hudson */ { PCI_DEVICE(0x1022, 0x780d), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, + /* AMD Raven */ + { PCI_DEVICE(0x1022, 0x15e3), + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, /* ATI HDMI */ { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 8428a8ebde2db1e988e41a58497a28beb7ce1705 upstream.
parse_audio_feature_unit() contains a code dividing potentially with zero when a malformed FU descriptor is passed. Although there is already a sanity check, it checks only the value zero, hence it can still lead to a zero-division when a value 1 is passed there.
Fix it by correcting the sanity check (and the error message thereof).
Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0") Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/usb/mixer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1385,9 +1385,9 @@ static int parse_audio_feature_unit(stru return -EINVAL; } csize = hdr->bControlSize; - if (!csize) { + if (csize <= 1) { usb_audio_dbg(state->chip, - "unit %u: invalid bControlSize == 0\n", + "unit %u: invalid bControlSize <= 1\n", unitid); return -EINVAL; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Markus Elfring elfring@users.sourceforge.net
commit f6c8a317ab208aee223776327c06f23342492d54 upstream.
Source code review for a specific software refactoring showed the need for another correction because the error code "-1" was returned so far if a call of the function "sony_call_snc_handle" failed here. Thus assign the return value from these two function calls also to the variable "err" and provide it in case of a failure.
Fixes: d6f15ed876b83a1a0eba1d0473eef58acc95444a ("sony-laptop: use soft rfkill status stored in hw") Suggested-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lkml.org/lkml/2017/10/31/463 Link: https://lkml.kernel.org/r/CAHp75VcMkXCioCzmLE0+BTmkqc5RSOx9yPO0ectVHMrMvewgwg@mail.gmail.com Signed-off-by: Markus Elfring elfring@users.sourceforge.net Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/platform/x86/sony-laptop.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1654,17 +1654,19 @@ static int sony_nc_setup_rfkill(struct a if (!rfk) return -ENOMEM;
- if (sony_call_snc_handle(sony_rfkill_handle, 0x200, &result) < 0) { + err = sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); + if (err < 0) { rfkill_destroy(rfk); - return -1; + return err; } hwblock = !(result & 0x1);
- if (sony_call_snc_handle(sony_rfkill_handle, - sony_rfkill_address[nc_type], - &result) < 0) { + err = sony_call_snc_handle(sony_rfkill_handle, + sony_rfkill_address[nc_type], + &result); + if (err < 0) { rfkill_destroy(rfk); - return -1; + return err; } swblock = !(result & 0x2);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
commit 2638fd0f92d4397884fd991d8f4925cb3f081901 upstream.
Denys provided an awesome KASAN report pointing to an use after free in xt_TCPMSS
I have provided three patches to fix this issue, either in xt_TCPMSS or in xt_tcpudp.c. It seems xt_TCPMSS patch has the smallest possible impact.
Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: Denys Fedoryshchenko nuclearcat@nuclearcat.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/netfilter/xt_TCPMSS.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -104,7 +104,7 @@ tcpmss_mangle_packet(struct sk_buff *skb tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); tcp_hdrlen = tcph->doff * 4;
- if (len < tcp_hdrlen) + if (len < tcp_hdrlen || tcp_hdrlen < sizeof(struct tcphdr)) return -1;
if (info->mss == XT_TCPMSS_CLAMP_PMTU) { @@ -156,6 +156,10 @@ tcpmss_mangle_packet(struct sk_buff *skb if (len > tcp_hdrlen) return 0;
+ /* tcph->doff has 4 bits, do not wrap it to 0 */ + if (tcp_hdrlen >= 15 * 4) + return 0; + /* * MSS Option not found ?! add it.. */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski luto@amacapital.net
commit 6b078f5de7fc0851af4102493c7b5bb07e49c4cb upstream.
The pvclock vdso code was too abstracted to understand easily and excessively paranoid. Simplify it for a huge speedup.
This opens the door for additional simplifications, as the vdso no longer accesses the pvti for any vcpu other than vcpu 0.
Before, vclock_gettime using kvm-clock took about 45ns on my machine. With this change, it takes 29ns, which is almost as fast as the pure TSC implementation.
Signed-off-by: Andy Lutomirski luto@amacapital.net Reviewed-by: Paolo Bonzini pbonzini@redhat.com Cc: Borislav Petkov bp@alien8.de Cc: Brian Gerst brgerst@gmail.com Cc: Denys Vlasenko dvlasenk@redhat.com Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/6b51dcc41f1b101f963945c5ec7093d72bdac429.1449702533... Signed-off-by: Ingo Molnar mingo@kernel.org [bwh: Backported to 3.16: - Open-code rdtsc_ordered() - Adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -78,47 +78,59 @@ static notrace const struct pvclock_vsys
static notrace cycle_t vread_pvclock(int *mode) { - const struct pvclock_vsyscall_time_info *pvti; + const struct pvclock_vcpu_time_info *pvti = &get_pvti(0)->pvti; cycle_t ret; - u64 last; - u32 version; - u8 flags; - unsigned cpu, cpu1; - + u64 tsc, pvti_tsc; + u64 last, delta, pvti_system_time; + u32 version, pvti_tsc_to_system_mul, pvti_tsc_shift;
/* - * Note: hypervisor must guarantee that: - * 1. cpu ID number maps 1:1 to per-CPU pvclock time info. - * 2. that per-CPU pvclock time info is updated if the - * underlying CPU changes. - * 3. that version is increased whenever underlying CPU - * changes. + * Note: The kernel and hypervisor must guarantee that cpu ID + * number maps 1:1 to per-CPU pvclock time info. + * + * Because the hypervisor is entirely unaware of guest userspace + * preemption, it cannot guarantee that per-CPU pvclock time + * info is updated if the underlying CPU changes or that that + * version is increased whenever underlying CPU changes. * + * On KVM, we are guaranteed that pvti updates for any vCPU are + * atomic as seen by *all* vCPUs. This is an even stronger + * guarantee than we get with a normal seqlock. + * + * On Xen, we don't appear to have that guarantee, but Xen still + * supplies a valid seqlock using the version field. + + * We only do pvclock vdso timing at all if + * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to + * mean that all vCPUs have matching pvti and that the TSC is + * synced, so we can just look at vCPU 0's pvti. */ - do { - cpu = __getcpu() & VGETCPU_CPU_MASK; - /* TODO: We can put vcpu id into higher bits of pvti.version. - * This will save a couple of cycles by getting rid of - * __getcpu() calls (Gleb). - */ - - pvti = get_pvti(cpu); - - version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags); - - /* - * Test we're still on the cpu as well as the version. - * We could have been migrated just after the first - * vgetcpu but before fetching the version, so we - * wouldn't notice a version change. - */ - cpu1 = __getcpu() & VGETCPU_CPU_MASK; - } while (unlikely(cpu != cpu1 || - (pvti->pvti.version & 1) || - pvti->pvti.version != version));
- if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) + if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { *mode = VCLOCK_NONE; + return 0; + } + + do { + version = pvti->version; + + /* This is also a read barrier, so we'll read version first. */ + rdtsc_barrier(); + tsc = __native_read_tsc(); + + pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; + pvti_tsc_shift = pvti->tsc_shift; + pvti_system_time = pvti->system_time; + pvti_tsc = pvti->tsc_timestamp; + + /* Make sure that the version double-check is last. */ + smp_rmb(); + } while (unlikely((version & 1) || version != pvti->version)); + + delta = tsc - pvti_tsc; + ret = pvti_system_time + + pvclock_scale_delta(delta, pvti_tsc_to_system_mul, + pvti_tsc_shift);
/* refer to tsc.c read_tsc() comment for rationale */ last = gtod->cycle_last;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Maciej W. Rozycki" macro@mips.com
commit 547da673173de51f73887377eb275304775064ad upstream.
Fix a commit 7aeb753b5353 ("MIPS: Implement task_user_regset_view.") regression, then activated by commit 6a9c001b7ec3 ("MIPS: Switch ELF core dumper to use regsets.)", that caused n32 processes to dump o32 core files by failing to set the EF_MIPS_ABI2 flag in the ELF core file header's `e_flags' member:
$ file tls-core tls-core: ELF 32-bit MSB executable, MIPS, N32 MIPS64 rel2 version 1 (SYSV), [...] $ ./tls-core Aborted (core dumped) $ file core core: ELF 32-bit MSB core file MIPS, MIPS-I version 1 (SYSV), SVR4-style $
Previously the flag was set as the result of a:
statement placed in arch/mips/kernel/binfmt_elfn32.c, however in the regset case, i.e. when CORE_DUMP_USE_REGSET is set, ELF_CORE_EFLAGS is no longer used by `fill_note_info' in fs/binfmt_elf.c, and instead the `->e_flags' member of the regset view chosen is. We have the views defined in arch/mips/kernel/ptrace.c, however only an o32 and an n64 one, and the latter is used for n32 as well. Consequently an o32 core file is incorrectly dumped from n32 processes (the ELF32 vs ELF64 class is chosen elsewhere, and the 32-bit one is correctly selected for n32).
Correct the issue then by defining an n32 regset view and using it as appropriate. Issue discovered in GDB testing.
Fixes: 7aeb753b5353 ("MIPS: Implement task_user_regset_view.") Signed-off-by: Maciej W. Rozycki macro@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: Djordje Todorovic djordje.todorovic@rt-rk.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/17617/ Signed-off-by: James Hogan jhogan@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/mips/kernel/ptrace.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -522,6 +522,19 @@ static const struct user_regset_view use .n = ARRAY_SIZE(mips64_regsets), };
+#ifdef CONFIG_MIPS32_N32 + +static const struct user_regset_view user_mipsn32_view = { + .name = "mipsn32", + .e_flags = EF_MIPS_ABI2, + .e_machine = ELF_ARCH, + .ei_osabi = ELF_OSABI, + .regsets = mips64_regsets, + .n = ARRAY_SIZE(mips64_regsets), +}; + +#endif /* CONFIG_MIPS32_N32 */ + #endif /* CONFIG_64BIT */
const struct user_regset_view *task_user_regset_view(struct task_struct *task) @@ -533,6 +546,10 @@ const struct user_regset_view *task_user if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) return &user_mips_view; #endif +#ifdef CONFIG_MIPS32_N32 + if (test_tsk_thread_flag(task, TIF_32BIT_ADDR)) + return &user_mipsn32_view; +#endif return &user_mips64_view; #endif }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Christian König christian.koenig@amd.com
commit 4d98e5ee6084f6d7bc578c5d5f86de7156aaa4cb upstream.
When the mutex is locked just in the moment we copy it we end up with a warning that we release a locked mutex.
Fix this by properly reinitializing the mutex.
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/gpu/drm/ttm/ttm_bo_util.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -463,6 +463,7 @@ static int ttm_buffer_object_transfer(st INIT_LIST_HEAD(&fbo->lru); INIT_LIST_HEAD(&fbo->swap); INIT_LIST_HEAD(&fbo->io_reserve_lru); + mutex_init(&fbo->wu_mutex); drm_vma_node_reset(&fbo->vma_node); atomic_set(&fbo->cpu_writers, 0);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: James Morse james.morse@arm.com
commit 4f89fa286f6729312e227e7c2d764e8e7b9d340e upstream.
Replace ghes_io{re,un}map_pfn_{nmi,irq}()s use of ioremap_page_range() with __set_fixmap() as ioremap_page_range() may sleep to allocate a new level of page-table, even if its passed an existing final-address to use in the mapping.
The GHES driver can only be enabled for architectures that select HAVE_ACPI_APEI: Add fixmap entries to both x86 and arm64.
clear_fixmap() does the TLB invalidation in __set_fixmap() for arm64 and __set_pte_vaddr() for x86. In each case its the same as the respective arch_apei_flush_tlb_one().
Reported-by: Fengguang Wu fengguang.wu@intel.com Suggested-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: James Morse james.morse@arm.com Reviewed-by: Borislav Petkov bp@suse.de Tested-by: Tyler Baicar tbaicar@codeaurora.org Tested-by: Toshi Kani toshi.kani@hpe.com [ For the arm64 bits: ] Acked-by: Will Deacon will.deacon@arm.com [ For the x86 bits: ] Acked-by: Ingo Molnar mingo@kernel.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com [bwh: Backported to 3.16: - Drop arm64 changes; ghes is x86-only here - Don't use page or prot variables in ghes_ioremap_fn_{nmi,irq}() - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -103,6 +103,12 @@ enum fixed_addresses { #ifdef CONFIG_X86_INTEL_MID FIX_LNW_VRTC, #endif +#ifdef CONFIG_ACPI_APEI_GHES + /* Used for GHES mapping from assorted contexts */ + FIX_APEI_GHES_IRQ, + FIX_APEI_GHES_NMI, +#endif + __end_of_permanent_fixed_addresses,
/* --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -49,6 +49,7 @@ #include <linux/aer.h>
#include <acpi/ghes.h> +#include <asm/fixmap.h> #include <asm/mce.h> #include <asm/tlbflush.h> #include <asm/nmi.h> @@ -110,7 +111,7 @@ static DEFINE_RAW_SPINLOCK(ghes_nmi_lock * Because the memory area used to transfer hardware error information * from BIOS to Linux can be determined only in NMI, IRQ or timer * handler, but general ioremap can not be used in atomic context, so - * a special version of atomic ioremap is implemented for that. + * the fixmap is used instead. */
/* @@ -124,8 +125,8 @@ static DEFINE_RAW_SPINLOCK(ghes_nmi_lock /* virtual memory area for atomic ioremap */ static struct vm_struct *ghes_ioremap_area; /* - * These 2 spinlock is used to prevent atomic ioremap virtual memory - * area from being mapped simultaneously. + * These 2 spinlocks are used to prevent the fixmap entries from being used + * simultaneously. */ static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); @@ -165,44 +166,26 @@ static void ghes_ioremap_exit(void)
static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) { - unsigned long vaddr; + __set_fixmap(FIX_APEI_GHES_NMI, pfn << PAGE_SHIFT, PAGE_KERNEL);
- vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr); - ioremap_page_range(vaddr, vaddr + PAGE_SIZE, - pfn << PAGE_SHIFT, PAGE_KERNEL); - - return (void __iomem *)vaddr; + return (void __iomem *) fix_to_virt(FIX_APEI_GHES_NMI); }
static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) { - unsigned long vaddr; - - vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr); - ioremap_page_range(vaddr, vaddr + PAGE_SIZE, - pfn << PAGE_SHIFT, PAGE_KERNEL); + __set_fixmap(FIX_APEI_GHES_IRQ, pfn << PAGE_SHIFT, PAGE_KERNEL);
- return (void __iomem *)vaddr; + return (void __iomem *) fix_to_virt(FIX_APEI_GHES_IRQ); }
-static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) +static void ghes_iounmap_nmi(void) { - unsigned long vaddr = (unsigned long __force)vaddr_ptr; - void *base = ghes_ioremap_area->addr; - - BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); - unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - __flush_tlb_one(vaddr); + clear_fixmap(FIX_APEI_GHES_NMI); }
-static void ghes_iounmap_irq(void __iomem *vaddr_ptr) +static void ghes_iounmap_irq(void) { - unsigned long vaddr = (unsigned long __force)vaddr_ptr; - void *base = ghes_ioremap_area->addr; - - BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); - unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - __flush_tlb_one(vaddr); + clear_fixmap(FIX_APEI_GHES_IRQ); }
static int ghes_estatus_pool_init(void) @@ -341,10 +324,10 @@ static void ghes_copy_tofrom_phys(void * paddr += trunk; buffer += trunk; if (in_nmi) { - ghes_iounmap_nmi(vaddr); + ghes_iounmap_nmi(); raw_spin_unlock(&ghes_ioremap_lock_nmi); } else { - ghes_iounmap_irq(vaddr); + ghes_iounmap_irq(); spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); } }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra peterz@infradead.org
commit 3f3295709edea6268ff1609855f498035286af73 upstream.
The current int_sqrt() computation is sub-optimal for the case of small @x. Which is the interesting case when we're going to do cumulative distribution functions on idle times, which we assume to be a random variable, where the target residency of the deepest idle state gives an upper bound on the variable (5e6ns on recent Intel chips).
In the case of small @x, the compute loop:
while (m != 0) { b = y + m; y >>= 1;
if (x >= b) { x -= b; y += m; } m >>= 2; }
can be reduced to:
while (m > x) m >>= 2;
Because y==0, b==m and until x>=m y will remain 0.
And while this is computationally equivalent, it runs much faster because there's less code, in particular less branches.
cycles: branches: branch-misses:
OLD:
hot: 45.109444 +- 0.044117 44.333392 +- 0.002254 0.018723 +- 0.000593 cold: 187.737379 +- 0.156678 44.333407 +- 0.002254 6.272844 +- 0.004305
PRE:
hot: 67.937492 +- 0.064124 66.999535 +- 0.000488 0.066720 +- 0.001113 cold: 232.004379 +- 0.332811 66.999527 +- 0.000488 6.914634 +- 0.006568
POST:
hot: 43.633557 +- 0.034373 45.333132 +- 0.002277 0.023529 +- 0.000681 cold: 207.438411 +- 0.125840 45.333132 +- 0.002277 6.976486 +- 0.004219
Averages computed over all values <128k using a LFSR to generate order. Cold numbers have a LFSR based branch trace buffer 'confuser' ran between each int_sqrt() invocation.
Link: http://lkml.kernel.org/r/20171020164644.876503355@infradead.org Fixes: 30493cc9dddb ("lib/int_sqrt.c: optimize square root algorithm") Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Suggested-by: Anshul Garg aksgarg1989@gmail.com Acked-by: Linus Torvalds torvalds@linux-foundation.org Cc: Davidlohr Bueso dave@stgolabs.net Cc: Thomas Gleixner tglx@linutronix.de Cc: Ingo Molnar mingo@kernel.org Cc: Will Deacon will.deacon@arm.com Cc: Joe Perches joe@perches.com Cc: David Miller davem@davemloft.net Cc: Matthew Wilcox mawilcox@microsoft.com Cc: Kees Cook keescook@chromium.org Cc: Michael Davidson md@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- lib/int_sqrt.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c @@ -22,6 +22,9 @@ unsigned long int_sqrt(unsigned long x) return x;
m = 1UL << (BITS_PER_LONG - 2); + while (m > x) + m >>= 2; + while (m != 0) { b = y + m; y >>= 1;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Ghannam simo.ghannam@gmail.com
commit 7d11f77f84b27cef452cee332f4e469503084737 upstream.
set rm->atomic.op_active to 0 when rds_pin_pages() fails or the user supplied address is invalid, this prevents a NULL pointer usage in rds_atomic_free_op()
Signed-off-by: Mohamed Ghannam simo.ghannam@gmail.com Acked-by: Santosh Shilimkar santosh.shilimkar@oracle.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/rds/rdma.c | 1 + 1 file changed, 1 insertion(+)
--- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -855,6 +855,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, err: if (page) put_page(page); + rm->atomic.op_active = 0; kfree(rm->atomic.op_notifier);
return ret;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Watt jpewhacker@gmail.com
commit f02fee227e5f21981152850744a6084ff3fa94ee upstream.
The option was incorrectly masking off all other options.
Signed-off-by: Joshua Watt JPEWhacker@gmail.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/nfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1319,7 +1319,7 @@ static int nfs_parse_mount_options(char mnt->options |= NFS_OPTION_MIGRATION; break; case Opt_nomigration: - mnt->options &= NFS_OPTION_MIGRATION; + mnt->options &= ~NFS_OPTION_MIGRATION; break;
/*
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Majd Dibbiny majd@mellanox.com
commit 31fde034a8bd964a5c7c1a5663fc87a913158db2 upstream.
The UMR's QP is created by calling mlx5_ib_create_qp directly, and therefore the send CQ and the recv CQ on the ibqp weren't assigned.
Assign them right after calling the mlx5_ib_create_qp to assure that any access to those pointers will work as expected and won't crash the system as might happen as part of reset flow.
Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Signed-off-by: Majd Dibbiny majd@mellanox.com Reviewed-by: Yishai Hadas yishaih@mellanox.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/infiniband/hw/mlx5/main.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1164,6 +1164,8 @@ static int create_umr_res(struct mlx5_ib qp->real_qp = qp; qp->uobject = NULL; qp->qp_type = MLX5_IB_QPT_REG_UMR; + qp->send_cq = init_attr->send_cq; + qp->recv_cq = init_attr->recv_cq;
attr->qp_state = IB_QPS_INIT; attr->port_num = 1;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown neilb@suse.com
commit 302ec300ef8a545a7fc7f667e5fd743b091c2eeb upstream.
Commit ecc0c469f277 ("autofs: don't fail mount for transient error") was meant to replace an 'if' with a 'switch', but instead added the 'switch' leaving the case in place.
Link: http://lkml.kernel.org/r/87zi6wstmw.fsf@notabene.neil.brown.name Fixes: ecc0c469f277 ("autofs: don't fail mount for transient error") Reported-by: Ben Hutchings ben.hutchings@codethink.co.uk Signed-off-by: NeilBrown neilb@suse.com Cc: Ian Kent raven@themaw.net Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/autofs4/waitq.c | 1 - 1 file changed, 1 deletion(-)
--- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -174,7 +174,6 @@ static void autofs4_notify_daemon(struct
mutex_unlock(&sbi->wq_mutex);
- if (autofs4_write(sbi, pipe, &pkt, pktsz)) switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { case 0: break;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: alex chen alex.chen@huawei.com
commit 28f5a8a7c033cbf3e32277f4cc9c6afd74f05300 upstream.
we should wait dio requests to finish before inode lock in ocfs2_setattr(), otherwise the following deadlock will happen:
process 1 process 2 process 3 truncate file 'A' end_io of writing file 'A' receiving the bast messages ocfs2_setattr ocfs2_inode_lock_tracker ocfs2_inode_lock_full inode_dio_wait __inode_dio_wait -->waiting for all dio requests finish dlm_proxy_ast_handler dlm_do_local_bast ocfs2_blocking_ast ocfs2_generic_handle_bast set OCFS2_LOCK_BLOCKED flag dio_end_io dio_bio_end_aio dio_complete ocfs2_dio_end_io ocfs2_dio_end_io_write ocfs2_inode_lock __ocfs2_cluster_lock ocfs2_wait_for_mask -->waiting for OCFS2_LOCK_BLOCKED flag to be cleared, that is waiting for 'process 1' unlocking the inode lock inode_dio_end -->here dec the i_dio_count, but will never be called, so a deadlock happened.
Link: http://lkml.kernel.org/r/59F81636.70508@huawei.com Signed-off-by: Alex Chen alex.chen@huawei.com Reviewed-by: Jun Piao piaojun@huawei.com Reviewed-by: Joseph Qi jiangqi903@gmail.com Acked-by: Changwei Ge ge.changwei@h3c.com Cc: Mark Fasheh mfasheh@versity.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/ocfs2/file.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1152,6 +1152,13 @@ int ocfs2_setattr(struct dentry *dentry, dquot_initialize(inode); size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { + /* + * Here we should wait dio to finish before inode lock + * to avoid a deadlock between ocfs2_setattr() and + * ocfs2_dio_end_io_write() + */ + inode_dio_wait(inode); + status = ocfs2_rw_lock(inode, 1); if (status < 0) { mlog_errno(status); @@ -1171,8 +1178,6 @@ int ocfs2_setattr(struct dentry *dentry, if (status) goto bail_unlock;
- inode_dio_wait(inode); - if (i_size_read(inode) >= attr->ia_size) { if (ocfs2_should_order_data(inode)) { status = ocfs2_begin_ordered_truncate(inode,
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King colin.king@canonical.com
commit 3993b112dac968612b0b213ed59cb30f50b0015b upstream.
There are checks on fs_info in __btrfs_panic to avoid dereferencing a null fs_info, however, there is a call to btrfs_crit that may also dereference a null fs_info. Fix this by adding a check to see if fs_info is null and only print the s_id if fs_info is non-null.
Detected by CoverityScan CID#401973 ("Dereference after null check")
Fixes: efe120a067c8 ("Btrfs: convert printk to btrfs_ and fix BTRFS prefix") Signed-off-by: Colin Ian King colin.king@canonical.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/btrfs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -185,7 +185,6 @@ static const char * const logtypes[] = {
void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) { - struct super_block *sb = fs_info->sb; char lvl[4]; struct va_format vaf; va_list args; @@ -207,7 +206,8 @@ void btrfs_printk(const struct btrfs_fs_ vaf.fmt = fmt; vaf.va = &args;
- printk("%sBTRFS %s (device %s): %pV\n", lvl, type, sb->s_id, &vaf); + printk("%sBTRFS %s (device %s): %pV\n", lvl, type, + fs_info ? fs_info->sb->s_id : "<unknown>", &vaf);
va_end(args); }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit f72271e2a0ae4277d53c4053f5eed8bb346ba38a upstream.
The original issue being fixed in this patch was seen with the ixgbe driver, but the same issue exists with i40evf as well, as the code is very similar. read_barrier_depends is not sufficient to ensure loads following it are not speculatively loaded out of order by the CPU, which can result in stale data being loaded, causing potential system crashes.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Andrew Bowers andrewx.bowers@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -216,7 +216,7 @@ static bool i40e_clean_tx_irq(struct i40 break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* we have caught up to head, no work left to do */ if (tx_head == tx_desc)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brent Taylor motobud@gmail.com
commit 30863e38ebeb500a31cecee8096fb5002677dd9b upstream.
When mtdoops calls mtd_panic_write(), it eventually calls panic_nand_write() in nand_base.c. In order to properly wait for the nand chip to be ready in panic_nand_wait(), the chip must first be selected.
When using the atmel nand flash controller, a panic would occur due to a NULL pointer exception.
Fixes: 2af7c6539931 ("mtd: Add panic_write for NAND flashes") Signed-off-by: Brent Taylor motobud@gmail.com Signed-off-by: Boris Brezillon boris.brezillon@free-electrons.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/mtd/nand/nand_base.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2466,15 +2466,18 @@ static int panic_nand_write(struct mtd_i size_t *retlen, const uint8_t *buf) { struct nand_chip *chip = mtd->priv; + int chipnr = (int)(to >> chip->chip_shift); struct mtd_oob_ops ops; int ret;
- /* Wait for the device to get ready */ - panic_nand_wait(mtd, chip, 400); - /* Grab the device */ panic_nand_get_device(chip, mtd, FL_WRITING);
+ chip->select_chip(mtd, chipnr); + + /* Wait for the device to get ready */ + panic_nand_wait(mtd, chip, 400); + ops.len = len; ops.datbuf = (uint8_t *)buf; ops.oobbuf = NULL;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault g.nault@alphalink.fr
commit cdd10c9627496ad25c87ce6394e29752253c69d3 upstream.
If l2tp_tunnel_delete() or l2tp_tunnel_closeall() deletes a session right after pppol2tp_release() orphaned its socket, then the 'sock' variable of the pppol2tp_session_close() callback is NULL. Yet the session is still used by pppol2tp_release().
Therefore we need to take an extra reference in any case, to prevent l2tp_tunnel_delete() or l2tp_tunnel_closeall() from freeing the session.
Since the pppol2tp_session_close() callback is only set if the session is associated to a PPPOL2TP socket and that both l2tp_tunnel_delete() and l2tp_tunnel_closeall() hold the PPPOL2TP socket before calling pppol2tp_session_close(), we're sure that pppol2tp_session_close() and pppol2tp_session_destruct() are paired and called in the right order. So the reference taken by the former will be released by the later.
Signed-off-by: Guillaume Nault g.nault@alphalink.fr Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/l2tp/l2tp_ppp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -456,11 +456,11 @@ static void pppol2tp_session_close(struc
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
- if (sock) { + if (sock) inet_shutdown(sock, 2); - /* Don't let the session go away before our socket does */ - l2tp_session_inc_refcount(session); - } + + /* Don't let the session go away before our socket does */ + l2tp_session_inc_refcount(session); }
/* Really kill the session socket. (Called from sock_put() if
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long lucien.xin@gmail.com
commit e39d5246111399dbc6e11cd39fd8580191b86c47 upstream.
Now when creating fnhe for redirect, it sets fnhe_expires for this new route cache. But when updating the exist one, it doesn't do it. It will cause this fnhe never to be expired.
Paolo already noticed it before, in Jianlin's test case, it became even worse:
When ip route flush cache, the old fnhe is not to be removed, but only clean it's members. When redirect comes again, this fnhe will be found and updated, but never be expired due to fnhe_expires not being set.
So fix it by simply updating fnhe_expires even it's for redirect.
Fixes: aee06da6726d ("ipv4: use seqlock for nh_exceptions") Reported-by: Jianlin Shi jishi@redhat.com Acked-by: Hannes Frederic Sowa hannes@stressinduktion.org Signed-off-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/ipv4/route.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -650,10 +650,9 @@ static void update_or_create_fnhe(struct if (fnhe) { if (gw) fnhe->fnhe_gw = gw; - if (pmtu) { + if (pmtu) fnhe->fnhe_pmtu = pmtu; - fnhe->fnhe_expires = max(1UL, expires); - } + fnhe->fnhe_expires = max(1UL, expires); /* Update all cached dsts too */ rt = rcu_dereference(fnhe->fnhe_rth_input); if (rt)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Coly Li colyli@suse.de
commit 91af8300d9c1d7c6b6a2fd754109e08d4798b8d8 upstream.
In bcache code, sysfs entries are created before all resources get allocated, e.g. allocation thread of a cache set.
There is posibility for NULL pointer deference if a resource is accessed but which is not initialized yet. Indeed Jorg Bornschein catches one on cache set allocation thread and gets a kernel oops.
The reason for this bug is, when bch_bucket_alloc() is called during cache set registration and attaching, ca->alloc_thread is not properly allocated and initialized yet, call wake_up_process() on ca->alloc_thread triggers NULL pointer deference failure. A simple and fast fix is, before waking up ca->alloc_thread, checking whether it is allocated, and only wake up ca->alloc_thread when it is not NULL.
Signed-off-by: Coly Li colyli@suse.de Reported-by: Jorg Bornschein jb@capsec.org Cc: Kent Overstreet kent.overstreet@gmail.com Reviewed-by: Michael Lyle mlyle@lyle.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/md/bcache/alloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -406,7 +406,8 @@ long bch_bucket_alloc(struct cache *ca,
finish_wait(&ca->set->bucket_wait, &w); out: - wake_up_process(ca->alloc_thread); + if (ca->alloc_thread) + wake_up_process(ca->alloc_thread);
trace_bcache_alloc(ca, reserve);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shriya shriyak@linux.vnet.ibm.com
commit cd77b5ce208c153260ed7882d8910f2395bfaabd upstream.
The call to /proc/cpuinfo in turn calls cpufreq_quick_get() which returns the last frequency requested by the kernel, but may not reflect the actual frequency the processor is running at. This patch makes a call to cpufreq_get() instead which returns the current frequency reported by the hardware.
Fixes: fb5153d05a7d ("powerpc: powernv: Implement ppc_md.get_proc_freq()") Signed-off-by: Shriya shriyak@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/powerpc/platforms/powernv/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -309,7 +309,7 @@ unsigned long pnv_get_proc_freq(unsigned { unsigned long ret_freq;
- ret_freq = cpufreq_quick_get(cpu) * 1000ul; + ret_freq = cpufreq_get(cpu) * 1000ul;
/* * If the backend cpufreq driver does not exist,
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka sgruszka@redhat.com
commit bfa62a52cad93686bb8d8171ea5288813248a7c6 upstream.
ENOENT usb error mean "specified interface or endpoint does not exist or is not enabled". Mark device not present when we encounter this error similar like we do with ENODEV error.
Otherwise we can have infinite loop in rt2x00usb_work_rxdone(), because we remove and put again RX entries to the queue infinitely.
We can have similar situation when submit urb will fail all the time with other error, so we need consider to limit number of entries processed by rxdone work. But for now, since the patch fixes reproducible soft lockup issue on single processor systems and taken ENOENT error meaning, let apply this fix.
Patch adds additional ENOENT check not only in rx kick routine, but also on other places where we check for ENODEV error.
Reported-by: Richard Genoud richard.genoud@gmail.com Debugged-by: Richard Genoud richard.genoud@gmail.com Signed-off-by: Stanislaw Gruszka sgruszka@redhat.com Tested-by: Richard Genoud richard.genoud@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -62,7 +62,7 @@ int rt2x00usb_vendor_request(struct rt2x * -ENODEV: Device has disappeared, no point continuing. * All other errors: Try again. */ - else if (status == -ENODEV) { + else if (status == -ENODEV || status == -ENOENT) { clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); break; } @@ -325,7 +325,7 @@ static bool rt2x00usb_kick_tx_entry(stru
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (status) { - if (status == -ENODEV) + if (status == -ENODEV || status == -ENOENT) clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); @@ -414,7 +414,7 @@ static bool rt2x00usb_kick_rx_entry(stru
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (status) { - if (status == -ENODEV) + if (status == -ENODEV || status == -ENOENT) clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ingo Molnar mingo@kernel.org
commit d51953b0873358d13b189996e6976dfa12a9b59d upstream.
This build failure triggers on 64-bit allmodconfig:
arch/x86/platform/uv/uv_nmi.c:493:2: error: implicit declaration of function ‘clocksource_touch_watchdog’ [-Werror=implicit-function-declaration]
which is caused by recent changes exposing a missing clocksource.h include in uv_nmi.c:
cc1e24fdb064 x86/vdso: Remove pvclock fixmap machinery
this file got clocksource.h indirectly via fixmap.h - that stealth route of header inclusion is now gone.
Cc: Borislav Petkov bp@alien8.de Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/platform/uv/uv_nmi.c | 1 + 1 file changed, 1 insertion(+)
--- a/arch/x86/platform/uv/uv_nmi.c +++ b/arch/x86/platform/uv/uv_nmi.c @@ -28,6 +28,7 @@ #include <linux/nmi.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/clocksource.h>
#include <asm/apic.h> #include <asm/current.h>
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Andrew F. Davis" afd@ti.com
commit 8adc430603d67e76a0f8491df21654f691acda62 upstream.
The binding states the reset GPIO property shall be named "cirrus,gpio-nreset" and this is what the driver looks for, but the example uses "gpio-reset". Fix this here.
Fixes: 3bb40619aca8 ("ASoC: cs42l56: bindings: sound: Add bindings for CS42L56 CODEC")
Signed-off-by: Andrew F. Davis afd@ti.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- Documentation/devicetree/bindings/sound/cs42l56.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/sound/cs42l56.txt +++ b/Documentation/devicetree/bindings/sound/cs42l56.txt @@ -55,7 +55,7 @@ Example: codec: codec@4b { compatible = "cirrus,cs42l56"; reg = <0x4b>; - gpio-reset = <&gpio 10 0>; + cirrus,gpio-nreset = <&gpio 10 0>; cirrus,chgfreq-divisor = <0x05>; cirrus.ain1_ref_cfg; cirrus,micbias-lvl = <5>;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit db86be3a12d0b6e5c5b51c2ab2a48f06329cb590 upstream.
We're freeing the list iterator so we should be using the _safe() version of hlist_for_each_entry().
Fixes: 88b4a07e6610 ("[PATCH] eCryptfs: Public key transport mechanism") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Tyler Hicks tyhicks@canonical.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/ecryptfs/messaging.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c @@ -443,15 +443,16 @@ void ecryptfs_release_messaging(void) } if (ecryptfs_daemon_hash) { struct ecryptfs_daemon *daemon; + struct hlist_node *n; int i;
mutex_lock(&ecryptfs_daemon_hash_mux); for (i = 0; i < (1 << ecryptfs_hash_bits); i++) { int rc;
- hlist_for_each_entry(daemon, - &ecryptfs_daemon_hash[i], - euid_chain) { + hlist_for_each_entry_safe(daemon, n, + &ecryptfs_daemon_hash[i], + euid_chain) { rc = ecryptfs_exorcise_daemon(daemon); if (rc) printk(KERN_ERR "%s: Error whilst "
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Juerg Haefliger juerg.haefliger@canonical.com
This reverts commit abe3029e4febfa18e4a9562a792465182b3992a0.
Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kernel/kvmclock.c | 5 ----- arch/x86/mm/kaiser.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-)
--- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -24,7 +24,6 @@ #include <linux/percpu.h> #include <linux/hardirq.h> #include <linux/memblock.h> -#include <linux/kaiser.h>
#include <asm/x86_init.h> #include <asm/reboot.h> @@ -287,10 +286,6 @@ int __init kvm_setup_vsyscall_timeinfo(v if (!hv_clock) return 0;
- /* FIXME: Need to add pvclock pages to user-space page tables */ - if (kaiser_enabled) - return 0; - size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
preempt_disable(); --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -322,7 +322,7 @@ silent_disable: */ void __init kaiser_init(void) { - int cpu, idx; + int cpu;
if (!kaiser_enabled) return;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@sandisk.com
commit 59b6986dbfcdab96a971f9663221849de79a7556 upstream.
Allocate a task management request structure for all task management requests, including task reassignment. This change avoids that the se_tmr->response assignment dereferences an uninitialized se_tmr pointer.
Reported-by: Moshe David mdavid@infinidat.com Signed-off-by: Bart Van Assche bart.vanassche@sandisk.com Reviewed-by: Hannes Reinecke hare@suse.com Reviewed-by: Christoph Hellwig hch@lst.de Cc: Moshe David mdavid@infinidat.com Signed-off-by: Nicholas Bellinger nab@linux-iscsi.org [bwh: Backported to 3.16: - Add definition of TMR_UNKNOWN - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1754,7 +1754,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ struct iscsi_tm *hdr; int out_of_order_cmdsn = 0, ret; bool sess_ref = false; - u8 function; + u8 function, tcm_function = TMR_UNKNOWN;
hdr = (struct iscsi_tm *) buf; hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; @@ -1800,10 +1800,6 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ * LIO-Target $FABRIC_MOD */ if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { - - u8 tcm_function; - int ret; - transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, conn->sess->se_sess, 0, DMA_NONE, @@ -1840,15 +1836,14 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ return iscsit_add_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); } - - ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, - tcm_function, GFP_KERNEL); - if (ret < 0) - return iscsit_add_reject_cmd(cmd, + } + ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, tcm_function, + GFP_KERNEL); + if (ret < 0) + return iscsit_add_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
- cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; - } + cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req;
cmd->iscsi_opcode = ISCSI_OP_SCSI_TMFUNC; cmd->i_state = ISTATE_SEND_TASKMGTRSP; --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -230,6 +230,7 @@ enum tcm_tmreq_table { TMR_LUN_RESET = 5, TMR_TARGET_WARM_RESET = 6, TMR_TARGET_COLD_RESET = 7, + TMR_UNKNOWN = 0xff, };
/* fabric independent task management response values */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King colin.king@canonical.com
commit 2b2f5ff00f63847d95adad6289bd8b05f5983dd5 upstream.
This patch fixes a RTC wakealarm issue, namely, the event fires during hibernate and is not cleared from the list, causing hwclock to block.
The current enqueuing does not trigger an alarm if any expired timers already exist on the timerqueue. This can occur when a RTC wake alarm is used to wake a machine out of hibernate and the resumed state has old expired timers that have not been removed from the timer queue. This fix skips over any expired timers and triggers an alarm if there are no pending timers on the timerqueue. Note that the skipped expired timer will get reaped later on, so there is no need to clean it up immediately.
The issue can be reproduced by putting a machine into hibernate and waking it with the RTC wakealarm. Running the example RTC test program from tools/testing/selftests/timers/rtctest.c after the hibernate will block indefinitely. With the fix, it no longer blocks after the hibernate resume.
BugLink: http://bugs.launchpad.net/bugs/1333569
Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Alexandre Belloni alexandre.belloni@free-electrons.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/rtc/interface.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -778,9 +778,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); */ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) { + struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); + struct rtc_time tm; + ktime_t now; + timer->enabled = 1; + __rtc_read_time(rtc, &tm); + now = rtc_tm_to_ktime(tm); + + /* Skip over expired timers */ + while (next) { + if (next->expires.tv64 >= now.tv64) + break; + next = timerqueue_iterate_next(next); + } + timerqueue_add(&rtc->timerqueue, &timer->node); - if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { + if (!next) { struct rtc_wkalrm alarm; int err; alarm.time = rtc_ktime_to_tm(timer->node.expires);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit 33ec6dbc5a02677509d97fe36cd2105753f0f0ea upstream.
Fix child node-lookup during probe, which ended up searching the whole device tree depth-first starting at parent rather than just matching on its children.
Note that the original premature free of the parent node has already been fixed separately, but that fix was apparently never backported to stable.
Fixes: 9ac33b0ce81f ("CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)") Fixes: 660e15519399 ("clk: ti: dra7-atl-clock: Fix of_node reference counting") Cc: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Johan Hovold johan@kernel.org Acked-by: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Stephen Boyd sboyd@codeaurora.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/clk/ti/clk-dra7-atl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -262,8 +262,7 @@ static int of_dra7_atl_clk_probe(struct
/* Get configuration for the ATL instances */ snprintf(prop, sizeof(prop), "atl%u", i); - of_node_get(node); - cfg_node = of_find_node_by_name(node, prop); + cfg_node = of_get_child_by_name(node, prop); if (cfg_node) { ret = of_property_read_u32(cfg_node, "bws", &cdesc->bws);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Roman Kapl rka@sysgo.com
commit 4f626a4ac8f57ddabf06d03870adab91e463217f upstream.
The function for byteswapping the data send to/from atombios was buggy for num_bytes not divisible by four. The function must be aware of the fact that after byte-swapping the u32 units, valid bytes might end up after the num_bytes boundary.
This patch was tested on kernel 3.12 and allowed us to sucesfully use DisplayPort on and Radeon SI card. Namely it fixed the link training and EDID readout.
The function is patched both in radeon and amd drivers, since the functions and the fixes are identical.
Signed-off-by: Roman Kapl rka@sysgo.com Signed-off-by: Alex Deucher alexander.deucher@amd.com [bwh: Backported to 3.16: drop changes in amdgpu] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -45,34 +45,32 @@ static char *pre_emph_names[] = {
/***** radeon AUX functions *****/
-/* Atom needs data in little endian format - * so swap as appropriate when copying data to - * or from atom. Note that atom operates on - * dw units. +/* Atom needs data in little endian format so swap as appropriate when copying + * data to or from atom. Note that atom operates on dw units. + * + * Use to_le=true when sending data to atom and provide at least + * ALIGN(num_bytes,4) bytes in the dst buffer. + * + * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4) + * byes in the src buffer. */ void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) { #ifdef __BIG_ENDIAN - u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ - u32 *dst32, *src32; + u32 src_tmp[5], dst_tmp[5]; int i; + u8 align_num_bytes = ALIGN(num_bytes, 4);
- memcpy(src_tmp, src, num_bytes); - src32 = (u32 *)src_tmp; - dst32 = (u32 *)dst_tmp; if (to_le) { - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = cpu_to_le32(src32[i]); - memcpy(dst, dst_tmp, num_bytes); + memcpy(src_tmp, src, num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = cpu_to_le32(src_tmp[i]); + memcpy(dst, dst_tmp, align_num_bytes); } else { - u8 dws = num_bytes & ~3; - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = le32_to_cpu(src32[i]); - memcpy(dst, dst_tmp, dws); - if (num_bytes % 4) { - for (i = 0; i < (num_bytes % 4); i++) - dst[dws+i] = dst_tmp[dws+i]; - } + memcpy(src_tmp, src, align_num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = le32_to_cpu(src_tmp[i]); + memcpy(dst, dst_tmp, num_bytes); } #else memcpy(dst, src, num_bytes);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger nab@linux-iscsi.org
commit 3fc9fb13a4b2576aeab86c62fd64eb29ab68659c upstream.
This patch fixes a se_cmd->cmd_kref reference leak that can occur when a non immediate TMR is proceeded our of command sequence number order, and CMDSN_LOWER_THAN_EXP is returned by iscsit_sequence_cmd().
To address this bug, call target_put_sess_cmd() during this special case following what iscsit_process_scsi_cmd() does upon CMDSN_LOWER_THAN_EXP.
Cc: Mike Christie mchristi@redhat.com Cc: Hannes Reinecke hare@suse.com Signed-off-by: Nicholas Bellinger nab@linux-iscsi.org [bwh: Backported to 3.16: target_put_sess_cmd() takes an se_session pointer too] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/target/iscsi/iscsi_target.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1917,12 +1917,14 @@ attach:
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); - if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) + if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) { out_of_order_cmdsn = 1; - else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) + } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { + target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); return 0; - else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) + } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { return -1; + } } iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nadav Amit namit@cs.technion.ac.il
commit 4566654bb9be9e8864df417bb72ceee5136b6a6a upstream.
Guest which sets the PAT CR to invalid value should get a #GP. Currently, if vmx supports loading PAT CR during entry, then the value is not checked. This patch makes the required check in that case.
Signed-off-by: Nadav Amit namit@cs.technion.ac.il Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/vmx.c | 2 ++ arch/x86/kvm/x86.c | 5 +++-- arch/x86/kvm/x86.h | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2599,6 +2599,8 @@ static int vmx_set_msr(struct kvm_vcpu * break; case MSR_IA32_CR_PAT: if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { + if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data)) + return 1; vmcs_write64(GUEST_IA32_PAT, data); vcpu->arch.pat = data; break; --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1742,7 +1742,7 @@ static bool valid_mtrr_type(unsigned t) return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */ }
-static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) +bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) { int i;
@@ -1768,12 +1768,13 @@ static bool mtrr_valid(struct kvm_vcpu * /* variable MTRRs */ return valid_mtrr_type(data & 0xff); } +EXPORT_SYMBOL_GPL(kvm_mtrr_valid);
static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data) { u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
- if (!mtrr_valid(vcpu, msr, data)) + if (!kvm_mtrr_valid(vcpu, msr, data)) return 1;
if (msr == MSR_MTRRdefType) { --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -132,6 +132,8 @@ int kvm_write_guest_virt_system(struct x gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception);
+bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data); + #define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ | XSTATE_BNDREGS | XSTATE_BNDCSR) extern u64 host_xcr0;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit 34be4dbf87fc3e474a842305394534216d428f5d upstream.
isofs uses a 'char' variable to load the number of years since 1900 for an inode timestamp. On architectures that use a signed char type by default, this results in an invalid date for anything beyond 2027.
This changes the function argument to a 'u8' array, which is defined the same way on all architectures, and unambiguously lets us use years until 2155.
This should be backported to all kernels that might still be in use by that date.
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/isofs/isofs.h | 2 +- fs/isofs/rock.h | 2 +- fs/isofs/util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
--- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h @@ -103,7 +103,7 @@ static inline unsigned int isonum_733(ch /* Ignore bigendian datum due to broken mastering programs */ return get_unaligned_le32(p); } -extern int iso_date(char *, int); +extern int iso_date(u8 *, int);
struct inode; /* To make gcc happy */
--- a/fs/isofs/rock.h +++ b/fs/isofs/rock.h @@ -65,7 +65,7 @@ struct RR_PL_s { };
struct stamp { - char time[7]; + __u8 time[7]; /* actually 6 unsigned, 1 signed */ } __attribute__ ((packed));
struct RR_TF_s { --- a/fs/isofs/util.c +++ b/fs/isofs/util.c @@ -14,7 +14,7 @@ * to GMT. Thus we should always be correct. */
-int iso_date(char * p, int flag) +int iso_date(u8 *p, int flag) { int year, month, day, hour, minute, second, tz; int crtime, days, i;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland mark.rutland@arm.com
commit c80ed088a519da53f27b798a69748eaabc66aadf upstream.
The vdso tries to check for a NULL res pointer in __kernel_clock_getres, but only checks the lower 32 bits as is uses CBZ on the W register the res pointer is held in.
Thus, if the res pointer happened to be aligned to a 4GiB boundary, we'd spuriously skip storing the timespec to it, while returning a zero error code to the caller.
Prevent this by checking the whole pointer, using CBZ on the X register the res pointer is held in.
Fixes: 9031fefde6f2ac1d ("arm64: VDSO support") Signed-off-by: Mark Rutland mark.rutland@arm.com Reported-by: Andrew Pinski apinski@cavium.com Reported-by: Mark Salyzyn salyzyn@android.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Will Deacon will.deacon@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/arm64/kernel/vdso/gettimeofday.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -186,7 +186,7 @@ ENTRY(__kernel_clock_getres) b.ne 4f ldr x2, 6f 2: - cbz w1, 3f + cbz x1, 3f stp xzr, x2, [x1]
3: /* res == NULL. */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Lynch nathan_lynch@mentor.com
commit e1b6b6ce55a0a25c8aa8af019095253b2133a41a upstream.
The vdso implementation of clock_getres currently returns 0 (success) whenever a null timespec is provided by the caller, regardless of the clock id supplied.
This behavior is incorrect. It should fall back to syscall when an unrecognized clock id is passed, even when the timespec argument is null. This ensures that clock_getres always returns an error for invalid clock ids.
Signed-off-by: Nathan Lynch nathan_lynch@mentor.com Acked-by: Will Deacon will.deacon@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/arm64/kernel/vdso/gettimeofday.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -174,8 +174,6 @@ ENDPROC(__kernel_clock_gettime) /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */ ENTRY(__kernel_clock_getres) .cfi_startproc - cbz w1, 3f - cmp w0, #CLOCK_REALTIME ccmp w0, #CLOCK_MONOTONIC, #0x4, ne b.ne 1f @@ -188,6 +186,7 @@ ENTRY(__kernel_clock_getres) b.ne 4f ldr x2, 6f 2: + cbz w1, 3f stp xzr, x2, [x1]
3: /* res == NULL. */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
commit 1f2cac107c591c24b60b115d6050adc213d10fc0 upstream.
sg.c calls into the blktrace functions without holding the proper queue mutex for doing setup, start/stop, or teardown.
Add internal unlocked variants, and export the ones that do the proper locking.
Fixes: 6da127ad0918 ("blktrace: Add blktrace ioctls to SCSI generic devices") Tested-by: Dmitry Vyukov dvyukov@google.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- kernel/trace/blktrace.c | 58 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 10 deletions(-)
--- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -307,7 +307,7 @@ static void blk_trace_cleanup(struct blk blk_unregister_tracepoints(); }
-int blk_trace_remove(struct request_queue *q) +static int __blk_trace_remove(struct request_queue *q) { struct blk_trace *bt;
@@ -320,6 +320,17 @@ int blk_trace_remove(struct request_queu
return 0; } + +int blk_trace_remove(struct request_queue *q) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_remove(q); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_remove);
static ssize_t blk_dropped_read(struct file *filp, char __user *buffer, @@ -536,9 +547,8 @@ err: return ret; }
-int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, - struct block_device *bdev, - char __user *arg) +static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev, + struct block_device *bdev, char __user *arg) { struct blk_user_trace_setup buts; int ret; @@ -557,6 +567,19 @@ int blk_trace_setup(struct request_queue } return 0; } + +int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, + struct block_device *bdev, + char __user *arg) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_setup(q, name, dev, bdev, arg); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_setup);
#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) @@ -593,7 +616,7 @@ static int compat_blk_trace_setup(struct } #endif
-int blk_trace_startstop(struct request_queue *q, int start) +static int __blk_trace_startstop(struct request_queue *q, int start) { int ret; struct blk_trace *bt = q->blk_trace; @@ -632,6 +655,17 @@ int blk_trace_startstop(struct request_q
return ret; } + +int blk_trace_startstop(struct request_queue *q, int start) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_startstop(q, start); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_startstop);
/* @@ -662,7 +696,7 @@ int blk_trace_ioctl(struct block_device switch (cmd) { case BLKTRACESETUP: bdevname(bdev, b); - ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); + ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); break; #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) case BLKTRACESETUP32: @@ -673,10 +707,10 @@ int blk_trace_ioctl(struct block_device case BLKTRACESTART: start = 1; case BLKTRACESTOP: - ret = blk_trace_startstop(q, start); + ret = __blk_trace_startstop(q, start); break; case BLKTRACETEARDOWN: - ret = blk_trace_remove(q); + ret = __blk_trace_remove(q); break; default: ret = -ENOTTY; @@ -694,10 +728,14 @@ int blk_trace_ioctl(struct block_device **/ void blk_trace_shutdown(struct request_queue *q) { + mutex_lock(&q->blk_trace_mutex); + if (q->blk_trace) { - blk_trace_startstop(q, 0); - blk_trace_remove(q); + __blk_trace_startstop(q, 0); + __blk_trace_remove(q); } + + mutex_unlock(&q->blk_trace_mutex); }
/*
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" ebiederm@xmission.com
commit 7c8a61d9ee1df0fb4747879fa67a99614eb62fec upstream.
Alexandar Potapenko while testing the kernel with KMSAN and syzkaller discovered that in some configurations sctp would leak 4 bytes of kernel stack.
Working with his reproducer I discovered that those 4 bytes that are leaked is the scope id of an ipv6 address returned by recvmsg.
With a little code inspection and a shrewd guess I discovered that sctp_inet6_skb_msgname only initializes the scope_id field for link local ipv6 addresses to the interface index the link local address pertains to instead of initializing the scope_id field for all ipv6 addresses.
That is almost reasonable as scope_id's are meaniningful only for link local addresses. Set the scope_id in all other cases to 0 which is not a valid interface index to make it clear there is nothing useful in the scope_id field.
There should be no danger of breaking userspace as the stack leak guaranteed that previously meaningless random data was being returned.
Fixes: 372f525b495c ("SCTP: Resync with LKSCTP tree.") History-tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git Reported-by: Alexander Potapenko glider@google.com Tested-by: Alexander Potapenko glider@google.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backported to 3.16: - Adjust context - Add braces] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -787,6 +787,8 @@ static void sctp_inet6_skb_msgname(struc if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { struct sctp_ulpevent *ev = sctp_skb2event(skb); addr->v6.sin6_scope_id = ev->iif; + } else { + addr->v6.sin6_scope_id = 0; } }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao houtao1@huawei.com
commit b9a41d21dceadf8104812626ef85dc56ee8a60ed upstream.
The following BUG_ON was hit when testing repeat creation and removal of DM devices:
kernel BUG at drivers/md/dm.c:2919! CPU: 7 PID: 750 Comm: systemd-udevd Not tainted 4.1.44 Call Trace: [<ffffffff81649e8b>] dm_get_from_kobject+0x34/0x3a [<ffffffff81650ef1>] dm_attr_show+0x2b/0x5e [<ffffffff817b46d1>] ? mutex_lock+0x26/0x44 [<ffffffff811df7f5>] sysfs_kf_seq_show+0x83/0xcf [<ffffffff811de257>] kernfs_seq_show+0x23/0x25 [<ffffffff81199118>] seq_read+0x16f/0x325 [<ffffffff811de994>] kernfs_fop_read+0x3a/0x13f [<ffffffff8117b625>] __vfs_read+0x26/0x9d [<ffffffff8130eb59>] ? security_file_permission+0x3c/0x44 [<ffffffff8117bdb8>] ? rw_verify_area+0x83/0xd9 [<ffffffff8117be9d>] vfs_read+0x8f/0xcf [<ffffffff81193e34>] ? __fdget_pos+0x12/0x41 [<ffffffff8117c686>] SyS_read+0x4b/0x76 [<ffffffff817b606e>] system_call_fastpath+0x12/0x71
The bug can be easily triggered, if an extra delay (e.g. 10ms) is added between the test of DMF_FREEING & DMF_DELETING and dm_get() in dm_get_from_kobject().
To fix it, we need to ensure the test of DMF_FREEING & DMF_DELETING and dm_get() are done in an atomic way, so _minor_lock is used.
The other callers of dm_get() have also been checked to be OK: some callers invoke dm_get() under _minor_lock, some callers invoke it under _hash_lock, and dm_start_request() invoke it after increasing md->open_count.
Signed-off-by: Hou Tao houtao1@huawei.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/md/dm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2912,11 +2912,15 @@ struct mapped_device *dm_get_from_kobjec
md = container_of(kobj, struct mapped_device, kobj_holder.kobj);
- if (test_bit(DMF_FREEING, &md->flags) || - dm_deleting_md(md)) - return NULL; - + spin_lock(&_minor_lock); + if (test_bit(DMF_FREEING, &md->flags) || dm_deleting_md(md)) { + md = NULL; + goto out; + } dm_get(md); +out: + spin_unlock(&_minor_lock); + return md; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern stern@rowland.harvard.edu
commit 2ef47001b3ee3ded579b7532ebdcf8680e4d8c54 upstream.
The USB kerneldoc says that the actual_length field "is read in non-iso completion functions", but the usbfs driver uses it for all URB types in processcompl(). Since not all of the host controller drivers set actual_length for isochronous URBs, programs using usbfs with some host controllers don't work properly. For example, Minas reports that a USB camera controlled by libusb doesn't work properly with a dwc2 controller.
It doesn't seem worthwhile to change the HCDs and the documentation, since the in-kernel USB class drivers evidently don't rely on actual_length for isochronous transfers. The easiest solution is for usbfs to calculate the actual_length value for itself, by adding up the lengths of the individual packets in an isochronous transfer.
Signed-off-by: Alan Stern stern@rowland.harvard.edu CC: Minas Harutyunyan Minas.Harutyunyan@synopsys.com Reported-and-tested-by: wlf wulf@rock-chips.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/core/devio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1650,6 +1650,18 @@ static int proc_unlinkurb(struct usb_dev return 0; }
+static void compute_isochronous_actual_length(struct urb *urb) +{ + unsigned int i; + + if (urb->number_of_packets > 0) { + urb->actual_length = 0; + for (i = 0; i < urb->number_of_packets; i++) + urb->actual_length += + urb->iso_frame_desc[i].actual_length; + } +} + static int processcompl(struct async *as, void __user * __user *arg) { struct urb *urb = as->urb; @@ -1657,6 +1669,7 @@ static int processcompl(struct async *as void __user *addr = as->userurb; unsigned int i;
+ compute_isochronous_actual_length(urb); if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) goto err_out; @@ -1826,6 +1839,7 @@ static int processcompl_compat(struct as void __user *addr = as->userurb; unsigned int i;
+ compute_isochronous_actual_length(urb); if (as->userbuffer && urb->actual_length) { if (copy_urb_data_to_user(as->userbuffer, urb)) return -EFAULT;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Seri ben@armis.com
commit 06e7e776ca4d36547e503279aeff996cbb292c16 upstream.
In the function l2cap_parse_conf_rsp and in the function l2cap_parse_conf_req the following variable is declared without initialization:
struct l2cap_conf_efs efs;
In addition, when parsing input configuration parameters in both of these functions, the switch case for handling EFS elements may skip the memcpy call that will write to the efs variable:
... case L2CAP_CONF_EFS: if (olen == sizeof(efs)) memcpy(&efs, (void *)val, olen); ...
The olen in the above if is attacker controlled, and regardless of that if, in both of these functions the efs variable would eventually be added to the outgoing configuration request that is being built:
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), (unsigned long) &efs);
So by sending a configuration request, or response, that contains an L2CAP_CONF_EFS element, but with an element length that is not sizeof(efs) - the memcpy to the uninitialized efs variable can be avoided, and the uninitialized variable would be returned to the attacker (16 bytes).
This issue has been assigned CVE-2017-1000410
Cc: Marcel Holtmann marcel@holtmann.org Cc: Gustavo Padovan gustavo@padovan.org Cc: Johan Hedberg johan.hedberg@gmail.com Signed-off-by: Ben Seri ben@armis.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/bluetooth/l2cap_core.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
--- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3349,9 +3349,10 @@ static int l2cap_parse_conf_req(struct l break;
case L2CAP_CONF_EFS: - remote_efs = 1; - if (olen == sizeof(efs)) + if (olen == sizeof(efs)) { + remote_efs = 1; memcpy(&efs, (void *) val, olen); + } break;
case L2CAP_CONF_EWS: @@ -3570,16 +3571,17 @@ static int l2cap_parse_conf_rsp(struct l break;
case L2CAP_CONF_EFS: - if (olen == sizeof(efs)) + if (olen == sizeof(efs)) { memcpy(&efs, (void *)val, olen);
- if (chan->local_stype != L2CAP_SERV_NOTRAFIC && - efs.stype != L2CAP_SERV_NOTRAFIC && - efs.stype != chan->local_stype) - return -ECONNREFUSED; + if (chan->local_stype != L2CAP_SERV_NOTRAFIC && + efs.stype != L2CAP_SERV_NOTRAFIC && + efs.stype != chan->local_stype) + return -ECONNREFUSED;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs, endptr - ptr); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), + (unsigned long) &efs, endptr - ptr); + } break;
case L2CAP_CONF_FCS:
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shuah Khan shuahkh@osg.samsung.com
commit be6123df1ea8f01ee2f896a16c2b7be3e4557a5a upstream.
stub_send_ret_submit() handles urb with a potential null transfer_buffer, when it replays a packet with potential malicious data that could contain a null buffer. Add a check for the condition when actual_length > 0 and transfer_buffer is null.
Reported-by: Secunia Research vuln@secunia.com Signed-off-by: Shuah Khan shuahkh@osg.samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/usbip/stub_tx.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -178,6 +178,13 @@ static int stub_send_ret_submit(struct s memset(&pdu_header, 0, sizeof(pdu_header)); memset(&msg, 0, sizeof(msg));
+ if (urb->actual_length > 0 && !urb->transfer_buffer) { + dev_err(&sdev->udev->dev, + "urb: actual_length %d transfer_buffer null\n", + urb->actual_length); + return -1; + } + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) iovnum = 2 + urb->number_of_packets; else
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit ae0c585d93dfaf923d2c7eb44b2c3ab92854ea9b upstream.
The original issue being fixed in this patch was seen with the ixgbe driver, but the same issue exists with ixgbevf as well, as the code is very similar. read_barrier_depends is not sufficient to ensure loads following it are not speculatively loaded out of order by the CPU, which can result in stale data being loaded, causing potential system crashes.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Andrew Bowers andrewx.bowers@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -249,7 +249,7 @@ static bool ixgbevf_clean_tx_irq(struct break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* if DD is not set pending work has not been completed */ if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit 0a9a17e3bb4564caf4bfe2a6783ae1287667d188 upstream.
This patch fixes an issue seen on Power systems with ixgbe which results in skb list corruption and an eventual kernel oops. The following is what was observed:
CPU 1 CPU2 ============================ ============================ 1: ixgbe_xmit_frame_ring ixgbe_clean_tx_irq 2: first->skb = skb eop_desc = tx_buffer->next_to_watch 3: ixgbe_tx_map read_barrier_depends() 4: wmb check adapter written status bit 5: first->next_to_watch = tx_desc napi_consume_skb(tx_buffer->skb ..); 6: writel(i, tx_ring->tail);
The read_barrier_depends is insufficient to ensure that tx_buffer->skb does not get loaded prior to tx_buffer->next_to_watch, which then results in loading a stale skb pointer. This patch replaces the read_barrier_depends with smp_rmb to ensure loads are ordered with respect to the load of tx_buffer->next_to_watch.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Andrew Bowers andrewx.bowers@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1086,7 +1086,7 @@ static bool ixgbe_clean_tx_irq(struct ix break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* if DD is not set pending work has not been completed */ if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tuomas Tynkkynen tuomas@tuxera.com
commit 8ee031631546cf2f7859cc69593bd60bbdd70b46 upstream.
Commit fd2421f54423 ("fs/9p: When doing inode lookup compare qid details and inode mode bits.") transformed v9fs_qid_iget() to use iget5_locked() instead of iget_locked(). However, the test() callback is not checking fid.path at all, which means that a lookup in the inode cache can now accidentally locate a completely wrong inode from the same inode hash bucket if the other fields (qid.type and qid.version) match.
Fixes: fd2421f54423 ("fs/9p: When doing inode lookup compare qid details and inode mode bits.") Reviewed-by: Latchesar Ionkov lucho@ionkov.net Signed-off-by: Tuomas Tynkkynen tuomas@tuxera.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/9p/vfs_inode.c | 3 +++ fs/9p/vfs_inode_dotl.c | 3 +++ 2 files changed, 6 insertions(+)
--- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -483,6 +483,9 @@ static int v9fs_test_inode(struct inode
if (v9inode->qid.type != st->qid.type) return 0; + + if (v9inode->qid.path != st->qid.path) + return 0; return 1; }
--- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -87,6 +87,9 @@ static int v9fs_test_inode_dotl(struct i
if (v9inode->qid.type != st->qid.type) return 0; + + if (v9inode->qid.path != st->qid.path) + return 0; return 1; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever chuck.lever@oracle.com
commit c05cefcc72416a37eba5a2b35f0704ed758a9145 upstream.
Before traversing a referral and performing a mount, the mounted-on directory looks strange:
dr-xr-xr-x. 2 4294967294 4294967294 0 Dec 31 1969 dir.0
nfs4_get_referral is wiping out any cached attributes with what was returned via GETATTR(fs_locations), but the bit mask for that operation does not request any file attributes.
Retrieve owner and timestamp information so that the memcpy in nfs4_get_referral fills in more attributes.
Changes since v1: - Don't request attributes that the client unconditionally replaces - Request only MOUNTED_ON_FILEID or FILEID attribute, not both - encode_fs_locations() doesn't use the third bitmask word
Fixes: 6b97fd3da1ea ("NFSv4: Follow a referral") Suggested-by: Pradeep Thomas pradeepthomas@gmail.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/nfs/nfs4proc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
--- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -243,15 +243,12 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATT };
const u32 nfs4_fs_locations_bitmap[3] = { - FATTR4_WORD0_TYPE - | FATTR4_WORD0_CHANGE + FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_FSID | FATTR4_WORD0_FILEID | FATTR4_WORD0_FS_LOCATIONS, - FATTR4_WORD1_MODE - | FATTR4_WORD1_NUMLINKS - | FATTR4_WORD1_OWNER + FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV | FATTR4_WORD1_SPACE_USED @@ -6015,9 +6012,7 @@ static int _nfs4_proc_fs_locations(struc struct page *page) { struct nfs_server *server = NFS_SERVER(dir); - u32 bitmask[3] = { - [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, - }; + u32 bitmask[3]; struct nfs4_fs_locations_arg args = { .dir_fh = NFS_FH(dir), .name = name, @@ -6036,12 +6031,15 @@ static int _nfs4_proc_fs_locations(struc
dprintk("%s: start\n", __func__);
+ bitmask[0] = nfs4_fattr_bitmap[0] | FATTR4_WORD0_FS_LOCATIONS; + bitmask[1] = nfs4_fattr_bitmap[1]; + /* Ask for the fileid of the absent filesystem if mounted_on_fileid * is not supported */ if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) - bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; + bitmask[0] &= ~FATTR4_WORD0_FILEID; else - bitmask[0] |= FATTR4_WORD0_FILEID; + bitmask[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
nfs_fattr_init(&fs_locations->fattr); fs_locations->server = server;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit 2339536d229df25c71c0900fc619289229bfecf6 upstream.
Make sure to kill the interrupt-in URB after a failed open request. Apart from saving power (and avoiding stale input after a later successful open), this also prevents a NULL-deref in the completion handler if the port is manually unbound.
Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Fixes: 704577861d5e ("USB: serial: metro-usb: get data from device in Uni-Directional mode.") Signed-off-by: Johan Hovold johan@kernel.org [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/serial/metro-usb.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -217,7 +217,7 @@ static int metrousb_open(struct tty_stru dev_err(&port->dev, "%s - failed submitting interrupt in urb, error code=%d\n", __func__, result); - goto exit; + return result; }
/* Send activate cmd to device */ @@ -226,11 +226,16 @@ static int metrousb_open(struct tty_stru dev_err(&port->dev, "%s - failed to configure device, error code=%d\n", __func__, result); - goto exit; + goto err_kill_urb; }
dev_dbg(&port->dev, "%s - port open\n", __func__); -exit: + + return 0; + +err_kill_urb: + usb_kill_urb(port->interrupt_in_urb); + return result; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit 1e1f9ca546556e508d021545861f6b5fc75a95fe upstream.
The original issue being fixed in this patch was seen with the ixgbe driver, but the same issue exists with igbvf as well, as the code is very similar. read_barrier_depends is not sufficient to ensure loads following it are not speculatively loaded out of order by the CPU, which can result in stale data being loaded, causing potential system crashes.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/igbvf/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -808,7 +808,7 @@ static bool igbvf_clean_tx_irq(struct ig break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* if DD is not set pending work has not been completed */ if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)))
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi peter.ujfalusi@ti.com
commit 660e1551939931657808d47838a3f443c0e83fd0 upstream.
of_find_node_by_name() will call of_node_put() on the node so we need to get it first to avoid warnings. The cfg_node needs to be put after we have finished processing the properties.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Tested-by: Nishanth Menon nm@ti.com Signed-off-by: Stephen Boyd sboyd@codeaurora.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/clk/ti/clk-dra7-atl.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -262,6 +262,7 @@ static int of_dra7_atl_clk_probe(struct
/* Get configuration for the ATL instances */ snprintf(prop, sizeof(prop), "atl%u", i); + of_node_get(node); cfg_node = of_find_node_by_name(node, prop); if (cfg_node) { ret = of_property_read_u32(cfg_node, "bws", @@ -275,6 +276,7 @@ static int of_dra7_atl_clk_probe(struct atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i), cdesc->aws); } + of_node_put(cfg_node); }
cdesc->probed = true;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu mhiramat@kernel.org
commit 12a78d43de767eaf8fb272facb7a7b6f2dc6a9df upstream.
The kbuild test robot reported this build warning:
Warning: arch/x86/tools/test_get_len found difference at <jump_table>:ffffffff8103dd2c
Warning: ffffffff8103dd82: f6 09 d8 testb $0xd8,(%rcx) Warning: objdump says 3 bytes, but insn_get_length() says 2 Warning: decoded and checked 1569014 instructions with 1 warnings
This sequence seems to be a new instruction not in the opcode map in the Intel SDM.
The instruction sequence is "F6 09 d8", means Group3(F6), MOD(00)REG(001)RM(001), and 0xd8. Intel SDM vol2 A.4 Table A-6 said the table index in the group is "Encoding of Bits 5,4,3 of the ModR/M Byte (bits 2,1,0 in parenthesis)"
In that table, opcodes listed by the index REG bits as:
000 001 010 011 100 101 110 111 TEST Ib/Iz,(undefined),NOT,NEG,MUL AL/rAX,IMUL AL/rAX,DIV AL/rAX,IDIV AL/rAX
So, it seems TEST Ib is assigned to 001.
Add the new pattern.
Reported-by: kbuild test robot fengguang.wu@intel.com Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/lib/x86-opcode-map.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt @@ -814,7 +814,7 @@ EndTable
GrpTable: Grp3_1 0: TEST Eb,Ib -1: +1: TEST Eb,Ib 2: NOT Eb 3: NEG Eb 4: MUL AL,Eb
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Steffen Alexander.Steffen@infineon.com
commit ee70bc1e7b63ac8023c9ff9475d8741e397316e7 upstream.
tpm_transmit() does not offer an explicit interface to indicate the number of valid bytes in the communication buffer. Instead, it relies on the commandSize field in the TPM header that is encoded within the buffer. Therefore, ensure that a) enough data has been written to the buffer, so that the commandSize field is present and b) the commandSize field does not announce more data than has been written to the buffer.
This should have been fixed with CVE-2011-1161 long ago, but apparently a correct version of that patch never made it into the kernel.
Signed-off-by: Alexander Steffen Alexander.Steffen@infineon.com Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Tested-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/char/tpm/tpm-dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -139,6 +139,12 @@ static ssize_t tpm_write(struct file *fi return -EFAULT; }
+ if (in_size < 6 || + in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) { + mutex_unlock(&priv->buffer_mutex); + return -EINVAL; + } + /* atomic tpm command send and result receive */ out_size = tpm_transmit(priv->chip, priv->data_buffer, sizeof(priv->data_buffer));
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dongho Sim dh.sim@samsung.com
commit 33be828ada7274ebcade2001f16e5b4e33a4636e upstream.
There are redundant lines in allocate_data_block.
In this function, we call refresh_sit_entry with old seg and old curseg. After that, we call locate_dirty_segment with old curseg.
But, the new address is always allocated from old curseg and we call locate_dirty_segment with old curseg in refresh_sit_entry. So, we do not need to call locate_dirty_segment with old curseg again.
We've discussed like below:
Jaegeuk said: "When considering SSR, we need to take care of the following scenario. - old segno : X - new address : Z - old curseg : Y This means, a new block is supposed to be written to Z from X. And Z is newly allocated in the same path from Y.
In that case, we should trigger locate_dirty_segment for Y, since it was a current_segment and can be dirty owing to SSR. But that was not included in the dirty list."
Changman said: "We already choosed old curseg(Y) and then we allocate new address(Z) from old curseg(Y). After that we call refresh_sit_entry(old address, new address). In the funcation, we call locate_dirty_segment with old seg and old curseg. So calling locate_dirty_segment after refresh_sit_entry again is redundant."
Jaegeuk said: "Right. The new address is always allocated from old_curseg."
Reviewed-by: Chao Yu chao2.yu@samsung.com Signed-off-by: Dongho Sim dh.sim@samsung.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/f2fs/segment.c | 3 --- 1 file changed, 3 deletions(-)
--- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -969,14 +969,12 @@ void allocate_data_block(struct f2fs_sb_ { struct sit_info *sit_i = SIT_I(sbi); struct curseg_info *curseg; - unsigned int old_cursegno;
curseg = CURSEG_I(sbi, type);
mutex_lock(&curseg->curseg_mutex);
*new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); - old_cursegno = curseg->segno;
/* * __add_sum_entry should be resided under the curseg_mutex @@ -997,7 +995,6 @@ void allocate_data_block(struct f2fs_sb_ * since SSR needs latest valid block information. */ refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr); - locate_dirty_segment(sbi, old_cursegno);
mutex_unlock(&sit_i->sentry_lock);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: John David Anglin dave.anglin@bell.net
commit 05f016d2ca7a4fab99d5d5472168506ddf95e74f upstream.
As noted by Christoph Biedl, passing a pointer size of 4 in the new CAS implementation causes a kernel crash. The attached patch corrects the off by one error in the argument validity check.
In reviewing the code, I noticed that we only perform word operations with the pointer size argument. The subi instruction intentionally uses a word condition on 64-bit kernels. Nullification was used instead of a cmpib instruction as the branch should never be taken. The shlw pseudo-operation generates a depw,z instruction and it clears the target before doing a shift left word deposit. Thus, we don't need to clip the upper 32 bits of this argument on 64-bit kernels.
Tested with a gcc testsuite run with a 64-bit kernel. The gcc atomic code in libgcc is the only direct user of the new CAS implementation that I am aware of.
Signed-off-by: John David Anglin dave.anglin@bell.net Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/parisc/kernel/syscall.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -690,15 +690,15 @@ cas_action: /* ELF32 Process entry path */ lws_compare_and_swap_2: #ifdef CONFIG_64BIT - /* Clip the input registers */ + /* Clip the input registers. We don't need to clip %r23 as we + only use it for word operations */ depdi 0, 31, 32, %r26 depdi 0, 31, 32, %r25 depdi 0, 31, 32, %r24 - depdi 0, 31, 32, %r23 #endif
/* Check the validity of the size pointer */ - subi,>>= 4, %r23, %r0 + subi,>>= 3, %r23, %r0 b,n lws_exit_nosys
/* Jump to the functions which will load the old and new values into
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit 11e3e8d6d9274bf630859b4c47bc4e4d76f289db upstream.
The elf_fdpic code shows a harmless warning when built with MMU disabled, I ran into this now that fdpic is available on ARM randconfig builds since commit 50b2b2e691cd ("ARM: add ELF_FDPIC support").
fs/binfmt_elf_fdpic.c: In function 'elf_fdpic_dump_segments': fs/binfmt_elf_fdpic.c:1501:17: error: unused variable 'addr' [-Werror=unused-variable]
This adds another #ifdef around the variable declaration to shut up the warning.
Fixes: e6c1baa9b562 ("convert the rest of binfmt_elf_fdpic to dump_emit()") Acked-by: Nicolas Pitre nico@linaro.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/binfmt_elf_fdpic.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1487,7 +1487,9 @@ static bool elf_fdpic_dump_segments(stru struct vm_area_struct *vma;
for (vma = current->mm->mmap; vma; vma = vma->vm_next) { +#ifdef CONFIG_MMU unsigned long addr; +#endif
if (!maydump(vma, cprm->mm_flags)) continue;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "William A. Kennington III" wak@google.com
commit 71e24d7731a2903b1ae2bba2b2971c654d9c2aa6 upstream.
The current code checks the completion map to look for the first token that is complete. In some cases, a completion can come in but the token can still be on lease to the caller processing the completion. If this completed but unreleased token is the first token found in the bitmap by another tasks trying to acquire a token, then the __test_and_set_bit call will fail since the token will still be on lease. The acquisition will then fail with an EBUSY.
This patch reorganizes the acquisition code to look at the opal_async_token_map for an unleased token. If the token has no lease it must have no outstanding completions so we should never see an EBUSY, unless we have leased out too many tokens. Since opal_async_get_token_inrerruptible is protected by a semaphore, we will practically never see EBUSY anymore.
Fixes: 8d7248232208 ("powerpc/powernv: Infrastructure to support OPAL async completion") Signed-off-by: William A. Kennington III wak@google.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/powerpc/platforms/powernv/opal-async.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -38,18 +38,18 @@ int __opal_async_get_token(void) int token;
spin_lock_irqsave(&opal_async_comp_lock, flags); - token = find_first_bit(opal_async_complete_map, opal_max_async_tokens); + token = find_first_zero_bit(opal_async_token_map, opal_max_async_tokens); if (token >= opal_max_async_tokens) { token = -EBUSY; goto out; }
- if (__test_and_set_bit(token, opal_async_token_map)) { + if (!__test_and_clear_bit(token, opal_async_complete_map)) { token = -EBUSY; goto out; }
- __clear_bit(token, opal_async_complete_map); + __set_bit(token, opal_async_token_map);
out: spin_unlock_irqrestore(&opal_async_comp_lock, flags);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit 3e351275655d3c84dc28abf170def9786db5176d upstream.
We could allocate less memory than intended because we do:
bfad->regdata = kzalloc(len << 2, GFP_KERNEL);
The shift can overflow leading to a crash. This is debugfs code so the impact is very small. I fixed the network version of this in March with commit 13e2d5187f6b ("bna: integer overflow bug in debugfs").
Fixes: ab2a9ba189e8 ("[SCSI] bfa: add debugfs support") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/scsi/bfa/bfad_debugfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -254,7 +254,8 @@ bfad_debugfs_write_regrd(struct file *fi struct bfad_s *bfad = port->bfad; struct bfa_s *bfa = &bfad->bfa; struct bfa_ioc_s *ioc = &bfa->ioc; - int addr, len, rc, i; + int addr, rc, i; + u32 len; u32 *regbuf; void __iomem *rb, *reg_addr; unsigned long flags; @@ -274,7 +275,7 @@ bfad_debugfs_write_regrd(struct file *fi }
rc = sscanf(kern_buf, "%x:%x", &addr, &len); - if (rc < 2) { + if (rc < 2 || len > (UINT_MAX >> 2)) { printk(KERN_INFO "bfad[%d]: %s failed to read user buf\n", bfad->inst_no, __func__);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit c70ca38960399a63d5c048b7b700612ea321d17e upstream.
Make srpt_parse_i_port_id() return a negative value if hex2bin() fails.
Fixes: commit a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/infiniband/ulp/srpt/ib_srpt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3521,7 +3521,7 @@ static int srpt_parse_i_port_id(u8 i_por { const char *p; unsigned len, count, leading_zero_bytes; - int ret, rc; + int ret;
p = name; if (strnicmp(p, "0x", 2) == 0) @@ -3533,10 +3533,9 @@ static int srpt_parse_i_port_id(u8 i_por count = min(len / 2, 16U); leading_zero_bytes = 16 - count; memset(i_port_id, 0, leading_zero_bytes); - rc = hex2bin(i_port_id + leading_zero_bytes, p, count); - if (rc < 0) - pr_debug("hex2bin failed for srpt_parse_i_port_id: %d\n", rc); - ret = 0; + ret = hex2bin(i_port_id + leading_zero_bytes, p, count); + if (ret < 0) + pr_debug("hex2bin failed for srpt_parse_i_port_id: %d\n", ret); out: return ret; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Markus Elfring elfring@users.sourceforge.net
commit bfba2b3e21b9426c0f9aca00f3cad8631b2da170 upstream.
Move a debug message so that a null pointer access can not happen for the variable "vout" in this function.
Fixes: 5c7ab6348e7b3fcca2b8ee548306c774472971e2 ("V4L/DVB: V4L2: Add support for OMAP2/3 V4L2 display driver on top of DSS2")
Signed-off-by: Markus Elfring elfring@users.sourceforge.net Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/media/platform/omap/omap_vout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -1017,11 +1017,12 @@ static int omap_vout_open(struct file *f struct omap_vout_device *vout = NULL;
vout = video_drvdata(file); - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
if (vout == NULL) return -ENODEV;
+ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); + /* for now, we only support single open */ if (vout->opened) return -EBUSY;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jan Harkes jaharkes@cs.cmu.edu
commit d337b66a4c52c7b04eec661d86c2ef6e168965a2 upstream.
When an application called fsync on a file in Coda a small request with just the file identifier was allocated, but the declared length was set to the size of union of all possible upcall requests.
This bug has been around for a very long time and is now caught by the extra checking in usercopy that was introduced in Linux-4.8.
The exposure happens when the Coda cache manager process reads the fsync upcall request at which point it is killed. As a result there is nobody servicing any further upcalls, trapping any processes that try to access the mounted Coda filesystem.
Signed-off-by: Jan Harkes jaharkes@cs.cmu.edu Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/coda/upcall.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -446,8 +446,7 @@ int venus_fsync(struct super_block *sb, UPARG(CODA_FSYNC);
inp->coda_fsync.VFid = *fid; - error = coda_upcall(coda_vcp(sb), sizeof(union inputArgs), - &outsize, inp); + error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
CODA_FREE(inp, insize); return error;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nadav Amit namit@vmware.com
commit c3eec59659cf25916647d2178c541302bb4822ad upstream.
rq_reqbuf is allocated using kvmalloc() but released in one occasion using kfree() instead of kvfree().
The issue was found using grep based on a similar bug.
Fixes: d7e09d0397e8 ("add Lustre file system client support") Fixes: ee0ec1946ec2 ("lustre: ptlrpc: Replace uses of OBD_{ALLOC,FREE}_LARGE")
Cc: Peng Tao bergwolf@gmail.com Cc: Oleg Drokin oleg.drokin@intel.com Cc: James Simmons jsimmons@infradead.org
Signed-off-by: Nadav Amit namit@vmware.com Signed-off-by: Andreas Dilger andreas.dilger@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: use OBD_FREE_LARGE()] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/lustre/lustre/ptlrpc/sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -867,7 +867,7 @@ void sptlrpc_request_out_callback(struct if (req->rq_pool || !req->rq_reqbuf) return;
- OBD_FREE(req->rq_reqbuf, req->rq_reqbuf_len); + OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len); req->rq_reqbuf = NULL; req->rq_reqbuf_len = 0; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
Reviewed-by: James Simmons jsimmons@infradead.org
From: Nadav Amit namit@vmware.com
commit c3eec59659cf25916647d2178c541302bb4822ad upstream.
rq_reqbuf is allocated using kvmalloc() but released in one occasion using kfree() instead of kvfree().
The issue was found using grep based on a similar bug.
Fixes: d7e09d0397e8 ("add Lustre file system client support") Fixes: ee0ec1946ec2 ("lustre: ptlrpc: Replace uses of OBD_{ALLOC,FREE}_LARGE")
Cc: Peng Tao bergwolf@gmail.com Cc: Oleg Drokin oleg.drokin@intel.com Cc: James Simmons jsimmons@infradead.org
Signed-off-by: Nadav Amit namit@vmware.com Signed-off-by: Andreas Dilger andreas.dilger@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: use OBD_FREE_LARGE()] Signed-off-by: Ben Hutchings ben@decadent.org.uk
drivers/staging/lustre/lustre/ptlrpc/sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -867,7 +867,7 @@ void sptlrpc_request_out_callback(struct if (req->rq_pool || !req->rq_reqbuf) return;
- OBD_FREE(req->rq_reqbuf, req->rq_reqbuf_len);
- OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len); req->rq_reqbuf = NULL; req->rq_reqbuf_len = 0;
}
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Rohner andreas.rohner@gmx.net
commit 31ccb1f7ba3cfe29631587d451cf5bb8ab593550 upstream.
There is a race condition between nilfs_dirty_inode() and nilfs_set_file_dirty().
When a file is opened, nilfs_dirty_inode() is called to update the access timestamp in the inode. It calls __nilfs_mark_inode_dirty() in a separate transaction. __nilfs_mark_inode_dirty() caches the ifile buffer_head in the i_bh field of the inode info structure and marks it as dirty.
After some data was written to the file in another transaction, the function nilfs_set_file_dirty() is called, which adds the inode to the ns_dirty_files list.
Then the segment construction calls nilfs_segctor_collect_dirty_files(), which goes through the ns_dirty_files list and checks the i_bh field. If there is a cached buffer_head in i_bh it is not marked as dirty again.
Since nilfs_dirty_inode() and nilfs_set_file_dirty() use separate transactions, it is possible that a segment construction that writes out the ifile occurs in-between the two. If this happens the inode is not on the ns_dirty_files list, but its ifile block is still marked as dirty and written out.
In the next segment construction, the data for the file is written out and nilfs_bmap_propagate() updates the b-tree. Eventually the bmap root is written into the i_bh block, which is not dirty, because it was written out in another segment construction.
As a result the bmap update can be lost, which leads to file system corruption. Either the virtual block address points to an unallocated DAT block, or the DAT entry will be reused for something different.
The error can remain undetected for a long time. A typical error message would be one of the "bad btree" errors or a warning that a DAT entry could not be found.
This bug can be reproduced reliably by a simple benchmark that creates and overwrites millions of 4k files.
Link: http://lkml.kernel.org/r/1509367935-3086-2-git-send-email-konishi.ryusuke@la... Signed-off-by: Andreas Rohner andreas.rohner@gmx.net Signed-off-by: Ryusuke Konishi konishi.ryusuke@lab.ntt.co.jp Tested-by: Andreas Rohner andreas.rohner@gmx.net Tested-by: Ryusuke Konishi konishi.ryusuke@lab.ntt.co.jp Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/nilfs2/segment.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1883,8 +1883,6 @@ static int nilfs_segctor_collect_dirty_f "failed to get inode block.\n"); return err; } - mark_buffer_dirty(ibh); - nilfs_mdt_mark_dirty(ifile); spin_lock(&nilfs->ns_inode_lock); if (likely(!ii->i_bh)) ii->i_bh = ibh; @@ -1893,6 +1891,10 @@ static int nilfs_segctor_collect_dirty_f goto retry; }
+ // Always redirty the buffer to avoid race condition + mark_buffer_dirty(ii->i_bh); + nilfs_mdt_mark_dirty(ifile); + clear_bit(NILFS_I_QUEUED, &ii->i_state); set_bit(NILFS_I_BUSY, &ii->i_state); list_move_tail(&ii->i_dirty, &sci->sc_dirty_files);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit 74d471b598444b7f2d964930f7234779c80960a0 upstream.
Make sure to free the port private data before returning after a failed probe attempt.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/serial/garmin_gps.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1414,6 +1414,12 @@ static int garmin_port_probe(struct usb_ usb_set_serial_port_data(port, garmin_data_p);
status = garmin_init_session(port); + if (status) + goto err_free; + + return 0; +err_free: + kfree(garmin_data_p);
return status; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe jgunthorpe@obsidianresearch.com
commit 299ee123e19889d511092347f5fc14db0f10e3a6 upstream.
The SCTP socket extensions API document describes the v4mapping option as follows:
8.1.15. Set/Clear IPv4 Mapped Addresses (SCTP_I_WANT_MAPPED_V4_ADDR)
This socket option is a Boolean flag which turns on or off the mapping of IPv4 addresses. If this option is turned on, then IPv4 addresses will be mapped to V6 representation. If this option is turned off, then no mapping will be done of V4 addresses and a user will receive both PF_INET6 and PF_INET type addresses on the socket. See [RFC3542] for more details on mapped V6 addresses.
This description isn't really in line with what the code does though.
Introduce addr_to_user (renamed addr_v4map), which should be called before any sockaddr is passed back to user space. The new function places the sockaddr into the correct format depending on the SCTP_I_WANT_MAPPED_V4_ADDR option.
Audit all places that touched v4mapped and either sanely construct a v4 or v6 address then call addr_to_user, or drop the unnecessary v4mapped check entirely.
Audit all places that call addr_to_user and verify they are on a sycall return path.
Add a custom getname that formats the address properly.
Several bugs are addressed: - SCTP_I_WANT_MAPPED_V4_ADDR=0 often returned garbage for addresses to user space - The addr_len returned from recvmsg was not correct when returning AF_INET on a v6 socket - flowlabel and scope_id were not zerod when promoting a v4 to v6 - Some syscalls like bind and connect behaved differently depending on v4mapped
Tested bind, getpeername, getsockname, connect, and recvmsg for proper behaviour in v4mapped = 1 and 0 cases.
Signed-off-by: Neil Horman nhorman@tuxdriver.com Tested-by: Jason Gunthorpe jgunthorpe@obsidianresearch.com Signed-off-by: Jason Gunthorpe jgunthorpe@obsidianresearch.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- include/net/sctp/sctp.h | 2 + include/net/sctp/structs.h | 8 +-- net/sctp/ipv6.c | 156 ++++++++++++++++++++++++--------------------- net/sctp/protocol.c | 12 ++-- net/sctp/socket.c | 33 +++++----- net/sctp/transport.c | 4 +- net/sctp/ulpevent.c | 2 +- 7 files changed, 112 insertions(+), 105 deletions(-)
--- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -583,6 +583,8 @@ static inline void sctp_v6_map_v4(union static inline void sctp_v4_map_v6(union sctp_addr *addr) { addr->v6.sin6_family = AF_INET6; + addr->v6.sin6_flowinfo = 0; + addr->v6.sin6_scope_id = 0; addr->v6.sin6_port = addr->v4.sin_port; addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; addr->v6.sin6_addr.s6_addr32[0] = 0; --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -465,10 +465,6 @@ struct sctp_af { int saddr); void (*from_sk) (union sctp_addr *, struct sock *sk); - void (*to_sk_saddr) (union sctp_addr *, - struct sock *sk); - void (*to_sk_daddr) (union sctp_addr *, - struct sock *sk); void (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, __be16 port, int iif); @@ -509,7 +505,9 @@ struct sctp_pf { int (*supported_addrs)(const struct sctp_sock *, __be16 *); struct sock *(*create_accept_sk) (struct sock *sk, struct sctp_association *asoc); - void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); + int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); + void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); + void (*to_sk_daddr)(union sctp_addr *, struct sock *sk); struct sctp_af *af; };
--- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -434,7 +434,7 @@ static void sctp_v6_from_sk(union sctp_a /* Initialize sk->sk_rcv_saddr from sctp_addr. */ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) { - if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { + if (addr->sa.sa_family == AF_INET) { sk->sk_v6_rcv_saddr.s6_addr32[0] = 0; sk->sk_v6_rcv_saddr.s6_addr32[1] = 0; sk->sk_v6_rcv_saddr.s6_addr32[2] = htonl(0x0000ffff); @@ -448,7 +448,7 @@ static void sctp_v6_to_sk_saddr(union sc /* Initialize sk->sk_daddr from sctp_addr. */ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) { - if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { + if (addr->sa.sa_family == AF_INET) { sk->sk_v6_daddr.s6_addr32[0] = 0; sk->sk_v6_daddr.s6_addr32[1] = 0; sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); @@ -558,8 +558,6 @@ static int sctp_v6_available(union sctp_ if (IPV6_ADDR_ANY == type) return 1; if (type == IPV6_ADDR_MAPPED) { - if (sp && !sp->v4mapped) - return 0; if (sp && ipv6_only_sock(sctp_opt2sk(sp))) return 0; sctp_v6_map_v4(addr); @@ -589,8 +587,6 @@ static int sctp_v6_addr_valid(union sctp /* Note: This routine is used in input, so v4-mapped-v6 * are disallowed here when there is no sctp_sock. */ - if (!sp || !sp->v4mapped) - return 0; if (sp && ipv6_only_sock(sctp_opt2sk(sp))) return 0; sctp_v6_map_v4(addr); @@ -688,11 +684,23 @@ out: return newsk; }
-/* Map v4 address to mapped v6 address */ -static void sctp_v6_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr) +/* Format a sockaddr for return to user space. This makes sure the return is + * AF_INET or AF_INET6 depending on the SCTP_I_WANT_MAPPED_V4_ADDR option. + */ +static int sctp_v6_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) { - if (sp->v4mapped && AF_INET == addr->sa.sa_family) - sctp_v4_map_v6(addr); + if (sp->v4mapped) { + if (addr->sa.sa_family == AF_INET) + sctp_v4_map_v6(addr); + } else { + if (addr->sa.sa_family == AF_INET6 && + ipv6_addr_v4mapped(&addr->v6.sin6_addr)) + sctp_v6_map_v4(addr); + } + + if (addr->sa.sa_family == AF_INET) + return sizeof(struct sockaddr_in); + return sizeof(struct sockaddr_in6); }
/* Where did this skb come from? */ @@ -719,82 +727,68 @@ static void sctp_v6_ecn_capable(struct s inet6_sk(sk)->tclass |= INET_ECN_ECT_0; }
-/* Initialize a PF_INET6 socket msg_name. */ -static void sctp_inet6_msgname(char *msgname, int *addr_len) -{ - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)msgname; - sin6->sin6_family = AF_INET6; - sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; /*FIXME */ - *addr_len = sizeof(struct sockaddr_in6); -} - /* Initialize a PF_INET msgname from a ulpevent. */ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, char *msgname, int *addrlen) { - struct sockaddr_in6 *sin6, *sin6from; - - if (msgname) { - union sctp_addr *addr; - struct sctp_association *asoc; - - asoc = event->asoc; - sctp_inet6_msgname(msgname, addrlen); - sin6 = (struct sockaddr_in6 *)msgname; - sin6->sin6_port = htons(asoc->peer.port); - addr = &asoc->peer.primary_addr; - - /* Note: If we go to a common v6 format, this code - * will change. - */ - - /* Map ipv4 address into v4-mapped-on-v6 address. */ - if (sctp_sk(asoc->base.sk)->v4mapped && - AF_INET == addr->sa.sa_family) { - sctp_v4_map_v6((union sctp_addr *)sin6); - sin6->sin6_addr.s6_addr32[3] = - addr->v4.sin_addr.s_addr; - return; - } - - sin6from = &asoc->peer.primary_addr.v6; - sin6->sin6_addr = sin6from->sin6_addr; - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) - sin6->sin6_scope_id = sin6from->sin6_scope_id; + union sctp_addr *addr; + struct sctp_association *asoc; + union sctp_addr *paddr; + + if (!msgname) + return; + + addr = (union sctp_addr *)msgname; + asoc = event->asoc; + paddr = &asoc->peer.primary_addr; + + if (paddr->sa.sa_family == AF_INET) { + addr->v4.sin_family = AF_INET; + addr->v4.sin_port = htons(asoc->peer.port); + addr->v4.sin_addr = paddr->v4.sin_addr; + } else { + addr->v6.sin6_family = AF_INET6; + addr->v6.sin6_flowinfo = 0; + if (ipv6_addr_type(&paddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) + addr->v6.sin6_scope_id = paddr->v6.sin6_scope_id; + else + addr->v6.sin6_scope_id = 0; + addr->v6.sin6_port = htons(asoc->peer.port); + addr->v6.sin6_addr = paddr->v6.sin6_addr; } + + *addrlen = sctp_v6_addr_to_user(sctp_sk(asoc->base.sk), addr); }
/* Initialize a msg_name from an inbound skb. */ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname, int *addr_len) { + union sctp_addr *addr; struct sctphdr *sh; - struct sockaddr_in6 *sin6;
- if (msgname) { - sctp_inet6_msgname(msgname, addr_len); - sin6 = (struct sockaddr_in6 *)msgname; - sh = sctp_hdr(skb); - sin6->sin6_port = sh->source; - - /* Map ipv4 address into v4-mapped-on-v6 address. */ - if (sctp_sk(skb->sk)->v4mapped && - ip_hdr(skb)->version == 4) { - sctp_v4_map_v6((union sctp_addr *)sin6); - sin6->sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr; - return; - } + if (!msgname) + return;
- /* Otherwise, just copy the v6 address. */ - sin6->sin6_addr = ipv6_hdr(skb)->saddr; - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { + addr = (union sctp_addr *)msgname; + sh = sctp_hdr(skb); + + if (ip_hdr(skb)->version == 4) { + addr->v4.sin_family = AF_INET; + addr->v4.sin_port = sh->source; + addr->v4.sin_addr.s_addr = ip_hdr(skb)->saddr; + } else { + addr->v6.sin6_family = AF_INET6; + addr->v6.sin6_flowinfo = 0; + addr->v6.sin6_port = sh->source; + addr->v6.sin6_addr = ipv6_hdr(skb)->saddr; + if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { struct sctp_ulpevent *ev = sctp_skb2event(skb); - sin6->sin6_scope_id = ev->iif; + addr->v6.sin6_scope_id = ev->iif; } } + + *addr_len = sctp_v6_addr_to_user(sctp_sk(skb->sk), addr); }
/* Do we support this AF? */ @@ -870,9 +864,6 @@ static int sctp_inet6_bind_verify(struct return 0; } rcu_read_unlock(); - } else if (type == IPV6_ADDR_MAPPED) { - if (!opt->v4mapped) - return 0; }
af = opt->pf->af; @@ -927,6 +918,23 @@ static int sctp_inet6_supported_addrs(co return 1; }
+/* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */ +static int sctp_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer) +{ + int rc; + + rc = inet6_getname(sock, uaddr, uaddr_len, peer); + + if (rc != 0) + return rc; + + *uaddr_len = sctp_v6_addr_to_user(sctp_sk(sock->sk), + (union sctp_addr *)uaddr); + + return rc; +} + static const struct proto_ops inet6_seqpacket_ops = { .family = PF_INET6, .owner = THIS_MODULE, @@ -935,7 +943,7 @@ static const struct proto_ops inet6_seqp .connect = inet_dgram_connect, .socketpair = sock_no_socketpair, .accept = inet_accept, - .getname = inet6_getname, + .getname = sctp_getname, .poll = sctp_poll, .ioctl = inet6_ioctl, .listen = sctp_inet_listen, @@ -987,8 +995,6 @@ static struct sctp_af sctp_af_inet6 = { .copy_addrlist = sctp_v6_copy_addrlist, .from_skb = sctp_v6_from_skb, .from_sk = sctp_v6_from_sk, - .to_sk_saddr = sctp_v6_to_sk_saddr, - .to_sk_daddr = sctp_v6_to_sk_daddr, .from_addr_param = sctp_v6_from_addr_param, .to_addr_param = sctp_v6_to_addr_param, .cmp_addr = sctp_v6_cmp_addr, @@ -1018,7 +1024,9 @@ static struct sctp_pf sctp_pf_inet6 = { .send_verify = sctp_inet6_send_verify, .supported_addrs = sctp_inet6_supported_addrs, .create_accept_sk = sctp_v6_create_accept_sk, - .addr_v4map = sctp_v6_addr_v4map, + .addr_to_user = sctp_v6_addr_to_user, + .to_sk_saddr = sctp_v6_to_sk_saddr, + .to_sk_daddr = sctp_v6_to_sk_daddr, .af = &sctp_af_inet6, };
--- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -578,10 +578,10 @@ out: return newsk; }
-/* Map address, empty for v4 family */ -static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr) +static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) { - /* Empty */ + /* No address mapping for V4 sockets */ + return sizeof(struct sockaddr_in); }
/* Dump the v4 addr to the seq file. */ @@ -978,7 +978,9 @@ static struct sctp_pf sctp_pf_inet = { .send_verify = sctp_inet_send_verify, .supported_addrs = sctp_inet_supported_addrs, .create_accept_sk = sctp_v4_create_accept_sk, - .addr_v4map = sctp_v4_addr_v4map, + .addr_to_user = sctp_v4_addr_to_user, + .to_sk_saddr = sctp_v4_to_sk_saddr, + .to_sk_daddr = sctp_v4_to_sk_daddr, .af = &sctp_af_inet };
@@ -1049,8 +1051,6 @@ static struct sctp_af sctp_af_inet = { .copy_addrlist = sctp_v4_copy_addrlist, .from_skb = sctp_v4_from_skb, .from_sk = sctp_v4_from_sk, - .to_sk_saddr = sctp_v4_to_sk_saddr, - .to_sk_daddr = sctp_v4_to_sk_daddr, .from_addr_param = sctp_v4_from_addr_param, .to_addr_param = sctp_v4_to_addr_param, .cmp_addr = sctp_v4_cmp_addr, --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -254,7 +254,7 @@ static struct sctp_transport *sctp_addr_ if (id_asoc && (id_asoc != addr_asoc)) return NULL;
- sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), + sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk), (union sctp_addr *)addr);
return transport; @@ -396,7 +396,7 @@ static int sctp_do_bind(struct sock *sk, /* Copy back into socket for getsockname() use. */ if (!ret) { inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num); - af->to_sk_saddr(addr, sk); + sp->pf->to_sk_saddr(addr, sk); }
return ret; @@ -1053,7 +1053,6 @@ static int __sctp_connect(struct sock *s struct sctp_association *asoc2; struct sctp_transport *transport; union sctp_addr to; - struct sctp_af *af; sctp_scope_t scope; long timeo; int err = 0; @@ -1081,6 +1080,8 @@ static int __sctp_connect(struct sock *s /* Walk through the addrs buffer and count the number of addresses. */ addr_buf = kaddrs; while (walk_size < addrs_size) { + struct sctp_af *af; + if (walk_size + sizeof(sa_family_t) > addrs_size) { err = -EINVAL; goto out_free; @@ -1205,8 +1206,7 @@ static int __sctp_connect(struct sock *s
/* Initialize sk's dport and daddr for getpeername() */ inet_sk(sk)->inet_dport = htons(asoc->peer.port); - af = sctp_get_af_specific(sa_addr->sa.sa_family); - af->to_sk_daddr(sa_addr, sk); + sp->pf->to_sk_daddr(sa_addr, sk); sk->sk_err = 0;
/* in-kernel sockets don't generally have a file allocated to them @@ -4166,7 +4166,7 @@ static int sctp_getsockopt_sctp_status(s memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, transport->af_specific->sockaddr_len); /* Map ipv4 address into v4-mapped-on-v6 address. */ - sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), + sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk), (union sctp_addr *)&status.sstat_primary.spinfo_address); status.sstat_primary.spinfo_state = transport->state; status.sstat_primary.spinfo_cwnd = transport->cwnd; @@ -4324,8 +4324,8 @@ static int sctp_getsockopt_autoclose(str int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) { struct sctp_association *asoc = sctp_id2assoc(sk, id); + struct sctp_sock *sp = sctp_sk(sk); struct socket *sock; - struct sctp_af *af; int err = 0;
/* Do not peel off from one netns to another one. */ @@ -4357,8 +4357,7 @@ int sctp_do_peeloff(struct sock *sk, sct /* Make peeled-off sockets more like 1-1 accepted sockets. * Set the daddr and initialize id to something more random */ - af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); - af->to_sk_daddr(&asoc->peer.primary_addr, sk); + sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk);
/* Populate the fields of the newsk from the oldsk and migrate the * asoc to the newsk. @@ -4742,8 +4741,8 @@ static int sctp_getsockopt_peer_addrs(st list_for_each_entry(from, &asoc->peer.transport_addr_list, transports) { memcpy(&temp, &from->ipaddr, sizeof(temp)); - sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); - addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; + addrlen = sctp_get_pf_specific(sk->sk_family) + ->addr_to_user(sp, &temp); if (space_left < addrlen) return -ENOMEM; if (copy_to_user(to, &temp, addrlen)) @@ -4787,9 +4786,9 @@ static int sctp_copy_laddrs(struct sock if (!temp.v4.sin_port) temp.v4.sin_port = htons(port);
- sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), - &temp); - addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; + addrlen = sctp_get_pf_specific(sk->sk_family) + ->addr_to_user(sctp_sk(sk), &temp); + if (space_left < addrlen) { cnt = -ENOMEM; break; @@ -4877,8 +4876,8 @@ static int sctp_getsockopt_local_addrs(s */ list_for_each_entry(addr, &bp->address_list, list) { memcpy(&temp, &addr->a, sizeof(temp)); - sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); - addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; + addrlen = sctp_get_pf_specific(sk->sk_family) + ->addr_to_user(sp, &temp); if (space_left < addrlen) { err = -ENOMEM; /*fixme: right error?*/ goto out; @@ -4937,7 +4936,7 @@ static int sctp_getsockopt_primary_addr( memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, asoc->peer.primary_path->af_specific->sockaddr_len);
- sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, + sctp_get_pf_specific(sk->sk_family)->addr_to_user(sp, (union sctp_addr *)&prim.ssp_addr);
if (put_user(len, optlen)) --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -289,8 +289,8 @@ void sctp_transport_route(struct sctp_tr */ if (asoc && (!asoc->peer.primary_path || (transport == asoc->peer.active_path))) - opt->pf->af->to_sk_saddr(&transport->saddr, - asoc->base.sk); + opt->pf->to_sk_saddr(&transport->saddr, + asoc->base.sk); } else transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; } --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -341,7 +341,7 @@ struct sctp_ulpevent *sctp_ulpevent_make memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage));
/* Map ipv4 address into v4-mapped-on-v6 address. */ - sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map( + sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_to_user( sctp_sk(asoc->base.sk), (union sctp_addr *)&spc->spc_aaddr);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Lepton Wu ytht.net@gmail.com
This finally resolve crash if loaded under qemu + haxm. Haitao Shan pointed out that the reason of that crash is that NX bit get set for page tables. It seems we missed checking if _PAGE_NX is supported in kaiser_add_user_map
Link: https://www.spinics.net/lists/kernel/msg2689835.html
Reviewed-by: Guenter Roeck groeck@chromium.org Signed-off-by: Lepton Wu ytht.net@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org (backported from Greg K-H's 4.4 stable-queue) Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/mm/kaiser.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index 2d5ac54dbcee..7cb57d14ddc0 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -195,6 +195,8 @@ static int kaiser_add_user_map(const void *__start_addr, unsigned long size, * requires that not to be #defined to 0): so mask it off here. */ flags &= ~_PAGE_GLOBAL; + if (!(__supported_pte_mask & _PAGE_NX)) + flags &= ~_PAGE_NX;
for (; address < end_addr; address += PAGE_SIZE) { target_address = get_pa_from_mapping(address);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel jroedel@suse.de
commit ec154bf56b276a0bb36079a5d22a267b5f417801 upstream.
The notifier function will take the dmar_global_lock too, so lockdep complains about inverse locking order when the notifier is registered under the dmar_global_lock.
Reported-by: Jan Kiszka jan.kiszka@siemens.com Fixes: 59ce0515cdaf ('iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens') Signed-off-by: Joerg Roedel jroedel@suse.de [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/iommu/dmar.c | 7 +++++-- drivers/iommu/intel-iommu.c | 10 ++++++++++ include/linux/dmar.h | 1 + 3 files changed, 16 insertions(+), 2 deletions(-)
--- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -718,13 +718,16 @@ int __init dmar_dev_scope_init(void) dmar_free_pci_notify_info(info); } } - - bus_register_notifier(&pci_bus_type, &dmar_pci_bus_nb); }
return dmar_dev_scope_status; }
+void dmar_register_bus_notifier(void) +{ + bus_register_notifier(&pci_bus_type, &dmar_pci_bus_nb); +} +
int __init dmar_table_init(void) { --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4044,6 +4044,16 @@ int __init intel_iommu_init(void) goto out_free_dmar; }
+ up_write(&dmar_global_lock); + + /* + * The bus notifier takes the dmar_global_lock, so lockdep will + * complain later when we register it under the lock. + */ + dmar_register_bus_notifier(); + + down_write(&dmar_global_lock); + if (no_iommu || dmar_disabled) goto out_free_dmar;
--- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -100,6 +100,7 @@ static inline bool dmar_rcu_check(void)
extern int dmar_table_init(void); extern int dmar_dev_scope_init(void); +extern void dmar_register_bus_notifier(void); extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, struct dmar_dev_scope **devices, u16 segment); extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit c4cb99185b4cc96c0a1c70104dc21ae14d7e7f28 upstream.
The original issue being fixed in this patch was seen with the ixgbe driver, but the same issue exists with igb as well, as the code is very similar. read_barrier_depends is not sufficient to ensure loads following it are not speculatively loaded out of order by the CPU, which can result in stale data being loaded, causing potential system crashes.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6360,7 +6360,7 @@ static bool igb_clean_tx_irq(struct igb_ break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* if DD is not set pending work has not been completed */ if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)))
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 3d4e8303f2c747c8540a0a0126d0151514f6468b upstream.
Some timer compat ioctls have NULL checks of timer instance with snd_BUG_ON() that bring up WARN_ON() when the debug option is set. Actually the condition can be met in the normal situation and it's confusing and bad to spew kernel warnings with stack trace there. Let's remove snd_BUG_ON() invocation and replace with the simple checks. Also, correct the error code to EBADFD to follow the native ioctl error handling.
Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/core/timer_compat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/sound/core/timer_compat.c +++ b/sound/core/timer_compat.c @@ -40,11 +40,11 @@ static int snd_timer_user_info_compat(st struct snd_timer *t;
tu = file->private_data; - if (snd_BUG_ON(!tu->timeri)) - return -ENXIO; + if (!tu->timeri) + return -EBADFD; t = tu->timeri->timer; - if (snd_BUG_ON(!t)) - return -ENXIO; + if (!t) + return -EBADFD; memset(&info, 0, sizeof(info)); info.card = t->card ? t->card->number : -1; if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) @@ -73,8 +73,8 @@ static int snd_timer_user_status_compat( struct snd_timer_status32 status; tu = file->private_data; - if (snd_BUG_ON(!tu->timeri)) - return -ENXIO; + if (!tu->timeri) + return -EBADFD; memset(&status, 0, sizeof(status)); status.tstamp.tv_sec = tu->tstamp.tv_sec; status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Anna Schumaker Anna.Schumaker@Netapp.com
commit 3944369db701f075092357b511fd9f5755771585 upstream.
There isn't an obvious way to acquire and release the RCU lock during a tracepoint, so we can't use the rpc_peeraddr2str() function here. Instead, rely on the client's cl_hostname, which should have similar enough information without needing an rcu_dereference().
Reported-by: Dave Jones davej@codemonkey.org.uk Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com [bwh: Backported to 3.16: Drop changes in nfs4_inode{,_stateid}_callback_event()] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/nfs/nfs4trace.h | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-)
--- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -201,17 +201,13 @@ DECLARE_EVENT_CLASS(nfs4_clientid_event, TP_ARGS(clp, error),
TP_STRUCT__entry( - __string(dstaddr, - rpc_peeraddr2str(clp->cl_rpcclient, - RPC_DISPLAY_ADDR)) + __string(dstaddr, clp->cl_hostname) __field(int, error) ),
TP_fast_assign( __entry->error = error; - __assign_str(dstaddr, - rpc_peeraddr2str(clp->cl_rpcclient, - RPC_DISPLAY_ADDR)); + __assign_str(dstaddr, clp->cl_hostname); ),
TP_printk(
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit d937cd6790a2bef2d07b500487646bd794c039bb upstream.
When the usb-audio descriptor contains the malformed feature unit description with a too short length, the driver may access out-of-bounds. Add a sanity check of the header size at the beginning of parse_audio_feature_unit().
Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0") Reported-by: Andrey Konovalov andreyknvl@google.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/usb/mixer.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1378,6 +1378,12 @@ static int parse_audio_feature_unit(stru __u8 *bmaControls;
if (state->mixer->protocol == UAC_VERSION_1) { + if (hdr->bLength < 7) { + usb_audio_err(state->chip, + "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } csize = hdr->bControlSize; if (!csize) { usb_audio_dbg(state->chip, @@ -1395,6 +1401,12 @@ static int parse_audio_feature_unit(stru } } else { struct uac2_feature_unit_descriptor *ftr = _ftr; + if (hdr->bLength < 6) { + usb_audio_err(state->chip, + "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } csize = 4; channels = (hdr->bLength - 6) / 4 - 1; bmaControls = ftr->bmaControls;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini pbonzini@redhat.com
commit 15038e14724799b8c205beb5f20f9e54896013c3 upstream.
For many years some users of assigned devices have reported worse performance on AMD processors with NPT than on AMD without NPT, Intel or bare metal.
The reason turned out to be that SVM is discarding the guest PAT setting and uses the default (PA0=PA4=WB, PA1=PA5=WT, PA2=PA6=UC-, PA3=UC). The guest might be using a different setting, and especially might want write combining but isn't getting it (instead getting slow UC or UC- accesses).
Thanks a lot to geoff@hostfission.com for noticing the relation to the g_pat setting. The patch has been tested also by a bunch of people on VFIO users forums.
Fixes: 709ddebf81cb40e3c36c6109a7892e8b93a09464 Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=196409 Signed-off-by: Paolo Bonzini pbonzini@redhat.com Reviewed-by: David Hildenbrand david@redhat.com Tested-by: Nick Sarnie commendsarnex@gmail.com Signed-off-by: Radim Krčmář rkrcmar@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/svm.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3157,6 +3157,13 @@ static int svm_set_msr(struct kvm_vcpu * u32 ecx = msr->index; u64 data = msr->data; switch (ecx) { + case MSR_IA32_CR_PAT: + if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data)) + return 1; + vcpu->arch.pat = data; + svm->vmcb->save.g_pat = data; + mark_dirty(svm->vmcb, VMCB_NPT); + break; case MSR_IA32_TSC: kvm_write_tsc(vcpu, msr); break;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ladislav Michl ladis@linux-mips.org
commit c98769475575c8a585f5b3952f4b5f90266f699b upstream.
While usb_control_msg function expects timeout in miliseconds, a value of HZ is used. Replace it with USB_CTRL_GET_TIMEOUT and also fix error message which looks like: udlfb: Read EDID byte 78 failed err ffffff92 as error is either negative errno or number of bytes transferred use %d format specifier.
Returned EDID is in second byte, so return error when less than two bytes are received.
Fixes: 18dffdf8913a ("staging: udlfb: enhance EDID and mode handling support") Signed-off-by: Ladislav Michl ladis@linux-mips.org Cc: Bernie Thompson bernie@plugable.com Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/video/fbdev/udlfb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -769,11 +769,11 @@ static int dlfb_get_edid(struct dlfb_dat
for (i = 0; i < len; i++) { ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), (0x02), - (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, - HZ); - if (ret < 1) { - pr_err("Read EDID byte %d failed err %x\n", i, ret); + usb_rcvctrlpipe(dev->udev, 0), 0x02, + (0x80 | (0x02 << 5)), i << 8, 0xA1, + rbuf, 2, USB_CTRL_GET_TIMEOUT); + if (ret < 2) { + pr_err("Read EDID byte %d failed: %d\n", i, ret); i--; break; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shuah Khan shuahkh@osg.samsung.com
commit 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 upstream.
get_pipe() routine doesn't validate the input endpoint number and uses to reference ep_in and ep_out arrays. Invalid endpoint number can trigger BUG(). Range check the epnum and returning error instead of calling BUG().
Change caller stub_recv_cmd_submit() to handle the get_pipe() error return.
Reported-by: Secunia Research vuln@secunia.com Signed-off-by: Shuah Khan shuahkh@osg.samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/staging/usbip/stub_rx.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
--- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -342,15 +342,15 @@ static int get_pipe(struct stub_device * struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL;
+ if (epnum < 0 || epnum > 15) + goto err_ret; + if (dir == USBIP_DIR_IN) ep = udev->ep_in[epnum & 0x7f]; else ep = udev->ep_out[epnum & 0x7f]; - if (!ep) { - dev_err(&sdev->udev->dev, "no such endpoint?, %d\n", - epnum); - BUG(); - } + if (!ep) + goto err_ret;
epd = &ep->desc; if (usb_endpoint_xfer_control(epd)) { @@ -381,9 +381,10 @@ static int get_pipe(struct stub_device * return usb_rcvisocpipe(udev, epnum); }
+err_ret: /* NOT REACHED */ - dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum); - return 0; + dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum); + return -1; }
static void masking_bogus_flags(struct urb *urb) @@ -449,6 +450,9 @@ static void stub_recv_cmd_submit(struct struct usb_device *udev = sdev->udev; int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
+ if (pipe == -1) + return; + priv = stub_priv_alloc(sdev, pdu); if (!priv) return;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Michał Mirosław mirq-linux@rere.qmqm.pl
commit 54eff2264d3e9fd7e3987de1d7eba1d3581c631e upstream.
According to comments in code and common sense, cclk_lp uses its own divisor, not cclk_g's.
Fixes: b08e8c0ecc42 ("clk: tegra: add clock support for Tegra30") Signed-off-by: Michał Mirosław mirq-linux@rere.qmqm.pl Acked-By: Peter De Schrijver pdeschrijver@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/clk/tegra/clk-tegra30.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1060,7 +1060,7 @@ static void __init tegra30_super_clk_ini * U71 divider of cclk_lp. */ clk = tegra_clk_register_divider("pll_p_out3_cclklp", "pll_p_out3", - clk_base + SUPER_CCLKG_DIVIDER, 0, + clk_base + SUPER_CCLKLP_DIVIDER, 0, TEGRA_DIVIDER_INT, 16, 8, 1, NULL); clk_register_clkdev(clk, "pll_p_out3_cclklp", NULL);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexandre Belloni alexandre.belloni@free-electrons.com
commit 74717b28cb32e1ad3c1042cafd76b264c8c0f68d upstream.
If there is any non expired timer in the queue, the RTC alarm is never set. This is an issue when adding a timer that expires before the next non expired timer.
Ensure the RTC alarm is set in that case.
Fixes: 2b2f5ff00f63 ("rtc: interface: ignore expired timers when enqueuing new timers") Signed-off-by: Alexandre Belloni alexandre.belloni@free-electrons.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/rtc/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -794,7 +794,7 @@ static int rtc_timer_enqueue(struct rtc_ }
timerqueue_add(&rtc->timerqueue, &timer->node); - if (!next) { + if (!next || ktime_before(timer->node.expires, next->expires)) { struct rtc_wkalrm alarm; int err; alarm.time = rtc_ktime_to_tm(timer->node.expires);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens heiko.carstens@de.ibm.com
commit d6e646ad7cfa7034d280459b2b2546288f247144 upstream.
For PREEMPT enabled kernels the runtime instrumentation (RI) code contains a possible use-after-free bug. If a task that makes use of RI exits, it will execute do_exit() while still enabled for preemption.
That function will call exit_thread_runtime_instr() via exit_thread(). If exit_thread_runtime_instr() gets preempted after the RI control block of the task has been freed but before the pointer to it is set to NULL, then save_ri_cb(), called from switch_to(), will write to already freed memory.
Avoid this and simply disable preemption while freeing the control block and setting the pointer to NULL.
Fixes: e4b8b3f33fca ("s390: add support for runtime instrumentation") Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/s390/kernel/runtime_instr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -53,12 +53,14 @@ void exit_thread_runtime_instr(void) { struct task_struct *task = current;
+ preempt_disable(); if (!task->thread.ri_cb) return; disable_runtime_instr(); kfree(task->thread.ri_cb); task->thread.ri_signum = 0; task->thread.ri_cb = NULL; + preempt_enable(); }
static void runtime_instr_int_handler(struct ext_code ext_code, @@ -100,9 +102,7 @@ SYSCALL_DEFINE2(s390_runtime_instr, int, return -EOPNOTSUPP;
if (command == S390_RUNTIME_INSTR_STOP) { - preempt_disable(); exit_thread_runtime_instr(); - preempt_enable(); return 0; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Fischer douglas.fischer@outlook.com
commit 771394a54148f18926ca86414e51c69eda27d0cd upstream.
Add USB PID/VID for Sierra Wireless EM7355 LTE modem QDL firmware update mode.
Signed-off-by: Douglas Fischer douglas.fischer@outlook.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/serial/qcserial.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -147,6 +147,7 @@ static const struct usb_device_id id_tab {DEVICE_SWI(0x114f, 0x68a2)}, /* Sierra Wireless MC7750 */ {DEVICE_SWI(0x1199, 0x68a2)}, /* Sierra Wireless MC7710 */ {DEVICE_SWI(0x1199, 0x901c)}, /* Sierra Wireless EM7700 */ + {DEVICE_SWI(0x1199, 0x901e)}, /* Sierra Wireless EM7355 QDL */ {DEVICE_SWI(0x1199, 0x901f)}, /* Sierra Wireless EM7355 */ {DEVICE_SWI(0x1199, 0x9040)}, /* Sierra Wireless Modem */ {DEVICE_SWI(0x1199, 0x9051)}, /* Netgear AirCard 340U */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit 67a3b63a54cbe18944191f43d644686731cf30c7 upstream.
gcc-8 points out a condition that almost certainly doesn't do what the author had in mind:
drivers/gpu/drm/gma500/mdfld_intel_display.c: In function 'mdfldWaitForPipeEnable': drivers/gpu/drm/gma500/mdfld_intel_display.c:102:37: error: bitwise comparison always evaluates to false [-Werror=tautological-compare]
This changes it to a simple bit mask operation to check whether the bit is set.
Fixes: 026abc333205 ("gma500: initial medfield merge") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20170905074741.435324-1-arnd@a... Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/gpu/drm/gma500/mdfld_intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_d /* Wait for for the pipe enable to take effect. */ for (count = 0; count < COUNT_MAX; count++) { temp = REG_READ(map->conf); - if ((temp & PIPEACONF_PIPE_STATE) == 1) + if (temp & PIPEACONF_PIPE_STATE) break; } }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings ben@decadent.org.uk
commit c15562c0dcb2c7f26e891923b784cf1926b8c833 upstream.
usbip_host_driver.h now depends on several additional headers, which need to be installed along with it.
Fixes: 021aed845303 ("staging: usbip: userspace: migrate usbip_host_driver ...") Fixes: 3391ba0e2792 ("usbip: tools: Extract generic code to be shared with ...") Signed-off-by: Ben Hutchings ben@decadent.org.uk Acked-by: Shuah Khan shuahkh@osg.samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/usbip/userspace/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/staging/usbip/userspace/Makefile.am +++ b/drivers/staging/usbip/userspace/Makefile.am @@ -1,6 +1,7 @@ SUBDIRS := libsrc src includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ - usbip_common.h vhci_driver.h usbip_host_driver.h) + usbip_common.h vhci_driver.h usbip_host_driver.h \ + list.h sysfs_utils.h)
dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 0a62d6c966956d77397c32836a5bbfe3af786fc1 upstream.
The helper functions to parse and look for the clock source, selector and multiplier unit may return the descriptor with a too short length than required, while there is no sanity check in the caller side. Add some sanity checks in the parsers, at least, to guarantee the given descriptor size, for avoiding the potential crashes.
Fixes: 79f920fbff56 ("ALSA: usb-audio: parse clock topology of UAC2 devices") Reported-by: Andrey Konovalov andreyknvl@google.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/usb/clock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -43,7 +43,7 @@ static struct uac_clock_source_descripto while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_SOURCE))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) return cs; }
@@ -59,8 +59,11 @@ static struct uac_clock_selector_descrip while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_SELECTOR))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) { + if (cs->bLength < 5 + cs->bNrInPins) + return NULL; return cs; + } }
return NULL; @@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descr while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_MULTIPLIER))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) return cs; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Boshi Wang wangboshi@huawei.com
commit ebe7c0a7be92bbd34c6ff5b55810546a0ee05bee upstream.
The hash_setup function always sets the hash_setup_done flag, even when the hash algorithm is invalid. This prevents the default hash algorithm defined as CONFIG_IMA_DEFAULT_HASH from being used.
This patch sets hash_setup_done flag only for valid hash algorithms.
Fixes: e7a2ad7eb6f4 "ima: enable support for larger default filedata hash algorithms" Signed-off-by: Boshi Wang wangboshi@huawei.com Signed-off-by: Mimi Zohar zohar@linux.vnet.ibm.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- security/integrity/ima/ima_main.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -52,6 +52,8 @@ static int __init hash_setup(char *str) ima_hash_algo = HASH_ALGO_SHA1; else if (strncmp(str, "md5", 3) == 0) ima_hash_algo = HASH_ALGO_MD5; + else + return 1; goto out; }
@@ -61,6 +63,8 @@ static int __init hash_setup(char *str) break; } } + if (i == HASH_ALGO__LAST) + return 1; out: hash_setup_done = 1; return 1;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit 8a0d18c62121d3c554a83eb96e2752861d84d937 upstream.
This patch fixes the following kernel crash:
general protection fault: 0000 [#1] PREEMPT SMP Workqueue: ib_mad2 timeout_sends [ib_core] Call Trace: ib_sa_path_rec_callback+0x1c4/0x1d0 [ib_core] send_handler+0xb2/0xd0 [ib_core] timeout_sends+0x14d/0x220 [ib_core] process_one_work+0x200/0x630 worker_thread+0x4e/0x3b0 kthread+0x113/0x150
Fixes: commit aef9ec39c47f ("IB: Add SCSI RDMA Protocol (SRP) initiator") Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Doug Ledford dledford@redhat.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -600,12 +600,19 @@ static void srp_path_rec_completion(int
static int srp_lookup_path(struct srp_target_port *target) { - int ret; + int ret = -ENODEV;
target->path.numb_path = 1;
init_completion(&target->done);
+ /* + * Avoid that the SCSI host can be removed by srp_remove_target() + * before srp_path_rec_completion() is called. + */ + if (!scsi_host_get(target->scsi_host)) + goto out; + target->path_query_id = ib_sa_path_rec_get(&srp_sa_client, target->srp_host->srp_dev->dev, target->srp_host->port, @@ -619,18 +626,24 @@ static int srp_lookup_path(struct srp_ta GFP_KERNEL, srp_path_rec_completion, target, &target->path_query); - if (target->path_query_id < 0) - return target->path_query_id; + ret = target->path_query_id; + if (ret < 0) + goto put;
ret = wait_for_completion_interruptible(&target->done); if (ret < 0) return ret;
- if (target->status < 0) + ret = target->status; + if (ret < 0) shost_printk(KERN_WARNING, target->scsi_host, PFX "Path record query failed\n");
- return target->status; +put: + scsi_host_put(target->scsi_host); + +out: + return ret; }
static int srp_send_req(struct srp_target_port *target)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit 1dbc080c9ef6bcfba652ef0d6ae919b8c7c85a1d upstream.
FIFO_MODE() is a macro expression with a '<<' operator, which gcc points out could be misread as a '<':
drivers/input/misc/adxl34x.c: In function 'adxl34x_probe': drivers/input/misc/adxl34x.c:799:36: error: '<<' in boolean context, did you mean '<' ? [-Werror=int-in-bool-context]
While utility of this warning is being disputed (Chief Penguin: "This warning is clearly pure garbage.") FIFO_MODE() extracts range of values, with 0 being FIFO_BYPASS, and not something that is logically boolean.
This converts the test to an explicit comparison with FIFO_BYPASS, making it clearer to gcc and the reader what is intended.
Fixes: e27c729219ad ("Input: add driver for ADXL345/346 Digital Accelerometers") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/input/misc/adxl34x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -796,7 +796,7 @@ struct adxl34x *adxl34x_probe(struct dev
if (pdata->watermark) { ac->int_mask |= WATERMARK; - if (!FIFO_MODE(pdata->fifo_mode)) + if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) ac->pdata.fifo_mode |= FIFO_STREAM; } else { ac->int_mask |= DATA_READY;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg johannes.berg@intel.com
commit 44905265bc155e0237c76c25bf5ddf740d85a8f2 upstream.
For mesh, this is simply wrong - there's no SSID, only the mesh ID, so don't expose it at all. For (P2P) client, it's wrong, because it exposes an internal value that's only used when certain APIs are used. For AP, it's actually the only correct case, so leave that. All other interface types shouldn't be setting this anyway, so there it won't change anything.
Fixes: b84e7a05f619 ("nl80211: send the NL80211_ATTR_SSID in nl80211_send_iface()") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/wireless/nl80211.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
--- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2341,10 +2341,32 @@ static int nl80211_send_iface(struct sk_ } }
- if (wdev->ssid_len) { - if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) + wdev_lock(wdev); + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + if (wdev->ssid_len && + nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) goto nla_put_failure; + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_ADHOC: { + const u8 *ssid_ie; + if (!wdev->current_bss) + break; + ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, + WLAN_EID_SSID); + if (!ssid_ie) + break; + if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) + goto nla_put_failure; + break; + } + default: + /* nothing */ + break; } + wdev_unlock(wdev);
return genlmsg_end(msg, hdr);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Yunlong Song yunlong.song@huawei.com
commit 65f1b80b33378501ea552ef085e9c31739af356c upstream.
This reverts commit 5e443818fa0b2a2845561ee25bec181424fb2889
The commit should be reverted because call sequence of below two parts of code must be kept: a. update sit information, it needs to be updated before segment allocation since latter allocation may trigger SSR, and SSR allocation needs latest valid block information of all segments. b. update segment status, it needs to be updated after segment allocation since we can skip updating current opened segment status.
Fixes: 5e443818fa0b ("f2fs: handle dirty segments inside refresh_sit_entry") Suggested-by: Chao Yu yuchao0@huawei.com Signed-off-by: Yunlong Song yunlong.song@huawei.com Reviewed-by: Chao Yu yuchao0@huawei.com [Jaegeuk Kim: remove refresh_sit_entry function] Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org [bwh: Backported to 3.16: - Don't delete refresh_sit_entry(); it has another caller here - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -988,13 +988,24 @@ void allocate_data_block(struct f2fs_sb_
stat_inc_block_count(sbi, curseg);
- if (!__has_curseg_space(sbi, type)) - sit_i->s_ops->allocate_segment(sbi, type, false); /* * SIT information should be updated before segment allocation, * since SSR needs latest valid block information. */ - refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr); + update_sit_entry(sbi, *new_blkaddr, 1); + if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) + update_sit_entry(sbi, old_blkaddr, -1); + + if (!__has_curseg_space(sbi, type)) + sit_i->s_ops->allocate_segment(sbi, type, false); + + /* + * segment dirty status should be updated after segment allocation, + * so we just need to update status only one time after previous + * segment being closed. + */ + locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); + locate_dirty_segment(sbi, GET_SEGNO(sbi, *new_blkaddr));
mutex_unlock(&sit_i->sentry_lock);
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tuomas Tynkkynen tuomas@tuxera.com
commit 9523feac272ccad2ad8186ba4fcc89103754de52 upstream.
Because userspace gets Very Unhappy when calls like stat() and execve() return -EINTR on 9p filesystem mounts. For instance, when bash is looking in PATH for things to execute and some SIGCHLD interrupts stat(), bash can throw a spurious 'command not found' since it doesn't retry the stat().
In practice, hitting the problem is rare and needs a really slow/bogged down 9p server.
Signed-off-by: Tuomas Tynkkynen tuomas@tuxera.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk [bwh: Backported to 3.16: drop changes in trans_xen.c] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/net/9p/client.c +++ b/net/9p/client.c @@ -753,8 +753,7 @@ p9_client_rpc(struct p9_client *c, int8_ } again: /* Wait for the response */ - err = wait_event_interruptible(*req->wq, - req->status >= REQ_STATUS_RCVD); + err = wait_event_killable(*req->wq, req->status >= REQ_STATUS_RCVD);
/* * Make sure our req is coherent with regard to updates in other --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -292,8 +292,8 @@ req_retry: if (err == -ENOSPC) { chan->ring_bufs_avail = 0; spin_unlock_irqrestore(&chan->lock, flags); - err = wait_event_interruptible(*chan->vc_wq, - chan->ring_bufs_avail); + err = wait_event_killable(*chan->vc_wq, + chan->ring_bufs_avail); if (err == -ERESTARTSYS) return err;
@@ -324,7 +324,7 @@ static int p9_get_mapped_pages(struct vi * Other zc request to finish here */ if (atomic_read(&vp_pinned) >= chan->p9_max_pages) { - err = wait_event_interruptible(vp_wq, + err = wait_event_killable(vp_wq, (atomic_read(&vp_pinned) < chan->p9_max_pages)); if (err == -ERESTARTSYS) return err; @@ -454,8 +454,8 @@ req_retry_pinned: if (err == -ENOSPC) { chan->ring_bufs_avail = 0; spin_unlock_irqrestore(&chan->lock, flags); - err = wait_event_interruptible(*chan->vc_wq, - chan->ring_bufs_avail); + err = wait_event_killable(*chan->vc_wq, + chan->ring_bufs_avail); if (err == -ERESTARTSYS) goto err_out;
@@ -472,8 +472,7 @@ req_retry_pinned: virtqueue_kick(chan->vq); spin_unlock_irqrestore(&chan->lock, flags); p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); - err = wait_event_interruptible(*req->wq, - req->status >= REQ_STATUS_RCVD); + err = wait_event_killable(*req->wq, req->status >= REQ_STATUS_RCVD); /* * Non kernel buffers are pinned, unpin them */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 51e3ae81ec58e95f10a98ef3dd6d7bce5d8e35a2 upstream.
If there are pending writes subject to delayed allocation, then i_size will show size after the writes have completed, while i_disksize contains the value of i_size on the disk (since the writes have not been persisted to disk).
If fallocate(2) is called with the FALLOC_FL_KEEP_SIZE flag, either with or without the FALLOC_FL_ZERO_RANGE flag set, and the new size after the fallocate(2) is between i_size and i_disksize, then after a crash, if a journal commit has resulted in the changes made by the fallocate() call to be persisted after a crash, but the delayed allocation write has not resolved itself, i_size would not be updated, and this would cause the following e2fsck complaint:
Inode 12, end of extent exceeds allowed value (logical block 33, physical block 33441, len 7)
This can only take place on a sparse file, where the fallocate(2) call is allocating blocks in a range which is before a pending delayed allocation write which is extending i_size. Since this situation is quite rare, and the window in which the crash must take place is typically < 30 seconds, in practice this condition will rarely happen.
Nevertheless, it can be triggered in testing, and in particular by xfstests generic/456.
Signed-off-by: Theodore Ts'o tytso@mit.edu Reported-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/ext4/extents.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4810,7 +4810,8 @@ static long ext4_zero_range(struct file }
if (!(mode & FALLOC_FL_KEEP_SIZE) && - offset + len > i_size_read(inode)) { + (offset + len > i_size_read(inode) || + offset + len > EXT4_I(inode)->i_disksize)) { new_size = offset + len; ret = inode_newsize_ok(inode, new_size); if (ret) @@ -4956,7 +4957,8 @@ long ext4_fallocate(struct file *file, i }
if (!(mode & FALLOC_FL_KEEP_SIZE) && - offset + len > i_size_read(inode)) { + (offset + len > i_size_read(inode) || + offset + len > EXT4_I(inode)->i_disksize)) { new_size = offset + len; ret = inode_newsize_ok(inode, new_size); if (ret)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bernhard Rosenkraenzer bernhard.rosenkranzer@linaro.org
commit a0fea6027f19c62727315aba1a7fae75a9caa842 upstream.
Without this patch, K70 LUX keyboards don't work, saying usb 3-3: unable to read config index 0 descriptor/all usb 3-3: can't read configurations, error -110 usb usb3-port3: unable to enumerate USB device
Signed-off-by: Bernhard Rosenkraenzer Bernhard.Rosenkranzer@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -218,6 +218,9 @@ static const struct usb_device_id usb_qu /* Corsair Strafe RGB */ { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
+ /* Corsair K70 LUX */ + { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, + /* MIDI keyboard WORLDE MINI */ { USB_DEVICE(0x1c75, 0x0204), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim jaegeuk@kernel.org
commit 5b4267d195dd887c4412e34b5a7365baa741b679 upstream.
If there's some data written through inline data or dentry, we need to shouw st_blocks. This fixes reporting zero blocks even though there is small written data.
Reviewed-by: Chao Yu yuchao0@huawei.com [Jaegeuk Kim: avoid link file for quotacheck] Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org [bwh: Backported to 3.16: - Inline dentries are not supported - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -460,6 +460,11 @@ int f2fs_getattr(struct vfsmount *mnt, struct inode *inode = dentry->d_inode; generic_fillattr(inode, stat); stat->blocks <<= 3; + + /* we need to show initial sectors used for inline_data/dentries */ + if (S_ISREG(inode->i_mode) && f2fs_has_inline_data(inode)) + stat->blocks += (stat->size + 511) >> 9; + return 0; }
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young sean@mess.org
commit 3e45067f94bbd61dec0619b1c32744eb0de480c8 upstream.
The ioctl LIRC_SET_REC_TIMEOUT would set a timeout of 704ns if called with a timeout of 4294968us.
Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/media/rc/ir-lirc-codec.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -289,11 +289,14 @@ static long ir_lirc_ioctl(struct file *f if (!dev->max_timeout) return -ENOSYS;
+ /* Check for multiply overflow */ + if (val > U32_MAX / 1000) + return -EINVAL; + tmp = val * 1000;
- if (tmp < dev->min_timeout || - tmp > dev->max_timeout) - return -EINVAL; + if (tmp < dev->min_timeout || tmp > dev->max_timeout) + return -EINVAL;
dev->timeout = tmp; break;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian King brking@linux.vnet.ibm.com
commit 52c6912fde0133981ee50ba08808f257829c4c93 upstream.
The original issue being fixed in this patch was seen with the ixgbe driver, but the same issue exists with i40e as well, as the code is very similar. read_barrier_depends is not sufficient to ensure loads following it are not speculatively loaded out of order by the CPU, which can result in stale data being loaded, causing potential system crashes.
Signed-off-by: Brian King brking@linux.vnet.ibm.com Acked-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Andrew Bowers andrewx.bowers@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3047,7 +3047,7 @@ static bool i40e_clean_fdir_tx_irq(struc break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* if the descriptor isn't done, no work yet to do */ if (!(eop_desc->cmd_type_offset_bsz & --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -657,7 +657,7 @@ static bool i40e_clean_tx_irq(struct i40 break;
/* prevent any other reads prior to eop_desc */ - read_barrier_depends(); + smp_rmb();
/* we have caught up to head, no work left to do */ if (tx_head == tx_desc)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit f658f17b5e0e339935dca23e77e0f3cad591926b upstream.
The usb-audio driver may trigger an out-of-bound access at parsing a malformed selector unit, as it checks the header length only after evaluating bNrInPins field, which can be already above the given length. Fix it by adding the length check beforehand.
Fixes: 99fc86450c43 ("ALSA: usb-mixer: parse descriptors with structs") Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/usb/mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2020,7 +2020,8 @@ static int parse_audio_selector_unit(str const struct usbmix_name_map *map; char **namelist;
- if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) { + if (desc->bLength < 5 || !desc->bNrInPins || + desc->bLength < 5 + desc->bNrInPins) { usb_audio_err(state->chip, "invalid SELECTOR UNIT descriptor %d\n", unitid); return -EINVAL;
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula jani.nikula@intel.com
commit 348e4058ebf53904e817eec7a1b25327143c2ed2 upstream.
While technically CHV isn't DDI, we do look at the VBT based DDI port info for HDMI DDC pin and DP AUX channel. (We call these "alternate", but they're really just something that aren't platform defaults.)
In commit e4ab73a13291 ("drm/i915: Respect alternate_ddc_pin for all DDI ports") Ville writes, "IIRC there may be CHV system that might actually need this."
I'm not sure why there couldn't be even more platforms that need this, but start conservative, and parse the info for CHV in addition to DDI.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100553 Reported-by: Marek Wilczewski mw@3cte.pl Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/d0815082cb98487618429b62414854... [bwh: Backported to 3.16: IS_CHERRYVIEW() takes a drm_device pointer] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/gpu/drm/i915/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1007,7 +1007,7 @@ static void parse_ddi_ports(struct drm_i struct drm_device *dev = dev_priv->dev; enum port port;
- if (!HAS_DDI(dev)) + if (!HAS_DDI(dev) && !IS_CHERRYVIEW(dev)) return;
if (!dev_priv->vbt.child_dev_num)
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit b3defb791b26ea0683a93a4f49c77ec45ec96f10 upstream.
The ALSA sequencer ioctls have no protection against racy calls while the concurrent operations may lead to interfere with each other. As reported recently, for example, the concurrent calls of setting client pool with a combination of write calls may lead to either the unkillable dead-lock or UAF.
As a slightly big hammer solution, this patch introduces the mutex to make each ioctl exclusive. Although this may reduce performance via parallel ioctl calls, usually it's not demanded for sequencer usages, hence it should be negligible.
Reported-by: Luo Quan a4651386@163.com Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Takashi Iwai tiwai@suse.de [bwh: Backported to 3.16: ioctl dispatch is done from snd_seq_do_ioctl(); take the mutex and add ret variable there.] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- sound/core/seq/seq_clientmgr.c | 10 ++++++++-- sound/core/seq/seq_clientmgr.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-)
--- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -236,6 +236,7 @@ static struct snd_seq_client *seq_create rwlock_init(&client->ports_lock); mutex_init(&client->ports_mutex); INIT_LIST_HEAD(&client->ports_list_head); + mutex_init(&client->ioctl_mutex);
/* find free slot in the client table */ spin_lock_irqsave(&clients_lock, flags); @@ -2200,6 +2201,7 @@ static int snd_seq_do_ioctl(struct snd_s void __user *arg) { struct seq_ioctl_table *p; + int ret;
switch (cmd) { case SNDRV_SEQ_IOCTL_PVERSION: @@ -2213,8 +2215,12 @@ static int snd_seq_do_ioctl(struct snd_s if (! arg) return -EFAULT; for (p = ioctl_tables; p->cmd; p++) { - if (p->cmd == cmd) - return p->func(client, arg); + if (p->cmd == cmd) { + mutex_lock(&client->ioctl_mutex); + ret = p->func(client, arg); + mutex_unlock(&client->ioctl_mutex); + return ret; + } } pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -59,6 +59,7 @@ struct snd_seq_client { struct list_head ports_list_head; rwlock_t ports_lock; struct mutex ports_mutex; + struct mutex ioctl_mutex; int convert32; /* convert 32->64bit */
/* output pool */
3.16.54-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Corey Minyard cminyard@mvista.com
commit 392a17b10ec4320d3c0e96e2a23ebaad1123b989 upstream.
When I set the timeout to a specific value such as 500ms, the timeout event will not happen in time due to the overflow in function check_msg_timeout: ... ent->timeout -= timeout_period; if (ent->timeout > 0) return; ...
The type of timeout_period is long, but ent->timeout is unsigned long. This patch makes the type consistent.
Reported-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Corey Minyard cminyard@mvista.com Tested-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/char/ipmi/ipmi_msghandler.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4007,7 +4007,8 @@ smi_from_recv_msg(ipmi_smi_t intf, struc }
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, - struct list_head *timeouts, long timeout_period, + struct list_head *timeouts, + unsigned long timeout_period, int slot, unsigned long *flags, unsigned int *waiting_msgs) { @@ -4020,8 +4021,8 @@ static void check_msg_timeout(ipmi_smi_t if (!ent->inuse) return;
- ent->timeout -= timeout_period; - if (ent->timeout > 0) { + if (timeout_period < ent->timeout) { + ent->timeout -= timeout_period; (*waiting_msgs)++; return; } @@ -4088,7 +4089,8 @@ static void check_msg_timeout(ipmi_smi_t } }
-static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period) +static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, + unsigned long timeout_period) { struct list_head timeouts; struct ipmi_recv_msg *msg, *msg2;
On 02/10/2018 08:31 PM, Ben Hutchings wrote:
This is the start of the stable review cycle for the 3.16.54 release. There are 136 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Feb 13 12:00:00 UTC 2018. Anything received after that time might be too late.
Build results: total: 136 pass: 136 fail: 0 Qemu test results: total: 108 pass: 108 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
linux-stable-mirror@lists.linaro.org