Skip to contentSkip to conversation

4.5.1-stable review

PATCH In review Greg Kroah-Hartman 11 participants 253 messages Apr 10, 2016 – Apr 13, 2016 Page 1 of 2

Subsystems (4)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.5.1-stable review

This is the start of the stable review cycle for the 4.5.1 release. There are 238 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Tue Apr 12 18:34:18 UTC 2016. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.5.1-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 4.5.1-rc1

Andi Kleen <[email protected]>
perf/x86/intel: Fix PEBS data source interpretation on Nehalem/Westmere

Jiri Olsa <[email protected]>
perf/x86/intel: Use PAGE_SIZE for PEBS buffer size on Core2

Kan Liang <[email protected]>
perf/x86/intel: Fix PEBS warning by only restoring active PMU in pmi

Kan Liang <[email protected]>
perf/x86/intel/uncore: Remove SBOX support for BDX-DE

Stephane Eranian <[email protected]>
perf/x86/pebs: Add workaround for broken OVFL status on HSW+

Thomas Gleixner <[email protected]>
sched/cputime: Fix steal time accounting vs. CPU hotplug

Hannes Reinecke <[email protected]>
scsi_common: do not clobber fixed sense information

Lukas Wunner <[email protected]>
PM / sleep: Clear pm_suspend_global_flags upon hibernate

Len Brown <[email protected]>
intel_idle: prevent SKL-H boot failure when C8+C9+C10 enabled

Aaro Koskinen <[email protected]>
mtd: onenand: fix deadlock in onenand_block_markbad

Vlastimil Babka <[email protected]>
mm/page_alloc: prevent merging between isolated and other pageblocks

Joseph Qi <[email protected]>
ocfs2/dlm: fix BUG in dlm_move_lockres_to_recovery_list

Joseph Qi <[email protected]>
ocfs2/dlm: fix race between convert and recovery

Junxiao Bi <[email protected]>
ocfs2: o2hb: fix double free bug

Vladis Dronov <[email protected]>
Input: ati_remote2 - fix crashes on detecting device with invalid descriptor

Oliver Neukum <[email protected]>
Input: ims-pcu - sanity check against missing interfaces

Benjamin Tissoires <[email protected]>
Input: synaptics - handle spurious release of trackstick buttons, again

Tejun Heo <[email protected]>
writeback, cgroup: fix use of the wrong bdi_writeback which mismatches the inode

Tejun Heo <[email protected]>
writeback, cgroup: fix premature wb_put() in locked_inode_to_wb_and_lock_list()

Lukas Wunner <[email protected]>
ACPI / PM: Runtime resume devices when waking from hibernate

Ludovic Desroches <[email protected]>
ARM: dts: at91: sama5d4 Xplained: don't disable hsmci regulator

Ludovic Desroches <[email protected]>
ARM: dts: at91: sama5d3 Xplained: don't disable hsmci regulator

J. Bruce Fields <[email protected]>
nfsd: fix deadlock secinfo+readdir compound

J. Bruce Fields <[email protected]>
nfsd4: fix bad bounds checking

Jenny Derzhavetz <[email protected]>
iser-target: Rework connection termination

Jenny Derzhavetz <[email protected]>
iser-target: Separate flows for np listeners and connections cma events

Jenny Derzhavetz <[email protected]>
iser-target: Add new state ISER_CONN_BOUND to isert_conn

Jenny Derzhavetz <[email protected]>
iser-target: Fix identification of login rx descriptor type

Himanshu Madhani <[email protected]>
target: Fix target_release_cmd_kref shutdown comp leak

Eric Anholt <[email protected]>
clk: bcm2835: Fix setting of PLL divider clock rates

Alexander Kochetkov <[email protected]>
clk: rockchip: add hclk_cpubus to the list of rk3188 critical clocks

Heiko Stuebner <[email protected]>
clk: rockchip: rk3368: fix hdmi_cec gate-register

Heiko Stuebner <[email protected]>
clk: rockchip: rk3368: fix parents of video encoder/decoder

Heiko Stuebner <[email protected]>
clk: rockchip: rk3368: fix cpuclk core dividers

Heiko Stuebner <[email protected]>
clk: rockchip: rk3368: fix cpuclk mux bit of big cpu-cluster

Brent Taylor <[email protected]>
mmc: atmel-mci: Check pdata for NULL before dereferencing it at DMA config

Adrian Hunter <[email protected]>
mmc: sdhci: Fix override of timeout clk wrt max_busy_timeout

Lucas Stach <[email protected]>
mmc: tegra: properly disable card clock

Jon Hunter <[email protected]>
mmc: tegra: Disable UHS-I modes for tegra114

Russell King <[email protected]>
mmc: sdhci-pxav3: fix higher speed mode capabilities

Russell King <[email protected]>
mmc: sdhci: fix data timeout (part 2)

Russell King <[email protected]>
mmc: sdhci: fix data timeout (part 1)

Russell King <[email protected]>
mmc: sdhci: plug DMA mapping leak on error

Russell King <[email protected]>
mmc: sdhci: avoid unnecessary mapping/unmapping of align buffer

Russell King <[email protected]>
mmc: sdhci: further fix for DMA unmapping in sdhci_post_req()

Russell King <[email protected]>
mmc: sdhci: fix command response CRC error handling

Russell King <[email protected]>
mmc: sdhci: clean up command error handling

Russell King <[email protected]>
mmc: sdhci: move initialisation of command error member

Magnus Damm <[email protected]>
mmc: mmc_spi: Add Card Detect comments and fix CD GPIO case

Shawn Lin <[email protected]>
mmc: block: fix ABI regression of mmc_blk_ioctl

John Dahlstrom <[email protected]>
ideapad-laptop: Add ideapad Y700 (15) to the no_hw_rfkill DMI list

Guenter Roeck <[email protected]>
MAINTAINERS: Update mailing list and web page for hwmon subsystem

Jiri Kosina <[email protected]>
kbuild/mkspec: fix grub2 installkernel issue

Jan Beulich <[email protected]>
scripts/kconfig: allow building with make 3.80 again

Julia Lawall <[email protected]>
scripts/coccinelle: modernize &

Peter Zijlstra <[email protected]>
bitops: Do not default to __clear_bit() for __clear_bit_unlock()

Steven Rostedt (Red Hat) <[email protected]>
tracing: Fix trace_printk() to print when not using bprintk()

Steven Rostedt (Red Hat) <[email protected]>
tracing: Fix crash from reading trace_pipe with sendfile

Steven Rostedt (Red Hat) <[email protected]>
tracing: Have preempt(irqs)off trace preempt disabled functions

Eric Huang <[email protected]>
drm/amd/powerplay: add uvd/vce dpm enabling flag to fix the performance issue for CZ

Ken Wang <[email protected]>
drm/amdgpu: include the right version of gmc header files for iceland

Alex Deucher <[email protected]>
drm/amdgpu: disable runtime pm on PX laptops without dGPU power control

Dave Airlie <[email protected]>
drm/radeon/mst: fix regression in lane/link handling.

Alex Deucher <[email protected]>
drm/radeon: rework fbdev handling on chips with no connectors

Mario Kleiner <[email protected]>
drm/radeon: Don't drop DP 2.7 Ghz link setup on some cards.

Alex Deucher <[email protected]>
drm/radeon: disable runtime pm on PX laptops without dGPU power control

Dan Carpenter <[email protected]>
drm/vc4: Return -EFAULT on copy_from_user() failure

Aurelien Jacquiot <[email protected]>
rapidio/rionet: fix deadlock on SMP

Jann Horn <[email protected]>
fs/coredump: prevent fsuid=0 dumps into user-controlled directories

Jan Kiszka <[email protected]>
scripts/gdb: account for changes in module data structure

Seth Forshee <[email protected]>
fuse: Add reference counting for fuse_io_priv

Robert Doebbelin <[email protected]>
fuse: do not use iocb after it may have been freed

Ming Lei <[email protected]>
md: multipath: don't hardcopy bio in .make_request path

NeilBrown <[email protected]>
md/raid5: preserve STRIPE_PREREAD_ACTIVE in break_stripe_batch_list

Shaohua Li <[email protected]>
raid10: include bio_end_io_list in nr_queued to prevent freeze_array hang

Shaohua Li <[email protected]>
RAID5: revert e9e4c377e2f563 to fix a livelock

Shaohua Li <[email protected]>
RAID5: check_reshape() shouldn't call mddev_suspend

Jes Sorensen <[email protected]>
md/raid5: Compare apples to apples (or sectors to sectors)

Nate Dailey <[email protected]>
raid1: include bio_end_io_list in nr_queued to prevent freeze_array hang

Mateusz Guzik <[email protected]>
xfs: fix two memory leaks in xfs_attr_list.c error paths

Nikolay Borisov <[email protected]>
quota: Fix possible GPF due to uninitialised pointers

Vineet Gupta <[email protected]>
ARC: bitops: Remove non relevant comments

Lada Trimasova <[email protected]>
ARC: [BE] readl()/writel() to work in Big Endian CPU configuration

Alexey Brodkin <[email protected]>

    ARC: [plat-axs10x] add Ethernet PHY description in .dts

Max Filippov <[email protected]>
xtensa: clear all DBREAKC registers on start

Max Filippov <[email protected]>
xtensa: fix preemption in {clear,copy}_user_highpage

Max Filippov <[email protected]>
xtensa: ISS: don't hang if stdin EOF is reached

Rabin Vincent <[email protected]>
splice: handle zero nr_pages in splice_to_pipe()

Dmitry V. Levin <[email protected]>
vfs: show_vfsstat: do not ignore errors from show_devname method

Vinayak Menon <[email protected]>
of: alloc anywhere from memblock if range not specified

Hante Meuleman <[email protected]>
brcmfmac: Increase nr of supported flowrings.

Dmitri Epshtein <[email protected]>
net: mvneta: enable change MAC address when interface is up

Tejun Heo <[email protected]>
cgroup: ignore css_sets associated with dead cgroups during migration

Johan Hedberg <[email protected]>
Bluetooth: Fix potential buffer overflow with Add Advertising

Dmitry Tunin <[email protected]>

    Bluetooth: Add new AR3012 ID 0489:e095

Michael S. Tsirkin <[email protected]>
watchdog: rc32434_wdt: fix ioctl error handling

Joshua Hunt <[email protected]>
watchdog: don't run proc_watchdog_update if new value is same as old

Aaro Koskinen <[email protected]>
drivers/firmware/broadcom/bcm47xx_nvram.c: fix incorrect __ioread32_copy

Luis R. Rodriguez <[email protected]>
ia64: define ioremap_uc()

Johannes Weiner <[email protected]>
mm: memcontrol: reclaim and OOM kill when shrinking memory.max below usage

Johannes Weiner <[email protected]>
mm: memcontrol: reclaim when shrinking memory.high below usage

Eric Wheeler <[email protected]>
bcache: fix cache_set_flush() NULL pointer dereference on OOM

Eric Wheeler <[email protected]>
bcache: fix race of writeback thread starting before complete initialization

Eric Wheeler <[email protected]>
bcache: cleaned up error handling around register_cache()

Bart Van Assche <[email protected]>
IB/srpt: Simplify srpt_handle_tsk_mgmt()

Bart Van Assche <[email protected]>
brd: Fix discard request processing

Catalin Marinas <[email protected]>
arm64: Update PTE_RDONLY in set_pte_at() for PROT_NONE permission

Geert Uytterhoeven <[email protected]>

    gpio: pca953x: Fix pca953x_gpio_set_multiple() on 64-bit

OGAWA Hirofumi <[email protected]>
jbd2: fix FS corruption possibility in jbd2_journal_destroy() on umount path

Kamal Mostafa <[email protected]>
tools/hv: Use include/uapi with __EXPORTED_HEADERS__

Takashi Iwai <[email protected]>
ALSA: hda - Fix missing ELD update at unplugging

Takashi Iwai <[email protected]>
ALSA: hda - Workaround for unbalanced i915 power refcount by concurrent probe

Takashi Iwai <[email protected]>
ALSA: hda - Fix forgotten HDMI monitor_present update

Takashi Iwai <[email protected]>
ALSA: hda - Really restrict i915 notifier to HSW+

Takashi Iwai <[email protected]>
ALSA: hda - Fix spurious kernel WARNING on Baytrail HDMI

Takashi Iwai <[email protected]>
ALSA: hda - Limit i915 HDMI binding only for HSW and later

Takashi Iwai <[email protected]>
ALSA: hda - Fix unconditional GPIO toggle via automute

Aaron Plattner <[email protected]>

    ALSA: hda - Add new GPU codec ID 0x10de0082 to snd-hda

Hui Wang <[email protected]>
ALSA: hda - fix the mic mute button and led problem for a Lenovo AIO

Takashi Iwai <[email protected]>
ALSA: hda - Don't handle ELD notify from invalid port

Vittorio Gambaletta (VittGam) <[email protected]>
ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41.

Takashi Iwai <[email protected]>
ALSA: pcm: Avoid "BUG:" string for warnings again

Takashi Iwai <[email protected]>
ALSA: hda - Apply reboot D3 fix for CX20724 codec, too

Takashi Iwai <[email protected]>
ALSA: hda - Fix unexpected resume through regmap code path

Asai Thambi SP <[email protected]>
mtip32xx: Cleanup queued requests after surprise removal

Asai Thambi SP <[email protected]>
mtip32xx: Implement timeout handler

Asai Thambi SP <[email protected]>
mtip32xx: Handle FTL rebuild failure state during device initialization

Asai Thambi SP <[email protected]>
mtip32xx: Handle safe removal during IO

Asai Thambi SP <[email protected]>
mtip32xx: Fix for rmmod crash when drive is in FTL rebuild

Asai Thambi SP <[email protected]>
mtip32xx: Print exact time when an internal command is interrupted

Asai Thambi SP <[email protected]>
mtip32xx: Remove unwanted code from taskfile error handler

Asai Thambi SP <[email protected]>
mtip32xx: Fix broken service thread handling

Asai Thambi SP <[email protected]>
mtip32xx: Avoid issuing standby immediate cmd during FTL rebuild

Tiffany Lin <[email protected]>
media: v4l2-compat-ioctl32: fix missing length copy in put_v4l2_buffer32

Philipp Zabel <[email protected]>
coda: fix first encoded frame payload

Hans de Goede <[email protected]>
bttv: Width must be a multiple of 16 when capturing planar formats

Hans Verkuil <[email protected]>
adv7511: TX_EDID_PRESENT is still 1 after a disconnect

Hans de Goede <[email protected]>
saa7134: Fix bytesperline not being set correctly for planar formats

Sebastian Frias <[email protected]>
8250: use callbacks to access UART_DLL/UART_DLM

Peter Hurley <[email protected]>
net: irda: Fix use-after-free in irtty_open()

Peter Hurley <[email protected]>
tty: Fix GPF in flush_to_ldisc(), part 2

H Hartley Sweeten <[email protected]>
staging: comedi: ni_mio_common: fix the ni_write[blw]() functions

Vladimir Zapolskiy <[email protected]>
staging: android: ion_test: fix check of platform_device_register_simple() error code

Spencer E. Olson <[email protected]>
staging: comedi: ni_tiocmd: change mistaken use of start_src for start_arg

Benjamin Tissoires <[email protected]>
HID: fix hid_ignore_special_drivers module parameter

Benjamin Tissoires <[email protected]>
HID: multitouch: force retrieving of Win8 signature blob

Dmitry Torokhov <[email protected]>
HID: i2c-hid: fix OOB write in i2c_hid_set_or_send_report()

Grazvydas Ignotas <[email protected]>
HID: logitech: fix Dual Action gamepad support

Jarkko Sakkinen <[email protected]>
tpm: fix the cleanup of struct tpm_chip

Harald Hoyer <[email protected]>
tpm_eventlog.c: fix binary_bios_measurements

Jarkko Sakkinen <[email protected]>
tpm_crb: tpm2_shutdown() must be called before tpm_chip_unregister()

Jarkko Sakkinen <[email protected]>
tpm: fix the rollback in tpm_chip_register()

Alexander Usyskin <[email protected]>
mei: bus: check if the device is enabled before data transfer

David Howells <[email protected]>
X.509: Fix leap year handling again

Boris BREZILLON <[email protected]>
crypto: marvell/cesa - forward devm_ioremap_resource() error code

Vladimir Zapolskiy <[email protected]>
crypto: ux500 - fix checks of error code returned by devm_ioremap_resource()

Vladimir Zapolskiy <[email protected]>
crypto: atmel - fix checks of error code returned by devm_ioremap_resource()

Dan Carpenter <[email protected]>
crypto: keywrap - memzero the correct memory

Tom Lendacky <[email protected]>
crypto: ccp - memset request context to zero during import

Tom Lendacky <[email protected]>
crypto: ccp - Don't assume export/import areas are aligned

Tom Lendacky <[email protected]>
crypto: ccp - Limit the amount of information exported

Tom Lendacky <[email protected]>
crypto: ccp - Add hash state import and export support

Dmitry Tunin <[email protected]>

    Bluetooth: btusb: Add a new AR3012 ID 13d3:3472

Dmitry Tunin <[email protected]>

    Bluetooth: btusb: Add a new AR3012 ID 04ca:3014

Dmitry Tunin <[email protected]>

    Bluetooth: btusb: Add new AR3012 ID 13d3:3395

Vladis Dronov <[email protected]>
ALSA: usb-audio: Fix double-free in error paths after snd_usb_add_audio_stream() call

Takashi Iwai <[email protected]>
ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()

Victor Clément <[email protected]>
ALSA: usb-audio: add Microsoft HD-5001 to quirks

Takashi Iwai <[email protected]>
ALSA: usb-audio: Add sanity checks for endpoint accesses

Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk()

Josh Boyer <[email protected]>
Input: powermate - fix oops with malicious USB descriptors

Hans de Goede <[email protected]>
pwc: Add USB id for Philips Spc880nc webcam

Anthony Wong <[email protected]>
rt2x00: add new rt2800usb device Buffalo WLI-UC-G450

Bjørn Mork <[email protected]>
USB: option: add "D-Link DWM-221 B1" device id

Josh Boyer <[email protected]>
USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices

Martyn Welch <[email protected]>

    USB: serial: cp210x: Adding GE Healthcare Device ID

Oliver Neukum <[email protected]>
USB: cypress_m8: add endpoint sanity check

Oliver Neukum <[email protected]>
USB: digi_acceleport: do sanity checking for the number of ports

Oliver Neukum <[email protected]>
USB: mct_u232: add sanity checking in probe

Oliver Neukum <[email protected]>
USB: usb_driver_claim_interface: add sanity checking

Josh Boyer <[email protected]>
USB: iowarrior: fix oops with malicious USB descriptors

Oliver Neukum <[email protected]>
USB: cdc-acm: more sanity checking

Hans de Goede <[email protected]>
USB: uas: Reduce can_queue to MAX_CMNDS

Oliver Neukum <[email protected]>
usb: hub: fix a typo in hub_port_init() leading to wrong logic

Oliver Neukum <[email protected]>
usb: retry reset if a device times out

Bryn M. Reeves <[email protected]>
dm: fix rq_end_stats() NULL pointer in dm_requeue_original_request()

Joe Thornber <[email protected]>
dm cache: make sure every metadata function checks fail_io

Joe Thornber <[email protected]>
dm thin metadata: don't issue prefetches if a transaction abort has failed

Mike Snitzer <[email protected]>
dm: fix excessive dm-mq context switching

DingXiang <[email protected]>
dm snapshot: disallow the COW and origin devices from being identical

Dan Williams <[email protected]>
libnvdimm, pmem: fix kmap_atomic() leak in error path

Jerry Hoemann <[email protected]>
libnvdimm: Fix security issue with DSM IOCTL.

Alan <[email protected]>
aic7xxx: Fix queue depth handling

Maurizio Lombardi <[email protected]>
be2iscsi: set the boot_kset pointer to NULL in case of failure

Vitaly Kuznetsov <[email protected]>
scsi: storvsc: fix SRB_STATUS_ABORTED handling

Finn Thain <[email protected]>
ncr5380: Call scsi_eh_prep_cmnd() and scsi_eh_restore_cmnd() as and when appropriate

Finn Thain <[email protected]>
ncr5380: Fix NCR5380_select() EH checks and result handling

Finn Thain <[email protected]>
ncr5380: Forget aborted commands

Finn Thain <[email protected]>

    ncr5380: Dont re-enter NCR5380_select()

Finn Thain <[email protected]>
ncr5380: Dont release lock for PIO transfer

Finn Thain <[email protected]>
ncr5380: Correctly clear command pointers and lists after bus reset

Martin K. Petersen <[email protected]>
sd: Fix discard granularity when LBPRZ=1

Raghava Aditya Renukunta <[email protected]>
aacraid: Set correct msix count for EEH recovery

Raghava Aditya Renukunta <[email protected]>
aacraid: Fix memory leak in aac_fib_map_free

Raghava Aditya Renukunta <[email protected]>
aacraid: Fix RRQ overload

Douglas Gilbert <[email protected]>
sg: fix dxferp in from_to case

Nadav Amit <[email protected]>
x86/mm: TLB_REMOTE_SEND_IPI should count pages

Andy Lutomirski <[email protected]>
x86/iopl: Fix iopl capability check on Xen PV

Andy Lutomirski <[email protected]>
x86/iopl/64: Properly context-switch IOPL on Xen PV

Dave Jones <[email protected]>
x86/apic: Fix suspicious RCU usage in smp_trace_call_function_interrupt()

Thomas Gleixner <[email protected]>
x86/irq: Cure live lock in fixup_irqs()

Lorenzo Pieralisi <[email protected]>
PCI: ACPI: IA64: fix IO port generic range check

Bjorn Helgaas <[email protected]>
PCI: Disable IO/MEM decoding for devices with non-compliant BARs

Phil Elwell <[email protected]>
pinctrl-bcm2835: Fix cut-and-paste error in "pull" parsing

Sebastian Ott <[email protected]>
s390/pci: enforce fmb page boundary rule

Heiko Carstens <[email protected]>
s390/cpumf: add missing lpp magic initialization

Martin Schwidefsky <[email protected]>
s390: fix floating pointer register corruption (again)

Dan Carpenter <[email protected]>
EDAC, amd64_edac: Shift wrapping issue in f1x_get_norm_dct_addr()

Tony Luck <[email protected]>
EDAC/sb_edac: Fix computation of channel address

David Hildenbrand <[email protected]>
sched/preempt, sh: kmap_coherent relies on disabled preemption

Byungchul Park <[email protected]>
sched/fair: Avoid using decay_load_missed() with a negative value

Chris Friesen <[email protected]>
sched/cputime: Fix steal_account_process_tick() to always return jiffies

Zhang Rui <[email protected]>
Thermal: Ignore invalid trip points

Jiri Olsa <[email protected]>
perf tools: Fix python extension build

Wang Nan <[email protected]>
perf tools: Fix checking asprintf return value

Andi Kleen <[email protected]>
perf tools: Dont stop PMU parsing on alias parse error

Alexander Shishkin <[email protected]>
perf/core: Fix perf_sched_count derailment

Paolo Bonzini <[email protected]>
KVM: VMX: fix nested vpid for old KVM guests

Paolo Bonzini <[email protected]>
KVM: VMX: avoid guest hang on invalid invvpid instruction

Paolo Bonzini <[email protected]>
KVM: VMX: avoid guest hang on invalid invept instruction

Paolo Bonzini <[email protected]>
KVM: fix spin_lock_init order on x86

Radim Krčmář <[email protected]>
KVM: i8254: change PIT discard tick policy

Paolo Bonzini <[email protected]>
KVM: x86: fix missed hardware breakpoints

Bjorn Helgaas <[email protected]>
x86/PCI: Mark Broadwell-EP Home Agent & PCU as having non-compliant BARs

Stephane Eranian <[email protected]>
perf/x86/intel: Add definition for PT PMI bit

Andy Lutomirski <[email protected]>
x86/entry/compat: Keep TS_COMPAT set during signal delivery

Borislav Petkov <[email protected]>
x86/microcode: Untangle from BLK_DEV_INITRD

Borislav Petkov <[email protected]>
x86/microcode/intel: Make early loader look for builtin microcode too

-------------

Diffstat:

 Documentation/cgroup-v2.txt                        |   6 +
 MAINTAINERS                                        |  96 ++++----
 Makefile                                           |   4 +-
 arch/arc/boot/dts/axs10x_mb.dtsi                   |   8 +
 arch/arc/include/asm/bitops.h                      |  15 --
 arch/arc/include/asm/io.h                          |  18 +-
 arch/arm/boot/dts/at91-sama5d3_xplained.dts        |   1 +
 arch/arm/boot/dts/at91-sama5d4_xplained.dts        |   1 +
 arch/arm64/include/asm/pgtable.h                   |   3 +-
 arch/ia64/include/asm/io.h                         |   1 +
 arch/s390/include/asm/pci.h                        |   2 +-
 arch/s390/kernel/entry.S                           | 106 +-------
 arch/s390/kernel/setup.c                           |   1 +
 arch/s390/pci/pci.c                                |   5 +-
 arch/sh/mm/kmap.c                                  |   2 +
 arch/um/drivers/mconsole_kern.c                    |   2 +-
 arch/x86/Kconfig                                   |  27 ++-
 arch/x86/entry/common.c                            |  23 +-
 arch/x86/include/asm/apic.h                        |   2 +-
 arch/x86/include/asm/hw_irq.h                      |   1 +
 arch/x86/include/asm/microcode.h                   |  26 ++
 arch/x86/include/asm/perf_event.h                  |   1 +
 arch/x86/include/asm/xen/hypervisor.h              |   2 +
 arch/x86/kernel/apic/vector.c                      |  88 +++++--
 arch/x86/kernel/cpu/microcode/intel.c              |  38 +--
 arch/x86/kernel/cpu/perf_event.c                   |  13 +
 arch/x86/kernel/cpu/perf_event.h                   |   3 +
 arch/x86/kernel/cpu/perf_event_intel.c             |  27 ++-
 arch/x86/kernel/cpu/perf_event_intel_ds.c          |  24 +-
 .../x86/kernel/cpu/perf_event_intel_uncore_snbep.c |   8 +-
 arch/x86/kernel/cpu/perf_event_knc.c               |   4 +-
 arch/x86/kernel/ioport.c                           |  12 +-
 arch/x86/kernel/process_64.c                       |  12 +
 arch/x86/kvm/i8254.c                               |  12 +-
 arch/x86/kvm/vmx.c                                 |  16 +-
 arch/x86/kvm/x86.c                                 |   1 +
 arch/x86/mm/tlb.c                                  |  12 +-
 arch/x86/pci/fixup.c                               |   7 +
 arch/x86/xen/enlighten.c                           |   2 +-
 arch/xtensa/kernel/head.S                          |   2 +-
 arch/xtensa/mm/cache.c                             |   8 +-
 arch/xtensa/platforms/iss/console.c                |  10 +-
 block/blk-core.c                                   |   2 +-
 crypto/asymmetric_keys/x509_cert_parser.c          |   8 +-
 crypto/keywrap.c                                   |   4 +-
 drivers/acpi/resource.c                            |  14 +-
 drivers/acpi/sleep.c                               |   1 +
 drivers/block/brd.c                                |   2 +-
 drivers/block/mtip32xx/mtip32xx.c                  | 267 ++++++++++++++++-----
 drivers/block/mtip32xx/mtip32xx.h                  |  11 +-
 drivers/bluetooth/ath3k.c                          |   8 +
 drivers/bluetooth/btusb.c                          |   4 +
 drivers/char/tpm/tpm-chip.c                        |  14 +-
 drivers/char/tpm/tpm_crb.c                         |   4 +-
 drivers/char/tpm/tpm_eventlog.c                    |  14 +-
 drivers/clk/bcm/clk-bcm2835.c                      |  12 +-
 drivers/clk/rockchip/clk-rk3188.c                  |   1 +
 drivers/clk/rockchip/clk-rk3368.c                  |  48 ++--
 drivers/crypto/atmel-aes.c                         |   4 +-
 drivers/crypto/atmel-sha.c                         |   4 +-
 drivers/crypto/atmel-tdes.c                        |   4 +-
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c           |  36 +++
 drivers/crypto/ccp/ccp-crypto-sha.c                |  40 +++
 drivers/crypto/ccp/ccp-crypto.h                    |  22 ++
 drivers/crypto/marvell/cesa.c                      |   2 +-
 drivers/crypto/ux500/cryp/cryp_core.c              |   4 +-
 drivers/crypto/ux500/hash/hash_core.c              |   4 +-
 drivers/edac/amd64_edac.c                          |   2 +-
 drivers/edac/sb_edac.c                             |  26 +-
 drivers/firmware/broadcom/bcm47xx_nvram.c          |   5 +-
 drivers/gpio/gpio-pca953x.c                        |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c   |   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c             |   4 +-
 drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c     |   5 +
 drivers/gpu/drm/radeon/atombios_encoders.c         |   6 +-
 drivers/gpu/drm/radeon/radeon_atpx_handler.c       |   8 +-
 drivers/gpu/drm/radeon/radeon_device.c             |   8 +-
 drivers/gpu/drm/radeon/radeon_display.c            |   6 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c             |  12 +-
 drivers/gpu/drm/radeon/radeon_fb.c                 |  19 +-
 drivers/gpu/drm/vc4/vc4_bo.c                       |   7 +-
 drivers/hid/hid-core.c                             |   8 +-
 drivers/hid/hid-multitouch.c                       |   5 +
 drivers/hid/i2c-hid/i2c-hid.c                      |  16 +-
 drivers/idle/intel_idle.c                          | 108 +++++++--
 drivers/infiniband/ulp/isert/ib_isert.c            | 122 +++++-----
 drivers/infiniband/ulp/isert/ib_isert.h            |   2 +-
 drivers/infiniband/ulp/srpt/ib_srpt.c              |  59 +----
 drivers/input/misc/ati_remote2.c                   |  36 ++-
 drivers/input/misc/ims-pcu.c                       |   4 +
 drivers/input/misc/powermate.c                     |   3 +
 drivers/input/mouse/synaptics.c                    |   5 +-
 drivers/md/bcache/super.c                          |  46 +++-
 drivers/md/dm-cache-metadata.c                     |  98 +++++---
 drivers/md/dm-cache-metadata.h                     |   4 +-
 drivers/md/dm-cache-target.c                       |  12 +-
 drivers/md/dm-snap.c                               |   9 +
 drivers/md/dm-table.c                              |  36 ++-
 drivers/md/dm-thin-metadata.c                      |   5 +-
 drivers/md/dm.c                                    |  15 +-
 drivers/md/multipath.c                             |   4 +-
 drivers/md/raid1.c                                 |   7 +-
 drivers/md/raid10.c                                |   7 +-
 drivers/md/raid5.c                                 |  51 ++--
 drivers/md/raid5.h                                 |   4 +-
 drivers/media/i2c/adv7511.c                        |  21 +-
 drivers/media/pci/bt8xx/bttv-driver.c              |  26 +-
 drivers/media/pci/saa7134/saa7134-video.c          |  18 +-
 drivers/media/platform/coda/coda-bit.c             |   2 +-
 drivers/media/usb/pwc/pwc-if.c                     |   6 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c      |  21 +-
 drivers/misc/mei/bus.c                             |   9 +
 drivers/mmc/card/block.c                           |  24 +-
 drivers/mmc/host/atmel-mci.c                       |   2 +-
 drivers/mmc/host/mmc_spi.c                         |   6 +
 drivers/mmc/host/sdhci-pxav3.c                     |   6 +-
 drivers/mmc/host/sdhci-tegra.c                     |  14 +-
 drivers/mmc/host/sdhci.c                           | 142 ++++++-----
 drivers/mtd/onenand/onenand_base.c                 |   3 +-
 drivers/net/ethernet/marvell/mvneta.c              |   2 +-
 drivers/net/irda/irtty-sir.c                       |  10 -
 drivers/net/rionet.c                               |   4 +-
 .../broadcom/brcm80211/brcmfmac/flowring.c         |  38 +--
 .../broadcom/brcm80211/brcmfmac/flowring.h         |  20 +-
 .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c  |  11 +-
 .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h  |   2 +-
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c     |   1 +
 drivers/nvdimm/bus.c                               |   8 +-
 drivers/nvdimm/pmem.c                              |  11 +-
 drivers/of/of_reserved_mem.c                       |   4 +-
 drivers/pci/probe.c                                |  14 ++
 drivers/pinctrl/bcm/pinctrl-bcm2835.c              |   2 +-
 drivers/platform/x86/ideapad-laptop.c              |  14 ++
 drivers/scsi/NCR5380.c                             | 133 +++++-----
 drivers/scsi/aacraid/aacraid.h                     |   2 +
 drivers/scsi/aacraid/commsup.c                     |  37 ++-
 drivers/scsi/aacraid/linit.c                       |  12 +-
 drivers/scsi/aacraid/src.c                         |  30 +--
 drivers/scsi/aic7xxx/aic7xxx_osm.c                 |   1 +
 drivers/scsi/atari_NCR5380.c                       | 133 +++++-----
 drivers/scsi/be2iscsi/be_main.c                    |   1 +
 drivers/scsi/scsi_common.c                         |  12 +-
 drivers/scsi/sd.c                                  |   2 +-
 drivers/scsi/sg.c                                  |   3 +-
 drivers/scsi/storvsc_drv.c                         |   5 +-
 drivers/staging/android/ion/ion_test.c             |   4 +-
 drivers/staging/comedi/drivers/ni_mio_common.c     |  12 +-
 drivers/staging/comedi/drivers/ni_tiocmd.c         |   2 +-
 drivers/target/target_core_transport.c             |   2 -
 drivers/thermal/thermal_core.c                     |  13 +-
 drivers/tty/serial/8250/8250_port.c                |  18 +-
 drivers/usb/class/cdc-acm.c                        |   3 +
 drivers/usb/core/driver.c                          |   6 +-
 drivers/usb/core/hub.c                             |  16 +-
 drivers/usb/misc/iowarrior.c                       |   6 +
 drivers/usb/serial/cp210x.c                        |   1 +
 drivers/usb/serial/cypress_m8.c                    |  11 +-
 drivers/usb/serial/digi_acceleport.c               |  19 ++
 drivers/usb/serial/ftdi_sio.c                      |   4 +
 drivers/usb/serial/ftdi_sio_ids.h                  |   8 +
 drivers/usb/serial/mct_u232.c                      |   9 +-
 drivers/usb/serial/option.c                        |   2 +
 drivers/usb/storage/uas.c                          |   2 +-
 drivers/watchdog/rc32434_wdt.c                     |   2 +-
 fs/coredump.c                                      |  30 ++-
 fs/fhandle.c                                       |   2 +-
 fs/fs-writeback.c                                  |  37 ++-
 fs/fuse/cuse.c                                     |   4 +-
 fs/fuse/file.c                                     |  33 ++-
 fs/fuse/fuse_i.h                                   |   9 +
 fs/jbd2/journal.c                                  |  17 +-
 fs/nfsd/nfs4proc.c                                 |   1 +
 fs/nfsd/nfs4xdr.c                                  |  13 +-
 fs/ocfs2/cluster/heartbeat.c                       |   4 +-
 fs/ocfs2/dlm/dlmconvert.c                          |  24 +-
 fs/ocfs2/dlm/dlmrecovery.c                         |   1 -
 fs/open.c                                          |   6 +-
 fs/proc_namespace.c                                |   2 +
 fs/quota/dquot.c                                   |   3 +-
 fs/splice.c                                        |   3 +
 fs/xfs/xfs_attr_list.c                             |  19 +-
 include/asm-generic/bitops/lock.h                  |  14 +-
 include/linux/cgroup-defs.h                        |   3 +
 include/linux/device-mapper.h                      |   2 +
 include/linux/fs.h                                 |   2 +-
 include/linux/kernel.h                             |   6 +-
 include/linux/pci.h                                |   1 +
 include/linux/thermal.h                            |   2 +
 include/linux/tty.h                                |   2 +-
 include/sound/hdaudio.h                            |   2 +
 kernel/cgroup.c                                    |  20 +-
 kernel/events/core.c                               |   7 +-
 kernel/power/hibernate.c                           |   1 +
 kernel/sched/core.c                                |   1 +
 kernel/sched/cputime.c                             |  14 +-
 kernel/sched/fair.c                                |  12 +-
 kernel/sched/sched.h                               |  13 +
 kernel/sysctl_binary.c                             |   2 +-
 kernel/trace/trace.c                               |   5 +-
 kernel/trace/trace_irqsoff.c                       |   8 +-
 kernel/trace/trace_printk.c                        |   3 +
 kernel/watchdog.c                                  |   9 +-
 mm/memcontrol.c                                    |  44 +++-
 mm/page_alloc.c                                    |  46 +++-
 net/bluetooth/mgmt.c                               |   4 +
 scripts/coccinelle/iterators/use_after_iter.cocci  |   2 +-
 scripts/gdb/linux/modules.py                       |   5 +-
 scripts/gdb/linux/symbols.py                       |   2 +-
 scripts/kconfig/Makefile                           |   4 +-
 scripts/package/mkspec                             |   8 +-
 sound/core/pcm_lib.c                               |   2 +-
 sound/hda/hdac_device.c                            |  16 ++
 sound/hda/hdac_regmap.c                            |  69 ++++--
 sound/pci/hda/patch_cirrus.c                       |   8 +-
 sound/pci/hda/patch_conexant.c                     |   7 +-
 sound/pci/hda/patch_hdmi.c                         |  43 +++-
 sound/pci/hda/patch_realtek.c                      |   1 +
 sound/pci/intel8x0.c                               |   1 +
 sound/usb/clock.c                                  |   2 +
 sound/usb/endpoint.c                               |   3 +
 sound/usb/mixer_quirks.c                           |   4 +
 sound/usb/pcm.c                                    |   2 +
 sound/usb/quirks.c                                 |  27 ++-
 sound/usb/stream.c                                 |   6 +-
 tools/hv/Makefile                                  |   2 +
 tools/perf/util/parse-events.c                     |   6 +-
 tools/perf/util/pmu.c                              |  15 +-
 tools/perf/util/setup.py                           |   4 +
 virt/kvm/kvm_main.c                                |  21 +-
 230 files changed, 2359 insertions(+), 1266 deletions(-)
author maintainer
#1 lore raw

PATCH 1/238 x86/microcode/intel: Make early loader look for builtin microcode too

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Borislav Petkov <[email protected]>

commit 264285ac01673e70557c43ecee338ce97c4c0672 upstream.

Set the initrd @start depending on the presence of an initrd. Otherwise, builtin microcode loading doesn't work as the start is wrong and we're using it to compute offset to the microcode blobs.

---
 arch/x86/kernel/cpu/microcode/intel.c |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/microcode/intel.c +16 -8
@@ -551,10 +551,14 @@ scan_microcode(struct mc_saved_data *mc_
 	cd.data = NULL;
 	cd.size = 0;
 
-	cd = find_cpio_data(p, (void *)start, size, &offset);
-	if (!cd.data) {
+	/* try built-in microcode if no initrd */
+	if (!size) {
 		if (!load_builtin_intel_microcode(&cd))
 			return UCODE_ERROR;
+	} else {
+		cd = find_cpio_data(p, (void *)start, size, &offset);
+		if (!cd.data)
+			return UCODE_ERROR;
 	}
 
 	return get_matching_model_microcode(0, start, cd.data, cd.size,
@@ -728,16 +732,20 @@ void __init load_ucode_intel_bsp(void)
 	struct boot_params *p;
 
 	p	= (struct boot_params *)__pa_nodebug(&boot_params);
-	start	= p->hdr.ramdisk_image;
 	size	= p->hdr.ramdisk_size;
 
-	_load_ucode_intel_bsp(
-			(struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
-			(unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
-			start, size);
+	/*
+	 * Set start only if we have an initrd image. We cannot use initrd_start
+	 * because it is not set that early yet.
+	 */
+	start	= (size ? p->hdr.ramdisk_image : 0);
+
+	_load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
+			      (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
+			      start, size);
 #else
-	start	= boot_params.hdr.ramdisk_image + PAGE_OFFSET;
 	size	= boot_params.hdr.ramdisk_size;
+	start	= (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
 
 	_load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size);
 #endif
author maintainer
#2 lore raw

PATCH 2/238 x86/microcode: Untangle from BLK_DEV_INITRD

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Borislav Petkov <[email protected]>

commit 5f9c01aa7c49a2d74474d6d879a797b8badf29e6 upstream.

Thomas Voegtle reported that doing oldconfig with a .config which has CONFIG_MICROCODE enabled but BLK_DEV_INITRD disabled prevents the microcode loading mechanism from being built.

So untangle it from the BLK_DEV_INITRD dependency so that oldconfig doesn't turn it off and add an explanatory text to its Kconfig help what the supported methods for supplying microcode are.

---
 arch/x86/Kconfig                      |   23 ++++++++++++-----------
 arch/x86/include/asm/microcode.h      |   26 ++++++++++++++++++++++++++
 arch/x86/kernel/cpu/microcode/intel.c |   14 ++++----------
 3 files changed, 42 insertions(+), 21 deletions(-)
arch/x86/Kconfig +12 -11
@@ -1160,22 +1160,23 @@ config MICROCODE
 	bool "CPU microcode loading support"
 	default y
 	depends on CPU_SUP_AMD || CPU_SUP_INTEL
-	depends on BLK_DEV_INITRD
 	select FW_LOADER
 	---help---
-
 	  If you say Y here, you will be able to update the microcode on
-	  certain Intel and AMD processors. The Intel support is for the
-	  IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
-	  Xeon etc. The AMD support is for families 0x10 and later. You will
-	  obviously need the actual microcode binary data itself which is not
-	  shipped with the Linux kernel.
+	  Intel and AMD processors. The Intel support is for the IA32 family,
+	  e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The
+	  AMD support is for families 0x10 and later. You will obviously need
+	  the actual microcode binary data itself which is not shipped with
+	  the Linux kernel.
 
-	  This option selects the general module only, you need to select
-	  at least one vendor specific module as well.
+	  The preferred method to load microcode from a detached initrd is described
+	  in Documentation/x86/early-microcode.txt. For that you need to enable
+	  CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
+	  initrd for microcode blobs.
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called microcode.
+	  In addition, you can build-in the microcode into the kernel. For that you
+	  need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode
+	  to the CONFIG_EXTRA_FIRMWARE config option.
 
 config MICROCODE_INTEL
 	bool "Intel microcode loading support"
arch/x86/include/asm/microcode.h +26 -0
@@ -3,6 +3,7 @@
 
 #include <asm/cpu.h>
 #include <linux/earlycpio.h>
+#include <linux/initrd.h>
 
 #define native_rdmsr(msr, val1, val2)			\
 do {							\
@@ -143,4 +144,29 @@ static inline void reload_early_microcod
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
 #endif
+
+static inline unsigned long get_initrd_start(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	return initrd_start;
+#else
+	return 0;
+#endif
+}
+
+static inline unsigned long get_initrd_start_addr(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+#ifdef CONFIG_X86_32
+	unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+
+	return (unsigned long)__pa_nodebug(*initrd_start_p);
+#else
+	return get_initrd_start();
+#endif
+#else /* CONFIG_BLK_DEV_INITRD */
+	return 0;
+#endif
+}
+
 #endif /* _ASM_X86_MICROCODE_H */
arch/x86/kernel/cpu/microcode/intel.c +4 -10
@@ -694,7 +694,7 @@ int __init save_microcode_in_initrd_inte
 	if (count == 0)
 		return ret;
 
-	copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count);
+	copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, get_initrd_start(), count);
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
 		pr_err("Cannot save microcode patches from initrd.\n");
@@ -756,20 +756,14 @@ void load_ucode_intel_ap(void)
 	struct mc_saved_data *mc_saved_data_p;
 	struct ucode_cpu_info uci;
 	unsigned long *mc_saved_in_initrd_p;
-	unsigned long initrd_start_addr;
 	enum ucode_state ret;
 #ifdef CONFIG_X86_32
-	unsigned long *initrd_start_p;
 
-	mc_saved_in_initrd_p =
-		(unsigned long *)__pa_nodebug(mc_saved_in_initrd);
+	mc_saved_in_initrd_p = (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
 	mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
-	initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
-	initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
 #else
-	mc_saved_data_p = &mc_saved_data;
 	mc_saved_in_initrd_p = mc_saved_in_initrd;
-	initrd_start_addr = initrd_start;
+	mc_saved_data_p = &mc_saved_data;
 #endif
 
 	/*
@@ -781,7 +775,7 @@ void load_ucode_intel_ap(void)
 
 	collect_cpu_info_early(&uci);
 	ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
-			     initrd_start_addr, &uci);
+			     get_initrd_start_addr(), &uci);
 
 	if (ret != UCODE_OK)
 		return;
author maintainer
#3 lore raw

PATCH 3/238 x86/entry/compat: Keep TS_COMPAT set during signal delivery

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Lutomirski <[email protected]>

commit 4e79e182b419172e35936a47f098509092d69817 upstream.

Signal delivery needs to know the sign of an interrupted syscall's return value in order to detect -ERESTART variants. Normally this works independently of bitness because syscalls internally return long. Under ptrace, however, this can break, and syscall_get_error is supposed to sign-extend regs->ax if needed.

We were clearing TS_COMPAT too early, though, and this prevented sign extension, which subtly broke syscall restart under ptrace.

Cc Al Viro <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Brian Gerst <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Shuah Khan <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes c5c46f59e4e7 ("x86/entry: Add new, comprehensible entry and exit handlers written in C")
---
 arch/x86/entry/common.c |   23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)
arch/x86/entry/common.c +13 -10
@@ -268,6 +268,7 @@ static void exit_to_usermode_loop(struct
 /* Called with IRQs disabled. */
 __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
 {
+	struct thread_info *ti = pt_regs_to_thread_info(regs);
 	u32 cached_flags;
 
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
@@ -275,12 +276,22 @@ __visible inline void prepare_exit_to_us
 
 	lockdep_sys_exit();
 
-	cached_flags =
-		READ_ONCE(pt_regs_to_thread_info(regs)->flags);
+	cached_flags = READ_ONCE(ti->flags);
 
 	if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
 		exit_to_usermode_loop(regs, cached_flags);
 
+#ifdef CONFIG_COMPAT
+	/*
+	 * Compat syscalls set TS_COMPAT.  Make sure we clear it before
+	 * returning to user mode.  We need to clear it *after* signal
+	 * handling, because syscall restart has a fixup for compat
+	 * syscalls.  The fixup is exercised by the ptrace_syscall_32
+	 * selftest.
+	 */
+	ti->status &= ~TS_COMPAT;
+#endif
+
 	user_enter();
 }
 
@@ -332,14 +343,6 @@ __visible inline void syscall_return_slo
 	if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
 		syscall_slow_exit_work(regs, cached_flags);
 
-#ifdef CONFIG_COMPAT
-	/*
-	 * Compat syscalls set TS_COMPAT.  Make sure we clear it before
-	 * returning to user mode.
-	 */
-	ti->status &= ~TS_COMPAT;
-#endif
-
 	local_irq_disable();
 	prepare_exit_to_usermode(regs);
 }
author maintainer
#4 lore raw

PATCH 4/238 perf/x86/intel: Add definition for PT PMI bit

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stephane Eranian <[email protected]>

commit 5690ae28e472d25e330ad0c637a5cea3fc39fb32 upstream.

This patch adds a definition for GLOBAL_OVFL_STATUS bit 55 which is used with the Processor Trace (PT) feature.

---
 arch/x86/include/asm/perf_event.h |    1 +
 1 file changed, 1 insertion(+)
arch/x86/include/asm/perf_event.h +1 -0
@@ -165,6 +165,7 @@ struct x86_pmu_capability {
 #define GLOBAL_STATUS_ASIF				BIT_ULL(60)
 #define GLOBAL_STATUS_COUNTERS_FROZEN			BIT_ULL(59)
 #define GLOBAL_STATUS_LBRS_FROZEN			BIT_ULL(58)
+#define GLOBAL_STATUS_TRACE_TOPAPMI			BIT_ULL(55)
 
 /*
  * IBS cpuid feature detection
author maintainer
#5 lore raw

PATCH 5/238 x86/PCI: Mark Broadwell-EP Home Agent & PCU as having non-compliant BARs

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bjorn Helgaas <[email protected]>

commit b894157145e4ac7598d7062bc93320898a5e059e upstream.

The Home Agent and PCU PCI devices in Broadwell-EP have a non-BAR register where a BAR should be. We don't know what the side effects of sizing the "BAR" would be, and we don't know what address space the "BAR" might appear to describe.

Mark these devices as having non-compliant BARs so the PCI core doesn't touch them.

---
 arch/x86/pci/fixup.c |    7 +++++++
 1 file changed, 7 insertions(+)
arch/x86/pci/fixup.c +7 -0
@@ -540,3 +540,10 @@ static void twinhead_reserve_killing_zon
         }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone);
+
+static void pci_bdwep_bar(struct pci_dev *dev)
+{
+	dev->non_compliant_bars = 1;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar);
author maintainer
#6 lore raw

PATCH 6/238 KVM: x86: fix missed hardware breakpoints

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paolo Bonzini <[email protected]>

commit 4e422bdd2f849d98fffccbc3295c2f0996097fb3 upstream.

Sometimes when setting a breakpoint a process doesn't stop on it. This is because the debug registers are not loaded correctly on VCPU load.

The following simple reproducer from Oleg Nesterov tries using debug registers in both the host and the guest, for example by running "./bp 0 1" on the host and "./bp 14 15" under QEMU.

    #include <unistd.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/wait.h>
    #include <sys/ptrace.h>
    #include <sys/user.h>
    #include <asm/debugreg.h>
    #include <assert.h>

    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

    unsigned long encode_dr7(int drnum, int enable, unsigned int type, unsigned int len)
    {
        unsigned long dr7;

        dr7 = ((len | type) & 0xf)
            << (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
        if (enable)
            dr7 |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));

        return dr7;
    }

    int write_dr(int pid, int dr, unsigned long val)
    {
        return ptrace(PTRACE_POKEUSER, pid,
                offsetof (struct user, u_debugreg[dr]),
                val);
    }

    void set_bp(pid_t pid, void *addr)
    {
        unsigned long dr7;
        assert(write_dr(pid, 0, (long)addr) == 0);
        dr7 = encode_dr7(0, 1, DR_RW_EXECUTE, DR_LEN_1);
        assert(write_dr(pid, 7, dr7) == 0);
    }

    void *get_rip(int pid)
    {
        return (void*)ptrace(PTRACE_PEEKUSER, pid,
                offsetof(struct user, regs.rip), 0);
    }

    void test(int nr)
    {
        void *bp_addr = &&label + nr, *bp_hit;
        int pid;

        printf("test bp %d\n", nr);
        assert(nr < 16); // see 16 asm nops below

        pid = fork();
        if (!pid) {
            assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0);
            kill(getpid(), SIGSTOP);
            for (;;) {
                label: asm (
                    "nop; nop; nop; nop;"
                    "nop; nop; nop; nop;"
                    "nop; nop; nop; nop;"
                    "nop; nop; nop; nop;"
                );
            }
        }

        assert(pid == wait(NULL));
        set_bp(pid, bp_addr);

        for (;;) {
            assert(ptrace(PTRACE_CONT, pid, 0, 0) == 0);
            assert(pid == wait(NULL));

            bp_hit = get_rip(pid);
            if (bp_hit != bp_addr)
                fprintf(stderr, "ERR!! hit wrong bp %ld != %d\n",
                    bp_hit - &&label, nr);
        }
    }

    int main(int argc, const char *argv[])
    {
        while (--argc) {
            int nr = atoi(*++argv);
            if (!fork())
                test(nr);
        }

        while (wait(NULL) > 0)
            ;
        return 0;
    }
---
 arch/x86/kvm/x86.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kvm/x86.c +1 -0
@@ -2752,6 +2752,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
 	}
 
 	kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+	vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD;
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
author maintainer
#7 lore raw

PATCH 8/238 KVM: fix spin_lock_init order on x86

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paolo Bonzini <[email protected]>

commit e9ad4ec8379ad1ba6f68b8ca1c26b50b5ae0a327 upstream.

Moving the initialization earlier is needed in 4.6 because kvm_arch_init_vm is now using mmu_lock, causing lockdep to complain:

[  284.440294] INFO: trying to register non-static key.
[  284.445259] the code is fine but needs lockdep annotation.
[  284.450736] turning off the locking correctness validator.
...
[  284.528318]  [<ffffffff810aecc3>] lock_acquire+0xd3/0x240
[  284.533733]  [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.541467]  [<ffffffff81715581>] _raw_spin_lock+0x41/0x80
[  284.546960]  [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.554707]  [<ffffffffa0305aa0>] kvm_page_track_register_notifier+0x20/0x60 [kvm]
[  284.562281]  [<ffffffffa02ece70>] kvm_mmu_init_vm+0x20/0x30 [kvm]
[  284.568381]  [<ffffffffa02dbf7a>] kvm_arch_init_vm+0x1ea/0x200 [kvm]
[  284.574740]  [<ffffffffa02bff3f>] kvm_dev_ioctl+0xbf/0x4d0 [kvm]

However, it also helps fixing a preexisting problem, which is why this patch is also good for stable kernels: kvm_create_vm was incrementing current->mm->mm_count but not decrementing it at the out_err label (in case kvm_init_mmu_notifier failed). The new initialization order makes it possible to add the required mmdrop without adding a new error label.

---
 virt/kvm/kvm_main.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)
virt/kvm/kvm_main.c +11 -10
@@ -537,6 +537,16 @@ static struct kvm *kvm_create_vm(unsigne
 	if (!kvm)
 		return ERR_PTR(-ENOMEM);
 
+	spin_lock_init(&kvm->mmu_lock);
+	atomic_inc(&current->mm->mm_count);
+	kvm->mm = current->mm;
+	kvm_eventfd_init(kvm);
+	mutex_init(&kvm->lock);
+	mutex_init(&kvm->irq_lock);
+	mutex_init(&kvm->slots_lock);
+	atomic_set(&kvm->users_count, 1);
+	INIT_LIST_HEAD(&kvm->devices);
+
 	r = kvm_arch_init_vm(kvm, type);
 	if (r)
 		goto out_err_no_disable;
@@ -569,16 +579,6 @@ static struct kvm *kvm_create_vm(unsigne
 			goto out_err;
 	}
 
-	spin_lock_init(&kvm->mmu_lock);
-	kvm->mm = current->mm;
-	atomic_inc(&kvm->mm->mm_count);
-	kvm_eventfd_init(kvm);
-	mutex_init(&kvm->lock);
-	mutex_init(&kvm->irq_lock);
-	mutex_init(&kvm->slots_lock);
-	atomic_set(&kvm->users_count, 1);
-	INIT_LIST_HEAD(&kvm->devices);
-
 	r = kvm_init_mmu_notifier(kvm);
 	if (r)
 		goto out_err;
@@ -603,6 +603,7 @@ out_err_no_disable:
 	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
 		kvm_free_memslots(kvm, kvm->memslots[i]);
 	kvm_arch_free_vm(kvm);
+	mmdrop(current->mm);
 	return ERR_PTR(r);
 }
 
author maintainer
#8 lore raw

PATCH 9/238 KVM: VMX: avoid guest hang on invalid invept instruction

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paolo Bonzini <[email protected]>

commit 2849eb4f99d54925c543db12917127f88b3c38ff upstream.

A guest executing an invalid invept instruction would hang because the instruction pointer was not updated.

Fixes bfd0a56b90005f8c8a004baf407ad90045c2b11e
---
 arch/x86/kvm/vmx.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kvm/vmx.c +1 -0
@@ -7398,6 +7398,7 @@ static int handle_invept(struct kvm_vcpu
 	if (!(types & (1UL << type))) {
 		nested_vmx_failValid(vcpu,
 				VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+		skip_emulated_instruction(vcpu);
 		return 1;
 	}
 
author maintainer
#9 lore raw

PATCH 10/238 KVM: VMX: avoid guest hang on invalid invvpid instruction

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paolo Bonzini <[email protected]>

commit f6870ee9e53430f2a318ccf0dd5e66bb46194e43 upstream.

A guest executing an invalid invvpid instruction would hang because the instruction pointer was not updated.

Reported-by [email protected]
Fixes 99b83ac893b84ed1a62ad6d1f2b6cc32026b9e85
---
 arch/x86/kvm/vmx.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kvm/vmx.c +1 -0
@@ -7457,6 +7457,7 @@ static int handle_invvpid(struct kvm_vcp
 	if (!(types & (1UL << type))) {
 		nested_vmx_failValid(vcpu,
 			VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+		skip_emulated_instruction(vcpu);
 		return 1;
 	}
 
author maintainer
#10 lore raw

PATCH 11/238 KVM: VMX: fix nested vpid for old KVM guests

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paolo Bonzini <[email protected]>

commit ef697a712a6165aea7779c295604b099e8bfae2e upstream.

Old KVM guests invoke single-context invvpid without actually checking whether it is supported. This was fixed by commit 518c8ae ("KVM: VMX:
Make sure single type invvpid is supported before issuing invvpid instruction", 2010-08-01) and the patch after, but pre-2.6.36 kernels lack it including RHEL 6.

Reported-by [email protected]
Fixes 99b83ac893b84ed1a62ad6d1f2b6cc32026b9e85
---
 arch/x86/kvm/vmx.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx.c +13 -1
@@ -2702,8 +2702,15 @@ static void nested_vmx_setup_ctls_msrs(s
 	} else
 		vmx->nested.nested_vmx_ept_caps = 0;
 
+	/*
+	 * Old versions of KVM use the single-context version without
+	 * checking for support, so declare that it is supported even
+	 * though it is treated as global context.  The alternative is
+	 * not failing the single-context invvpid, and it is worse.
+	 */
 	if (enable_vpid)
 		vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
+				VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
 				VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
 	else
 		vmx->nested.nested_vmx_vpid_caps = 0;
@@ -7474,12 +7481,17 @@ static int handle_invvpid(struct kvm_vcp
 	}
 
 	switch (type) {
+	case VMX_VPID_EXTENT_SINGLE_CONTEXT:
+		/*
+		 * Old versions of KVM use the single-context version so we
+		 * have to support it; just treat it the same as all-context.
+		 */
 	case VMX_VPID_EXTENT_ALL_CONTEXT:
 		__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
 		nested_vmx_succeed(vcpu);
 		break;
 	default:
-		/* Trap single context invalidation invvpid calls */
+		/* Trap individual address invalidation invvpid calls */
 		BUG_ON(1);
 		break;
 	}
author maintainer
#11 lore raw

PATCH 12/238 perf/core: Fix perf_sched_count derailment

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexander Shishkin <[email protected]>

commit 927a5570855836e5d5859a80ce7e91e963545e8f upstream.

The error path in perf_event_open() is such that asking for a sampling event on a PMU that doesn't generate interrupts will end up in dropping the perf_sched_count even though it hasn't been incremented for this event yet.

Given a sufficient amount of these calls, we'll end up disabling scheduler's jump label even though we'd still have active events in the system, thereby facilitating the arrival of the infernal regions upon us.

I'm fixing this by moving account_event() inside perf_event_alloc().

---
 kernel/events/core.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
kernel/events/core.c +3 -4
@@ -8001,6 +8001,9 @@ perf_event_alloc(struct perf_event_attr
 		}
 	}
 
+	/* symmetric to unaccount_event() in _free_event() */
+	account_event(event);
+
 	return event;
 
 err_per_task:
@@ -8364,8 +8367,6 @@ SYSCALL_DEFINE5(perf_event_open,
 		}
 	}
 
-	account_event(event);
-
 	/*
 	 * Special case software events and allow them to be part of
 	 * any hardware group.
@@ -8662,8 +8663,6 @@ perf_event_create_kernel_counter(struct
 	/* Mark owner so we could distinguish it from user events. */
 	event->owner = TASK_TOMBSTONE;
 
-	account_event(event);
-
 	ctx = find_get_context(event->pmu, task, event);
 	if (IS_ERR(ctx)) {
 		err = PTR_ERR(ctx);
author maintainer
#12 lore raw

PATCH 13/238 perf tools: Dont stop PMU parsing on alias parse error

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andi Kleen <[email protected]>

commit 940db6dcd3f4659303fdf6befe7416adc4d24118 upstream.

When an error happens during alias parsing currently the complete parsing of all attributes of the PMU is stopped. This is breaks old perf on a newer kernel that may have not-yet-know alias attributes (such as .scale or .per-pkg).

Continue when some attribute is unparseable.

This is IMHO a stable candidate and should be backported to older versions to avoid problems with newer kernels.

v2: Print warnings when something goes wrong.
v3: Change warning to debug output

---
 tools/perf/util/pmu.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
tools/perf/util/pmu.c +8 -7
@@ -284,13 +284,12 @@ static int pmu_aliases_parse(char *dir,
 {
 	struct dirent *evt_ent;
 	DIR *event_dir;
-	int ret = 0;
 
 	event_dir = opendir(dir);
 	if (!event_dir)
 		return -EINVAL;
 
-	while (!ret && (evt_ent = readdir(event_dir))) {
+	while ((evt_ent = readdir(event_dir))) {
 		char path[PATH_MAX];
 		char *name = evt_ent->d_name;
 		FILE *file;
@@ -306,17 +305,19 @@ static int pmu_aliases_parse(char *dir,
 
 		snprintf(path, PATH_MAX, "%s/%s", dir, name);
 
-		ret = -EINVAL;
 		file = fopen(path, "r");
-		if (!file)
-			break;
+		if (!file) {
+			pr_debug("Cannot open %s\n", path);
+			continue;
+		}
 
-		ret = perf_pmu__new_alias(head, dir, name, file);
+		if (perf_pmu__new_alias(head, dir, name, file) < 0)
+			pr_debug("Cannot set up %s\n", name);
 		fclose(file);
 	}
 
 	closedir(event_dir);
-	return ret;
+	return 0;
 }
 
 /*
author maintainer
#13 lore raw

PATCH 14/238 perf tools: Fix checking asprintf return value

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wang Nan <[email protected]>

commit 26dee028d365fbc0e3326606a8520260b4462381 upstream.

According to man pages, asprintf returns -1 when failure. This patch fixes two incorrect return value checker.

Cc Adrian Hunter <[email protected]>
Cc Alexei Starovoitov <[email protected]>
Cc Brendan Gregg <[email protected]>
Cc Cody P Schafer <[email protected]>
Cc He Kuang <[email protected]>
Cc Jeremie Galarneau <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Kirill Smelkov <[email protected]>
Cc Li Zefan <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Zefan Li <[email protected]>
Fixes ffeb883e5662 ("perf tools: Show proper error message for wrong terms of hw/sw events")
---
 tools/perf/util/parse-events.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/parse-events.c +3 -3
@@ -2101,11 +2101,11 @@ char *parse_events_formats_error_string(
 
 	/* valid terms */
 	if (additional_terms) {
-		if (!asprintf(&str, "valid terms: %s,%s",
-			      additional_terms, static_terms))
+		if (asprintf(&str, "valid terms: %s,%s",
+			     additional_terms, static_terms) < 0)
 			goto fail;
 	} else {
-		if (!asprintf(&str, "valid terms: %s", static_terms))
+		if (asprintf(&str, "valid terms: %s", static_terms) < 0)
 			goto fail;
 	}
 	return str;
author maintainer
#14 lore raw

PATCH 15/238 perf tools: Fix python extension build

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Olsa <[email protected]>

commit 67d5268908283c187e0a460048a423256c2fb288 upstream.

The util/python-ext-sources file contains source files required to build the python extension relative to $(srctree)/tools/perf,

Such a file path $(FILE).c is handed over to the python extension build system, which builds the final object in the $(PYTHON_EXTBUILD)/tmp/$(FILE).o path.

After the build is done all files from $(PYTHON_EXTBUILD)lib/ are carried as the result binaries.

Above system fails when we add source file relative to ../lib, which we do for:

../lib/bitmap.c
../lib/find_bit.c
../lib/hweight.c
../lib/rbtree.c

All above objects will be built like:

  $(PYTHON_EXTBUILD)/tmp/../lib/bitmap.c
  $(PYTHON_EXTBUILD)/tmp/../lib/find_bit.c
  $(PYTHON_EXTBUILD)/tmp/../lib/hweight.c
  $(PYTHON_EXTBUILD)/tmp/../lib/rbtree.c

which accidentally happens to be final library path:

  $(PYTHON_EXTBUILD)/lib/

Changing setup.py to pass full paths of source files to Extension build class and thus keep all built objects under $(PYTHON_EXTBUILD)tmp directory.

---
 tools/perf/util/setup.py |    4 ++++
 1 file changed, 4 insertions(+)
tools/perf/util/setup.py +4 -0
@@ -22,6 +22,7 @@ cflags = getenv('CFLAGS', '').split()
 # switch off several checks (need to be at the end of cflags list)
 cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
 
+src_perf  = getenv('srctree') + '/tools/perf'
 build_lib = getenv('PYTHON_EXTBUILD_LIB')
 build_tmp = getenv('PYTHON_EXTBUILD_TMP')
 libtraceevent = getenv('LIBTRACEEVENT')
@@ -30,6 +31,9 @@ libapikfs = getenv('LIBAPI')
 ext_sources = [f.strip() for f in file('util/python-ext-sources')
 				if len(f.strip()) > 0 and f[0] != '#']
 
+# use full paths with source files
+ext_sources = map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)
+
 perf = Extension('perf',
 		  sources = ext_sources,
 		  include_dirs = ['util/include'],
author maintainer
#15 lore raw

PATCH 16/238 Thermal: Ignore invalid trip points

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhang Rui <[email protected]>

commit 81ad4276b505e987dd8ebbdf63605f92cd172b52 upstream.

In some cases, platform thermal driver may report invalid trip points, thermal core should not take any action for these trip points.

This fixed a regression that bogus trip point starts to screw up thermal control on some Lenovo laptops, after
commit bb431ba26c5cd0a17c941ca6c3a195a3a6d5d461

Author: Zhang Rui <[email protected]>
Date:   Fri Oct 30 16:31:47 2015 +0800

Thermal: initialize thermal zone device correctly

After thermal zone device registered, as we have not read any temperature before, thus tz->temperature should not be 0, which actually means 0C, and thermal trend is not available. In this case, we need specially handling for the first thermal_zone_device_update().

Both thermal core framework and step_wise governor is enhanced to handle this. And since the step_wise governor is the only one that uses trends, so it's the only thermal governor that needs to be updated.

---
 drivers/thermal/thermal_core.c |   13 ++++++++++++-
 include/linux/thermal.h        |    2 ++
 2 files changed, 14 insertions(+), 1 deletion(-)
drivers/thermal/thermal_core.c +12 -1
@@ -454,6 +454,10 @@ static void handle_thermal_trip(struct t
 {
 	enum thermal_trip_type type;
 
+	/* Ignore disabled trip points */
+	if (test_bit(trip, &tz->trips_disabled))
+		return;
+
 	tz->ops->get_trip_type(tz, trip, &type);
 
 	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
@@ -1800,6 +1804,7 @@ struct thermal_zone_device *thermal_zone
 {
 	struct thermal_zone_device *tz;
 	enum thermal_trip_type trip_type;
+	int trip_temp;
 	int result;
 	int count;
 	int passive = 0;
@@ -1871,9 +1876,15 @@ struct thermal_zone_device *thermal_zone
 		goto unregister;
 
 	for (count = 0; count < trips; count++) {
-		tz->ops->get_trip_type(tz, count, &trip_type);
+		if (tz->ops->get_trip_type(tz, count, &trip_type))
+			set_bit(count, &tz->trips_disabled);
 		if (trip_type == THERMAL_TRIP_PASSIVE)
 			passive = 1;
+		if (tz->ops->get_trip_temp(tz, count, &trip_temp))
+			set_bit(count, &tz->trips_disabled);
+		/* Check for bogus trip points */
+		if (trip_temp == 0)
+			set_bit(count, &tz->trips_disabled);
 	}
 
 	if (!passive) {
include/linux/thermal.h +2 -0
@@ -156,6 +156,7 @@ struct thermal_attr {
  * @trip_hyst_attrs:	attributes for trip points for sysfs: trip hysteresis
  * @devdata:	private pointer for device private data
  * @trips:	number of trip points the thermal zone supports
+ * @trips_disabled;	bitmap for disabled trips
  * @passive_delay:	number of milliseconds to wait between polls when
  *			performing passive cooling.
  * @polling_delay:	number of milliseconds to wait between polls when
@@ -191,6 +192,7 @@ struct thermal_zone_device {
 	struct thermal_attr *trip_hyst_attrs;
 	void *devdata;
 	int trips;
+	unsigned long trips_disabled;	/* bitmap for disabled trips */
 	int passive_delay;
 	int polling_delay;
 	int temperature;
author maintainer
#16 lore raw

PATCH 17/238 sched/cputime: Fix steal_account_process_tick() to always return jiffies

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chris Friesen <[email protected]>

commit f9c904b7613b8b4c85b10cd6b33ad41b2843fa9d upstream.

The callers of steal_account_process_tick() expect it to return whether a jiffy should be considered stolen or not.

Currently the return value of steal_account_process_tick() is in units of cputime, which vary between either jiffies or nsecs depending on CONFIG_VIRT_CPU_ACCOUNTING_GEN.

If cputime has nsecs granularity and there is a tiny amount of stolen time (a few nsecs, say) then we will consider the entire tick stolen and will not account the tick on user/system/idle, causing /proc/stats to show invalid data.

The fix is to change steal_account_process_tick() to accumulate the stolen time and only account it once it's worth a jiffy.

(Thanks to Frederic Weisbecker for suggestions to fix a bug in my first version of the patch.)

---
 kernel/sched/cputime.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
kernel/sched/cputime.c +7 -7
@@ -262,21 +262,21 @@ static __always_inline bool steal_accoun
 #ifdef CONFIG_PARAVIRT
 	if (static_key_false(&paravirt_steal_enabled)) {
 		u64 steal;
-		cputime_t steal_ct;
+		unsigned long steal_jiffies;
 
 		steal = paravirt_steal_clock(smp_processor_id());
 		steal -= this_rq()->prev_steal_time;
 
 		/*
-		 * cputime_t may be less precise than nsecs (eg: if it's
-		 * based on jiffies). Lets cast the result to cputime
+		 * steal is in nsecs but our caller is expecting steal
+		 * time in jiffies. Lets cast the result to jiffies
 		 * granularity and account the rest on the next rounds.
 		 */
-		steal_ct = nsecs_to_cputime(steal);
-		this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct);
+		steal_jiffies = nsecs_to_jiffies(steal);
+		this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies);
 
-		account_steal_time(steal_ct);
-		return steal_ct;
+		account_steal_time(jiffies_to_cputime(steal_jiffies));
+		return steal_jiffies;
 	}
 #endif
 	return false;
author maintainer
#17 lore raw

PATCH 18/238 sched/fair: Avoid using decay_load_missed() with a negative value

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Byungchul Park <[email protected]>

commit 7400d3bbaa229eb8e7631d28fb34afd7cd2c96ff upstream.

decay_load_missed() cannot handle nagative values, so we need to prevent using the function with a negative value.

Cc Chris Metcalf <[email protected]>
Cc Christoph Lameter <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Luiz Capitulino <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul E . McKenney <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes 59543275488d ("sched/fair: Prepare __update_cpu_load() to handle active tickless")
---
 kernel/sched/fair.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/sched/fair.c +10 -2
@@ -4459,9 +4459,17 @@ static void __update_cpu_load(struct rq
 
 		/* scale is effectively 1 << i now, and >> i divides by scale */
 
-		old_load = this_rq->cpu_load[i] - tickless_load;
+		old_load = this_rq->cpu_load[i];
 		old_load = decay_load_missed(old_load, pending_updates - 1, i);
-		old_load += tickless_load;
+		if (tickless_load) {
+			old_load -= decay_load_missed(tickless_load, pending_updates - 1, i);
+			/*
+			 * old_load can never be a negative value because a
+			 * decayed tickless_load cannot be greater than the
+			 * original tickless_load.
+			 */
+			old_load += tickless_load;
+		}
 		new_load = this_load;
 		/*
 		 * Round up the averaging division if load is increasing. This
author maintainer
#18 lore raw

PATCH 19/238 sched/preempt, sh: kmap_coherent relies on disabled preemption

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Hildenbrand <[email protected]>

commit b15d53d009558d14c4f394a6d1fa2039c7f45c43 upstream.

kmap_coherent needs disabled preemption to not schedule in the critical section, just like kmap_coherent on mips and kmap_atomic in general.

Fixes 8222dbe21e79 "sched/preempt, mm/fault: Decouple preemption from the page fault logic"
---
 arch/sh/mm/kmap.c |    2 ++
 1 file changed, 2 insertions(+)
arch/sh/mm/kmap.c +2 -0
@@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, u
 
 	BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
 
+	preempt_disable();
 	pagefault_disable();
 
 	idx = FIX_CMAP_END -
@@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr)
 	}
 
 	pagefault_enable();
+	preempt_enable();
 }
author maintainer
#19 lore raw

PATCH 20/238 EDAC/sb_edac: Fix computation of channel address

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Luck <[email protected]>

commit eb1af3b71f9d83e45f2fd2fd649356e98e1c582c upstream.

Large memory Haswell-EX systems with multiple DIMMs per channel were sometimes reporting the wrong DIMM.

Found three problems:

1) Debug printouts for socket and channel interleave were not interpreting

    the register fields correctly. The socket interleave field is a 2^X
    value (0=1, 1=2, 2=4, 3=8). The channel interleave is X+1 (0=1, 1=2,
    2=3. 3=4).

2) Actual use of the socket interleave value didn't interpret as 2^X

3) Conversion of address to channel address was complicated, and wrong.

---
 drivers/edac/sb_edac.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)
drivers/edac/sb_edac.c +10 -16
@@ -1839,8 +1839,8 @@ static void get_memory_layout(const stru
 		edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
 			 n_tads, gb, (mb*1000)/1024,
 			 ((u64)tmp_mb) << 20L,
-			 (u32)TAD_SOCK(reg),
-			 (u32)TAD_CH(reg),
+			 (u32)(1 << TAD_SOCK(reg)),
+			 (u32)TAD_CH(reg) + 1,
 			 (u32)TAD_TGT0(reg),
 			 (u32)TAD_TGT1(reg),
 			 (u32)TAD_TGT2(reg),
@@ -2118,7 +2118,7 @@ static int get_memory_error_data(struct
 	}
 
 	ch_way = TAD_CH(reg) + 1;
-	sck_way = TAD_SOCK(reg) + 1;
+	sck_way = 1 << TAD_SOCK(reg);
 
 	if (ch_way == 3)
 		idx = addr >> 6;
@@ -2175,7 +2175,7 @@ static int get_memory_error_data(struct
 		 n_tads,
 		 addr,
 		 limit,
-		 (u32)TAD_SOCK(reg),
+		 sck_way,
 		 ch_way,
 		 offset,
 		 idx,
@@ -2190,18 +2190,12 @@ static int get_memory_error_data(struct
 			offset, addr);
 		return -EINVAL;
 	}
-	addr -= offset;
-	/* Store the low bits [0:6] of the addr */
-	ch_addr = addr & 0x7f;
-	/* Remove socket wayness and remove 6 bits */
-	addr >>= 6;
-	addr = div_u64(addr, sck_xch);
-#if 0
-	/* Divide by channel way */
-	addr = addr / ch_way;
-#endif
-	/* Recover the last 6 bits */
-	ch_addr |= addr << 6;
+
+	ch_addr = addr - offset;
+	ch_addr >>= (6 + shiftup);
+	ch_addr /= ch_way * sck_way;
+	ch_addr <<= (6 + shiftup);
+	ch_addr |= addr & ((1 << (6 + shiftup)) - 1);
 
 	/*
 	 * Step 3) Decode rank
author maintainer
#20 lore raw

PATCH 21/238 EDAC, amd64_edac: Shift wrapping issue in f1x_get_norm_dct_addr()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 6f3508f61c814ee852c199988a62bd954c50dfc1 upstream.

dct_sel_base_off is declared as a u64 but we're only using the lower 32 bits because of a shift wrapping bug. This can possibly truncate the upper 16 bits of DctSelBaseOffset[47:26], causing us to misdecode the CS row.

Fixes c8e518d5673d ('amd64_edac: Sanitize f10_get_base_addr_offset')
Cc Aravind Gopalakrishnan <[email protected]>
Cc linux-edac <[email protected]>
---
 drivers/edac/amd64_edac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/amd64_edac.c +1 -1
@@ -1452,7 +1452,7 @@ static u64 f1x_get_norm_dct_addr(struct
 	u64 chan_off;
 	u64 dram_base		= get_dram_base(pvt, range);
 	u64 hole_off		= f10_dhar_offset(pvt);
-	u64 dct_sel_base_off	= (pvt->dct_sel_hi & 0xFFFFFC00) << 16;
+	u64 dct_sel_base_off	= (u64)(pvt->dct_sel_hi & 0xFFFFFC00) << 16;
 
 	if (hi_rng) {
 		/*
author maintainer
#21 lore raw

PATCH 22/238 s390: fix floating pointer register corruption (again)

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Martin Schwidefsky <[email protected]>

commit e370e4769463a65dcf8806fa26d2874e0542ac41 upstream.

There is a tricky interaction between the machine check handler and the critical sections of load_fpu_regs and save_fpu_regs functions. If the machine check interrupts one of the two functions the critical section cleanup will complete the function before the machine check handler s390_do_machine_check is called. Trouble is that the machine check handler needs to validate the floating point registers *before* and not *after* the completion of load_fpu_regs/save_fpu_regs.

The simplest solution is to rewind the PSW to the start of the load_fpu_regs/save_fpu_regs and retry the function after the return from the machine check handler.

---
 arch/s390/kernel/entry.S |  106 -----------------------------------------------
 1 file changed, 2 insertions(+), 104 deletions(-)
arch/s390/kernel/entry.S +2 -104
@@ -1199,114 +1199,12 @@ cleanup_critical:
 	.quad	.Lpsw_idle_lpsw
 
 .Lcleanup_save_fpu_regs:
-	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
-	bor	%r14
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_done)
-	jhe	5f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_fp)
-	jhe	4f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_vx_high)
-	jhe	3f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_vx_low)
-	jhe	2f
-	clg	%r9,BASED(.Lcleanup_save_fpu_fpc_end)
-	jhe	1f
-	lg	%r2,__LC_CURRENT
-	aghi	%r2,__TASK_thread
-0:	# Store floating-point controls
-	stfpc	__THREAD_FPU_fpc(%r2)
-1:	# Load register save area and check if VX is active
-	lg	%r3,__THREAD_FPU_regs(%r2)
-	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
-	jz	4f			  # no VX -> store FP regs
-2:	# Store vector registers (V0-V15)
-	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
-3:	# Store vector registers (V16-V31)
-	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
-	j	5f			  # -> done, set CIF_FPU flag
-4:	# Store floating-point registers
-	std	0,0(%r3)
-	std	1,8(%r3)
-	std	2,16(%r3)
-	std	3,24(%r3)
-	std	4,32(%r3)
-	std	5,40(%r3)
-	std	6,48(%r3)
-	std	7,56(%r3)
-	std	8,64(%r3)
-	std	9,72(%r3)
-	std	10,80(%r3)
-	std	11,88(%r3)
-	std	12,96(%r3)
-	std	13,104(%r3)
-	std	14,112(%r3)
-	std	15,120(%r3)
-5:	# Set CIF_FPU flag
-	oi	__LC_CPU_FLAGS+7,_CIF_FPU
-	lg	%r9,48(%r11)		# return from save_fpu_regs
+	larl	%r9,save_fpu_regs
 	br	%r14
-.Lcleanup_save_fpu_fpc_end:
-	.quad	.Lsave_fpu_regs_fpc_end
-.Lcleanup_save_fpu_regs_vx_low:
-	.quad	.Lsave_fpu_regs_vx_low
-.Lcleanup_save_fpu_regs_vx_high:
-	.quad	.Lsave_fpu_regs_vx_high
-.Lcleanup_save_fpu_regs_fp:
-	.quad	.Lsave_fpu_regs_fp
-.Lcleanup_save_fpu_regs_done:
-	.quad	.Lsave_fpu_regs_done
 
 .Lcleanup_load_fpu_regs:
-	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
-	bnor	%r14
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_done)
-	jhe	1f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_fp)
-	jhe	2f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_vx_high)
-	jhe	3f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_vx)
-	jhe	4f
-	lg	%r4,__LC_CURRENT
-	aghi	%r4,__TASK_thread
-	lfpc	__THREAD_FPU_fpc(%r4)
-	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
-	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
-	jz	2f				# -> no VX, load FP regs
-4:	# Load V0 ..V15 registers
-	VLM	%v0,%v15,0,%r4
-3:	# Load V16..V31 registers
-	VLM	%v16,%v31,256,%r4
-	j	1f
-2:	# Load floating-point registers
-	ld	0,0(%r4)
-	ld	1,8(%r4)
-	ld	2,16(%r4)
-	ld	3,24(%r4)
-	ld	4,32(%r4)
-	ld	5,40(%r4)
-	ld	6,48(%r4)
-	ld	7,56(%r4)
-	ld	8,64(%r4)
-	ld	9,72(%r4)
-	ld	10,80(%r4)
-	ld	11,88(%r4)
-	ld	12,96(%r4)
-	ld	13,104(%r4)
-	ld	14,112(%r4)
-	ld	15,120(%r4)
-1:	# Clear CIF_FPU bit
-	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
-	lg	%r9,48(%r11)		# return from load_fpu_regs
+	larl	%r9,load_fpu_regs
 	br	%r14
-.Lcleanup_load_fpu_regs_vx:
-	.quad	.Lload_fpu_regs_vx
-.Lcleanup_load_fpu_regs_vx_high:
-	.quad	.Lload_fpu_regs_vx_high
-.Lcleanup_load_fpu_regs_fp:
-	.quad	.Lload_fpu_regs_fp
-.Lcleanup_load_fpu_regs_done:
-	.quad	.Lload_fpu_regs_done
 
 /*
  * Integer constants
author maintainer
#22 lore raw

PATCH 23/238 s390/cpumf: add missing lpp magic initialization

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Heiko Carstens <[email protected]>

commit 8f100bb1ff27873dd71f636da670e503b9ade3c6 upstream.

Add the missing lpp magic initialization for cpu 0. Without this all samples on cpu 0 do not have the most significant bit set in the program parameter field, which we use to distinguish between guest and host samples if the pid is also 0.

We did initialize the lpp magic in the absolute zero lowcore but forgot that when switching to the allocated lowcore on cpu 0 only.

Fixes e22cf8ca6f75 ("s390/cpumf: rework program parameter setting to detect guest samples")
---
 arch/s390/kernel/setup.c |    1 +
 1 file changed, 1 insertion(+)
arch/s390/kernel/setup.c +1 -0
@@ -327,6 +327,7 @@ static void __init setup_lowcore(void)
 		+ PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
 	lc->current_task = (unsigned long) init_thread_union.thread_info.task;
 	lc->thread_info = (unsigned long) &init_thread_union;
+	lc->lpp = LPP_MAGIC;
 	lc->machine_flags = S390_lowcore.machine_flags;
 	lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
 	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
author maintainer
#23 lore raw

PATCH 24/238 s390/pci: enforce fmb page boundary rule

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sebastian Ott <[email protected]>

commit 80c544ded25ac14d7cc3e555abb8ed2c2da99b84 upstream.

The function measurement block must not cross a page boundary. Ensure that by raising the alignment requirement to the smallest power of 2 larger than the size of the fmb.

Fixes d0b088531 ("s390/pci: performance statistics and debug infrastructure")
---
 arch/s390/include/asm/pci.h |    2 +-
 arch/s390/pci/pci.c         |    5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)
arch/s390/include/asm/pci.h +1 -1
@@ -45,7 +45,7 @@ struct zpci_fmb {
 	u64 rpcit_ops;
 	u64 dma_rbytes;
 	u64 dma_wbytes;
-} __packed __aligned(16);
+} __packed __aligned(64);
 
 enum zpci_state {
 	ZPCI_FN_STATE_RESERVED,
arch/s390/pci/pci.c +4 -1
@@ -864,8 +864,11 @@ static inline int barsize(u8 size)
 
 static int zpci_mem_init(void)
 {
+	BUILD_BUG_ON(!is_power_of_2(__alignof__(struct zpci_fmb)) ||
+		     __alignof__(struct zpci_fmb) < sizeof(struct zpci_fmb));
+
 	zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
-				16, 0, NULL);
+					   __alignof__(struct zpci_fmb), 0, NULL);
 	if (!zdev_fmb_cache)
 		goto error_fmb;
 
author maintainer
#24 lore raw

PATCH 25/238 pinctrl-bcm2835: Fix cut-and-paste error in "pull" parsing

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Phil Elwell <[email protected]>

commit 2c7e3306d23864d49f686f22e56e180ff0fffb7f upstream.

The DT bindings for pinctrl-bcm2835 allow both the function and pull to contain either one entry or one per pin. However, an error in the DT parsing can cause failures if the number of pulls differs from the number of functions.

---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/bcm/pinctrl-bcm2835.c +1 -1
@@ -779,7 +779,7 @@ static int bcm2835_pctl_dt_node_to_map(s
 		}
 		if (num_pulls) {
 			err = of_property_read_u32_index(np, "brcm,pull",
-					(num_funcs > 1) ? i : 0, &pull);
+					(num_pulls > 1) ? i : 0, &pull);
 			if (err)
 				goto out;
 			err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
author maintainer
#25 lore raw

PATCH 26/238 PCI: Disable IO/MEM decoding for devices with non-compliant BARs

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bjorn Helgaas <[email protected]>

commit b84106b4e2290c081cdab521fa832596cdfea246 upstream.

The PCI config header (first 64 bytes of each device's config space) is defined by the PCI spec so generic software can identify the device and manage its usage of I/O, memory, and IRQ resources.

Some non-spec-compliant devices put registers other than BARs where the BARs should be. When the PCI core sizes these "BARs", the reads and writes it does may have unwanted side effects, and the "BAR" may appear to describe non-sensical address space.

Add a flag bit to mark non-compliant devices so we don't touch their BARs. Turn off IO/MEM decoding to prevent the devices from consuming address space, since we can't read the BARs to find out what that address space would be.

---
 drivers/pci/probe.c |   14 ++++++++++++++
 include/linux/pci.h |    1 +
 2 files changed, 15 insertions(+)
drivers/pci/probe.c +14 -0
@@ -179,6 +179,9 @@ int __pci_read_base(struct pci_dev *dev,
 	u16 orig_cmd;
 	struct pci_bus_region region, inverted_region;
 
+	if (dev->non_compliant_bars)
+		return 0;
+
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
 	/* No printks while decoding is disabled! */
@@ -1171,6 +1174,7 @@ static void pci_msi_setup_pci_dev(struct
 int pci_setup_device(struct pci_dev *dev)
 {
 	u32 class;
+	u16 cmd;
 	u8 hdr_type;
 	int pos = 0;
 	struct pci_bus_region region;
@@ -1214,6 +1218,16 @@ int pci_setup_device(struct pci_dev *dev
 	/* device class may be changed after fixup */
 	class = dev->class >> 8;
 
+	if (dev->non_compliant_bars) {
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+			dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+			cmd &= ~PCI_COMMAND_IO;
+			cmd &= ~PCI_COMMAND_MEMORY;
+			pci_write_config_word(dev, PCI_COMMAND, cmd);
+		}
+	}
+
 	switch (dev->hdr_type) {		    /* header type */
 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
 		if (class == PCI_CLASS_BRIDGE_PCI)
include/linux/pci.h +1 -0
@@ -359,6 +359,7 @@ struct pci_dev {
 	unsigned int	io_window_1k:1;	/* Intel P2P bridge 1K I/O windows */
 	unsigned int	irq_managed:1;
 	unsigned int	has_secondary_link:1;
+	unsigned int	non_compliant_bars:1;	/* broken BARs; ignore them */
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
#26 lore raw

Re: [PATCH 4.5 026/238] PCI: Disable IO/MEM decoding for devices with non-compliant BARs

Quoted 17 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bjorn Helgaas <[email protected]>

commit b84106b4e2290c081cdab521fa832596cdfea246 upstream.

The PCI config header (first 64 bytes of each device's config space) is defined by the PCI spec so generic software can identify the device and manage its usage of I/O, memory, and IRQ resources.

Some non-spec-compliant devices put registers other than BARs where the BARs should be.  When the PCI core sizes these "BARs", the reads and writes it does may have unwanted side effects, and the "BAR" may appear to describe non-sensical address space.

Quoted 4 lines

Add a flag bit to mark non-compliant devices so we don't touch their BARs. Turn off IO/MEM decoding to prevent the devices from consuming address space, since we can't read the BARs to find out what that address space would be.

[...]

No objection, but patch 005/238 seems to depend on this so please reorder them so bisection will work.

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#27 lore raw

Re: [PATCH 4.5 026/238] PCI: Disable IO/MEM decoding for devices with non-compliant BARs

Quoted 18 lines · Ben Hutchings
Quoted 17 lines · Greg Kroah-Hartman

4.5-stable review patch.��If anyone has any objections, please let me know.

------------------

From: Bjorn Helgaas <[email protected]>

commit b84106b4e2290c081cdab521fa832596cdfea246 upstream.

The PCI config header (first 64 bytes of each device's config space) is defined by the PCI spec so generic software can identify the device and manage its usage of I/O, memory, and IRQ resources.

Some non-spec-compliant devices put registers other than BARs where the BARs should be.��When the PCI core sizes these "BARs", the reads and writes it does may have unwanted side effects, and the "BAR" may appear to describe non-sensical address space.

Quoted 8 lines
Quoted 4 lines

Add a flag bit to mark non-compliant devices so we don't touch their BARs. Turn off IO/MEM decoding to prevent the devices from consuming address space, since we can't read the BARs to find out what that address space would be.

[...]

No objection, but patch 005/238 seems to depend on this so please reorder them so bisection will work.

Now reordered, thanks.

greg k-h

author maintainer
#28 lore raw

PATCH 27/238 PCI: ACPI: IA64: fix IO port generic range check

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lorenzo Pieralisi <[email protected]>

commit 4a2e7aab4ffce1e0e79b303dc2f9a03aa9f3a332 upstream.

The [0 - 64k] ACPI PCI IO port resource boundary check in:

acpi_dev_ioresource_flags()

is currently applied blindly in the ACPI resource parsing to all architectures, but only x86 suffers from that IO space limitation.

On arches (ie IA64 and ARM64) where IO space is memory mapped, the PCI root bridges IO resource windows are firstly initialized from the _CRS (in acpi_decode_space()) and contain the CPU physical address at which a root bridge decodes IO space in the CPU physical address space with the offset value representing the offset required to translate the PCI bus address into the CPU physical address.

The IO resource windows are then parsed and updated in arch code before creating and enumerating PCI buses (eg IA64 add_io_space()) to map in an arch specific way the obtained CPU physical address range to a slice of virtual address space reserved to map PCI IO space, ending up with PCI bridges resource windows containing IO resources like the following on a working IA64 configuration:

PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io 0x1000000-0x100ffff window] (bus address [0x0000-0xffff])
pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000fffff window] pci_bus 0000:00: root bus resource [mem 0x80000000-0x8fffffff window] pci_bus 0000:00: root bus resource [mem 0x80004000000-0x800ffffffff window] pci_bus 0000:00: root bus resource [bus 00]

This implies that the [0 - 64K] check in acpi_dev_ioresource_flags() leaves platforms with memory mapped IO space (ie IA64) broken (ie kernel can't claim IO resources since the host bridge IO resource is disabled and discarded by ACPI core code, see log on IA64 with missing root bridge IO resource, silently filtered by current [0 - 64k] check in acpi_dev_ioresource_flags()):

PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000fffff window] pci_bus 0000:00: root bus resource [mem 0x80000000-0x8fffffff window] pci_bus 0000:00: root bus resource [mem 0x80004000000-0x800ffffffff window] pci_bus 0000:00: root bus resource [bus 00]

[...]

pci 0000:00:03.0: [1002:515e] type 00 class 0x030000
pci 0000:00:03.0: reg 0x10: [mem 0x80000000-0x87ffffff pref] pci 0000:00:03.0: reg 0x14: [io 0x1000-0x10ff]
pci 0000:00:03.0: reg 0x18: [mem 0x88020000-0x8802ffff]
pci 0000:00:03.0: reg 0x30: [mem 0x88000000-0x8801ffff pref] pci 0000:00:03.0: supports D1 D2
pci 0000:00:03.0: can't claim BAR 1 [io 0x1000-0x10ff]: no compatible bridge window

For this reason, the IO port resources boundaries check in generic ACPI parsing code should be guarded with a CONFIG_X86 guard so that more arches (ie ARM64) can benefit from the generic ACPI resources parsing interface without incurring in unexpected resource filtering, fixing at the same time current breakage on IA64.

This patch factors out IO ports boundary [0 - 64k] check in generic ACPI code and makes the IO space check X86 specific to make sure that IO space resources are usable on other arches too.

Fixes 3772aea7d6f3 (ia64/PCI/ACPI: Use common ACPI resource parsing interface for host bridge)
---
 drivers/acpi/resource.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/acpi/resource.c +13 -1
@@ -27,8 +27,20 @@
 
 #ifdef CONFIG_X86
 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+static inline bool acpi_iospace_resource_valid(struct resource *res)
+{
+	/* On X86 IO space is limited to the [0 - 64K] IO port range */
+	return res->end < 0x10003;
+}
 #else
 #define valid_IRQ(i) (true)
+/*
+ * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical
+ * addresses mapping IO space in CPU physical address space, IO space
+ * resources can be placed anywhere in the 64-bit physical address space.
+ */
+static inline bool
+acpi_iospace_resource_valid(struct resource *res) { return true; }
 #endif
 
 static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
@@ -127,7 +139,7 @@ static void acpi_dev_ioresource_flags(st
 	if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
 		res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 
-	if (res->end >= 0x10003)
+	if (!acpi_iospace_resource_valid(res))
 		res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 
 	if (io_decode == ACPI_DECODE_16)
author maintainer
#29 lore raw

PATCH 28/238 x86/irq: Cure live lock in fixup_irqs()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 551adc60573cb68e3d55cacca9ba1b7437313df7 upstream.

Harry reported, that he's able to trigger a system freeze with cpu hot unplug. The freeze turned out to be a live lock caused by recent changes in irq_force_complete_move().

When fixup_irqs() and from there irq_force_complete_move() is called on the dying cpu, then all other cpus are in stop machine an wait for the dying cpu to complete the teardown. If there is a move of an interrupt pending then irq_force_complete_move() sends the cleanup IPI to the cpus in the old_domain mask and waits for them to clear the mask. That's obviously impossible as those cpus are firmly stuck in stop machine with interrupts disabled.

I should have known that, but I completely overlooked it being concentrated on the locking issues around the vectors. And the existance of the call to __irq_complete_move() in the code, which actually sends the cleanup IPI made it reasonable to wait for that cleanup to complete. That call was bogus even before the recent changes as it was just a pointless distraction.

We have to look at two cases:

1) The move_in_progress flag of the interrupt is set

This means the ioapic has been updated with the new vector, but it has not fired yet. In theory there is a race:

set_ioapic(new_vector) <-- Interrupt is raised before update is effective,
i.e. it's raised on the old vector.

So if the target cpu cannot handle that interrupt before the old vector is cleaned up, we get a spurious interrupt and in the worst case the ioapic irq line becomes stale, but my experiments so far have only resulted in spurious interrupts.

But in case of cpu hotplug this should be a non issue because if the affinity update happens right before all cpus rendevouz in stop machine, there is no way that the interrupt can be blocked on the target cpu because all cpus loops first with interrupts enabled in stop machine, so the old vector is not yet cleaned up when the interrupt fires.

So the only way to run into this issue is if the delivery of the interrupt on the apic/system bus would be delayed beyond the point where the target cpu disables interrupts in stop machine. I doubt that it can happen, but at least there is a theroretical chance. Virtualization might be able to expose this, but AFAICT the IOAPIC emulation is not as stupid as the real hardware.

I've spent quite some time over the weekend to enforce that situation, though I was not able to trigger the delayed case.

2) The move_in_progress flag is not set and the old_domain cpu mask is not empty.

That means, that an interrupt was delivered after the change and the cleanup IPI has been sent to the cpus in old_domain, but not all CPUs have responded to it yet.

In both cases we can assume that the next interrupt will arrive on the new vector, so we can cleanup the old vectors on the cpus in the old_domain cpu mask.

---
 arch/x86/include/asm/hw_irq.h |    1 
 arch/x86/kernel/apic/vector.c |   88 +++++++++++++++++++++++++++++++++---------
 2 files changed, 71 insertions(+), 18 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -0
@@ -141,6 +141,7 @@ struct irq_alloc_info {
 struct irq_cfg {
 	unsigned int		dest_apicid;
 	u8			vector;
+	u8			old_vector;
 };
 
 extern struct irq_cfg *irq_cfg(unsigned int irq);
arch/x86/kernel/apic/vector.c +70 -18

122 lines not on this page · raw message

author maintainer
#30 lore raw

PATCH 29/238 x86/apic: Fix suspicious RCU usage in smp_trace_call_function_interrupt()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dave Jones <[email protected]>

commit 7834c10313fb823e538f2772be78edcdeed2e6e3 upstream.

Since 4.4, I've been able to trigger this occasionally:

===============================
[ INFO: suspicious RCU usage. ]
4.5.0-rc7-think+ #3 Not tainted

-------------------------------
./arch/x86/include/asm/msr-trace.h:47 suspicious rcu_dereference_check() usage!

other info that might help us debug this:

RCU used illegally from idle CPU!
rcu_scheduler_active = 1, debug_locks = 1
RCU used illegally from extended quiescent state!
no locks held by swapper/3/0.

stack backtrace:
CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.5.0-rc7-think+ #3
 ffffffff92f821e0 1f3e5c340597d7fc ffff880468e07f10 ffffffff92560c2a
 ffff880462145280 0000000000000001 ffff880468e07f40 ffffffff921376a6
 ffffffff93665ea0 0000cc7c876d28da 0000000000000005 ffffffff9383dd60
Call Trace:
 <IRQ>  [<ffffffff92560c2a>] dump_stack+0x67/0x9d
 [<ffffffff921376a6>] lockdep_rcu_suspicious+0xe6/0x100
 [<ffffffff925ae7a7>] do_trace_write_msr+0x127/0x1a0
 [<ffffffff92061c83>] native_apic_msr_eoi_write+0x23/0x30
 [<ffffffff92054408>] smp_trace_call_function_interrupt+0x38/0x360
 [<ffffffff92d1ca60>] trace_call_function_interrupt+0x90/0xa0
 <EOI>  [<ffffffff92ac5124>] ? cpuidle_enter_state+0x1b4/0x520

Move the entering_irq() call before ack_APIC_irq(), because entering_irq() tells the RCU susbstems to end the extended quiescent state, so that the following trace call in ack_APIC_irq() works correctly.

Fixes 4787c368a9bc "x86/tracing: Add irq_enter/exit() in smp_trace_reschedule_interrupt()"
---
 arch/x86/include/asm/apic.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/apic.h +1 -1
@@ -644,8 +644,8 @@ static inline void entering_irq(void)
 
 static inline void entering_ack_irq(void)
 {
-	ack_APIC_irq();
 	entering_irq();
+	ack_APIC_irq();
 }
 
 static inline void ipi_entering_ack_irq(void)
author maintainer
#31 lore raw

PATCH 30/238 x86/iopl/64: Properly context-switch IOPL on Xen PV

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Lutomirski <[email protected]>

commit b7a584598aea7ca73140cb87b40319944dd3393f upstream.

On Xen PV, regs->flags doesn't reliably reflect IOPL and the exit-to-userspace code doesn't change IOPL. We need to context switch it manually.

I'm doing this without going through paravirt because this is specific to Xen PV. After the dust settles, we can merge this with the 32-bit code, tidy up the iopl syscall implementation, and remove the set_iopl pvop entirely.

Fixes XSA-171.

---
 arch/x86/include/asm/xen/hypervisor.h |    2 ++
 arch/x86/kernel/process_64.c          |   12 ++++++++++++
 arch/x86/xen/enlighten.c              |    2 +-
 3 files changed, 15 insertions(+), 1 deletion(-)
arch/x86/include/asm/xen/hypervisor.h +2 -0
@@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num);
 void xen_arch_unregister_cpu(int num);
 #endif
 
+extern void xen_set_iopl_mask(unsigned mask);
+
 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
arch/x86/kernel/process_64.c +12 -0
@@ -48,6 +48,7 @@
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
+#include <asm/xen/hypervisor.h>
 
 asmlinkage extern void ret_from_fork(void);
 
@@ -411,6 +412,17 @@ __switch_to(struct task_struct *prev_p,
 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
 		__switch_to_xtra(prev_p, next_p, tss);
 
+#ifdef CONFIG_XEN
+	/*
+	 * On Xen PV, IOPL bits in pt_regs->flags have no effect, and
+	 * current_pt_regs()->flags may not match the current task's
+	 * intended IOPL.  We need to switch it manually.
+	 */
+	if (unlikely(static_cpu_has(X86_FEATURE_XENPV) &&
+		     prev->iopl != next->iopl))
+		xen_set_iopl_mask(next->iopl);
+#endif
+
 	if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
 		/*
 		 * AMD CPUs have a misfeature: SYSRET sets the SS selector but
arch/x86/xen/enlighten.c +1 -1
@@ -961,7 +961,7 @@ static void xen_load_sp0(struct tss_stru
 	tss->x86_tss.sp0 = thread->sp0;
 }
 
-static void xen_set_iopl_mask(unsigned mask)
+void xen_set_iopl_mask(unsigned mask)
 {
 	struct physdev_set_iopl set_iopl;
 
author maintainer
#32 lore raw

PATCH 31/238 x86/iopl: Fix iopl capability check on Xen PV

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Lutomirski <[email protected]>

commit c29016cf41fe9fa994a5ecca607cf5f1cd98801e upstream.

iopl(3) is supposed to work if iopl is already 3, even if unprivileged. This didn't work right on Xen PV. Fix it.

---
 arch/x86/kernel/ioport.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
arch/x86/kernel/ioport.c +9 -3
@@ -96,9 +96,14 @@ asmlinkage long sys_ioperm(unsigned long
 SYSCALL_DEFINE1(iopl, unsigned int, level)
 {
 	struct pt_regs *regs = current_pt_regs();
-	unsigned int old = (regs->flags >> 12) & 3;
 	struct thread_struct *t = &current->thread;
 
+	/*
+	 * Careful: the IOPL bits in regs->flags are undefined under Xen PV
+	 * and changing them has no effect.
+	 */
+	unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT;
+
 	if (level > 3)
 		return -EINVAL;
 	/* Trying to gain more privileges? */
@@ -106,8 +111,9 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
 		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
 	}
-	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-	t->iopl = level << 12;
+	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
+		(level << X86_EFLAGS_IOPL_BIT);
+	t->iopl = level << X86_EFLAGS_IOPL_BIT;
 	set_iopl_mask(t->iopl);
 
 	return 0;
author maintainer
#33 lore raw

PATCH 32/238 x86/mm: TLB_REMOTE_SEND_IPI should count pages

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nadav Amit <[email protected]>

commit 18c98243ddf05a1827ad2c359c5ac051101e7ff7 upstream.

TLB_REMOTE_SEND_IPI was recently introduced, but it counts bytes instead of pages. In addition, it does not report correctly the case in which flush_tlb_page flushes a page. Fix it to be consistent with other TLB counters.

Fixes 5b74283ab251b9d ("x86, mm: trace when an IPI is about to be sent")
Cc Mel Gorman <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 arch/x86/mm/tlb.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
arch/x86/mm/tlb.c +9 -3
@@ -106,8 +106,6 @@ static void flush_tlb_func(void *info)
 
 	if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
 		return;
-	if (!f->flush_end)
-		f->flush_end = f->flush_start + PAGE_SIZE;
 
 	count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
 	if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
@@ -135,12 +133,20 @@ void native_flush_tlb_others(const struc
 				 unsigned long end)
 {
 	struct flush_tlb_info info;
+
+	if (end == 0)
+		end = start + PAGE_SIZE;
 	info.flush_mm = mm;
 	info.flush_start = start;
 	info.flush_end = end;
 
 	count_vm_tlb_event(NR_TLB_REMOTE_FLUSH);
-	trace_tlb_flush(TLB_REMOTE_SEND_IPI, end - start);
+	if (end == TLB_FLUSH_ALL)
+		trace_tlb_flush(TLB_REMOTE_SEND_IPI, TLB_FLUSH_ALL);
+	else
+		trace_tlb_flush(TLB_REMOTE_SEND_IPI,
+				(end - start) >> PAGE_SHIFT);
+
 	if (is_uv_system()) {
 		unsigned int cpu;
 
author maintainer
#34 lore raw

PATCH 33/238 sg: fix dxferp in from_to case

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Douglas Gilbert <[email protected]>

commit 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 upstream.

One of the strange things that the original sg driver did was let the user provide both a data-out buffer (it followed the sg_header+cdb) _and_ specify a reply length greater than zero. What happened was that the user data-out buffer was copied into some kernel buffers and then the mid level was told a read type operation would take place with the data from the device overwriting the same kernel buffers. The user would then read those kernel buffers back into the user space.

Quoted 1 line
Quoted 1 line

From what I can tell, the above action was broken by commit fad7f01e61bf

("sg: set dxferp to NULL for READ with the older SG interface") in 2008 and syzkaller found that out recently.

Make sure that a user space pointer is passed through when data follows the sg_header structure and command. Fix the abnormal case when a non-zero reply_len is also given.

Fixes fad7f01e61bf737fe8a3740d803f000db57ecac6
---
 drivers/scsi/sg.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/sg.c +2 -1
@@ -652,7 +652,8 @@ sg_write(struct file *filp, const char _
 	else
 		hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
 	hp->dxfer_len = mxsize;
-	if (hp->dxfer_direction == SG_DXFER_TO_DEV)
+	if ((hp->dxfer_direction == SG_DXFER_TO_DEV) ||
+	    (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV))
 		hp->dxferp = (char __user *)buf + cmd_size;
 	else
 		hp->dxferp = NULL;
author maintainer
#35 lore raw

PATCH 34/238 aacraid: Fix RRQ overload

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit 3f4ce057d51a9c0ed9b01ba693df685d230ffcae upstream.

The driver utilizes an array of atomic variables to keep track of IO submissions to each vector. To submit an IO multiple threads iterate through the array to find a vector which has empty slots to send an IO. The reading and updating of the variable is not atomic, causing race conditions when a thread uses a full vector to submit an IO.

Fixed by mapping each FIB to a vector, the submission path then uses said vector to submit IO thereby removing the possibly of a race condition.The vector assignment is started from 1 since vector 0 is reserved for the use of AIF management FIBS.If the number of MSIx vectors is 1 (MSI or INTx mode) then all the fibs are allocated to vector 0.

---
 drivers/scsi/aacraid/aacraid.h |    2 ++
 drivers/scsi/aacraid/commsup.c |   28 ++++++++++++++++++++++++++++
 drivers/scsi/aacraid/src.c     |   30 +++++++-----------------------
 3 files changed, 37 insertions(+), 23 deletions(-)
drivers/scsi/aacraid/aacraid.h +2 -0
@@ -944,6 +944,7 @@ struct fib {
 	 */
 	struct list_head	fiblink;
 	void			*data;
+	u32			vector_no;
 	struct hw_fib		*hw_fib_va;		/* Actual shared object */
 	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
 };
@@ -2113,6 +2114,7 @@ static inline unsigned int cap_to_cyls(s
 int aac_acquire_irq(struct aac_dev *dev);
 void aac_free_irq(struct aac_dev *dev);
 const char *aac_driverinfo(struct Scsi_Host *);
+void aac_fib_vector_assign(struct aac_dev *dev);
 struct fib *aac_fib_alloc(struct aac_dev *dev);
 int aac_fib_setup(struct aac_dev *dev);
 void aac_fib_map_free(struct aac_dev *dev);
drivers/scsi/aacraid/commsup.c +28 -0
@@ -90,6 +90,28 @@ void aac_fib_map_free(struct aac_dev *de
 	dev->hw_fib_pa = 0;
 }
 
+void aac_fib_vector_assign(struct aac_dev *dev)
+{
+	u32 i = 0;
+	u32 vector = 1;
+	struct fib *fibptr = NULL;
+
+	for (i = 0, fibptr = &dev->fibs[i];
+		i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
+		i++, fibptr++) {
+		if ((dev->max_msix == 1) ||
+		  (i > ((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1)
+			- dev->vector_cap))) {
+			fibptr->vector_no = 0;
+		} else {
+			fibptr->vector_no = vector;
+			vector++;
+			if (vector == dev->max_msix)
+				vector = 1;
+		}
+	}
+}
+
 /**
  *	aac_fib_setup	-	setup the fibs
  *	@dev: Adapter to set up
@@ -151,6 +173,12 @@ int aac_fib_setup(struct aac_dev * dev)
 		hw_fib_pa = hw_fib_pa +
 			dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
 	}
+
+	/*
+	 *Assign vector numbers to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
 	/*
 	 *	Add the fib chain to the free list
 	 */
drivers/scsi/aacraid/src.c +7 -23
@@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message(
 				break;
 			if (dev->msi_enabled && dev->max_msix > 1)
 				atomic_dec(&dev->rrq_outstanding[vector_no]);
-			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 			dev->host_rrq[index++] = 0;
+			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 			if (index == (vector_no + 1) * dev->vector_cap)
 				index = vector_no * dev->vector_cap;
 			dev->host_rrq_idx[vector_no] = index;
@@ -452,36 +452,20 @@ static int aac_src_deliver_message(struc
 #endif
 
 	u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
+	u16 vector_no;
 
 	atomic_inc(&q->numpending);
 
 	if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
 	    dev->max_msix > 1) {
-		u_int16_t vector_no, first_choice = 0xffff;
-
-		vector_no = dev->fibs_pushed_no % dev->max_msix;
-		do {
-			vector_no += 1;
-			if (vector_no == dev->max_msix)
-				vector_no = 1;
-			if (atomic_read(&dev->rrq_outstanding[vector_no]) <
-			    dev->vector_cap)
-				break;
-			if (0xffff == first_choice)
-				first_choice = vector_no;
-			else if (vector_no == first_choice)
-				break;
-		} while (1);
-		if (vector_no == first_choice)
-			vector_no = 0;
-		atomic_inc(&dev->rrq_outstanding[vector_no]);
-		if (dev->fibs_pushed_no == 0xffffffff)
-			dev->fibs_pushed_no = 0;
-		else
-			dev->fibs_pushed_no++;
+		vector_no = fib->vector_no;
 		fib->hw_fib_va->header.Handle += (vector_no << 16);
+	} else {
+		vector_no = 0;
 	}
 
+	atomic_inc(&dev->rrq_outstanding[vector_no]);
+
 	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 		/* Calculate the amount to the fibsize bits */
 		fibsize = (hdr_size + 127) / 128 - 1;
author maintainer
#36 lore raw

PATCH 35/238 aacraid: Fix memory leak in aac_fib_map_free

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit f88fa79a61726ce9434df9b4aede36961f709f17 upstream.

aac_fib_map_free() calls pci_free_consistent() without checking that dev->hw_fib_va is not NULL and dev->max_fib_size is not zero.If they are indeed NULL/0, this will result in a hang as pci_free_consistent() will attempt to invalidate cache for the entire 64-bit address space (which would take a very long time).

Fixed by adding a check to make sure that dev->hw_fib_va and dev->max_fib_size are not NULL and 0 respectively.

Fixes 9ad5204d6 - "[SCSI]aacraid: incorrect dma mapping mask during blinked recover or user initiated reset"
---
 drivers/scsi/aacraid/commsup.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/scsi/aacraid/commsup.c +6 -3
@@ -83,9 +83,12 @@ static int fib_map_alloc(struct aac_dev
 
 void aac_fib_map_free(struct aac_dev *dev)
 {
-	pci_free_consistent(dev->pdev,
-	  dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
-	  dev->hw_fib_va, dev->hw_fib_pa);
+	if (dev->hw_fib_va && dev->max_fib_size) {
+		pci_free_consistent(dev->pdev,
+		(dev->max_fib_size *
+		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
+		dev->hw_fib_va, dev->hw_fib_pa);
+	}
 	dev->hw_fib_va = NULL;
 	dev->hw_fib_pa = 0;
 }
author maintainer
#37 lore raw

PATCH 36/238 aacraid: Set correct msix count for EEH recovery

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit ecc479e00db8eb110b200afe1effcb3df20ca7ae upstream.

During EEH recovery number of online CPU's might change thereby changing the number of MSIx vectors. Since each fib is allocated to a vector, changes in the number of vectors causes fib to be sent thru invalid vectors.In addition the correct number of MSIx vectors is not updated in the INIT struct sent to the controller, when it is reinitialized.

Fixed by reassigning vectors to fibs based on the updated number of MSIx vectors and updating the INIT structure before sending to controller.

---
 drivers/scsi/aacraid/linit.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/scsi/aacraid/linit.c +11 -1
@@ -1404,8 +1404,18 @@ static int aac_acquire_resources(struct
 
 	aac_adapter_enable_int(dev);
 
-	if (!dev->sync_mode)
+	/*max msix may change  after EEH
+	 * Re-assign vectors to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
+	if (!dev->sync_mode) {
+		/* After EEH recovery or suspend resume, max_msix count
+		 * may change, therfore updating in init as well.
+		 */
 		aac_adapter_start(dev);
+		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
+	}
 	return 0;
 
 error_iounmap:
#38 lore raw

Re: [PATCH 4.5 036/238] aacraid: Set correct msix count for EEH recovery

Quoted 8 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit ecc479e00db8eb110b200afe1effcb3df20ca7ae upstream.

Quoted 8 lines

During EEH recovery number of online CPU's might change thereby changing the number of MSIx vectors. Since each fib is allocated to a vector, changes in the number of vectors causes fib to be sent thru invalid vectors.In addition the correct number of MSIx vectors is not updated in the INIT struct sent to the controller, when it is reinitialized.

Fixed by reassigning vectors to fibs based on the updated number of MSIx vectors and updating the INIT structure before sending to controller.

Really?

[...]

Quoted 17 lines
drivers/scsi/aacraid/linit.c +0 -0
@@ -1404,8 +1404,18 @@ static int aac_acquire_resources(struct


  aac_adapter_enable_int(dev);

drivers/scsi/aacraid/linit.c +9 -1
-	if (!dev->sync_mode)
+	/*max msix may change  after EEH
+	 * Re-assign vectors to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
+	if (!dev->sync_mode) {
+		/* After EEH recovery or suspend resume, max_msix count
+		 * may change, therfore updating in init as well.
+		 */

  aac_adapter_start(dev);

drivers/scsi/aacraid/linit.c static int aac_acquire_resources(struct · line 1417

Quoted 1 line
drivers/scsi/aacraid/linit.c +1 -0
+		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);

Aren't these two lines in the wrong order?

Ben.

Quoted 4 lines
drivers/scsi/aacraid/linit.c +1 -0
+	}

  return 0;

 error_iounmap:

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
#39 lore raw

RE: [PATCH 4.5 036/238] aacraid: Set correct msix count for EEH recovery

Hello Ben,

Quoted 52 lines

-----Original Message-----
From: Ben Hutchings [mailto:[email protected]]
Sent: Monday, April 11, 2016 5:29 PM
To: Raghava Aditya Renukunta
Cc: [email protected]; Shane Seymour; Johannes Thumshirn; Martin K. Petersen; Greg Kroah-Hartman; LKML
Subject: Re: [PATCH 4.5 036/238] aacraid: Set correct msix count for EEH recovery

Quoted 9 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Raghava Aditya Renukunta <[email protected]>

commit ecc479e00db8eb110b200afe1effcb3df20ca7ae upstream.

During EEH recovery number of online CPU's might change thereby

changing

Quoted 7 lines

the number of MSIx vectors. Since each fib is allocated to a vector, changes in the number of vectors causes fib to be sent thru invalid vectors.In addition the correct number of MSIx vectors is not updated in the INIT struct sent to the controller, when it is reinitialized.

Fixed by reassigning vectors to fibs based on the updated number of MSIx vectors and updating the INIT structure before sending to controller.

Really?

[...]

Quoted 8 lines
drivers/scsi/aacraid/linit.c +1 -1
@@ -1404,8 +1404,18 @@ static int aac_acquire_resources(struct
 
  	aac_adapter_enable_int(dev);
 
-	if (!dev->sync_mode)
+	/*max msix may change  after EEH

drivers/scsi/aacraid/linit.c static int aac_acquire_resources(struct · line 1417

Quoted 10 lines
drivers/scsi/aacraid/linit.c +9 -0
+	 * Re-assign vectors to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
+	if (!dev->sync_mode) {
+		/* After EEH recovery or suspend resume, max_msix count
+		 * may change, therfore updating in init as well.
+		 */
  		aac_adapter_start(dev);
+		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);

Aren't these two lines in the wrong order?

Quoted 1 line

Ben.

You are right those are two lines are in the wrong order, I will submit another patch to correct that issue.

Raghava

Quoted 8 lines
Quoted 5 lines
drivers/scsi/aacraid/linit.c +1 -0
+	}
  	return 0;
 

 error_iounmap:

--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.

author maintainer
#40 lore raw

PATCH 37/238 sd: Fix discard granularity when LBPRZ=1

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Martin K. Petersen <[email protected]>

commit 6540a65da90c09590897310e31993b1f6e28485a upstream.

Commit 397737223c59 ("sd: Make discard granularity match logical block size when LBPRZ=1") accidentally set the granularity to one byte instead of one logical block on devices that provide deterministic zeroes after UNMAP.

---
 drivers/scsi/sd.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/sd.c +1 -1
@@ -648,7 +648,7 @@ static void sd_config_discard(struct scs
 	 */
 	if (sdkp->lbprz) {
 		q->limits.discard_alignment = 0;
-		q->limits.discard_granularity = 1;
+		q->limits.discard_granularity = logical_block_size;
 	} else {
 		q->limits.discard_alignment = sdkp->unmap_alignment *
 			logical_block_size;
author maintainer
#41 lore raw

PATCH 38/238 ncr5380: Correctly clear command pointers and lists after bus reset

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit 1884c2838f31e6bf20f21459ed9921f8c92ed3ef upstream.

Commands subject to exception handling are to be returned to the scsi mid-layer. Make sure that the various command pointers and command lists in the low-level driver are correctly cleansed of affected commands.

This fixes some bugs that I accidentally introduced in v4.5-rc1 including the removal of INIT_LIST_HEAD for the 'autosense' and 'disconnected' command lists, and the possible NULL pointer dereference in NCR5380_bus_reset() that was reported by Dan Carpenter.

hostdata->sensing may also point to an affected command so this pointer also has to be cleared. The abort handler calls complete_cmd() to take care of this; let's have the bus reset handler do the same.

The issue queue may also contain an affected command. If so, remove it. This also follows the abort handler logic.

Fixes 62717f537e1b ("ncr5380: Implement new eh_bus_reset_handler")
---
 drivers/scsi/NCR5380.c       |   19 ++++++++++++-------
 drivers/scsi/atari_NCR5380.c |   19 ++++++++++++-------
 2 files changed, 24 insertions(+), 14 deletions(-)
drivers/scsi/NCR5380.c +12 -7
@@ -2450,7 +2450,16 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	hostdata->selecting = NULL;
+	if (list_del_cmd(&hostdata->unissued, cmd)) {
+		cmd->result = DID_RESET << 16;
+		cmd->scsi_done(cmd);
+	}
+
+	if (hostdata->selecting) {
+		hostdata->selecting->result = DID_RESET << 16;
+		complete_cmd(instance, hostdata->selecting);
+		hostdata->selecting = NULL;
+	}
 
 	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2458,6 +2467,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	list_for_each_entry(ncmd, &hostdata->autosense, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2465,6 +2475,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->autosense);
 
 	if (hostdata->connected) {
 		set_host_byte(hostdata->connected, DID_RESET);
@@ -2472,12 +2483,6 @@ static int NCR5380_bus_reset(struct scsi
 		hostdata->connected = NULL;
 	}
 
-	if (hostdata->sensing) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->sensing);
-		hostdata->sensing = NULL;
-	}
-
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
 #ifdef REAL_DMA
drivers/scsi/atari_NCR5380.c +12 -7
@@ -2646,7 +2646,16 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	hostdata->selecting = NULL;
+	if (list_del_cmd(&hostdata->unissued, cmd)) {
+		cmd->result = DID_RESET << 16;
+		cmd->scsi_done(cmd);
+	}
+
+	if (hostdata->selecting) {
+		hostdata->selecting->result = DID_RESET << 16;
+		complete_cmd(instance, hostdata->selecting);
+		hostdata->selecting = NULL;
+	}
 
 	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2654,6 +2663,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	list_for_each_entry(ncmd, &hostdata->autosense, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2661,6 +2671,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->autosense);
 
 	if (hostdata->connected) {
 		set_host_byte(hostdata->connected, DID_RESET);
@@ -2668,12 +2679,6 @@ static int NCR5380_bus_reset(struct scsi
 		hostdata->connected = NULL;
 	}
 
-	if (hostdata->sensing) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->sensing);
-		hostdata->sensing = NULL;
-	}
-
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif
author maintainer
#42 lore raw

PATCH 39/238 ncr5380: Dont release lock for PIO transfer

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit 1678847ec93040ae8280d19c42ae0ba8a4233e6d upstream.

The calls to NCR5380_transfer_pio() for DATA IN and DATA OUT phases will modify cmd->SCp.this_residual, cmd->SCp.ptr and cmd->SCp.buffer. That works as long as EH does not intervene, which became possible in atari_NCR5380.c when I changed the locking to bring it closer to NCR5380.c.

If error recovery aborts the command, the scsi_cmnd in question and its buffer will be returned to the mid-layer. So the transfer has to cease, but it can't be stopped by the initiator because the target controls the bus phase.

The problem does not arise if the lock is not released. That was fine for atari_scsi, because it implements DMA. For the other drivers, we have to release the lock and re-enable interrupts for long PIO data transfers.

The solution is to split the transfer into small chunks. In between chunks the main loop releases the lock and re-enables interrupts. Thus interrupts can be serviced and eh_bus_reset_handler can intervene if need be.

This fixes an oops in NCR5380_transfer_pio() that can happen when the EH abort handler is invoked during DATA IN or DATA OUT phase.

Fixes 11d2f63b9cf5 ("ncr5380: Change instance->host_lock to hostdata->lock")
---
 drivers/scsi/NCR5380.c       |   16 +++++++++-------
 drivers/scsi/atari_NCR5380.c |   16 +++++++++-------
 2 files changed, 18 insertions(+), 14 deletions(-)
drivers/scsi/NCR5380.c +9 -7
@@ -1759,9 +1759,7 @@ static void NCR5380_information_transfer
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
 	int transfersize;
-#endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd;
@@ -1854,13 +1852,17 @@ static void NCR5380_information_transfer
 				} else
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
 				{
-					spin_unlock_irq(&hostdata->lock);
-					NCR5380_transfer_pio(instance, &phase,
-					                     (int *)&cmd->SCp.this_residual,
+					/* Break up transfer into 3 ms chunks,
+					 * presuming 6 accesses per handshake.
+					 */
+					transfersize = min((unsigned long)cmd->SCp.this_residual,
+					                   hostdata->accesses_per_ms / 2);
+					len = transfersize;
+					NCR5380_transfer_pio(instance, &phase, &len,
 					                     (unsigned char **)&cmd->SCp.ptr);
-					spin_lock_irq(&hostdata->lock);
+					cmd->SCp.this_residual -= transfersize - len;
 				}
-				break;
+				return;
 			case PHASE_MSGIN:
 				len = 1;
 				data = &tmp;
drivers/scsi/atari_NCR5380.c +9 -7
@@ -1838,9 +1838,7 @@ static void NCR5380_information_transfer
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
-#if defined(REAL_DMA)
 	int transfersize;
-#endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd;
@@ -1983,18 +1981,22 @@ static void NCR5380_information_transfer
 				} else
 #endif /* defined(REAL_DMA) */
 				{
-					spin_unlock_irq(&hostdata->lock);
-					NCR5380_transfer_pio(instance, &phase,
-					                     (int *)&cmd->SCp.this_residual,
+					/* Break up transfer into 3 ms chunks,
+					 * presuming 6 accesses per handshake.
+					 */
+					transfersize = min((unsigned long)cmd->SCp.this_residual,
+					                   hostdata->accesses_per_ms / 2);
+					len = transfersize;
+					NCR5380_transfer_pio(instance, &phase, &len,
 					                     (unsigned char **)&cmd->SCp.ptr);
-					spin_lock_irq(&hostdata->lock);
+					cmd->SCp.this_residual -= transfersize - len;
 				}
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
 				/* if we had intended to dma that command clear it */
 				if (sun3_dma_setup_done == cmd)
 					sun3_dma_setup_done = NULL;
 #endif
-				break;
+				return;
 			case PHASE_MSGIN:
 				len = 1;
 				data = &tmp;
author maintainer
#43 lore raw

PATCH 40/238 ncr5380: Dont re-enter NCR5380_select()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit 71a00593ec0c2e2c1720e4041cf2926ff1d07826 upstream.

Calling NCR5380_select() from the abort handler causes various problems. Firstly, it means potentially re-entering NCR5380_select(). Secondly, it means that the lock is released, which permits the EH handlers to be re-entered. The combination results in crashes. Don't do it.

Fixes 8b00c3d5d40d ("ncr5380: Implement new eh_abort_handler")
---
 drivers/scsi/NCR5380.c       |   16 ++++++++--------
 drivers/scsi/atari_NCR5380.c |   16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)
drivers/scsi/NCR5380.c +8 -8
@@ -2302,6 +2302,9 @@ static bool list_del_cmd(struct list_hea
  * If cmd was not found at all then presumably it has already been completed,
  * in which case return SUCCESS to try to avoid further EH measures.
  * If the command has not completed yet, we must not fail to find it.
+ *
+ * The lock protects driver data structures, but EH handlers also use it
+ * to serialize their own execution and prevent their own re-entry.
  */
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
@@ -2338,14 +2341,11 @@ static int NCR5380_abort(struct scsi_cmn
 	if (list_del_cmd(&hostdata->disconnected, cmd)) {
 		dsprintk(NDEBUG_ABORT, instance,
 		         "abort: removed %p from disconnected list\n", cmd);
-		cmd->result = DID_ERROR << 16;
-		if (!hostdata->connected)
-			NCR5380_select(instance, cmd);
-		if (hostdata->connected != cmd) {
-			complete_cmd(instance, cmd);
-			result = FAILED;
-			goto out;
-		}
+		/* Can't call NCR5380_select() and send ABORT because that
+		 * means releasing the lock. Need a bus reset.
+		 */
+		result = FAILED;
+		goto out;
 	}
 
 	if (hostdata->connected == cmd) {
drivers/scsi/atari_NCR5380.c +8 -8
@@ -2497,6 +2497,9 @@ static bool list_del_cmd(struct list_hea
  * If cmd was not found at all then presumably it has already been completed,
  * in which case return SUCCESS to try to avoid further EH measures.
  * If the command has not completed yet, we must not fail to find it.
+ *
+ * The lock protects driver data structures, but EH handlers also use it
+ * to serialize their own execution and prevent their own re-entry.
  */
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
@@ -2533,14 +2536,11 @@ static int NCR5380_abort(struct scsi_cmn
 	if (list_del_cmd(&hostdata->disconnected, cmd)) {
 		dsprintk(NDEBUG_ABORT, instance,
 		         "abort: removed %p from disconnected list\n", cmd);
-		cmd->result = DID_ERROR << 16;
-		if (!hostdata->connected)
-			NCR5380_select(instance, cmd);
-		if (hostdata->connected != cmd) {
-			complete_cmd(instance, cmd);
-			result = FAILED;
-			goto out;
-		}
+		/* Can't call NCR5380_select() and send ABORT because that
+		 * means releasing the lock. Need a bus reset.
+		 */
+		result = FAILED;
+		goto out;
 	}
 
 	if (hostdata->connected == cmd) {
author maintainer
#44 lore raw

PATCH 41/238 ncr5380: Forget aborted commands

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit dc183965282d28c82f192e39cbfa91da85505a6f upstream.

The list structures and related logic used in the NCR5380 driver mean that a command cannot be queued twice (i.e. can't appear on more than one queue and can't appear on the same queue more than once).

The abort handler must forget the command so that the mid-layer can re-use it. E.g. the ML may send it back to the LLD via via scsi_eh_get_sense().

Fix this and also fix two error paths, so that commands get forgotten iff completed.

Fixes 8b00c3d5d40d ("ncr5380: Implement new eh_abort_handler")
---
 drivers/scsi/NCR5380.c       |   62 +++++++++++--------------------------------
 drivers/scsi/atari_NCR5380.c |   62 +++++++++++--------------------------------
 2 files changed, 34 insertions(+), 90 deletions(-)
drivers/scsi/NCR5380.c +17 -45
@@ -1796,6 +1796,7 @@ static void NCR5380_information_transfer
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
 				complete_cmd(instance, cmd);
+				hostdata->connected = NULL;
 				return;
 #endif
 			case PHASE_DATAIN:
@@ -1845,7 +1846,6 @@ static void NCR5380_information_transfer
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
-						complete_cmd(instance, cmd);
 						/* XXX - need to source or sink data here, as appropriate */
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
@@ -2294,14 +2294,14 @@ static bool list_del_cmd(struct list_hea
  * [disconnected -> connected ->]...
  * [autosense -> connected ->] done
  *
- * If cmd is unissued then just remove it.
- * If cmd is disconnected, try to select the target.
- * If cmd is connected, try to send an abort message.
- * If cmd is waiting for autosense, give it a chance to complete but check
- * that it isn't left connected.
  * If cmd was not found at all then presumably it has already been completed,
  * in which case return SUCCESS to try to avoid further EH measures.
+ *
  * If the command has not completed yet, we must not fail to find it.
+ * We have no option but to forget the aborted command (even if it still
+ * lacks sense data). The mid-layer may re-issue a command that is in error
+ * recovery (see scsi_send_eh_cmnd), but the logic and data structures in
+ * this driver are such that a command can appear on one queue only.
  *
  * The lock protects driver data structures, but EH handlers also use it
  * to serialize their own execution and prevent their own re-entry.
@@ -2327,6 +2327,7 @@ static int NCR5380_abort(struct scsi_cmn
 		         "abort: removed %p from issue queue\n", cmd);
 		cmd->result = DID_ABORT << 16;
 		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
+		goto out;
 	}
 
 	if (hostdata->selecting == cmd) {
@@ -2344,6 +2345,8 @@ static int NCR5380_abort(struct scsi_cmn
 		/* Can't call NCR5380_select() and send ABORT because that
 		 * means releasing the lock. Need a bus reset.
 		 */
+		set_host_byte(cmd, DID_ERROR);
+		complete_cmd(instance, cmd);
 		result = FAILED;
 		goto out;
 	}
@@ -2351,45 +2354,9 @@ static int NCR5380_abort(struct scsi_cmn
 	if (hostdata->connected == cmd) {
 		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
 		hostdata->connected = NULL;
-		if (do_abort(instance)) {
-			set_host_byte(cmd, DID_ERROR);
-			complete_cmd(instance, cmd);
-			result = FAILED;
-			goto out;
-		}
-		set_host_byte(cmd, DID_ABORT);
 #ifdef REAL_DMA
 		hostdata->dma_len = 0;
 #endif
-		if (cmd->cmnd[0] == REQUEST_SENSE)
-			complete_cmd(instance, cmd);
-		else {
-			struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-
-			/* Perform autosense for this command */
-			list_add(&ncmd->list, &hostdata->autosense);
-		}
-	}
-
-	if (list_find_cmd(&hostdata->autosense, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: found %p on sense queue\n", cmd);
-		spin_unlock_irqrestore(&hostdata->lock, flags);
-		queue_work(hostdata->work_q, &hostdata->main_task);
-		msleep(1000);
-		spin_lock_irqsave(&hostdata->lock, flags);
-		if (list_del_cmd(&hostdata->autosense, cmd)) {
-			dsprintk(NDEBUG_ABORT, instance,
-			         "abort: removed %p from sense queue\n", cmd);
-			set_host_byte(cmd, DID_ABORT);
-			complete_cmd(instance, cmd);
-			goto out;
-		}
-	}
-
-	if (hostdata->connected == cmd) {
-		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
-		hostdata->connected = NULL;
 		if (do_abort(instance)) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
@@ -2397,9 +2364,14 @@ static int NCR5380_abort(struct scsi_cmn
 			goto out;
 		}
 		set_host_byte(cmd, DID_ABORT);
-#ifdef REAL_DMA
-		hostdata->dma_len = 0;
-#endif
+		complete_cmd(instance, cmd);
+		goto out;
+	}
+
+	if (list_del_cmd(&hostdata->autosense, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: removed %p from sense queue\n", cmd);
+		set_host_byte(cmd, DID_ERROR);
 		complete_cmd(instance, cmd);
 	}
 
drivers/scsi/atari_NCR5380.c +17 -45

110 lines not on this page · raw message

author maintainer
#45 lore raw

PATCH 42/238 ncr5380: Fix NCR5380_select() EH checks and result handling

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit ccf6efd78317ef6265829c81a3e1a19f628b1a2d upstream.

Add missing checks for EH abort during arbitration and selection. Rework the handling of NCR5380_select() result to improve clarity.

Fixes 707d62b37fbb ("ncr5380: Fix EH during arbitration and selection")
---
 drivers/scsi/NCR5380.c       |   16 +++++++++++-----
 drivers/scsi/atari_NCR5380.c |   16 +++++++++++-----
 2 files changed, 22 insertions(+), 10 deletions(-)
drivers/scsi/NCR5380.c +11 -5
@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *cmd;
 	int done;
 
 	do {
 		done = 1;
 
 		spin_lock_irq(&hostdata->lock);
-		while (!hostdata->connected &&
-		       (cmd = dequeue_next_cmd(instance))) {
+		while (!hostdata->connected && !hostdata->selecting) {
+			struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
+
+			if (!cmd)
+				break;
 
 			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
 
@@ -840,8 +842,7 @@ static void NCR5380_main(struct work_str
 			 * entire unit.
 			 */
 
-			cmd = NCR5380_select(instance, cmd);
-			if (!cmd) {
+			if (!NCR5380_select(instance, cmd)) {
 				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 			} else {
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
@@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(
 		/* Reselection interrupt */
 		goto out;
 	}
+	if (!hostdata->selecting) {
+		/* Command was aborted */
+		NCR5380_write(MODE_REG, MR_BASE);
+		goto out;
+	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
drivers/scsi/atari_NCR5380.c +11 -5
@@ -923,7 +923,6 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *cmd;
 	int done;
 
 	/*
@@ -936,8 +935,11 @@ static void NCR5380_main(struct work_str
 		done = 1;
 
 		spin_lock_irq(&hostdata->lock);
-		while (!hostdata->connected &&
-		       (cmd = dequeue_next_cmd(instance))) {
+		while (!hostdata->connected && !hostdata->selecting) {
+			struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
+
+			if (!cmd)
+				break;
 
 			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
 
@@ -960,8 +962,7 @@ static void NCR5380_main(struct work_str
 #ifdef SUPPORT_TAGS
 			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-			cmd = NCR5380_select(instance, cmd);
-			if (!cmd) {
+			if (!NCR5380_select(instance, cmd)) {
 				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 				maybe_release_dma_irq(instance);
 			} else {
@@ -1257,6 +1258,11 @@ static struct scsi_cmnd *NCR5380_select(
 		/* Reselection interrupt */
 		goto out;
 	}
+	if (!hostdata->selecting) {
+		/* Command was aborted */
+		NCR5380_write(MODE_REG, MR_BASE);
+		goto out;
+	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
author maintainer
#46 lore raw

PATCH 43/238 ncr5380: Call scsi_eh_prep_cmnd() and scsi_eh_restore_cmnd() as and when appropriate

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <[email protected]>

commit 8d5dbec3bcb24a7d071962448e0fecaca8c75cc7 upstream.

This bug causes the wrong command to have its sense pointer overwritten, which sometimes leads to a NULL pointer deref. Fix this by checking which command is being requeued before restoring the scsi_eh_save data.

It turns out that some targets will disconnect a REQUEST SENSE command. The autosense algorithm doesn't anticipate this. Hence multiple commands can end up undergoing autosense simultaneously, and they will all try to use the same scsi_eh_save struct, which won't work. Defer autosense when the scsi_eh_save storage is in use by another command.

Fixes f27db8eb98a1 ("ncr5380: Fix autosense bugs")
---
 drivers/scsi/NCR5380.c       |    4 ++--
 drivers/scsi/atari_NCR5380.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/NCR5380.c +2 -2
@@ -760,7 +760,7 @@ static struct scsi_cmnd *dequeue_next_cm
 	struct NCR5380_cmd *ncmd;
 	struct scsi_cmnd *cmd;
 
-	if (list_empty(&hostdata->autosense)) {
+	if (hostdata->sensing || list_empty(&hostdata->autosense)) {
 		list_for_each_entry(ncmd, &hostdata->unissued, list) {
 			cmd = NCR5380_to_scmd(ncmd);
 			dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
@@ -793,7 +793,7 @@ static void requeue_cmd(struct Scsi_Host
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
-	if (hostdata->sensing) {
+	if (hostdata->sensing == cmd) {
 		scsi_eh_restore_cmnd(cmd, &hostdata->ses);
 		list_add(&ncmd->list, &hostdata->autosense);
 		hostdata->sensing = NULL;
drivers/scsi/atari_NCR5380.c +2 -2
@@ -862,7 +862,7 @@ static struct scsi_cmnd *dequeue_next_cm
 	struct NCR5380_cmd *ncmd;
 	struct scsi_cmnd *cmd;
 
-	if (list_empty(&hostdata->autosense)) {
+	if (hostdata->sensing || list_empty(&hostdata->autosense)) {
 		list_for_each_entry(ncmd, &hostdata->unissued, list) {
 			cmd = NCR5380_to_scmd(ncmd);
 			dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
@@ -901,7 +901,7 @@ static void requeue_cmd(struct Scsi_Host
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
-	if (hostdata->sensing) {
+	if (hostdata->sensing == cmd) {
 		scsi_eh_restore_cmnd(cmd, &hostdata->ses);
 		list_add(&ncmd->list, &hostdata->autosense);
 		hostdata->sensing = NULL;
author maintainer
#47 lore raw

PATCH 44/238 scsi: storvsc: fix SRB_STATUS_ABORTED handling

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vitaly Kuznetsov <[email protected]>

commit ff06c5ffbcb4ffa542fb80c897be977956fafecc upstream.

Commit 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB status flags") filtered SRB_STATUS_AUTOSENSE_VALID out effectively making the (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID) case a dead code. The logic from this branch (e.g. storvsc_device_scan() call) is still required, fix the check.

Fixes 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB status flags")
---
 drivers/scsi/storvsc_drv.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/storvsc_drv.c +3 -2
@@ -914,8 +914,9 @@ static void storvsc_handle_error(struct
 		do_work = true;
 		process_err_fn = storvsc_remove_lun;
 		break;
-	case (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID):
-		if ((asc == 0x2a) && (ascq == 0x9)) {
+	case SRB_STATUS_ABORTED:
+		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+		    (asc == 0x2a) && (ascq == 0x9)) {
 			do_work = true;
 			process_err_fn = storvsc_device_scan;
 			/*
author maintainer
#48 lore raw

PATCH 45/238 be2iscsi: set the boot_kset pointer to NULL in case of failure

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maurizio Lombardi <[email protected]>

commit 84bd64993f916bcf86270c67686ecf4cea7b8933 upstream.

In beiscsi_setup_boot_info(), the boot_kset pointer should be set to NULL in case of failure otherwise an invalid pointer dereference may occur later.

---
 drivers/scsi/be2iscsi/be_main.c |    1 +
 1 file changed, 1 insertion(+)
drivers/scsi/be2iscsi/be_main.c +1 -0
@@ -4468,6 +4468,7 @@ put_shost:
 	scsi_host_put(phba->shost);
 free_kset:
 	iscsi_boot_destroy_kset(phba->boot_kset);
+	phba->boot_kset = NULL;
 	return -ENOMEM;
 }
 
author maintainer
#49 lore raw

PATCH 46/238 aic7xxx: Fix queue depth handling

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan <[email protected]>

commit 5a51a7abca133860a6f4429655a9eda3c4afde32 upstream.

We were setting the queue depth correctly, then setting it back to two. If you hit this as a bisection point then please send me an email as it would imply we've been hiding other bugs with this one.

---
 drivers/scsi/aic7xxx/aic7xxx_osm.c |    1 +
 1 file changed, 1 insertion(+)
drivers/scsi/aic7xxx/aic7xxx_osm.c +1 -0
@@ -1336,6 +1336,7 @@ ahc_platform_set_tags(struct ahc_softc *
 	case AHC_DEV_Q_TAGGED:
 		scsi_change_queue_depth(sdev,
 				dev->openings + dev->active);
+		break;
 	default:
 		/*
 		 * We allow the OS to queue 2 untagged transactions to
author maintainer
#50 lore raw

PATCH 47/238 libnvdimm: Fix security issue with DSM IOCTL.

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jerry Hoemann <[email protected]>

commit 07accfa9d1a8bac8262f6d24a94a54d2d1f35149 upstream.

Code attempts to prevent certain IOCTL DSM from being called when device is opened read only. This security feature can be trivially overcome by changing the size portion of the ioctl_command which isn't used.

Check only the _IOC_NR (i.e. the command).

---
 drivers/nvdimm/bus.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/nvdimm/bus.c +4 -4
@@ -513,10 +513,10 @@ static int __nd_ioctl(struct nvdimm_bus
 
 	/* fail write commands (when read-only) */
 	if (read_only)
-		switch (ioctl_cmd) {
-		case ND_IOCTL_VENDOR:
-		case ND_IOCTL_SET_CONFIG_DATA:
-		case ND_IOCTL_ARS_START:
+		switch (cmd) {
+		case ND_CMD_VENDOR:
+		case ND_CMD_SET_CONFIG_DATA:
+		case ND_CMD_ARS_START:
 			dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
 					nvdimm ? nvdimm_cmd_name(cmd)
 					: nvdimm_bus_cmd_name(cmd));
author maintainer
#51 lore raw

PATCH 48/238 libnvdimm, pmem: fix kmap_atomic() leak in error path

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Williams <[email protected]>

commit b5ebc8ec693281c3c1efff7459a069cbd8b9a149 upstream.

When we enounter a bad block we need to kunmap_atomic() before returning.

---
 drivers/nvdimm/pmem.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/nvdimm/pmem.c +7 -4
@@ -66,22 +66,25 @@ static int pmem_do_bvec(struct pmem_devi
 			unsigned int len, unsigned int off, int rw,
 			sector_t sector)
 {
+	int rc = 0;
 	void *mem = kmap_atomic(page);
 	phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
 	void __pmem *pmem_addr = pmem->virt_addr + pmem_off;
 
 	if (rw == READ) {
 		if (unlikely(is_bad_pmem(&pmem->bb, sector, len)))
-			return -EIO;
-		memcpy_from_pmem(mem + off, pmem_addr, len);
-		flush_dcache_page(page);
+			rc = -EIO;
+		else {
+			memcpy_from_pmem(mem + off, pmem_addr, len);
+			flush_dcache_page(page);
+		}
 	} else {
 		flush_dcache_page(page);
 		memcpy_to_pmem(pmem_addr, mem + off, len);
 	}
 
 	kunmap_atomic(mem);
-	return 0;
+	return rc;
 }
 
 static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
author maintainer
#52 lore raw

PATCH 49/238 dm snapshot: disallow the COW and origin devices from being identical

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: DingXiang <[email protected]>

commit 4df2bf466a9c9c92f40d27c4aa9120f4e8227bfc upstream.

Otherwise loading a "snapshot" table using the same device for the origin and COW devices, e.g.:

echo "0 20971520 snapshot 253:3 253:3 P 8" | dmsetup create snap

will trigger:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000098
[ 1958.979934] IP: [<ffffffffa040efba>] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot]
[ 1958.989655] PGD 0
[ 1958.991903] Oops: 0000 [#1] SMP
...
[ 1959.059647] CPU: 9 PID: 3556 Comm: dmsetup Tainted: G          IO    4.5.0-rc5.snitm+ #150
...
[ 1959.083517] task: ffff8800b9660c80 ti: ffff88032a954000 task.ti: ffff88032a954000
[ 1959.091865] RIP: 0010:[<ffffffffa040efba>]  [<ffffffffa040efba>] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot]
[ 1959.104295] RSP: 0018:ffff88032a957b30  EFLAGS: 00010246
[ 1959.110219] RAX: 0000000000000000 RBX: 0000000000000008 RCX: 0000000000000001
[ 1959.118180] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff880329334a00
[ 1959.126141] RBP: ffff88032a957b50 R08: 0000000000000000 R09: 0000000000000001
[ 1959.134102] R10: 000000000000000a R11: f000000000000000 R12: ffff880330884d80
[ 1959.142061] R13: 0000000000000008 R14: ffffc90001c13088 R15: ffff880330884d80
[ 1959.150021] FS:  00007f8926ba3840(0000) GS:ffff880333440000(0000) knlGS:0000000000000000
[ 1959.159047] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1959.165456] CR2: 0000000000000098 CR3: 000000032f48b000 CR4: 00000000000006e0
[ 1959.173415] Stack:
[ 1959.175656]  ffffc90001c13040 ffff880329334a00 ffff880330884ed0 ffff88032a957bdc
[ 1959.183946]  ffff88032a957bb8 ffffffffa040f225 ffff880329334a30 ffff880300000000
[ 1959.192233]  ffffffffa04133e0 ffff880329334b30 0000000830884d58 00000000569c58cf
[ 1959.200521] Call Trace:
[ 1959.203248]  [<ffffffffa040f225>] dm_exception_store_create+0x1d5/0x240 [dm_snapshot]
[ 1959.211986]  [<ffffffffa040d310>] snapshot_ctr+0x140/0x630 [dm_snapshot]
[ 1959.219469]  [<ffffffffa0005c44>] ? dm_split_args+0x64/0x150 [dm_mod]
[ 1959.226656]  [<ffffffffa0005ea7>] dm_table_add_target+0x177/0x440 [dm_mod]
[ 1959.234328]  [<ffffffffa0009203>] table_load+0x143/0x370 [dm_mod]
[ 1959.241129]  [<ffffffffa00090c0>] ? retrieve_status+0x1b0/0x1b0 [dm_mod]
[ 1959.248607]  [<ffffffffa0009e35>] ctl_ioctl+0x255/0x4d0 [dm_mod]
[ 1959.255307]  [<ffffffff813304e2>] ? memzero_explicit+0x12/0x20
[ 1959.261816]  [<ffffffffa000a0c3>] dm_ctl_ioctl+0x13/0x20 [dm_mod]
[ 1959.268615]  [<ffffffff81215eb6>] do_vfs_ioctl+0xa6/0x5c0
[ 1959.274637]  [<ffffffff81120d2f>] ? __audit_syscall_entry+0xaf/0x100
[ 1959.281726]  [<ffffffff81003176>] ? do_audit_syscall_entry+0x66/0x70
[ 1959.288814]  [<ffffffff81216449>] SyS_ioctl+0x79/0x90
[ 1959.294450]  [<ffffffff8167e4ae>] entry_SYSCALL_64_fastpath+0x12/0x71
...
[ 1959.323277] RIP  [<ffffffffa040efba>] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot]
[ 1959.333090]  RSP <ffff88032a957b30>
[ 1959.336978] CR2: 0000000000000098
[ 1959.344121] ---[ end trace b049991ccad1169e ]---
---
 drivers/md/dm-snap.c          |    9 +++++++++
 drivers/md/dm-table.c         |   36 ++++++++++++++++++++++++------------
 include/linux/device-mapper.h |    2 ++
 3 files changed, 35 insertions(+), 12 deletions(-)
drivers/md/dm-snap.c +9 -0
@@ -1105,6 +1105,7 @@ static int snapshot_ctr(struct dm_target
 	int i;
 	int r = -EINVAL;
 	char *origin_path, *cow_path;
+	dev_t origin_dev, cow_dev;
 	unsigned args_used, num_flush_bios = 1;
 	fmode_t origin_mode = FMODE_READ;
 
@@ -1135,11 +1136,19 @@ static int snapshot_ctr(struct dm_target
 		ti->error = "Cannot get origin device";
 		goto bad_origin;
 	}
+	origin_dev = s->origin->bdev->bd_dev;
 
 	cow_path = argv[0];
 	argv++;
 	argc--;
 
+	cow_dev = dm_get_dev_t(cow_path);
+	if (cow_dev && cow_dev == origin_dev) {
+		ti->error = "COW device cannot be the same as origin device";
+		r = -EINVAL;
+		goto bad_cow;
+	}
+
 	r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow);
 	if (r) {
 		ti->error = "Cannot get COW device";
drivers/md/dm-table.c +24 -12
@@ -365,6 +365,26 @@ static int upgrade_mode(struct dm_dev_in
 }
 
 /*
+ * Convert the path to a device
+ */
+dev_t dm_get_dev_t(const char *path)
+{
+	dev_t uninitialized_var(dev);
+	struct block_device *bdev;
+
+	bdev = lookup_bdev(path);
+	if (IS_ERR(bdev))
+		dev = name_to_dev_t(path);
+	else {
+		dev = bdev->bd_dev;
+		bdput(bdev);
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(dm_get_dev_t);
+
+/*
  * Add a device to the list, or just increment the usage count if
  * it's already present.
  */
@@ -372,23 +392,15 @@ int dm_get_device(struct dm_target *ti,
 		  struct dm_dev **result)
 {
 	int r;
-	dev_t uninitialized_var(dev);
+	dev_t dev;
 	struct dm_dev_internal *dd;
 	struct dm_table *t = ti->table;
-	struct block_device *bdev;
 
 	BUG_ON(!t);
 
-	/* convert the path to a device */
-	bdev = lookup_bdev(path);
-	if (IS_ERR(bdev)) {
-		dev = name_to_dev_t(path);
-		if (!dev)
-			return -ENODEV;
-	} else {
-		dev = bdev->bd_dev;
-		bdput(bdev);
-	}
+	dev = dm_get_dev_t(path);
+	if (!dev)
+		return -ENODEV;
 
 	dd = find_device(&t->devices, dev);
 	if (!dd) {
include/linux/device-mapper.h +2 -0
@@ -124,6 +124,8 @@ struct dm_dev {
 	char name[16];
 };
 
+dev_t dm_get_dev_t(const char *path);
+
 /*
  * Constructors should call these functions to ensure destination devices
  * are opened/closed correctly.
author maintainer
#53 lore raw

PATCH 50/238 dm: fix excessive dm-mq context switching

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mike Snitzer <[email protected]>

commit 6acfe68bac7e6f16dc312157b1fa6e2368985013 upstream.

Request-based DM's blk-mq support (dm-mq) was reported to be 50% slower than if an underlying null_blk device were used directly. One of the reasons for this drop in performance is that blk_insert_clone_request() was calling blk_mq_insert_request() with @async=true. This forced the use of kblockd_schedule_delayed_work_on() to run the blk-mq hw queues which ushered in ping-ponging between process context (fio in this case) and kblockd's kworker to submit the cloned request. The ftrace function_graph tracer showed:

kworker-2013 => fio-12190
fio-12190 => kworker-2013
...
kworker-2013 => fio-12190
fio-12190 => kworker-2013
...

Fixing blk_insert_clone_request()'s blk_mq_insert_request() call to _not_ use kblockd to submit the cloned requests isn't enough to eliminate the observed context switches.

In addition to this dm-mq specific blk-core fix, there are 2 DM core fixes to dm-mq that (when paired with the blk-core fix) completely eliminate the observed context switching:

1) don't blk_mq_run_hw_queues in blk-mq request completion

Motivated by desire to reduce overhead of dm-mq, punting to kblockd just increases context switches.

In my testing against a really fast null_blk device there was no benefit to running blk_mq_run_hw_queues() on completion (and no other blk-mq driver does this). So hopefully this change doesn't induce the need for yet another revert like commit 621739b00e16ca2d !

2) use blk_mq_complete_request() in dm_complete_request()

blk_complete_request() doesn't offer the traditional q->mq_ops vs .request_fn branching pattern that other historic block interfaces do (e.g. blk_get_request). Using blk_mq_complete_request() for blk-mq requests is important for performance. It should be noted that, like blk_complete_request(), blk_mq_complete_request() doesn't natively handle partial completions -- but the request-based DM-multipath target does provide the required partial completion support by dm.c:end_clone_bio() triggering requeueing of the request via dm-mpath.c:multipath_end_io()'s return of DM_ENDIO_REQUEUE.

dm-mq fix #2 is _much_ more important than #1 for eliminating the context switches.

Before: cpu          : usr=15.10%, sys=59.39%, ctx=7905181, majf=0, minf=475
After:  cpu          : usr=20.60%, sys=79.35%, ctx=2008, majf=0, minf=472

With these changes multithreaded async read IOPs improved from ~950K to ~1350K for this dm-mq stacked on null_blk test-case. The raw read IOPs of the underlying null_blk device for the same workload is ~1950K.

Fixes 7fb4898e0 ("block: add blk-mq support to blk_insert_cloned_request()")
Fixes bfebd1cdb ("dm: add full blk-mq support to request-based DM")
---
 block/blk-core.c |    2 +-
 drivers/md/dm.c  |   13 ++++++-------
 2 files changed, 7 insertions(+), 8 deletions(-)
block/blk-core.c +1 -1
@@ -2198,7 +2198,7 @@ int blk_insert_cloned_request(struct req
 	if (q->mq_ops) {
 		if (blk_queue_io_stat(q))
 			blk_account_io_start(rq, true);
-		blk_mq_insert_request(rq, false, true, true);
+		blk_mq_insert_request(rq, false, true, false);
 		return 0;
 	}
 
drivers/md/dm.c +6 -7
@@ -1109,12 +1109,8 @@ static void rq_completed(struct mapped_d
 	 * back into ->request_fn() could deadlock attempting to grab the
 	 * queue lock again.
 	 */
-	if (run_queue) {
-		if (md->queue->mq_ops)
-			blk_mq_run_hw_queues(md->queue, true);
-		else
-			blk_run_queue_async(md->queue);
-	}
+	if (!md->queue->mq_ops && run_queue)
+		blk_run_queue_async(md->queue);
 
 	/*
 	 * dm_put() must be at the end of this function. See the comment above
@@ -1336,7 +1332,10 @@ static void dm_complete_request(struct r
 	struct dm_rq_target_io *tio = tio_from_request(rq);
 
 	tio->error = error;
-	blk_complete_request(rq);
+	if (!rq->q->mq_ops)
+		blk_complete_request(rq);
+	else
+		blk_mq_complete_request(rq, error);
 }
 
 /*
author maintainer
#54 lore raw

PATCH 51/238 dm thin metadata: dont issue prefetches if a transaction abort has failed

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joe Thornber <[email protected]>

commit 2eae9e4489b4cf83213fa3bd508b5afca3f01780 upstream.

If a transaction abort has failed then we can no longer use the metadata device. Typically this happens if the superblock is unreadable.

This fix addresses a crash seen during metadata device failure testing.

Fixes 8a01a6af75 ("dm thin: prefetch missing metadata pages")
---
 drivers/md/dm-thin-metadata.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/md/dm-thin-metadata.c +4 -1
@@ -1981,5 +1981,8 @@ bool dm_pool_metadata_needs_check(struct
 
 void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd)
 {
-	dm_tm_issue_prefetches(pmd->tm);
+	down_read(&pmd->root_lock);
+	if (!pmd->fail_io)
+		dm_tm_issue_prefetches(pmd->tm);
+	up_read(&pmd->root_lock);
 }
author maintainer
#55 lore raw

PATCH 52/238 dm cache: make sure every metadata function checks fail_io

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joe Thornber <[email protected]>

commit d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b upstream.

Otherwise operations may be attempted that will only ever go on to crash (since the metadata device is either missing or unreliable if 'fail_io' is set).

---
 drivers/md/dm-cache-metadata.c |   98 ++++++++++++++++++++++++-----------------
 drivers/md/dm-cache-metadata.h |    4 -
 drivers/md/dm-cache-target.c   |   12 ++++-
 3 files changed, 71 insertions(+), 43 deletions(-)
drivers/md/dm-cache-metadata.c +59 -39
@@ -867,19 +867,40 @@ static int blocks_are_unmapped_or_clean(
 	return 0;
 }
 
-#define WRITE_LOCK(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+#define WRITE_LOCK(cmd)	\
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \
 		return -EINVAL; \
-	down_write(&cmd->root_lock)
+	}
 
 #define WRITE_LOCK_VOID(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \
 		return; \
-	down_write(&cmd->root_lock)
+	}
 
 #define WRITE_UNLOCK(cmd) \
 	up_write(&cmd->root_lock)
 
+#define READ_LOCK(cmd) \
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_read(&cmd->root_lock); \
+		return -EINVAL; \
+	}
+
+#define READ_LOCK_VOID(cmd)	\
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_read(&cmd->root_lock); \
+		return; \
+	}
+
+#define READ_UNLOCK(cmd) \
+	up_read(&cmd->root_lock)
+
 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
 {
 	int r;
@@ -1015,22 +1036,20 @@ int dm_cache_load_discards(struct dm_cac
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = __load_discards(cmd, fn, context);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
 
-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd)
+int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result)
 {
-	dm_cblock_t r;
+	READ_LOCK(cmd);
+	*result = cmd->cache_blocks;
+	READ_UNLOCK(cmd);
 
-	down_read(&cmd->root_lock);
-	r = cmd->cache_blocks;
-	up_read(&cmd->root_lock);
-
-	return r;
+	return 0;
 }
 
 static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
@@ -1188,9 +1207,9 @@ int dm_cache_load_mappings(struct dm_cac
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = __load_mappings(cmd, policy, fn, context);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1215,18 +1234,18 @@ static int __dump_mappings(struct dm_cac
 
 void dm_cache_dump(struct dm_cache_metadata *cmd)
 {
-	down_read(&cmd->root_lock);
+	READ_LOCK_VOID(cmd);
 	__dump_mappings(cmd);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 }
 
 int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd)
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = cmd->changed;
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1276,9 +1295,9 @@ int dm_cache_set_dirty(struct dm_cache_m
 void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd,
 				 struct dm_cache_statistics *stats)
 {
-	down_read(&cmd->root_lock);
+	READ_LOCK_VOID(cmd);
 	*stats = cmd->stats;
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 }
 
 void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
@@ -1312,9 +1331,9 @@ int dm_cache_get_free_metadata_block_cou
 {
 	int r = -EINVAL;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = dm_sm_get_nr_free(cmd->metadata_sm, result);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1324,9 +1343,9 @@ int dm_cache_get_metadata_dev_size(struc
 {
 	int r = -EINVAL;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1417,7 +1436,13 @@ int dm_cache_write_hints(struct dm_cache
 
 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result)
 {
-	return blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+	int r;
+
+	READ_LOCK(cmd);
+	r = blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+	READ_UNLOCK(cmd);
+
+	return r;
 }
 
 void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd)
@@ -1440,10 +1465,7 @@ int dm_cache_metadata_set_needs_check(st
 	struct dm_block *sblock;
 	struct cache_disk_superblock *disk_super;
 
-	/*
-	 * We ignore fail_io for this function.
-	 */
-	down_write(&cmd->root_lock);
+	WRITE_LOCK(cmd);
 	set_bit(NEEDS_CHECK, &cmd->flags);
 
 	r = superblock_lock(cmd, &sblock);
@@ -1458,19 +1480,17 @@ int dm_cache_metadata_set_needs_check(st
 	dm_bm_unlock(sblock);
 
 out:
-	up_write(&cmd->root_lock);
+	WRITE_UNLOCK(cmd);
 	return r;
 }
 
-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd)
+int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
 {
-	bool needs_check;
+	READ_LOCK(cmd);
+	*result = !!test_bit(NEEDS_CHECK, &cmd->flags);
+	READ_UNLOCK(cmd);
 
-	down_read(&cmd->root_lock);
-	needs_check = !!test_bit(NEEDS_CHECK, &cmd->flags);
-	up_read(&cmd->root_lock);
-
-	return needs_check;
+	return 0;
 }
 
 int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
drivers/md/dm-cache-metadata.h +2 -2
@@ -66,7 +66,7 @@ void dm_cache_metadata_close(struct dm_c
  * origin blocks to map to.
  */
 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size);
-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd);
+int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result);
 
 int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
 				   sector_t discard_block_size,
@@ -137,7 +137,7 @@ int dm_cache_write_hints(struct dm_cache
  */
 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result);
 
-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd);
+int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result);
 int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd);
 void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd);
 void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd);
drivers/md/dm-cache-target.c +10 -2
@@ -984,9 +984,14 @@ static void notify_mode_switch(struct ca
 
 static void set_cache_mode(struct cache *cache, enum cache_metadata_mode new_mode)
 {
-	bool needs_check = dm_cache_metadata_needs_check(cache->cmd);
+	bool needs_check;
 	enum cache_metadata_mode old_mode = get_cache_mode(cache);
 
+	if (dm_cache_metadata_needs_check(cache->cmd, &needs_check)) {
+		DMERR("unable to read needs_check flag, setting failure mode");
+		new_mode = CM_FAIL;
+	}
+
 	if (new_mode == CM_WRITE && needs_check) {
 		DMERR("%s: unable to switch cache to write mode until repaired.",
 		      cache_device_name(cache));
@@ -3510,6 +3515,7 @@ static void cache_status(struct dm_targe
 	char buf[BDEVNAME_SIZE];
 	struct cache *cache = ti->private;
 	dm_cblock_t residency;
+	bool needs_check;
 
 	switch (type) {
 	case STATUSTYPE_INFO:
@@ -3583,7 +3589,9 @@ static void cache_status(struct dm_targe
 		else
 			DMEMIT("rw ");
 
-		if (dm_cache_metadata_needs_check(cache->cmd))
+		r = dm_cache_metadata_needs_check(cache->cmd, &needs_check);
+
+		if (r || needs_check)
 			DMEMIT("needs_check ");
 		else
 			DMEMIT("- ");
#56 lore raw

Re: [PATCH 4.5 052/238] dm cache: make sure every metadata function checks fail_io

Quoted 1 line · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

I've dropped stable because this isn't actually broken, but...

Quoted 42 lines

------------------

From: Joe Thornber <[email protected]>

commit d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b upstream.

Otherwise operations may be attempted that will only ever go on to crash (since the metadata device is either missing or unreliable if 'fail_io' is set).

---
 drivers/md/dm-cache-metadata.c |   98 ++++++++++++++++++++++++----------------- drivers/md/dm-cache-metadata.h |    4 - drivers/md/dm-cache-target.c   |   12 ++++-

 3 files changed, 71 insertions(+), 43 deletions(-)
drivers/md/dm-cache-metadata.c +0 -0
@@ -867,19 +867,40 @@ static int blocks_are_unmapped_or_clean(
  	return 0;
  }

drivers/md/dm-cache-metadata.c +4 -2
-#define WRITE_LOCK(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+#define WRITE_LOCK(cmd)	\
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \

  return -EINVAL; \

drivers/md/dm-cache-metadata.c +1 -1
-	down_write(&cmd->root_lock)
+	}


 #define WRITE_LOCK_VOID(cmd) \

drivers/md/dm-cache-metadata.c +3 -1
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \

  return; \

drivers/md/dm-cache-metadata.c

Quoted 2 lines
drivers/md/dm-cache-metadata.c +1 -1
-	down_write(&cmd->root_lock)
+	}

Whenever a macro expands to multiple statements they should be wrapped up in do { ... } while (0) so the macro is safe to use in other compound statements.

That's not a regression for these existing macros, but:

Quoted 6 lines

 #define WRITE_UNLOCK(cmd) \
  up_write(&cmd->root_lock)

drivers/md/dm-cache-metadata.c +3 -0
+#define READ_LOCK(cmd) \
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \

drivers/md/dm-cache-metadata.c static int blocks_are_unmapped_or_clean( · line 899

Quoted 10 lines
drivers/md/dm-cache-metadata.c +10 -0
+		up_read(&cmd->root_lock); \
+		return -EINVAL; \
+	}
+
+#define READ_LOCK_VOID(cmd)	\
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_read(&cmd->root_lock); \
+		return; \
+	}

[...]

here you're repeating the same broken pattern in new macros.  Which checkpatch.pl would have complained about, if you'd thought to run it.

Hiding return statements in macros is another bad idea (who expects exceptions in C?).  And once we reject that bad idea, all these macros can be inline functions, like:

static inline bool dm_cm_read_lock(struct dm_cache_metadata *cmd)

{
	down_read(&cmd->root_lock);
	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
		up_read(&cmd->root_lock);
		return false;
	}
	return true;
}

/* ... */

	if (!dm_cm_read_lock(cmd))
		return -EINVAL;

Actually... I said this wasn't broken, but should the READ_LOCK macros really fail in case dm_bm_is_read_only(), or only if cmd->fail_io?

Ben.

--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.

#57 lore raw

Re: [PATCH 4.5 052/238] dm cache: make sure every metadata function checks fail_io

Quoted 91 lines · Ben Hutchings
Quoted 1 line · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

I've dropped stable because this isn't actually broken, but...

Quoted 42 lines

------------------

From: Joe Thornber <[email protected]>

commit d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b upstream.

Otherwise operations may be attempted that will only ever go on to crash (since the metadata device is either missing or unreliable if 'fail_io' is set).

---
 drivers/md/dm-cache-metadata.c |   98 ++++++++++++++++++++++++----------------- drivers/md/dm-cache-metadata.h |    4 - drivers/md/dm-cache-target.c   |   12 ++++-

 3 files changed, 71 insertions(+), 43 deletions(-)
drivers/md/dm-cache-metadata.c +0 -0
@@ -867,19 +867,40 @@ static int blocks_are_unmapped_or_clean(
  	return 0;
  }

drivers/md/dm-cache-metadata.c +4 -2
-#define WRITE_LOCK(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+#define WRITE_LOCK(cmd)	\
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \

  return -EINVAL; \

drivers/md/dm-cache-metadata.c +1 -1
-	down_write(&cmd->root_lock)
+	}


 #define WRITE_LOCK_VOID(cmd) \

drivers/md/dm-cache-metadata.c +3 -1
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
+	down_write(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_write(&cmd->root_lock); \

  return; \

drivers/md/dm-cache-metadata.c

Quoted 2 lines
drivers/md/dm-cache-metadata.c +1 -1
-	down_write(&cmd->root_lock)
+	}

Whenever a macro expands to multiple statements they should be wrapped up in do { ... } while (0) so the macro is safe to use in other compound statements.

That's not a regression for these existing macros, but:

Quoted 6 lines

 #define WRITE_UNLOCK(cmd) \
  up_write(&cmd->root_lock)

drivers/md/dm-cache-metadata.c +3 -0
+#define READ_LOCK(cmd) \
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \

drivers/md/dm-cache-metadata.c static int blocks_are_unmapped_or_clean( · line 899

Quoted 10 lines
drivers/md/dm-cache-metadata.c +10 -0
+		up_read(&cmd->root_lock); \
+		return -EINVAL; \
+	}
+
+#define READ_LOCK_VOID(cmd)	\
+	down_read(&cmd->root_lock); \
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
+		up_read(&cmd->root_lock); \
+		return; \
+	}

[...]

here you're repeating the same broken pattern in new macros.  Which checkpatch.pl would have complained about, if you'd thought to run it.

Hiding return statements in macros is another bad idea (who expects exceptions in C?).  And once we reject that bad idea, all these macros can be inline functions, like:

static inline bool dm_cm_read_lock(struct dm_cache_metadata *cmd)

{
	down_read(&cmd->root_lock);
	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
		up_read(&cmd->root_lock);
		return false;
	}
	return true;
}
Quoted 7 lines

/* ... */

	if (!dm_cm_read_lock(cmd))
		return -EINVAL;

Actually... I said this wasn't broken, but should the READ_LOCK macros really fail in case dm_bm_is_read_only(), or only if cmd->fail_io?

Thanks for the report!

I've staged this to go to Linus by the end of the week:
https://git.kernel.org/cgit/linux/kernel/git/device-mapper/linux-dm.git/commit/?h=dm-4.6&id=a64204672859248c89c8df796421442fb41e59ec

author maintainer
#58 lore raw

PATCH 53/238 dm: fix rq_end_stats() NULL pointer in dm_requeue_original_request()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryn M. Reeves <[email protected]>

commit 98dbc9c6c61698792e3a66f32f3bf066201d42d7 upstream.

An "old" (.request_fn) DM 'struct request' stores a pointer to the associated 'struct dm_rq_target_io' in rq->special.

dm_requeue_original_request(), previously named dm_requeue_unmapped_original_request(), called dm_unprep_request() to reset rq->special to NULL. But rq_end_stats() would go on to hit a NULL pointer deference because its call to tio_from_request() returned NULL.

Fix this by calling rq_end_stats() _before_ dm_unprep_request()

Fixes e262f34741 ("dm stats: add support for request-based DM devices")
---
 drivers/md/dm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm.c +1 -1
@@ -1210,9 +1210,9 @@ static void dm_requeue_original_request(
 {
 	int rw = rq_data_dir(rq);
 
+	rq_end_stats(md, rq);
 	dm_unprep_request(rq);
 
-	rq_end_stats(md, rq);
 	if (!rq->q->mq_ops)
 		old_requeue_request(rq);
 	else {
author maintainer
#59 lore raw

PATCH 54/238 usb: retry reset if a device times out

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 264904ccc33c604d4b3141bbd33808152dfac45b upstream.

Some devices I got show an inability to operate right after power on if they are already connected. They are beyond recovery if the descriptors are requested multiple times. So in case of a timeout we rather bail early and reset again. But it must be done only on the first loop lest we get into a reset/time out spiral that can be overcome with a retry.

This patch is a rework of a patch that fell through the cracks.
http://www.spinics.net/lists/linux-usb/msg103263.html

---
 drivers/usb/core/hub.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/core/hub.c +7 -1
@@ -4441,7 +4441,13 @@ hub_port_init(struct usb_hub *hub, struc
 						r = -EPROTO;
 					break;
 				}
-				if (r == 0)
+				/*
+				 * Some devices time out if they are powered on
+				 * when already connected. They need a second
+				 * reset. But only on the first attempt,
+				 * lest we get into a time out/reset loop
+				 */
+				if (r == 0  || (r == -ETIMEDOUT && j == 0))
 					break;
 			}
 			udev->descriptor.bMaxPacketSize0 =
author maintainer
#60 lore raw

PATCH 55/238 usb: hub: fix a typo in hub_port_init() leading to wrong logic

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 0d5ce778c43bf888328231bcdce05d5c860655aa upstream.

A typo of j for i led to a logic bug. To rule out future confusion, the variable names are made meaningful.

---
 drivers/usb/core/hub.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/usb/core/hub.c +5 -5
@@ -4292,7 +4292,7 @@ hub_port_init(struct usb_hub *hub, struc
 {
 	struct usb_device	*hdev = hub->hdev;
 	struct usb_hcd		*hcd = bus_to_hcd(hdev->bus);
-	int			i, j, retval;
+	int			retries, operations, retval, i;
 	unsigned		delay = HUB_SHORT_RESET_TIME;
 	enum usb_device_speed	oldspeed = udev->speed;
 	const char		*speed;
@@ -4394,7 +4394,7 @@ hub_port_init(struct usb_hub *hub, struc
 	 * first 8 bytes of the device descriptor to get the ep0 maxpacket
 	 * value.
 	 */
-	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+	for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) {
 		bool did_new_scheme = false;
 
 		if (use_new_scheme(udev, retry_counter)) {
@@ -4421,7 +4421,7 @@ hub_port_init(struct usb_hub *hub, struc
 			 * 255 is for WUSB devices, we actually need to use
 			 * 512 (WUSB1.0[4.8.1]).
 			 */
-			for (j = 0; j < 3; ++j) {
+			for (operations = 0; operations < 3; ++operations) {
 				buf->bMaxPacketSize0 = 0;
 				r = usb_control_msg(udev, usb_rcvaddr0pipe(),
 					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
@@ -4447,7 +4447,7 @@ hub_port_init(struct usb_hub *hub, struc
 				 * reset. But only on the first attempt,
 				 * lest we get into a time out/reset loop
 				 */
-				if (r == 0  || (r == -ETIMEDOUT && j == 0))
+				if (r == 0  || (r == -ETIMEDOUT && retries == 0))
 					break;
 			}
 			udev->descriptor.bMaxPacketSize0 =
@@ -4479,7 +4479,7 @@ hub_port_init(struct usb_hub *hub, struc
 		 * authorization will assign the final address.
 		 */
 		if (udev->wusb == 0) {
-			for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
+			for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) {
 				retval = hub_set_address(udev, devnum);
 				if (retval >= 0)
 					break;
author maintainer
#61 lore raw

PATCH 56/238 USB: uas: Reduce can_queue to MAX_CMNDS

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 55ff8cfbc4e12a7d2187df523938cc671fbebdd1 upstream.

The uas driver can never queue more then MAX_CMNDS (- 1) tags and tags are shared between luns, so there is no need to claim that we can_queue some random large number.

Not claiming that we can_queue 65536 commands, fixes the uas driver failing to initialize while allocating the tag map with a "Page allocation failure (order 7)" error on systems which have been running for a while and thus have fragmented memory.

---
 drivers/usb/storage/uas.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/uas.c +1 -1
@@ -812,7 +812,7 @@ static struct scsi_host_template uas_hos
 	.slave_configure = uas_slave_configure,
 	.eh_abort_handler = uas_eh_abort_handler,
 	.eh_bus_reset_handler = uas_eh_bus_reset_handler,
-	.can_queue = 65536,	/* Is there a limit on the _host_ ? */
+	.can_queue = MAX_CMNDS,
 	.this_id = -1,
 	.sg_tablesize = SG_NONE,
 	.skip_settle_delay = 1,
author maintainer
#62 lore raw

PATCH 57/238 USB: cdc-acm: more sanity checking

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 8835ba4a39cf53f705417b3b3a94eb067673f2c9 upstream.

An attack has become available which pretends to be a quirky device circumventing normal sanity checks and crashes the kernel by an insufficient number of interfaces. This patch adds a check to the code path for quirky devices.

---
 drivers/usb/class/cdc-acm.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/class/cdc-acm.c +3 -0
@@ -1114,6 +1114,9 @@ static int acm_probe(struct usb_interfac
 	if (quirks == NO_UNION_NORMAL) {
 		data_interface = usb_ifnum_to_if(usb_dev, 1);
 		control_interface = usb_ifnum_to_if(usb_dev, 0);
+		/* we would crash */
+		if (!data_interface || !control_interface)
+			return -ENODEV;
 		goto skip_normal_probe;
 	}
 
author maintainer
#63 lore raw

PATCH 58/238 USB: iowarrior: fix oops with malicious USB descriptors

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Boyer <[email protected]>

commit 4ec0ef3a82125efc36173062a50624550a900ae0 upstream.

The iowarrior driver expects at least one valid endpoint. If given malicious descriptors that specify 0 for the number of endpoints, it will crash in the probe function. Ensure there is at least one endpoint on the interface before using it.

The full report of this issue can be found here:
http://seclists.org/bugtraq/2016/Mar/87

---
 drivers/usb/misc/iowarrior.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/misc/iowarrior.c +6 -0
@@ -787,6 +787,12 @@ static int iowarrior_probe(struct usb_in
 	iface_desc = interface->cur_altsetting;
 	dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
 
+	if (iface_desc->desc.bNumEndpoints < 1) {
+		dev_err(&interface->dev, "Invalid number of endpoints\n");
+		retval = -EINVAL;
+		goto error;
+	}
+
 	/* set up the endpoint information */
 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 		endpoint = &iface_desc->endpoint[i].desc;
#64 lore raw

Re: [PATCH 4.5 058/238] USB: iowarrior: fix oops with malicious USB descriptors

Quoted 4 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

Quoted 8 lines

From: Josh Boyer <[email protected]>

commit 4ec0ef3a82125efc36173062a50624550a900ae0 upstream.

The iowarrior driver expects at least one valid endpoint.  If given malicious descriptors that specify 0 for the number of endpoints, it will crash in the probe function.  Ensure there is at least one endpoint on the interface before using it.

[...]

Which means our imaginary attacker will move on to providing a single endpoint of the wrong type.  You've fixed the driver to reject the PoC descriptor without thinking about what the driver actually requires.

I don't see the point of applying this to stable; it doesn't provide any meaningful security benefit.

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#65 lore raw

Re: [PATCH 4.5 058/238] USB: iowarrior: fix oops with malicious USB descriptors

Quoted 14 lines · Ben Hutchings
Quoted 4 lines · Greg Kroah-Hartman

4.5-stable review patch.��If anyone has any objections, please let me know.

------------------

Quoted 8 lines

From: Josh Boyer <[email protected]>

commit 4ec0ef3a82125efc36173062a50624550a900ae0 upstream.

The iowarrior driver expects at least one valid endpoint.��If given malicious descriptors that specify 0 for the number of endpoints, it will crash in the probe function.��Ensure there is at least one endpoint on the interface before using it.

Quoted 8 lines

[...]

Which means our imaginary attacker will move on to providing a single endpoint of the wrong type. �You've fixed the driver to reject the PoC descriptor without thinking about what the driver actually requires.

I don't see the point of applying this to stable; it doesn't provide any meaningful security benefit.

Well, it's one hurdle down, but yes, it needs to be fixed "correctly" Ideally all of these types of issues can be fixed in the USB core, I just need to carve out some time to resolve them, but for now, let's stay in sync with Linus's tree for this patch.

thanks,

greg k-h

author maintainer
#66 lore raw

PATCH 59/238 USB: usb_driver_claim_interface: add sanity checking

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 0b818e3956fc1ad976bee791eadcbb3b5fec5bfd upstream.

Attacks that trick drivers into passing a NULL pointer to usb_driver_claim_interface() using forged descriptors are known. This thwarts them by sanity checking.

---
 drivers/usb/core/driver.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/core/driver.c +5 -1
@@ -502,11 +502,15 @@ static int usb_unbind_interface(struct d
 int usb_driver_claim_interface(struct usb_driver *driver,
 				struct usb_interface *iface, void *priv)
 {
-	struct device *dev = &iface->dev;
+	struct device *dev;
 	struct usb_device *udev;
 	int retval = 0;
 	int lpm_disable_error;
 
+	if (!iface)
+		return -ENODEV;
+
+	dev = &iface->dev;
 	if (dev->driver)
 		return -EBUSY;
 
author maintainer
#67 lore raw

PATCH 60/238 USB: mct_u232: add sanity checking in probe

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 4e9a0b05257f29cf4b75f3209243ed71614d062e upstream.

An attack using the lack of sanity checking in probe is known. This patch checks for the existence of a second port.

CVE-2016-3136

---
 drivers/usb/serial/mct_u232.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/usb/serial/mct_u232.c +8 -1
@@ -376,14 +376,21 @@ static void mct_u232_msr_to_state(struct
 
 static int mct_u232_port_probe(struct usb_serial_port *port)
 {
+	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv;
 
+	/* check first to simplify error handling */
+	if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
+		dev_err(&port->dev, "expected endpoint missing\n");
+		return -ENODEV;
+	}
+
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	/* Use second interrupt-in endpoint for reading. */
-	priv->read_urb = port->serial->port[1]->interrupt_in_urb;
+	priv->read_urb = serial->port[1]->interrupt_in_urb;
 	priv->read_urb->context = port;
 
 	spin_lock_init(&priv->lock);
author maintainer
#68 lore raw

PATCH 61/238 USB: digi_acceleport: do sanity checking for the number of ports

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit 5a07975ad0a36708c6b0a5b9fea1ff811d0b0c1f upstream.

The driver can be crashed with devices that expose crafted descriptors with too few endpoints.

See: http://seclists.org/bugtraq/2016/Mar/61

[johan: fix OOB endpoint check and add error messages ]
---
 drivers/usb/serial/digi_acceleport.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/usb/serial/digi_acceleport.c +19 -0
@@ -1251,8 +1251,27 @@ static int digi_port_init(struct usb_ser
 
 static int digi_startup(struct usb_serial *serial)
 {
+	struct device *dev = &serial->interface->dev;
 	struct digi_serial *serial_priv;
 	int ret;
+	int i;
+
+	/* check whether the device has the expected number of endpoints */
+	if (serial->num_port_pointers < serial->type->num_ports + 1) {
+		dev_err(dev, "OOB endpoints missing\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < serial->type->num_ports + 1 ; i++) {
+		if (!serial->port[i]->read_urb) {
+			dev_err(dev, "bulk-in endpoint missing\n");
+			return -ENODEV;
+		}
+		if (!serial->port[i]->write_urb) {
+			dev_err(dev, "bulk-out endpoint missing\n");
+			return -ENODEV;
+		}
+	}
 
 	serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
 	if (!serial_priv)
author maintainer
#69 lore raw

PATCH 62/238 USB: cypress_m8: add endpoint sanity check

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <[email protected]>

commit c55aee1bf0e6b6feec8b2927b43f7a09a6d5f754 upstream.

An attack using missing endpoints exists.

CVE-2016-3137

---
 drivers/usb/serial/cypress_m8.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/usb/serial/cypress_m8.c +5 -6
@@ -447,6 +447,11 @@ static int cypress_generic_port_probe(st
 	struct usb_serial *serial = port->serial;
 	struct cypress_private *priv;
 
+	if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+		dev_err(&port->dev, "required endpoint is missing\n");
+		return -ENODEV;
+	}
+
 	priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -606,12 +611,6 @@ static int cypress_open(struct tty_struc
 		cypress_set_termios(tty, port, &priv->tmp_termios);
 
 	/* setup the port and start reading from the device */
-	if (!port->interrupt_in_urb) {
-		dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
-			__func__);
-		return -1;
-	}
-
 	usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
 		usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
 		port->interrupt_in_urb->transfer_buffer,
author maintainer
#70 lore raw

PATCH 63/238 USB: serial: cp210x: Adding GE Healthcare Device ID

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Martyn Welch <[email protected]>

commit cddc9434e3dcc37a85c4412fb8e277d3a582e456 upstream.

The CP2105 is used in the GE Healthcare Remote Alarm Box, with the Manufacturer ID of 0x1901 and Product ID of 0x0194.

---
 drivers/usb/serial/cp210x.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/cp210x.c +1 -0
@@ -165,6 +165,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
 	{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
 	{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
+	{ USB_DEVICE(0x1901, 0x0194) },	/* GE Healthcare Remote Alarm Box */
 	{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
 	{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
 	{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
author maintainer
#71 lore raw

PATCH 64/238 USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Boyer <[email protected]>

commit ea6db90e750328068837bed34cb1302b7a177339 upstream.

A Fedora user reports that the ftdi_sio driver works properly for the ICP DAS I-7561U device. Further, the user manual for these devices instructs users to load the driver and add the ids using the sysfs interface.

Add support for these in the driver directly so that the devices work out of the box instead of needing manual configuration.

---
 drivers/usb/serial/ftdi_sio.c     |    4 ++++
 drivers/usb/serial/ftdi_sio_ids.h |    8 ++++++++
 2 files changed, 12 insertions(+)
drivers/usb/serial/ftdi_sio.c +4 -0
@@ -1004,6 +1004,10 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
+	/* ICP DAS I-756xU devices */
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
 	{ }					/* Terminating entry */
 };
 
drivers/usb/serial/ftdi_sio_ids.h +8 -0
@@ -872,6 +872,14 @@
 #define NOVITUS_BONO_E_PID		0x6010
 
 /*
+ * ICPDAS I-756*U devices
+ */
+#define ICPDAS_VID			0x1b5c
+#define ICPDAS_I7560U_PID		0x0103
+#define ICPDAS_I7561U_PID		0x0104
+#define ICPDAS_I7563U_PID		0x0105
+
+/*
  * RT Systems programming cables for various ham radios
  */
 #define RTSYSTEMS_VID		0x2100	/* Vendor ID */
author maintainer
#72 lore raw

PATCH 66/238 rt2x00: add new rt2800usb device Buffalo WLI-UC-G450

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Anthony Wong <[email protected]>

commit f36f299068794ffc5026f25b6a1b3ed615ea832d upstream.

Add USB ID 0411:01fd for Buffalo WLI-UC-G450 wireless adapter, RT chipset 3593

---
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/ralink/rt2x00/rt2800usb.c +1 -0
@@ -1026,6 +1026,7 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x0411, 0x01a2) },
 	{ USB_DEVICE(0x0411, 0x01ee) },
 	{ USB_DEVICE(0x0411, 0x01a8) },
+	{ USB_DEVICE(0x0411, 0x01fd) },
 	/* Corega */
 	{ USB_DEVICE(0x07aa, 0x002f) },
 	{ USB_DEVICE(0x07aa, 0x003c) },
author maintainer
#73 lore raw

PATCH 67/238 pwc: Add USB id for Philips Spc880nc webcam

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 7445e45d19a09e5269dc85f17f9635be29d2f76c upstream.

SPC 880NC PC camera discussions:

	http://www.pclinuxos.com/forum/index.php/topic,135688.0.html
---
 drivers/media/usb/pwc/pwc-if.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/media/usb/pwc/pwc-if.c +6 -0
@@ -91,6 +91,7 @@ static const struct usb_device_id pwc_de
 	{ USB_DEVICE(0x0471, 0x0312) },
 	{ USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
 	{ USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
+	{ USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
 	{ USB_DEVICE(0x069A, 0x0001) }, /* Askey */
 	{ USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
 	{ USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -810,6 +811,11 @@ static int usb_pwc_probe(struct usb_inte
 			name = "Philips SPC 900NC webcam";
 			type_id = 740;
 			break;
+		case 0x032C:
+			PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
+			name = "Philips SPC 880NC webcam";
+			type_id = 740;
+			break;
 		default:
 			return -ENODEV;
 			break;
author maintainer
#74 lore raw

PATCH 68/238 Input: powermate - fix oops with malicious USB descriptors

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Boyer <[email protected]>

commit 9c6ba456711687b794dcf285856fc14e2c76074f upstream.

The powermate driver expects at least one valid USB endpoint in its probe function. If given malicious descriptors that specify 0 for the number of endpoints, it will crash. Validate the number of endpoints on the interface before using them.

The full report for this issue can be found here:
http://seclists.org/bugtraq/2016/Mar/85

---
 drivers/input/misc/powermate.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/input/misc/powermate.c +3 -0
@@ -307,6 +307,9 @@ static int powermate_probe(struct usb_in
 	int error = -ENOMEM;
 
 	interface = intf->cur_altsetting;
+	if (interface->desc.bNumEndpoints < 1)
+		return -EINVAL;
+
 	endpoint = &interface->endpoint[0].desc;
 	if (!usb_endpoint_is_int_in(endpoint))
 		return -EIO;
author maintainer
#75 lore raw

PATCH 69/238 ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 0f886ca12765d20124bd06291c82951fd49a33be upstream.

create_fixed_stream_quirk() may cause a NULL-pointer dereference by accessing the non-existing endpoint when a USB device with a malformed USB descriptor is used.

This patch avoids it simply by adding a sanity check of bNumEndpoints before the accesses.

Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125

---
 sound/usb/quirks.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/usb/quirks.c +6 -0
@@ -180,6 +180,12 @@ static int create_fixed_stream_quirk(str
 	}
 	alts = &iface->altsetting[fp->altset_idx];
 	altsd = get_iface_desc(alts);
+	if (altsd->bNumEndpoints < 1) {
+		kfree(fp);
+		kfree(rate_table);
+		return -EINVAL;
+	}
+
 	fp->protocol = altsd->bInterfaceProtocol;
 
 	if (fp->datainterval == 0)
author maintainer
#76 lore raw

PATCH 70/238 ALSA: usb-audio: Add sanity checks for endpoint accesses

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 447d6275f0c21f6cc97a88b3a0c601436a4cdf2a upstream.

Add some sanity check codes before actually accessing the endpoint via get_endpoint() in order to avoid the invalid access through a malformed USB descriptor. Mostly just checking bNumEndpoints, but in one place (snd_microii_spdif_default_get()), the validity of iface and altsetting index is checked as well.

Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125

---
 sound/usb/clock.c        |    2 ++
 sound/usb/endpoint.c     |    3 +++
 sound/usb/mixer_quirks.c |    4 ++++
 sound/usb/pcm.c          |    2 ++
 4 files changed, 11 insertions(+)
sound/usb/clock.c +2 -0
@@ -285,6 +285,8 @@ static int set_sample_rate_v1(struct snd
 	unsigned char data[3];
 	int err, crate;
 
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	/* if endpoint doesn't have sampling rate control, bail out */
sound/usb/endpoint.c +3 -0
@@ -438,6 +438,9 @@ exit_clear:
  *
  * New endpoints will be added to chip->ep_list and must be freed by
  * calling snd_usb_endpoint_free().
+ *
+ * For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that
+ * bNumEndpoints > 1 beforehand.
  */
 struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
 					      struct usb_host_interface *alts,
sound/usb/mixer_quirks.c +4 -0
@@ -1519,7 +1519,11 @@ static int snd_microii_spdif_default_get
 
 	/* use known values for that card: interface#1 altsetting#1 */
 	iface = usb_ifnum_to_if(chip->dev, 1);
+	if (!iface || iface->num_altsetting < 2)
+		return -EINVAL;
 	alts = &iface->altsetting[1];
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	err = snd_usb_ctl_msg(chip->dev,
sound/usb/pcm.c +2 -0
@@ -159,6 +159,8 @@ static int init_pitch_v1(struct snd_usb_
 	unsigned char data[1];
 	int err;
 
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	data[0] = 1;
author maintainer
#77 lore raw

PATCH 72/238 ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 902eb7fd1e4af3ac69b9b30f8373f118c92b9729 upstream.

Just a minor code cleanup: unify the error paths.

---
 sound/usb/quirks.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
sound/usb/quirks.c +11 -11
@@ -167,23 +167,18 @@ static int create_fixed_stream_quirk(str
 	stream = (fp->endpoint & USB_DIR_IN)
 		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 	err = snd_usb_add_audio_stream(chip, stream, fp);
-	if (err < 0) {
-		kfree(fp);
-		kfree(rate_table);
-		return err;
-	}
+	if (err < 0)
+		goto error;
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
-		kfree(fp);
-		kfree(rate_table);
-		return -EINVAL;
+		err = -EINVAL;
+		goto error;
 	}
 	alts = &iface->altsetting[fp->altset_idx];
 	altsd = get_iface_desc(alts);
 	if (altsd->bNumEndpoints < 1) {
-		kfree(fp);
-		kfree(rate_table);
-		return -EINVAL;
+		err = -EINVAL;
+		goto error;
 	}
 
 	fp->protocol = altsd->bInterfaceProtocol;
@@ -196,6 +191,11 @@ static int create_fixed_stream_quirk(str
 	snd_usb_init_pitch(chip, fp->iface, alts, fp);
 	snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
 	return 0;
+
+ error:
+	kfree(fp);
+	kfree(rate_table);
+	return err;
 }
 
 static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
author maintainer
#78 lore raw

PATCH 73/238 ALSA: usb-audio: Fix double-free in error paths after snd_usb_add_audio_stream() call

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vladis Dronov <[email protected]>

commit 836b34a935abc91e13e63053d0a83b24dfb5ea78 upstream.

create_fixed_stream_quirk(), snd_usb_parse_audio_interface() and create_uaxx_quirk() functions allocate the audioformat object by themselves and free it upon error before returning. However, once the object is linked to a stream, it's freed again in snd_usb_audio_pcm_free(), thus it'll be double-freed, eventually resulting in a memory corruption.

This patch fixes these failures in the error paths by unlinking the audioformat object before freeing it.

Based on a patch by Takashi Iwai <[email protected]>

[Note for stable backports:
this patch requires the commit 902eb7fd1e4a ('ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()')]

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1283358

---
 sound/usb/quirks.c |    4 ++++
 sound/usb/stream.c |    6 +++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
sound/usb/quirks.c +4 -0
@@ -150,6 +150,7 @@ static int create_fixed_stream_quirk(str
 		usb_audio_err(chip, "cannot memdup\n");
 		return -ENOMEM;
 	}
+	INIT_LIST_HEAD(&fp->list);
 	if (fp->nr_rates > MAX_NR_RATES) {
 		kfree(fp);
 		return -EINVAL;
@@ -193,6 +194,7 @@ static int create_fixed_stream_quirk(str
 	return 0;
 
  error:
+	list_del(&fp->list); /* unlink for avoiding double-free */
 	kfree(fp);
 	kfree(rate_table);
 	return err;
@@ -468,6 +470,7 @@ static int create_uaxx_quirk(struct snd_
 	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
 	fp->datainterval = 0;
 	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+	INIT_LIST_HEAD(&fp->list);
 
 	switch (fp->maxpacksize) {
 	case 0x120:
@@ -491,6 +494,7 @@ static int create_uaxx_quirk(struct snd_
 		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 	err = snd_usb_add_audio_stream(chip, stream, fp);
 	if (err < 0) {
+		list_del(&fp->list); /* unlink for avoiding double-free */
 		kfree(fp);
 		return err;
 	}
sound/usb/stream.c +5 -1
@@ -314,7 +314,9 @@ static struct snd_pcm_chmap_elem *conver
 /*
  * add this endpoint to the chip instance.
  * if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
+ * if not, create a new pcm stream. note, fp is added to the substream
+ * fmt_list and will be freed on the chip instance release. do not free
+ * fp or do remove it from the substream fmt_list to avoid double-free.
  */
 int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
 			     int stream,
@@ -675,6 +677,7 @@ int snd_usb_parse_audio_interface(struct
 					* (fp->maxpacksize & 0x7ff);
 		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
 		fp->clock = clock;
+		INIT_LIST_HEAD(&fp->list);
 
 		/* some quirks for attributes here */
 
@@ -723,6 +726,7 @@ int snd_usb_parse_audio_interface(struct
 		dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
 		err = snd_usb_add_audio_stream(chip, stream, fp);
 		if (err < 0) {
+			list_del(&fp->list); /* unlink for avoiding double-free */
 			kfree(fp->rate_table);
 			kfree(fp->chmap);
 			kfree(fp);
author maintainer
#79 lore raw

PATCH 74/238 Bluetooth: btusb: Add new AR3012 ID 13d3:3395

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Tunin <[email protected]>

commit 609574eb46335cfac1421a07c0505627cbbab1f0 upstream.

T: Bus=03 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3395 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

---
 drivers/bluetooth/ath3k.c |    2 ++
 drivers/bluetooth/btusb.c |    1 +
 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
@@ -113,6 +113,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3362) },
 	{ USB_DEVICE(0x13d3, 0x3375) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
+	{ USB_DEVICE(0x13d3, 0x3395) },
 	{ USB_DEVICE(0x13d3, 0x3402) },
 	{ USB_DEVICE(0x13d3, 0x3408) },
 	{ USB_DEVICE(0x13d3, 0x3423) },
@@ -175,6 +176,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c +1 -0
@@ -227,6 +227,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
author maintainer
#80 lore raw

PATCH 75/238 Bluetooth: btusb: Add a new AR3012 ID 04ca:3014

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Tunin <[email protected]>

commit 81d90442eac779938217c3444b240aa51fd3db47 upstream.

T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=03 Dev#= 5 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=04ca ProdID=3014 Rev=00.02
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

---
 drivers/bluetooth/ath3k.c |    2 ++
 drivers/bluetooth/btusb.c |    1 +
 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
@@ -92,6 +92,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04CA, 0x300d) },
 	{ USB_DEVICE(0x04CA, 0x300f) },
 	{ USB_DEVICE(0x04CA, 0x3010) },
+	{ USB_DEVICE(0x04CA, 0x3014) },
 	{ USB_DEVICE(0x0930, 0x0219) },
 	{ USB_DEVICE(0x0930, 0x021c) },
 	{ USB_DEVICE(0x0930, 0x0220) },
@@ -155,6 +156,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c +1 -0
@@ -206,6 +206,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
author maintainer
#81 lore raw

PATCH 76/238 Bluetooth: btusb: Add a new AR3012 ID 13d3:3472

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Tunin <[email protected]>

commit 75c6aca4765dbe3d0c1507ab5052f2e373dc2331 upstream.

T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3472 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

---
 drivers/bluetooth/ath3k.c |    2 ++
 drivers/bluetooth/btusb.c |    1 +
 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
@@ -119,6 +119,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3408) },
 	{ USB_DEVICE(0x13d3, 0x3423) },
 	{ USB_DEVICE(0x13d3, 0x3432) },
+	{ USB_DEVICE(0x13d3, 0x3472) },
 	{ USB_DEVICE(0x13d3, 0x3474) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
@@ -183,6 +184,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
drivers/bluetooth/btusb.c +1 -0
@@ -233,6 +233,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
author maintainer
#82 lore raw

PATCH 77/238 crypto: ccp - Add hash state import and export support

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tom Lendacky <[email protected]>

commit 952bce9792e6bf36fda09c2e5718abb5d9327369 upstream.

Commit 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero") added a check to prevent ahash algorithms from successfully registering if the import and export functions were not implemented. This prevents an oops in the hash_accept function of algif_hash. This commit causes the ccp-crypto module SHA support and AES CMAC support from successfully registering and causing the ccp-crypto module load to fail because the ahash import and export functions are not implemented.

Update the CCP Crypto API support to provide import and export support for ahash algorithms.

---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |   23 +++++++++++++++++++++++
 drivers/crypto/ccp/ccp-crypto-sha.c      |   23 +++++++++++++++++++++++
 2 files changed, 46 insertions(+)
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +23 -0
@@ -220,6 +220,26 @@ static int ccp_aes_cmac_digest(struct ah
 	return ccp_aes_cmac_finup(req);
 }
 
+static int ccp_aes_cmac_export(struct ahash_request *req, void *out)
+{
+	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_aes_cmac_req_ctx *state = out;
+
+	*state = *rctx;
+
+	return 0;
+}
+
+static int ccp_aes_cmac_import(struct ahash_request *req, const void *in)
+{
+	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
+	const struct ccp_aes_cmac_req_ctx *state = in;
+
+	*rctx = *state;
+
+	return 0;
+}
+
 static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 			       unsigned int key_len)
 {
@@ -352,10 +372,13 @@ int ccp_register_aes_cmac_algs(struct li
 	alg->final = ccp_aes_cmac_final;
 	alg->finup = ccp_aes_cmac_finup;
 	alg->digest = ccp_aes_cmac_digest;
+	alg->export = ccp_aes_cmac_export;
+	alg->import = ccp_aes_cmac_import;
 	alg->setkey = ccp_aes_cmac_setkey;
 
 	halg = &alg->halg;
 	halg->digestsize = AES_BLOCK_SIZE;
+	halg->statesize = sizeof(struct ccp_aes_cmac_req_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "cmac(aes)");
drivers/crypto/ccp/ccp-crypto-sha.c +23 -0
@@ -207,6 +207,26 @@ static int ccp_sha_digest(struct ahash_r
 	return ccp_sha_finup(req);
 }
 
+static int ccp_sha_export(struct ahash_request *req, void *out)
+{
+	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_sha_req_ctx *state = out;
+
+	*state = *rctx;
+
+	return 0;
+}
+
+static int ccp_sha_import(struct ahash_request *req, const void *in)
+{
+	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
+	const struct ccp_sha_req_ctx *state = in;
+
+	*rctx = *state;
+
+	return 0;
+}
+
 static int ccp_sha_setkey(struct crypto_ahash *tfm, const u8 *key,
 			  unsigned int key_len)
 {
@@ -403,9 +423,12 @@ static int ccp_register_sha_alg(struct l
 	alg->final = ccp_sha_final;
 	alg->finup = ccp_sha_finup;
 	alg->digest = ccp_sha_digest;
+	alg->export = ccp_sha_export;
+	alg->import = ccp_sha_import;
 
 	halg = &alg->halg;
 	halg->digestsize = def->digest_size;
+	halg->statesize = sizeof(struct ccp_sha_req_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
author maintainer
#83 lore raw

PATCH 78/238 crypto: ccp - Limit the amount of information exported

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tom Lendacky <[email protected]>

commit d1662165ae612ec8b5f94a6b07e65ea58b6dce34 upstream.

Since the exported information can be exposed to user-space, instead of exporting the entire request context only export the minimum information needed.

---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |   16 +++++++++++-----
 drivers/crypto/ccp/ccp-crypto-sha.c      |   20 +++++++++++++++-----
 drivers/crypto/ccp/ccp-crypto.h          |   22 ++++++++++++++++++++++
 3 files changed, 48 insertions(+), 10 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +11 -5
@@ -223,9 +223,12 @@ static int ccp_aes_cmac_digest(struct ah
 static int ccp_aes_cmac_export(struct ahash_request *req, void *out)
 {
 	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_aes_cmac_req_ctx *state = out;
+	struct ccp_aes_cmac_exp_ctx *state = out;
 
-	*state = *rctx;
+	state->null_msg = rctx->null_msg;
+	memcpy(state->iv, rctx->iv, sizeof(state->iv));
+	state->buf_count = rctx->buf_count;
+	memcpy(state->buf, rctx->buf, sizeof(state->buf));
 
 	return 0;
 }
@@ -233,9 +236,12 @@ static int ccp_aes_cmac_export(struct ah
 static int ccp_aes_cmac_import(struct ahash_request *req, const void *in)
 {
 	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
-	const struct ccp_aes_cmac_req_ctx *state = in;
+	const struct ccp_aes_cmac_exp_ctx *state = in;
 
-	*rctx = *state;
+	rctx->null_msg = state->null_msg;
+	memcpy(rctx->iv, state->iv, sizeof(rctx->iv));
+	rctx->buf_count = state->buf_count;
+	memcpy(rctx->buf, state->buf, sizeof(rctx->buf));
 
 	return 0;
 }
@@ -378,7 +384,7 @@ int ccp_register_aes_cmac_algs(struct li
 
 	halg = &alg->halg;
 	halg->digestsize = AES_BLOCK_SIZE;
-	halg->statesize = sizeof(struct ccp_aes_cmac_req_ctx);
+	halg->statesize = sizeof(struct ccp_aes_cmac_exp_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "cmac(aes)");
drivers/crypto/ccp/ccp-crypto-sha.c +15 -5
@@ -210,9 +210,14 @@ static int ccp_sha_digest(struct ahash_r
 static int ccp_sha_export(struct ahash_request *req, void *out)
 {
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_sha_req_ctx *state = out;
+	struct ccp_sha_exp_ctx *state = out;
 
-	*state = *rctx;
+	state->type = rctx->type;
+	state->msg_bits = rctx->msg_bits;
+	state->first = rctx->first;
+	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
+	state->buf_count = rctx->buf_count;
+	memcpy(state->buf, rctx->buf, sizeof(state->buf));
 
 	return 0;
 }
@@ -220,9 +225,14 @@ static int ccp_sha_export(struct ahash_r
 static int ccp_sha_import(struct ahash_request *req, const void *in)
 {
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	const struct ccp_sha_req_ctx *state = in;
+	const struct ccp_sha_exp_ctx *state = in;
 
-	*rctx = *state;
+	rctx->type = state->type;
+	rctx->msg_bits = state->msg_bits;
+	rctx->first = state->first;
+	memcpy(rctx->ctx, state->ctx, sizeof(rctx->ctx));
+	rctx->buf_count = state->buf_count;
+	memcpy(rctx->buf, state->buf, sizeof(rctx->buf));
 
 	return 0;
 }
@@ -428,7 +438,7 @@ static int ccp_register_sha_alg(struct l
 
 	halg = &alg->halg;
 	halg->digestsize = def->digest_size;
-	halg->statesize = sizeof(struct ccp_sha_req_ctx);
+	halg->statesize = sizeof(struct ccp_sha_exp_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
drivers/crypto/ccp/ccp-crypto.h +22 -0
@@ -129,6 +129,15 @@ struct ccp_aes_cmac_req_ctx {
 	struct ccp_cmd cmd;
 };
 
+struct ccp_aes_cmac_exp_ctx {
+	unsigned int null_msg;
+
+	u8 iv[AES_BLOCK_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[AES_BLOCK_SIZE];
+};
+
 /***** SHA related defines *****/
 #define MAX_SHA_CONTEXT_SIZE	SHA256_DIGEST_SIZE
 #define MAX_SHA_BLOCK_SIZE	SHA256_BLOCK_SIZE
@@ -171,6 +180,19 @@ struct ccp_sha_req_ctx {
 	struct ccp_cmd cmd;
 };
 
+struct ccp_sha_exp_ctx {
+	enum ccp_sha_type type;
+
+	u64 msg_bits;
+
+	unsigned int first;
+
+	u8 ctx[MAX_SHA_CONTEXT_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[MAX_SHA_BLOCK_SIZE];
+};
+
 /***** Common Context Structure *****/
 struct ccp_ctx {
 	int (*complete)(struct crypto_async_request *req, int ret);
author maintainer
#84 lore raw

PATCH 79/238 crypto: ccp - Dont assume export/import areas are aligned

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tom Lendacky <[email protected]>

commit b31dde2a5cb1bf764282abf934266b7193c2bc7c upstream.

Use a local variable for the exported and imported state so that alignment is not an issue. On export, set a local variable from the request context and then memcpy the contents of the local variable to the export memory area. On import, memcpy the import memory area into a local variable and then use the local variable to set the request context.

---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |   26 ++++++++++++++---------
 drivers/crypto/ccp/ccp-crypto-sha.c      |   34 ++++++++++++++++++-------------
 2 files changed, 36 insertions(+), 24 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +16 -10
@@ -223,12 +223,15 @@ static int ccp_aes_cmac_digest(struct ah
 static int ccp_aes_cmac_export(struct ahash_request *req, void *out)
 {
 	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_aes_cmac_exp_ctx *state = out;
+	struct ccp_aes_cmac_exp_ctx state;
 
-	state->null_msg = rctx->null_msg;
-	memcpy(state->iv, rctx->iv, sizeof(state->iv));
-	state->buf_count = rctx->buf_count;
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.null_msg = rctx->null_msg;
+	memcpy(state.iv, rctx->iv, sizeof(state.iv));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));
 
 	return 0;
 }
@@ -236,12 +239,15 @@ static int ccp_aes_cmac_export(struct ah
 static int ccp_aes_cmac_import(struct ahash_request *req, const void *in)
 {
 	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
-	const struct ccp_aes_cmac_exp_ctx *state = in;
+	struct ccp_aes_cmac_exp_ctx state;
+
+	/* 'in' may not be aligned so memcpy to local variable */
+	memcpy(&state, in, sizeof(state));
 
-	rctx->null_msg = state->null_msg;
-	memcpy(rctx->iv, state->iv, sizeof(rctx->iv));
-	rctx->buf_count = state->buf_count;
-	memcpy(rctx->buf, state->buf, sizeof(rctx->buf));
+	rctx->null_msg = state.null_msg;
+	memcpy(rctx->iv, state.iv, sizeof(rctx->iv));
+	rctx->buf_count = state.buf_count;
+	memcpy(rctx->buf, state.buf, sizeof(rctx->buf));
 
 	return 0;
 }
drivers/crypto/ccp/ccp-crypto-sha.c +20 -14
@@ -210,14 +210,17 @@ static int ccp_sha_digest(struct ahash_r
 static int ccp_sha_export(struct ahash_request *req, void *out)
 {
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_sha_exp_ctx *state = out;
+	struct ccp_sha_exp_ctx state;
 
-	state->type = rctx->type;
-	state->msg_bits = rctx->msg_bits;
-	state->first = rctx->first;
-	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
-	state->buf_count = rctx->buf_count;
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));
 
 	return 0;
 }
@@ -225,14 +228,17 @@ static int ccp_sha_export(struct ahash_r
 static int ccp_sha_import(struct ahash_request *req, const void *in)
 {
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	const struct ccp_sha_exp_ctx *state = in;
+	struct ccp_sha_exp_ctx state;
+
+	/* 'in' may not be aligned so memcpy to local variable */
+	memcpy(&state, in, sizeof(state));
 
-	rctx->type = state->type;
-	rctx->msg_bits = state->msg_bits;
-	rctx->first = state->first;
-	memcpy(rctx->ctx, state->ctx, sizeof(rctx->ctx));
-	rctx->buf_count = state->buf_count;
-	memcpy(rctx->buf, state->buf, sizeof(rctx->buf));
+	rctx->type = state.type;
+	rctx->msg_bits = state.msg_bits;
+	rctx->first = state.first;
+	memcpy(rctx->ctx, state.ctx, sizeof(rctx->ctx));
+	rctx->buf_count = state.buf_count;
+	memcpy(rctx->buf, state.buf, sizeof(rctx->buf));
 
 	return 0;
 }
#85 lore raw

Re: [PATCH 4.5 079/238] crypto: ccp - Dont assume export/import areas are aligned

Quoted 1 line · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

I object, because this introduces an information leak.

[...]

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 213

Quoted 8 lines
drivers/crypto/ccp/ccp-crypto-sha.c +1 -1
@@ -210,14 +210,17 @@ static int ccp_sha_digest(struct ahash_r
  static int ccp_sha_export(struct ahash_request *req, void *out)
  {
  	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_sha_exp_ctx *state = out;
+	struct ccp_sha_exp_ctx state;

The structure was defined in the previous patch as:

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 215

Quoted 2 lines
drivers/crypto/ccp/ccp-crypto-sha.c +2 -0
+struct ccp_sha_exp_ctx {
+	enum ccp_sha_type type;

There will be padding between type and msg_bits on most architectures.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 222

Quoted 7 lines
drivers/crypto/ccp/ccp-crypto-sha.c +7 -0
+	u64 msg_bits;
+	unsigned int first;
+
+	u8 ctx[MAX_SHA_CONTEXT_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[MAX_SHA_BLOCK_SIZE];

And more padding at the end of the structure.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 223

Quoted 1 line
drivers/crypto/ccp/ccp-crypto-sha.c +1 -0
+};

Back to the code:

Quoted 5 lines
drivers/crypto/ccp/ccp-crypto-sha.c +0 -5
-	state->type = rctx->type;
-	state->msg_bits = rctx->msg_bits;
-	state->first = rctx->first;
-	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
-	state->buf_count = rctx->buf_count;

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 223

Quoted 10 lines
drivers/crypto/ccp/ccp-crypto-sha.c +9 -1
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));

[...]

The padding was not initialised, but here we copy it to userland.

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#86 lore raw

Re: [PATCH 4.5 079/238] crypto: ccp - Dont assume export/import areas are aligned

Quoted 53 lines · Ben Hutchings
Quoted 1 line · Greg Kroah-Hartman

4.5-stable review patch.��If anyone has any objections, please let me know.

I object, because this introduces an information leak.

[...]

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 213

Quoted 8 lines
drivers/crypto/ccp/ccp-crypto-sha.c +1 -1
@@ -210,14 +210,17 @@ static int ccp_sha_digest(struct ahash_r
 �static int ccp_sha_export(struct ahash_request *req, void *out)
 �{
 �	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_sha_exp_ctx *state = out;
+	struct ccp_sha_exp_ctx state;

The structure was defined in the previous patch as:

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 215

Quoted 2 lines
drivers/crypto/ccp/ccp-crypto-sha.c +2 -0
+struct ccp_sha_exp_ctx {
+	enum ccp_sha_type type;

There will be padding between type and msg_bits on most architectures.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 222

Quoted 7 lines
drivers/crypto/ccp/ccp-crypto-sha.c +7 -0
+	u64 msg_bits;
+	unsigned int first;
+
+	u8 ctx[MAX_SHA_CONTEXT_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[MAX_SHA_BLOCK_SIZE];

And more padding at the end of the structure.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 223

Quoted 1 line
drivers/crypto/ccp/ccp-crypto-sha.c +1 -0
+};

Back to the code:

Quoted 15 lines
drivers/crypto/ccp/ccp-crypto-sha.c +9 -6
-	state->type = rctx->type;
-	state->msg_bits = rctx->msg_bits;
-	state->first = rctx->first;
-	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
-	state->buf_count = rctx->buf_count;
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));

[...]

Quoted 1 line

The padding was not initialised, but here we copy it to userland.

Nice catch. Given that the user/kernel structure here doesn't seem very sane (implicit padding, etc.), shouldn't that be where this is fixed up to be a properly packed structure? Or have padding where needed, along with a memset() call?

I'll leave this here, but will be expecting a follow-on patch to fix up the issues from the crypto developers.

thanks,

greg k-h

#87 lore raw

Re: [PATCH 4.5 079/238] crypto: ccp - Dont assume export/import areas are aligned

Quoted 54 lines · Greg Kroah-Hartman
Quoted 53 lines · Ben Hutchings
Quoted 1 line · Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

I object, because this introduces an information leak.

[...]

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 213

Quoted 8 lines
drivers/crypto/ccp/ccp-crypto-sha.c +1 -1
@@ -210,14 +210,17 @@ static int ccp_sha_digest(struct ahash_r
 static int ccp_sha_export(struct ahash_request *req, void *out)
 {
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
-	struct ccp_sha_exp_ctx *state = out;
+	struct ccp_sha_exp_ctx state;

The structure was defined in the previous patch as:

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 215

Quoted 2 lines
drivers/crypto/ccp/ccp-crypto-sha.c +2 -0
+struct ccp_sha_exp_ctx {
+	enum ccp_sha_type type;

There will be padding between type and msg_bits on most architectures.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 222

Quoted 7 lines
drivers/crypto/ccp/ccp-crypto-sha.c +7 -0
+	u64 msg_bits;
+	unsigned int first;
+
+	u8 ctx[MAX_SHA_CONTEXT_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[MAX_SHA_BLOCK_SIZE];

And more padding at the end of the structure.

drivers/crypto/ccp/ccp-crypto-sha.c static int ccp_sha_digest(struct ahash_r · line 223

Quoted 1 line
drivers/crypto/ccp/ccp-crypto-sha.c +1 -0
+};

Back to the code:

Quoted 15 lines
drivers/crypto/ccp/ccp-crypto-sha.c +9 -6
-	state->type = rctx->type;
-	state->msg_bits = rctx->msg_bits;
-	state->first = rctx->first;
-	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
-	state->buf_count = rctx->buf_count;
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));

[...]

Quoted 6 lines
Quoted 1 line

The padding was not initialised, but here we copy it to userland.

Nice catch. Given that the user/kernel structure here doesn't seem very sane (implicit padding, etc.), shouldn't that be where this is fixed up to be a properly packed structure? Or have padding where needed, along with a memset() call?

The structure is not meant for use outside the kernel - it's an opaque blob that will be processed by the driver import function. So would it be enough to just memset the struct ccp_sha_exp_ctx state variable to 0 before setting and copying it? That should take care of any padding not being initialized.

Thanks,
Tom

Quoted 8 lines

I'll leave this here, but will be expecting a follow-on patch to fix up the issues from the crypto developers.

thanks,

greg k-h

#88 lore raw

Re: [PATCH 4.5 079/238] crypto: ccp - Dont assume export/import areas are aligned

Quoted 5 lines · Tom Lendacky
Quoted 4 lines · Greg Kroah-Hartman
Quoted 2 lines · Ben Hutchings

On Sun, 2016-04-10 at 11:34 -0700, Greg Kroah-Hartman wrote:

[...]

Quoted 22 lines
Quoted 17 lines
Quoted 17 lines
Quoted 15 lines
drivers/crypto/ccp/ccp-crypto-sha.c +9 -6
-	state->type = rctx->type;
-	state->msg_bits = rctx->msg_bits;
-	state->first = rctx->first;
-	memcpy(state->ctx, rctx->ctx, sizeof(state->ctx));
-	state->buf_count = rctx->buf_count;
-	memcpy(state->buf, rctx->buf, sizeof(state->buf));
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));

[...]

Quoted 5 lines
Quoted 1 line

The padding was not initialised, but here we copy it to userland.

Nice catch.  Given that the user/kernel structure here doesn't seem very sane (implicit padding, etc.), shouldn't that be where this is fixed up to be a properly packed structure?  Or have padding where needed, along with a memset() call?

Quoted 5 lines

The structure is not meant for use outside the kernel - it's an opaque blob that will be processed by the driver import function. So would it be enough to just memset the struct ccp_sha_exp_ctx state variable to 0 before setting and copying it?  That should take care of any padding not being initialized.

I think that would be enough.

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#89 lore raw

PATCH 80/238 crypto: ccp - memset request context to zero during import

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tom Lendacky <[email protected]>

commit ce0ae266feaf35930394bd770c69778e4ef03ba9 upstream.

Since a crypto_ahash_import() can be called against a request context that has not had a crypto_ahash_init() performed, the request context needs to be cleared to insure there is no random data present. If not, the random data can result in a kernel oops during crypto_ahash_update().

---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |    1 +
 drivers/crypto/ccp/ccp-crypto-sha.c      |    1 +
 2 files changed, 2 insertions(+)
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +1 -0
@@ -244,6 +244,7 @@ static int ccp_aes_cmac_import(struct ah
 	/* 'in' may not be aligned so memcpy to local variable */
 	memcpy(&state, in, sizeof(state));
 
+	memset(rctx, 0, sizeof(*rctx));
 	rctx->null_msg = state.null_msg;
 	memcpy(rctx->iv, state.iv, sizeof(rctx->iv));
 	rctx->buf_count = state.buf_count;
drivers/crypto/ccp/ccp-crypto-sha.c +1 -0
@@ -233,6 +233,7 @@ static int ccp_sha_import(struct ahash_r
 	/* 'in' may not be aligned so memcpy to local variable */
 	memcpy(&state, in, sizeof(state));
 
+	memset(rctx, 0, sizeof(*rctx));
 	rctx->type = state.type;
 	rctx->msg_bits = state.msg_bits;
 	rctx->first = state.first;
author maintainer
#90 lore raw

PATCH 81/238 crypto: keywrap - memzero the correct memory

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 2b8b28fd232233c22fb61009dd8b0587390d2875 upstream.

We're clearing the wrong memory. The memory corruption is likely harmless because we weren't going to use that stack memory again but not zeroing is a potential information leak.

Fixes e28facde3c39 ('crypto: keywrap - add key wrapping block chaining mode')
---
 crypto/keywrap.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
crypto/keywrap.c +2 -2
@@ -212,7 +212,7 @@ static int crypto_kw_decrypt(struct blkc
 			  SEMIBSIZE))
 		ret = -EBADMSG;
 
-	memzero_explicit(&block, sizeof(struct crypto_kw_block));
+	memzero_explicit(block, sizeof(struct crypto_kw_block));
 
 	return ret;
 }
@@ -297,7 +297,7 @@ static int crypto_kw_encrypt(struct blkc
 	/* establish the IV for the caller to pick up */
 	memcpy(desc->info, block->A, SEMIBSIZE);
 
-	memzero_explicit(&block, sizeof(struct crypto_kw_block));
+	memzero_explicit(block, sizeof(struct crypto_kw_block));
 
 	return 0;
 }
author maintainer
#91 lore raw

PATCH 82/238 crypto: atmel - fix checks of error code returned by devm_ioremap_resource()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vladimir Zapolskiy <[email protected]>

commit 9b52d55f4f0e2bb9a34abbcf99e05e17f1b3b281 upstream.

The change fixes potential oops while accessing iomem on invalid address, if devm_ioremap_resource() fails due to some reason.

The devm_ioremap_resource() function returns ERR_PTR() and never returns NULL, which makes useless a following check for NULL.

Fixes b0e8b3417a62 ("crypto: atmel - use devm_xxx() managed function")
---
 drivers/crypto/atmel-aes.c  |    4 ++--
 drivers/crypto/atmel-sha.c  |    4 ++--
 drivers/crypto/atmel-tdes.c |    4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/crypto/atmel-aes.c +2 -2
@@ -2085,9 +2085,9 @@ static int atmel_aes_probe(struct platfo
 	}
 
 	aes_dd->io_base = devm_ioremap_resource(&pdev->dev, aes_res);
-	if (!aes_dd->io_base) {
+	if (IS_ERR(aes_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(aes_dd->io_base);
 		goto res_err;
 	}
 
drivers/crypto/atmel-sha.c +2 -2
@@ -1404,9 +1404,9 @@ static int atmel_sha_probe(struct platfo
 	}
 
 	sha_dd->io_base = devm_ioremap_resource(&pdev->dev, sha_res);
-	if (!sha_dd->io_base) {
+	if (IS_ERR(sha_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(sha_dd->io_base);
 		goto res_err;
 	}
 
drivers/crypto/atmel-tdes.c +2 -2
@@ -1417,9 +1417,9 @@ static int atmel_tdes_probe(struct platf
 	}
 
 	tdes_dd->io_base = devm_ioremap_resource(&pdev->dev, tdes_res);
-	if (!tdes_dd->io_base) {
+	if (IS_ERR(tdes_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(tdes_dd->io_base);
 		goto res_err;
 	}
 
author maintainer
#92 lore raw

PATCH 83/238 crypto: ux500 - fix checks of error code returned by devm_ioremap_resource()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vladimir Zapolskiy <[email protected]>

commit b62917a2622ebcb03a500ef20da47be80d8c8951 upstream.

The change fixes potential oops while accessing iomem on invalid address, if devm_ioremap_resource() fails due to some reason.

The devm_ioremap_resource() function returns ERR_PTR() and never returns NULL, which makes useless a following check for NULL.

Fixes 5a4eea2658c93 ("crypto: ux500 - Use devm_xxx() managed function")
---
 drivers/crypto/ux500/cryp/cryp_core.c |    4 ++--
 drivers/crypto/ux500/hash/hash_core.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/ux500/cryp/cryp_core.c +2 -2
@@ -1440,9 +1440,9 @@ static int ux500_cryp_probe(struct platf
 
 	device_data->phybase = res->start;
 	device_data->base = devm_ioremap_resource(dev, res);
-	if (!device_data->base) {
+	if (IS_ERR(device_data->base)) {
 		dev_err(dev, "[%s]: ioremap failed!", __func__);
-		ret = -ENOMEM;
+		ret = PTR_ERR(device_data->base);
 		goto out;
 	}
 
drivers/crypto/ux500/hash/hash_core.c +2 -2
@@ -1659,9 +1659,9 @@ static int ux500_hash_probe(struct platf
 
 	device_data->phybase = res->start;
 	device_data->base = devm_ioremap_resource(dev, res);
-	if (!device_data->base) {
+	if (IS_ERR(device_data->base)) {
 		dev_err(dev, "%s: ioremap() failed!\n", __func__);
-		ret = -ENOMEM;
+		ret = PTR_ERR(device_data->base);
 		goto out;
 	}
 	spin_lock_init(&device_data->ctx_lock);
author maintainer
#93 lore raw

PATCH 84/238 crypto: marvell/cesa - forward devm_ioremap_resource() error code

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Boris BREZILLON <[email protected]>

commit dfe97ad30e8c038261663a18b9e04b8b5bc07bea upstream.

Forward devm_ioremap_resource() error code instead of returning -ENOMEM.

Fixes f63601fd616a ("crypto: marvell/cesa - add a new driver for Marvell's CESA")
---
 drivers/crypto/marvell/cesa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/marvell/cesa.c +1 -1
@@ -420,7 +420,7 @@ static int mv_cesa_probe(struct platform
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
 	cesa->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(cesa->regs))
-		return -ENOMEM;
+		return PTR_ERR(cesa->regs);
 
 	ret = mv_cesa_dev_dma_init(cesa);
 	if (ret)
author maintainer
#94 lore raw

PATCH 85/238 X.509: Fix leap year handling again

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Howells <[email protected]>

commit ac4cbedfdf55455b4c447f17f0fa027dbf02b2a6 upstream.

There are still a couple of minor issues in the X.509 leap year handling:

(1) To avoid doing a modulus-by-400 in addition to a modulus-by-100 when determining whether the year is a leap year or not, I divided the year by 100 after doing the modulus-by-100, thereby letting the compiler do one instruction for both, and then did a modulus-by-4.

Unfortunately, I then passed the now-modified year value to mktime64() to construct a time value.

Since this isn't a fast path and since mktime64() does a bunch of divisions, just condense down to "% 400". It's also easier to read.

(2) The default month length for any February where the year doesn't divide by four exactly is obtained from the month_length[] array where the value is 29, not 28.

This is fixed by altering the table.

---
 crypto/asymmetric_keys/x509_cert_parser.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
crypto/asymmetric_keys/x509_cert_parser.c +4 -4
@@ -494,7 +494,7 @@ int x509_decode_time(time64_t *_t,  size
 		     unsigned char tag,
 		     const unsigned char *value, size_t vlen)
 {
-	static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30,
+	static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
 						       31, 31, 30, 31, 30, 31 };
 	const unsigned char *p = value;
 	unsigned year, mon, day, hour, min, sec, mon_len;
@@ -540,9 +540,9 @@ int x509_decode_time(time64_t *_t,  size
 		if (year % 4 == 0) {
 			mon_len = 29;
 			if (year % 100 == 0) {
-				year /= 100;
-				if (year % 4 != 0)
-					mon_len = 28;
+				mon_len = 28;
+				if (year % 400 == 0)
+					mon_len = 29;
 			}
 		}
 	}
author maintainer
#95 lore raw

PATCH 86/238 mei: bus: check if the device is enabled before data transfer

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexander Usyskin <[email protected]>

commit 15c13dfcad883a1e76b714480fb27be96247fd82 upstream.

The bus data transfer interface was missing the check if the device is in enabled state, this may lead to stack corruption during link reset.

---
 drivers/misc/mei/bus.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/misc/mei/bus.c +9 -0
@@ -53,6 +53,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl,
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
+
 	if (!mei_cl_is_connected(cl)) {
 		rets = -ENODEV;
 		goto out;
@@ -109,6 +114,10 @@ ssize_t __mei_cl_recv(struct mei_cl *cl,
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
 
 	cb = mei_cl_read_cb(cl, NULL);
 	if (cb)
author maintainer
#96 lore raw

PATCH 87/238 tpm: fix the rollback in tpm_chip_register()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jarkko Sakkinen <[email protected]>

commit 72c91ce8523ae5828fe5e4417ae0aaab53707a08 upstream.

Fixed the rollback and gave more self-documenting names for the functions.

Fixes d972b0523f ("tpm: fix call order in tpm-chip.c")
---
 drivers/char/tpm/tpm-chip.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/char/tpm/tpm-chip.c +5 -5
@@ -140,7 +140,7 @@ struct tpm_chip *tpmm_chip_alloc(struct
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
-static int tpm_dev_add_device(struct tpm_chip *chip)
+static int tpm_add_char_device(struct tpm_chip *chip)
 {
 	int rc;
 
@@ -151,7 +151,6 @@ static int tpm_dev_add_device(struct tpm
 			chip->devname, MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
-		device_unregister(&chip->dev);
 		return rc;
 	}
 
@@ -162,13 +161,14 @@ static int tpm_dev_add_device(struct tpm
 			chip->devname, MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
+		cdev_del(&chip->cdev);
 		return rc;
 	}
 
 	return rc;
 }
 
-static void tpm_dev_del_device(struct tpm_chip *chip)
+static void tpm_del_char_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
 	device_unregister(&chip->dev);
@@ -222,7 +222,7 @@ int tpm_chip_register(struct tpm_chip *c
 
 	tpm_add_ppi(chip);
 
-	rc = tpm_dev_add_device(chip);
+	rc = tpm_add_char_device(chip);
 	if (rc)
 		goto out_err;
 
@@ -274,6 +274,6 @@ void tpm_chip_unregister(struct tpm_chip
 		sysfs_remove_link(&chip->pdev->kobj, "ppi");
 
 	tpm1_chip_unregister(chip);
-	tpm_dev_del_device(chip);
+	tpm_del_char_device(chip);
 }
 EXPORT_SYMBOL_GPL(tpm_chip_unregister);
author maintainer
#97 lore raw

PATCH 88/238 tpm_crb: tpm2_shutdown() must be called before tpm_chip_unregister()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jarkko Sakkinen <[email protected]>

commit 99cda8cb4639de81cde785b5bab9bc52e916e594 upstream.

Wrong call order.

---
 drivers/char/tpm/tpm_crb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/tpm/tpm_crb.c +2 -2
@@ -302,11 +302,11 @@ static int crb_acpi_remove(struct acpi_d
 	struct device *dev = &device->dev;
 	struct tpm_chip *chip = dev_get_drvdata(dev);
 
-	tpm_chip_unregister(chip);
-
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		tpm2_shutdown(chip, TPM2_SU_CLEAR);
 
+	tpm_chip_unregister(chip);
+
 	return 0;
 }
 
author maintainer
#98 lore raw

PATCH 89/238 tpm_eventlog.c: fix binary_bios_measurements

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Harald Hoyer <[email protected]>

commit 186d124f07da193a8f47e491af85cb695d415f2f upstream.

The commit 0cc698af36ff ("vTPM: support little endian guests") copied the event, but without the event data, did an endian conversion on the size and tried to output the event data from the copied version, which has only have one byte of the data, resulting in garbage event data.

[[email protected]: fixed minor coding style issues and
renamed the local variable tempPtr as temp_ptr now that there is an excuse to do this.]

Fixes 0cc698af36ff ("vTPM: support little endian guests")
---
 drivers/char/tpm/tpm_eventlog.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/char/tpm/tpm_eventlog.c +10 -4
@@ -232,7 +232,7 @@ static int tpm_binary_bios_measurements_
 {
 	struct tcpa_event *event = v;
 	struct tcpa_event temp_event;
-	char *tempPtr;
+	char *temp_ptr;
 	int i;
 
 	memcpy(&temp_event, event, sizeof(struct tcpa_event));
@@ -242,10 +242,16 @@ static int tpm_binary_bios_measurements_
 	temp_event.event_type = do_endian_conversion(event->event_type);
 	temp_event.event_size = do_endian_conversion(event->event_size);
 
-	tempPtr = (char *)&temp_event;
+	temp_ptr = (char *) &temp_event;
 
-	for (i = 0; i < sizeof(struct tcpa_event) + temp_event.event_size; i++)
-		seq_putc(m, tempPtr[i]);
+	for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
+		seq_putc(m, temp_ptr[i]);
+
+	temp_ptr = (char *) v;
+
+	for (i = (sizeof(struct tcpa_event) - 1);
+	     i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
+		seq_putc(m, temp_ptr[i]);
 
 	return 0;
 
author maintainer
#99 lore raw

PATCH 90/238 tpm: fix the cleanup of struct tpm_chip

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jarkko Sakkinen <[email protected]>

commit 8e0ee3c9faed7ca68807ea45141775856c438ac0 upstream.

If the initialization fails before tpm_chip_register(), put_device() will be not called, which causes release callback not to be called. This patch fixes the issue by adding put_device() to devres list of the parent device.

Fixes 313d21eeab ("tpm: device class for tpm")
---
 drivers/char/tpm/tpm-chip.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/tpm/tpm-chip.c +3 -1
@@ -136,6 +136,8 @@ struct tpm_chip *tpmm_chip_alloc(struct
 	chip->cdev.owner = chip->pdev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
+	devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
+
 	return chip;
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
@@ -171,7 +173,7 @@ static int tpm_add_char_device(struct tp
 static void tpm_del_char_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
-	device_unregister(&chip->dev);
+	device_del(&chip->dev);
 }
 
 static int tpm1_chip_register(struct tpm_chip *chip)
author maintainer
#100 lore raw

PATCH 91/238 HID: logitech: fix Dual Action gamepad support

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Grazvydas Ignotas <[email protected]>

commit 5d74325a2201376a95520a4a38a1ce2c65761c49 upstream.

The patch that added Logitech Dual Action gamepad support forgot to update the special driver list for the device. This caused the logitech driver not to probe unless kernel module load order was favorable. Update the special driver list to fix it. Thanks to Simon Wood for the idea.

Cc Vitaly Katraew <[email protected]>
Fixes 56d0c8b7c8fb ("HID: add support for Logitech Dual Action gamepads")
---
 drivers/hid/hid-core.c |    1 +
 1 file changed, 1 insertion(+)
drivers/hid/hid-core.c +1 -0
@@ -1891,6 +1891,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
author maintainer
#101 lore raw

PATCH 92/238 HID: i2c-hid: fix OOB write in i2c_hid_set_or_send_report()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Torokhov <[email protected]>

commit 3b654288b196ceaa156029d9457ccbded0489b98 upstream.

Even though hid_hw_* checks that passed in data_len is less than HID_MAX_BUFFER_SIZE it is not enough, as i2c-hid does not necessarily allocate buffers of HID_MAX_BUFFER_SIZE but rather checks all device reports and select largest size. In-kernel users normally just send as much data as report needs, so there is no problem, but hidraw users can do whatever they please:

BUG: KASAN: slab-out-of-bounds in memcpy+0x34/0x54 at addr ffffffc07135ea80
Write of size 4101 by task syz-executor/8747
CPU: 2 PID: 8747 Comm: syz-executor Tainted: G    BU         3.18.0 #37
Hardware name: Google Tegra210 Smaug Rev 1,3+ (DT)
Call trace:
[<ffffffc00020ebcc>] dump_backtrace+0x0/0x258 arch/arm64/kernel/traps.c:83
[<ffffffc00020ee40>] show_stack+0x1c/0x2c arch/arm64/kernel/traps.c:172
[<     inline     >] __dump_stack lib/dump_stack.c:15
[<ffffffc001958114>] dump_stack+0x90/0x140 lib/dump_stack.c:50
[<     inline     >] print_error_description mm/kasan/report.c:97
[<     inline     >] kasan_report_error mm/kasan/report.c:278
[<ffffffc0004597dc>] kasan_report+0x268/0x530 mm/kasan/report.c:305
[<ffffffc0004592e8>] __asan_storeN+0x20/0x150 mm/kasan/kasan.c:718
[<ffffffc0004594e0>] memcpy+0x30/0x54 mm/kasan/kasan.c:299
[<ffffffc001306354>] __i2c_hid_command+0x2b0/0x7b4 drivers/hid/i2c-hid/i2c-hid.c:178
[<     inline     >] i2c_hid_set_or_send_report drivers/hid/i2c-hid/i2c-hid.c:321
[<ffffffc0013079a0>] i2c_hid_output_raw_report.isra.2+0x3d4/0x4b8 drivers/hid/i2c-hid/i2c-hid.c:589
[<ffffffc001307ad8>] i2c_hid_output_report+0x54/0x68 drivers/hid/i2c-hid/i2c-hid.c:602
[<     inline     >] hid_hw_output_report include/linux/hid.h:1039
[<ffffffc0012cc7a0>] hidraw_send_report+0x400/0x414 drivers/hid/hidraw.c:154
[<ffffffc0012cc7f4>] hidraw_write+0x40/0x64 drivers/hid/hidraw.c:177
[<ffffffc0004681dc>] vfs_write+0x1d4/0x3cc fs/read_write.c:534
[<     inline     >] SYSC_pwrite64 fs/read_write.c:627
[<ffffffc000468984>] SyS_pwrite64+0xec/0x144 fs/read_write.c:614

Object at ffffffc07135ea80, in cache kmalloc-512
Object allocated with size 268 bytes.

Let's check data length against the buffer size before attempting to copy data over.

---
 drivers/hid/i2c-hid/i2c-hid.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/hid/i2c-hid/i2c-hid.c +10 -6
@@ -283,17 +283,21 @@ static int i2c_hid_set_or_send_report(st
 	u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
 	u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister);
 	u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength);
+	u16 size;
+	int args_len;
+	int index = 0;
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	if (data_len > ihid->bufsize)
+		return -EINVAL;
 
-	/* hid_hw_* already checked that data_len < HID_MAX_BUFFER_SIZE */
-	u16 size =	2			/* size */ +
+	size =		2			/* size */ +
 			(reportID ? 1 : 0)	/* reportID */ +
 			data_len		/* buf */;
-	int args_len =	(reportID >= 0x0F ? 1 : 0) /* optional third byte */ +
+	args_len =	(reportID >= 0x0F ? 1 : 0) /* optional third byte */ +
 			2			/* dataRegister */ +
 			size			/* args */;
-	int index = 0;
-
-	i2c_hid_dbg(ihid, "%s\n", __func__);
 
 	if (!use_data && maxOutputLength == 0)
 		return -ENOSYS;
author maintainer
#102 lore raw

PATCH 93/238 HID: multitouch: force retrieving of Win8 signature blob

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Tissoires <[email protected]>

commit 45c5c6828214605eaefa6755c47bd1a2c7eb203e upstream.

The Synaptics 0x11e5 over I2C found in the Asus T100-CHI requires to fetch the signature blob to actually start sending events.

With this patch, we should be close enough to the Windows driver which checks the content of the blob at plugin to validate or not the touchscreen.

Fixes 6d4f5440 ("HID: multitouch: Fetch feature reports on demand for Win8 devices")
---
 drivers/hid/hid-multitouch.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/hid/hid-multitouch.c +5 -0
@@ -396,6 +396,11 @@ static void mt_feature_mapping(struct hi
 			td->is_buttonpad = true;
 
 		break;
+	case 0xff0000c5:
+		/* Retrieve the Win8 blob once to enable some devices */
+		if (usage->usage_index == 0)
+			mt_get_feature(hdev, field->report);
+		break;
 	}
 }
 
author maintainer
#103 lore raw

PATCH 94/238 HID: fix hid_ignore_special_drivers module parameter

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Tissoires <[email protected]>

commit 4392bf333388cabdad5afe5b1500002d7b9c318e upstream.

hid_ignore_special_drivers works fine until hid_scan_report autodetects and reassign devices (for hid-multitouch, hid-microsoft and hid-rmi).

Simplify the handling of the parameter: if it is there, use hid-generic, no matter what, and if not, scan the device or rely on the hid_have_special_driver table.

This was detected while trying to disable hid-multitouch on a Surface Pro cover which prevented to use the keyboard.

---
 drivers/hid/hid-core.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/hid/hid-core.c +4 -3
@@ -2616,9 +2616,10 @@ int hid_add_device(struct hid_device *hd
 	/*
 	 * Scan generic devices for group information
 	 */
-	if (hid_ignore_special_drivers ||
-	    (!hdev->group &&
-	     !hid_match_id(hdev, hid_have_special_driver))) {
+	if (hid_ignore_special_drivers) {
+		hdev->group = HID_GROUP_GENERIC;
+	} else if (!hdev->group &&
+		   !hid_match_id(hdev, hid_have_special_driver)) {
 		ret = hid_scan_report(hdev);
 		if (ret)
 			hid_warn(hdev, "bad device descriptor (%d)\n", ret);
author maintainer
#104 lore raw

PATCH 95/238 staging: comedi: ni_tiocmd: change mistaken use of start_src for start_arg

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Spencer E. Olson <[email protected]>

commit 1fd24a4702d2af0ea4d5845126cf57d4d1796216 upstream.

This fixes a bug in function ni_tio_input_inttrig(). The trigger number should be compared to cmd->start_arg, not cmd->start_src.

Fixes 6a760394d7eb ("staging: comedi: ni_tiocmd: clarify the cmd->start_arg validation and use")
---
 drivers/staging/comedi/drivers/ni_tiocmd.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/comedi/drivers/ni_tiocmd.c +1 -1
@@ -92,7 +92,7 @@ static int ni_tio_input_inttrig(struct c
 	unsigned long flags;
 	int ret = 0;
 
-	if (trig_num != cmd->start_src)
+	if (trig_num != cmd->start_arg)
 		return -EINVAL;
 
 	spin_lock_irqsave(&counter->lock, flags);
author maintainer
#105 lore raw

PATCH 96/238 staging: android: ion_test: fix check of platform_device_register_simple() error code

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vladimir Zapolskiy <[email protected]>

commit ccbc2a9e7878ff09bcaed4893c2a2d3adbb797e2 upstream.

On error platform_device_register_simple() returns ERR_PTR() value, check for NULL always fails. The change corrects the check itself and propagates the returned error upwards.

Fixes 81fb0b901397 ("staging: android: ion_test: unregister the platform device")
---
 drivers/staging/android/ion/ion_test.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/android/ion/ion_test.c +2 -2
@@ -285,8 +285,8 @@ static int __init ion_test_init(void)
 {
 	ion_test_pdev = platform_device_register_simple("ion-test",
 							-1, NULL, 0);
-	if (!ion_test_pdev)
-		return -ENODEV;
+	if (IS_ERR(ion_test_pdev))
+		return PTR_ERR(ion_test_pdev);
 
 	return platform_driver_probe(&ion_test_platform_driver, ion_test_probe);
 }
author maintainer
#106 lore raw

PATCH 3/5 perf/x86/intel: Fix PEBS warning by only restoring active PMU in pmi

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kan Liang <[email protected]>

commit 48253050e1a4b8b82c775185c1bc066a2a826f14 upstream.

This patch tries to fix a PEBS warning found in my stress test. The following perf command can easily trigger the pebs warning or spurious NMI error on Skylake/Broadwell/Haswell platforms:

  sudo perf record -e 'cpu/umask=0x04,event=0xc4/pp,cycles,branches,ref-cycles,cache-misses,cache-references' --call-graph fp -b -c1000 -a

Also the NMI watchdog must be enabled.

For this case, the events number is larger than counter number. So perf has to do multiplexing.

In perf_mux_hrtimer_handler, it does perf_pmu_disable(), schedule out old events, rotate_ctx, schedule in new events and finally perf_pmu_enable().

If the old events include precise event, the MSR_IA32_PEBS_ENABLE should be cleared when perf_pmu_disable(). The MSR_IA32_PEBS_ENABLE should keep 0 until the perf_pmu_enable() is called and the new event is precise event.

However, there is a corner case which could restore PEBS_ENABLE to stale value during the above period. In perf_pmu_disable(), GLOBAL_CTRL will be set to 0 to stop overflow and followed PMI. But there may be pending PMI from an earlier overflow, which cannot be stopped. So even GLOBAL_CTRL is cleared, the kernel still be possible to get PMI. At the end of the PMI handler, __intel_pmu_enable_all() will be called, which will restore the stale values if old events haven't scheduled out.

Once the stale pebs value is set, it's impossible to be corrected if the new events are non-precise. Because the pebs_enabled will be set to 0. x86_pmu.enable_all() will ignore the MSR_IA32_PEBS_ENABLE setting. As a result, the following NMI with stale PEBS_ENABLE trigger pebs warning.

The pending PMI after enabled=0 will become harmless if the NMI handler does not change the state. This patch checks cpuc->enabled in pmi and only restore the state when PMU is active.

Here is the dump:

  Call Trace:
   <NMI>  [<ffffffff813c3a2e>] dump_stack+0x63/0x85
   [<ffffffff810a46f2>] warn_slowpath_common+0x82/0xc0
   [<ffffffff810a483a>] warn_slowpath_null+0x1a/0x20
   [<ffffffff8100fe2e>] intel_pmu_drain_pebs_nhm+0x2be/0x320
   [<ffffffff8100caa9>] intel_pmu_handle_irq+0x279/0x460
   [<ffffffff810639b6>] ? native_write_msr_safe+0x6/0x40
   [<ffffffff811f290d>] ? vunmap_page_range+0x20d/0x330
   [<ffffffff811f2f11>] ?  unmap_kernel_range_noflush+0x11/0x20
   [<ffffffff8148379f>] ? ghes_copy_tofrom_phys+0x10f/0x2a0
   [<ffffffff814839c8>] ? ghes_read_estatus+0x98/0x170
   [<ffffffff81005a7d>] perf_event_nmi_handler+0x2d/0x50
   [<ffffffff810310b9>] nmi_handle+0x69/0x120
   [<ffffffff810316f6>] default_do_nmi+0xe6/0x100
   [<ffffffff810317f2>] do_nmi+0xe2/0x130
   [<ffffffff817aea71>] end_repeat_nmi+0x1a/0x1e
   [<ffffffff810639b6>] ? native_write_msr_safe+0x6/0x40
   [<ffffffff810639b6>] ? native_write_msr_safe+0x6/0x40
   [<ffffffff810639b6>] ? native_write_msr_safe+0x6/0x40
   <<EOE>>  <IRQ>  [<ffffffff81006df8>] ?  x86_perf_event_set_period+0xd8/0x180
   [<ffffffff81006eec>] x86_pmu_start+0x4c/0x100
   [<ffffffff8100722d>] x86_pmu_enable+0x28d/0x300
   [<ffffffff811994d7>] perf_pmu_enable.part.81+0x7/0x10
   [<ffffffff8119cb70>] perf_mux_hrtimer_handler+0x200/0x280
   [<ffffffff8119c970>] ?  __perf_install_in_context+0xc0/0xc0
   [<ffffffff8110f92d>] __hrtimer_run_queues+0xfd/0x280
   [<ffffffff811100d8>] hrtimer_interrupt+0xa8/0x190
   [<ffffffff81199080>] ?  __perf_read_group_add.part.61+0x1a0/0x1a0
   [<ffffffff81051bd8>] local_apic_timer_interrupt+0x38/0x60
   [<ffffffff817af01d>] smp_apic_timer_interrupt+0x3d/0x50
   [<ffffffff817ad15c>] apic_timer_interrupt+0x8c/0xa0
   <EOI>  [<ffffffff81199080>] ?  __perf_read_group_add.part.61+0x1a0/0x1a0
   [<ffffffff81123de5>] ?  smp_call_function_single+0xd5/0x130
   [<ffffffff81123ddb>] ?  smp_call_function_single+0xcb/0x130
   [<ffffffff81199080>] ?  __perf_read_group_add.part.61+0x1a0/0x1a0
   [<ffffffff8119765a>] event_function_call+0x10a/0x120
   [<ffffffff8119c660>] ? ctx_resched+0x90/0x90
   [<ffffffff811971e0>] ? cpu_clock_event_read+0x30/0x30
   [<ffffffff811976d0>] ? _perf_event_disable+0x60/0x60
   [<ffffffff8119772b>] _perf_event_enable+0x5b/0x70
   [<ffffffff81197388>] perf_event_for_each_child+0x38/0xa0
   [<ffffffff811976d0>] ? _perf_event_disable+0x60/0x60
   [<ffffffff811a0ffd>] perf_ioctl+0x12d/0x3c0
   [<ffffffff8134d855>] ? selinux_file_ioctl+0x95/0x1e0
   [<ffffffff8124a3a1>] do_vfs_ioctl+0xa1/0x5a0
   [<ffffffff81036d29>] ? sched_clock+0x9/0x10
   [<ffffffff8124a919>] SyS_ioctl+0x79/0x90
   [<ffffffff817ac4b2>] entry_SYSCALL_64_fastpath+0x1a/0xa4
  ---[ end trace aef202839fe9a71d ]---
  Uhhuh. NMI received for unknown reason 2d on CPU 2.
  Do you have a strange power saving mode enabled?
Cc Alexander Shishkin <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Vince Weaver <[email protected]>
[ Fixed various typos and other small details. ]
---
 arch/x86/kernel/cpu/perf_event.c       |   13 +++++++++++++
 arch/x86/kernel/cpu/perf_event_intel.c |   15 +++++++++++++--
 arch/x86/kernel/cpu/perf_event_knc.c   |    4 +++-
 3 files changed, 29 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/perf_event.c +13 -0
@@ -596,6 +596,19 @@ void x86_pmu_disable_all(void)
 	}
 }
 
+/*
+ * There may be PMI landing after enabled=0. The PMI hitting could be before or
+ * after disable_all.
+ *
+ * If PMI hits before disable_all, the PMU will be disabled in the NMI handler.
+ * It will not be re-enabled in the NMI handler again, because enabled=0. After
+ * handling the NMI, disable_all will be called, which will not change the
+ * state either. If PMI hits after disable_all, the PMU is already disabled
+ * before entering NMI handler. The NMI handler will not change the state
+ * either.
+ *
+ * So either situation is harmless.
+ */
 static void x86_pmu_disable(struct pmu *pmu)
 {
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
arch/x86/kernel/cpu/perf_event_intel.c +13 -2
@@ -1502,7 +1502,15 @@ static __initconst const u64 knl_hw_cach
 };
 
 /*
- * Use from PMIs where the LBRs are already disabled.
+ * Used from PMIs where the LBRs are already disabled.
+ *
+ * This function could be called consecutively. It is required to remain in
+ * disabled state if called consecutively.
+ *
+ * During consecutive calls, the same disable value will be written to related
+ * registers, so the PMU state remains unchanged. hw.state in
+ * intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive
+ * calls.
  */
 static void __intel_pmu_disable_all(void)
 {
@@ -1939,7 +1947,10 @@ again:
 		goto again;
 
 done:
-	__intel_pmu_enable_all(0, true);
+	/* Only restore PMU state when it's active. See x86_pmu_disable(). */
+	if (cpuc->enabled)
+		__intel_pmu_enable_all(0, true);
+
 	/*
 	 * Only unmask the NMI after the overflow counters
 	 * have been reset. This avoids spurious NMIs on
arch/x86/kernel/cpu/perf_event_knc.c +3 -1
@@ -263,7 +263,9 @@ again:
 		goto again;
 
 done:
-	knc_pmu_enable_all(0);
+	/* Only restore PMU state when it's active. See x86_pmu_disable(). */
+	if (cpuc->enabled)
+		knc_pmu_enable_all(0);
 
 	return handled;
 }
author maintainer
#107 lore raw

PATCH 97/238 staging: comedi: ni_mio_common: fix the ni_write[blw]() functions

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: H Hartley Sweeten <[email protected]>

commit bd3a3cd6c27b117fb9a43a38c8072c95332beecc upstream.

Memory mapped io (dev->mmio) should not also be writing to the ioport (dev->iobase) registers. Add the missing 'else' to these functions.

Fixes 0953ee4acca0 ("staging: comedi: ni_mio_common: checkpatch.pl cleanup (else not useful)")
---
 drivers/staging/comedi/drivers/ni_mio_common.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/staging/comedi/drivers/ni_mio_common.c +6 -6
@@ -246,24 +246,24 @@ static void ni_writel(struct comedi_devi
 {
 	if (dev->mmio)
 		writel(data, dev->mmio + reg);
-
-	outl(data, dev->iobase + reg);
+	else
+		outl(data, dev->iobase + reg);
 }
 
 static void ni_writew(struct comedi_device *dev, uint16_t data, int reg)
 {
 	if (dev->mmio)
 		writew(data, dev->mmio + reg);
-
-	outw(data, dev->iobase + reg);
+	else
+		outw(data, dev->iobase + reg);
 }
 
 static void ni_writeb(struct comedi_device *dev, uint8_t data, int reg)
 {
 	if (dev->mmio)
 		writeb(data, dev->mmio + reg);
-
-	outb(data, dev->iobase + reg);
+	else
+		outb(data, dev->iobase + reg);
 }
 
 static uint32_t ni_readl(struct comedi_device *dev, int reg)
author maintainer
#108 lore raw

PATCH 98/238 tty: Fix GPF in flush_to_ldisc(), part 2

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Hurley <[email protected]>

commit f33798deecbd59a2955f40ac0ae2bc7dff54c069 upstream.

commit 9ce119f318ba ("tty: Fix GPF in flush_to_ldisc()") fixed a GPF caused by a line discipline which does not define a receive_buf() method.

However, the vt driver (and speakup driver also) pushes selection data directly to the line discipline receive_buf() method via tty_ldisc_receive_buf(). Fix the same problem in tty_ldisc_receive_buf().

---
 include/linux/tty.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/tty.h +1 -1
@@ -589,7 +589,7 @@ static inline int tty_ldisc_receive_buf(
 		count = ld->ops->receive_buf2(ld->tty, p, f, count);
 	else {
 		count = min_t(int, count, ld->tty->receive_room);
-		if (count)
+		if (count && ld->ops->receive_buf)
 			ld->ops->receive_buf(ld->tty, p, f, count);
 	}
 	return count;
author maintainer
#109 lore raw

PATCH 99/238 net: irda: Fix use-after-free in irtty_open()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Hurley <[email protected]>

commit 401879c57f01cbf2da204ad2e8db910525c6dbea upstream.

The N_IRDA line discipline may access the previous line discipline's closed and already-fre private data on open [1].

The tty->disc_data field _never_ refers to valid data on entry to the line discipline's open() method. Rather, the ldisc is expected to initialize that field for its own use for the lifetime of the instance (ie. from open() to close() only).

[1]

    ==================================================================
    BUG: KASAN: use-after-free in irtty_open+0x422/0x550 at addr ffff8800331dd068
    Read of size 4 by task a.out/13960
    =============================================================================
    BUG kmalloc-512 (Tainted: G    B          ): kasan: bad access detected
    -----------------------------------------------------------------------------
    ...
    Call Trace:
     [<ffffffff815fa2ae>] __asan_report_load4_noabort+0x3e/0x40 mm/kasan/report.c:279
     [<ffffffff836938a2>] irtty_open+0x422/0x550 drivers/net/irda/irtty-sir.c:436
     [<ffffffff829f1b80>] tty_ldisc_open.isra.2+0x60/0xa0 drivers/tty/tty_ldisc.c:447
     [<ffffffff829f21c0>] tty_set_ldisc+0x1a0/0x940 drivers/tty/tty_ldisc.c:567
     [<     inline     >] tiocsetd drivers/tty/tty_io.c:2650
     [<ffffffff829da49e>] tty_ioctl+0xace/0x1fd0 drivers/tty/tty_io.c:2883
     [<     inline     >] vfs_ioctl fs/ioctl.c:43
     [<ffffffff816708ac>] do_vfs_ioctl+0x57c/0xe60 fs/ioctl.c:607
     [<     inline     >] SYSC_ioctl fs/ioctl.c:622
     [<ffffffff81671204>] SyS_ioctl+0x74/0x80 fs/ioctl.c:613
     [<ffffffff852a7876>] entry_SYSCALL_64_fastpath+0x16/0x7a
---
 drivers/net/irda/irtty-sir.c |   10 ----------
 1 file changed, 10 deletions(-)
drivers/net/irda/irtty-sir.c +0 -10
@@ -430,16 +430,6 @@ static int irtty_open(struct tty_struct
 
 	/* Module stuff handled via irda_ldisc.owner - Jean II */
 
-	/* First make sure we're not already connected. */
-	if (tty->disc_data != NULL) {
-		priv = tty->disc_data;
-		if (priv && priv->magic == IRTTY_MAGIC) {
-			ret = -EEXIST;
-			goto out;
-		}
-		tty->disc_data = NULL;		/* ### */
-	}
-
 	/* stop the underlying  driver */
 	irtty_stop_receiver(tty, TRUE);
 	if (tty->ops->stop)
author maintainer
#110 lore raw

PATCH 100/238 8250: use callbacks to access UART_DLL/UART_DLM

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sebastian Frias <[email protected]>

commit 0b41ce991052022c030fd868e03877700220b090 upstream.

Some UART HW has a single register combining UART_DLL/UART_DLM (this was probably forgotten in the change that introduced the callbacks, commit b32b19b8ffc05cbd3bf91c65e205f6a912ca15d9)

Fixes b32b19b8ffc0 ("[SERIAL] 8250: set divisor register correctly ...")
---
 drivers/tty/serial/8250/8250_port.c |   18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)
drivers/tty/serial/8250/8250_port.c +6 -12
@@ -731,22 +731,16 @@ static int size_fifo(struct uart_8250_po
  */
 static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
 {
-	unsigned char old_dll, old_dlm, old_lcr;
-	unsigned int id;
+	unsigned char old_lcr;
+	unsigned int id, old_dl;
 
 	old_lcr = serial_in(p, UART_LCR);
 	serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
+	old_dl = serial_dl_read(p);
+	serial_dl_write(p, 0);
+	id = serial_dl_read(p);
+	serial_dl_write(p, old_dl);
 
-	old_dll = serial_in(p, UART_DLL);
-	old_dlm = serial_in(p, UART_DLM);
-
-	serial_out(p, UART_DLL, 0);
-	serial_out(p, UART_DLM, 0);
-
-	id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
-
-	serial_out(p, UART_DLL, old_dll);
-	serial_out(p, UART_DLM, old_dlm);
 	serial_out(p, UART_LCR, old_lcr);
 
 	return id;
author maintainer
#111 lore raw

PATCH 101/238 saa7134: Fix bytesperline not being set correctly for planar formats

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 3e71da19f9dc22e39a755d6ae9678661abb66adc upstream.

bytesperline should be the bytesperline for the first plane for planar formats, not that of all planes combined.

This fixes a crash in xawtv caused by the wrong bpl.

---
 drivers/media/pci/saa7134/saa7134-video.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/media/pci/saa7134/saa7134-video.c +12 -6
@@ -1219,10 +1219,13 @@ static int saa7134_g_fmt_vid_cap(struct
 	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.field        = dev->field;
 	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
-	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * dev->fmt->depth) >> 3;
+	if (dev->fmt->planar)
+		f->fmt.pix.bytesperline = f->fmt.pix.width;
+	else
+		f->fmt.pix.bytesperline =
+			(f->fmt.pix.width * dev->fmt->depth) / 8;
 	f->fmt.pix.sizeimage =
-		f->fmt.pix.height * f->fmt.pix.bytesperline;
+		(f->fmt.pix.height * f->fmt.pix.width * dev->fmt->depth) / 8;
 	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 	return 0;
 }
@@ -1298,10 +1301,13 @@ static int saa7134_try_fmt_vid_cap(struc
 	if (f->fmt.pix.height > maxh)
 		f->fmt.pix.height = maxh;
 	f->fmt.pix.width &= ~0x03;
-	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * fmt->depth) >> 3;
+	if (fmt->planar)
+		f->fmt.pix.bytesperline = f->fmt.pix.width;
+	else
+		f->fmt.pix.bytesperline =
+			(f->fmt.pix.width * fmt->depth) / 8;
 	f->fmt.pix.sizeimage =
-		f->fmt.pix.height * f->fmt.pix.bytesperline;
+		(f->fmt.pix.height * f->fmt.pix.width * fmt->depth) / 8;
 	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 
 	return 0;
author maintainer
#112 lore raw

PATCH 102/238 adv7511: TX_EDID_PRESENT is still 1 after a disconnect

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans Verkuil <[email protected]>

commit b339a72e04a62f0b1882c43492fc712f1176b3e6 upstream.

The V4L2_CID_TX_EDID_PRESENT control reports if an EDID is present. The adv7511 however still reported the EDID present after disconnecting the HDMI cable. Fix the logic regarding this control. And when the EDID is disconnected also call ADV7511_EDID_DETECT to notify the bridge driver. This was also missing.

---
 drivers/media/i2c/adv7511.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
drivers/media/i2c/adv7511.c +15 -6
@@ -1161,12 +1161,23 @@ static void adv7511_dbg_dump_edid(int lv
 	}
 }
 
+static void adv7511_notify_no_edid(struct v4l2_subdev *sd)
+{
+	struct adv7511_state *state = get_adv7511_state(sd);
+	struct adv7511_edid_detect ed;
+
+	/* We failed to read the EDID, so send an event for this. */
+	ed.present = false;
+	ed.segment = adv7511_rd(sd, 0xc4);
+	v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+	v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x0);
+}
+
 static void adv7511_edid_handler(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct adv7511_state *state = container_of(dwork, struct adv7511_state, edid_handler);
 	struct v4l2_subdev *sd = &state->sd;
-	struct adv7511_edid_detect ed;
 
 	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
 
@@ -1191,9 +1202,7 @@ static void adv7511_edid_handler(struct
 	}
 
 	/* We failed to read the EDID, so send an event for this. */
-	ed.present = false;
-	ed.segment = adv7511_rd(sd, 0xc4);
-	v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+	adv7511_notify_no_edid(sd);
 	v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
 }
 
@@ -1264,7 +1273,6 @@ static void adv7511_check_monitor_presen
 	/* update read only ctrls */
 	v4l2_ctrl_s_ctrl(state->hotplug_ctrl, adv7511_have_hotplug(sd) ? 0x1 : 0x0);
 	v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, adv7511_have_rx_sense(sd) ? 0x1 : 0x0);
-	v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
 
 	if ((status & MASK_ADV7511_HPD_DETECT) && ((status & MASK_ADV7511_MSEN_DETECT) || state->edid.segments)) {
 		v4l2_dbg(1, debug, sd, "%s: hotplug and (rx-sense or edid)\n", __func__);
@@ -1294,6 +1302,7 @@ static void adv7511_check_monitor_presen
 		}
 		adv7511_s_power(sd, false);
 		memset(&state->edid, 0, sizeof(struct adv7511_state_edid));
+		adv7511_notify_no_edid(sd);
 	}
 }
 
@@ -1370,6 +1379,7 @@ static bool adv7511_check_edid_status(st
 		}
 		/* one more segment read ok */
 		state->edid.segments = segment + 1;
+		v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x1);
 		if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
 			/* Request next EDID segment */
 			v4l2_dbg(1, debug, sd, "%s: request segment %d\n", __func__, state->edid.segments);
@@ -1389,7 +1399,6 @@ static bool adv7511_check_edid_status(st
 		ed.present = true;
 		ed.segment = 0;
 		state->edid_detect_counter++;
-		v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
 		v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
 		return ed.present;
 	}
author maintainer
#113 lore raw

PATCH 103/238 bttv: Width must be a multiple of 16 when capturing planar formats

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 5c915c68763889f0183a1cc61c84bb228b60124a upstream.

On my bttv card "Hauppauge WinTV [card=10]" capturing in YV12 fmt at max size results in a solid green rectangle being captured (all colors 0 in YUV).

This turns out to be caused by max-width (924) not being a multiple of 16.

We've likely never hit this problem before since normally xawtv / tvtime, etc. will prefer packed pixel formats. But when using a video card which is using xf86-video-modesetting + glamor, only planar XVideo fmts are available, and xawtv will chose a matching capture format to avoid needing to do conversion, triggering the solid green window problem.

---
 drivers/media/pci/bt8xx/bttv-driver.c |   26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/media/pci/bt8xx/bttv-driver.c +20 -6
@@ -2334,6 +2334,19 @@ static int bttv_g_fmt_vid_overlay(struct
 	return 0;
 }
 
+static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt,
+					unsigned int *width_mask,
+					unsigned int *width_bias)
+{
+	if (fmt->flags & FORMAT_FLAGS_PLANAR) {
+		*width_mask = ~15; /* width must be a multiple of 16 pixels */
+		*width_bias = 8;   /* nearest */
+	} else {
+		*width_mask = ~3; /* width must be a multiple of 4 pixels */
+		*width_bias = 2;  /* nearest */
+	}
+}
+
 static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
 						struct v4l2_format *f)
 {
@@ -2343,6 +2356,7 @@ static int bttv_try_fmt_vid_cap(struct f
 	enum v4l2_field field;
 	__s32 width, height;
 	__s32 height2;
+	unsigned int width_mask, width_bias;
 	int rc;
 
 	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
@@ -2375,9 +2389,9 @@ static int bttv_try_fmt_vid_cap(struct f
 	width = f->fmt.pix.width;
 	height = f->fmt.pix.height;
 
+	bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
 	rc = limit_scaled_size_lock(fh, &width, &height, field,
-			       /* width_mask: 4 pixels */ ~3,
-			       /* width_bias: nearest */ 2,
+			       width_mask, width_bias,
 			       /* adjust_size */ 1,
 			       /* adjust_crop */ 0);
 	if (0 != rc)
@@ -2410,6 +2424,7 @@ static int bttv_s_fmt_vid_cap(struct fil
 	struct bttv_fh *fh = priv;
 	struct bttv *btv = fh->btv;
 	__s32 width, height;
+	unsigned int width_mask, width_bias;
 	enum v4l2_field field;
 
 	retval = bttv_switch_type(fh, f->type);
@@ -2424,9 +2439,10 @@ static int bttv_s_fmt_vid_cap(struct fil
 	height = f->fmt.pix.height;
 	field = f->fmt.pix.field;
 
+	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
 	retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field,
-			       /* width_mask: 4 pixels */ ~3,
-			       /* width_bias: nearest */ 2,
+			       width_mask, width_bias,
 			       /* adjust_size */ 1,
 			       /* adjust_crop */ 1);
 	if (0 != retval)
@@ -2434,8 +2450,6 @@ static int bttv_s_fmt_vid_cap(struct fil
 
 	f->fmt.pix.field = field;
 
-	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
 	/* update our state informations */
 	fh->fmt              = fmt;
 	fh->cap.field        = f->fmt.pix.field;
author maintainer
#114 lore raw

PATCH 104/238 coda: fix first encoded frame payload

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Philipp Zabel <[email protected]>

commit 74dc385cb450089b28c28be2c8a0baca296b95f9 upstream.

During the recent vb2_buffer restructuring, the calculation of the buffer payload reported to userspace was accidentally broken for the first encoded frame, counting only the length of the headers. This patch re-adds the length of the actual frame data.

Fixes 2d7007153f0c ("[media] media: videobuf2: Restructure vb2_buffer")
---
 drivers/media/platform/coda/coda-bit.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/coda/coda-bit.c +1 -1
@@ -1342,7 +1342,7 @@ static void coda_finish_encode(struct co
 
 	/* Calculate bytesused field */
 	if (dst_buf->sequence == 0) {
-		vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr +
 					ctx->vpu_header_size[0] +
 					ctx->vpu_header_size[1] +
 					ctx->vpu_header_size[2]);
author maintainer
#115 lore raw

PATCH 105/238 media: v4l2-compat-ioctl32: fix missing length copy in put_v4l2_buffer32

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tiffany Lin <[email protected]>

commit 7df5ab8774aa383c6d2bff00688d004585d96dfd upstream.

In v4l2-compliance utility, test QUERYBUF required correct length value to go through each planar to check planar's length in multi-planar buffer type

---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/media/v4l2-core/v4l2-compat-ioctl32.c +8 -13
@@ -415,7 +415,8 @@ static int get_v4l2_buffer32(struct v4l2
 		get_user(kp->index, &up->index) ||
 		get_user(kp->type, &up->type) ||
 		get_user(kp->flags, &up->flags) ||
-		get_user(kp->memory, &up->memory))
+		get_user(kp->memory, &up->memory) ||
+		get_user(kp->length, &up->length))
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -427,9 +428,6 @@ static int get_v4l2_buffer32(struct v4l2
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		if (get_user(kp->length, &up->length))
-			return -EFAULT;
-
 		num_planes = kp->length;
 		if (num_planes == 0) {
 			kp->m.planes = NULL;
@@ -462,16 +460,14 @@ static int get_v4l2_buffer32(struct v4l2
 	} else {
 		switch (kp->memory) {
 		case V4L2_MEMORY_MMAP:
-			if (get_user(kp->length, &up->length) ||
-				get_user(kp->m.offset, &up->m.offset))
+			if (get_user(kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
 			{
 			compat_long_t tmp;
 
-			if (get_user(kp->length, &up->length) ||
-			    get_user(tmp, &up->m.userptr))
+			if (get_user(tmp, &up->m.userptr))
 				return -EFAULT;
 
 			kp->m.userptr = (unsigned long)compat_ptr(tmp);
@@ -513,7 +509,8 @@ static int put_v4l2_buffer32(struct v4l2
 		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
 		put_user(kp->sequence, &up->sequence) ||
 		put_user(kp->reserved2, &up->reserved2) ||
-		put_user(kp->reserved, &up->reserved))
+		put_user(kp->reserved, &up->reserved) ||
+		put_user(kp->length, &up->length))
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
@@ -536,13 +533,11 @@ static int put_v4l2_buffer32(struct v4l2
 	} else {
 		switch (kp->memory) {
 		case V4L2_MEMORY_MMAP:
-			if (put_user(kp->length, &up->length) ||
-				put_user(kp->m.offset, &up->m.offset))
+			if (put_user(kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
-			if (put_user(kp->length, &up->length) ||
-				put_user(kp->m.userptr, &up->m.userptr))
+			if (put_user(kp->m.userptr, &up->m.userptr))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_OVERLAY:
author maintainer
#116 lore raw

PATCH 106/238 mtip32xx: Avoid issuing standby immediate cmd during FTL rebuild

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit d8a18d2d8f5de55666c6011ed175939d22c8e3d8 upstream.

Prevent standby immediate command from being issued in remove, suspend and shutdown paths, while drive is in FTL rebuild process.

---
 drivers/block/mtip32xx/mtip32xx.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +12 -8
@@ -3263,20 +3263,25 @@ out1:
 	return rv;
 }
 
-static void mtip_standby_drive(struct driver_data *dd)
+static int mtip_standby_drive(struct driver_data *dd)
 {
-	if (dd->sr)
-		return;
+	int rv = 0;
 
+	if (dd->sr || !dd->port)
+		return -ENODEV;
 	/*
 	 * Send standby immediate (E0h) to the drive so that it
 	 * saves its state.
 	 */
 	if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) &&
-	    !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))
-		if (mtip_standby_immediate(dd->port))
+	    !test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag) &&
+	    !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) {
+		rv = mtip_standby_immediate(dd->port);
+		if (rv)
 			dev_warn(&dd->pdev->dev,
 				"STANDBY IMMEDIATE failed\n");
+	}
+	return rv;
 }
 
 /*
@@ -3334,8 +3339,7 @@ static int mtip_hw_shutdown(struct drive
 	 * Send standby immediate (E0h) to the drive so that it
 	 * saves its state.
 	 */
-	if (!dd->sr && dd->port)
-		mtip_standby_immediate(dd->port);
+	mtip_standby_drive(dd);
 
 	return 0;
 }
@@ -3358,7 +3362,7 @@ static int mtip_hw_suspend(struct driver
 	 * Send standby immediate (E0h) to the drive
 	 * so that it saves its state.
 	 */
-	if (mtip_standby_immediate(dd->port) != 0) {
+	if (mtip_standby_drive(dd) != 0) {
 		dev_err(&dd->pdev->dev,
 			"Failed standby-immediate command\n");
 		return -EFAULT;
author maintainer
#117 lore raw

PATCH 107/238 mtip32xx: Fix broken service thread handling

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit cfc05bd31384c4898bf2437a4de5557f3cf9803a upstream.

Service thread does not detect the need for taskfile error hanlding. Fixed the flag condition to process taskfile error.

---
 drivers/block/mtip32xx/mtip32xx.c |    6 +++---
 drivers/block/mtip32xx/mtip32xx.h |    5 +++++
 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +3 -3
@@ -2917,9 +2917,7 @@ static int mtip_service_thread(void *dat
 		 * is in progress nor error handling is active
 		 */
 		wait_event_interruptible(port->svc_wait, (port->flags) &&
-			!(port->flags & MTIP_PF_PAUSE_IO));
-
-		set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+			(port->flags & MTIP_PF_SVC_THD_WORK));
 
 		if (kthread_should_stop() ||
 			test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
@@ -2929,6 +2927,8 @@ static int mtip_service_thread(void *dat
 				&dd->dd_flag)))
 			goto st_out;
 
+		set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+
 restart_eh:
 		/* Demux bits: start with error handling */
 		if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) {
drivers/block/mtip32xx/mtip32xx.h +5 -0
@@ -144,6 +144,11 @@ enum {
 	MTIP_PF_REBUILD_BIT         = 6,
 	MTIP_PF_SVC_THD_STOP_BIT    = 8,
 
+	MTIP_PF_SVC_THD_WORK	= ((1 << MTIP_PF_EH_ACTIVE_BIT) |
+				  (1 << MTIP_PF_ISSUE_CMDS_BIT) |
+				  (1 << MTIP_PF_REBUILD_BIT) |
+				  (1 << MTIP_PF_SVC_THD_STOP_BIT)),
+
 	/* below are bit numbers in 'dd_flag' defined in driver_data */
 	MTIP_DDF_SEC_LOCK_BIT	    = 0,
 	MTIP_DDF_REMOVE_PENDING_BIT = 1,
author maintainer
#118 lore raw

PATCH 108/238 mtip32xx: Remove unwanted code from taskfile error handler

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit e35b94738a2f7caa12017f69ef385cb6b8028965 upstream.

Remove setting and clearing MTIP_PF_EH_ACTIVE_BIT flag in mtip_handle_tfe() as they are redundant. Also avoid waking up service thread from mtip_handle_tfe() because it is already woken up in case of taskfile error.

---
 drivers/block/mtip32xx/mtip32xx.c |    9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +1 -8
@@ -618,8 +618,6 @@ static void mtip_handle_tfe(struct drive
 
 	port = dd->port;
 
-	set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
-
 	if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
 		cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL);
 		dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n");
@@ -628,7 +626,7 @@ static void mtip_handle_tfe(struct drive
 			cmd->comp_func(port, MTIP_TAG_INTERNAL,
 					cmd, PORT_IRQ_TF_ERR);
 		}
-		goto handle_tfe_exit;
+		return;
 	}
 
 	/* clear the tag accumulator */
@@ -771,11 +769,6 @@ static void mtip_handle_tfe(struct drive
 		}
 	}
 	print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
-
-handle_tfe_exit:
-	/* clear eh_active */
-	clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
-	wake_up_interruptible(&port->svc_wait);
 }
 
 /*
author maintainer
#119 lore raw

PATCH 109/238 mtip32xx: Print exact time when an internal command is interrupted

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit 5b7e0a8ac85e2dfd83830dc9e0b3554d153a37e3 upstream.

Print exact time when an internal command is interrupted.

---
 drivers/block/mtip32xx/mtip32xx.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +6 -2
@@ -1092,6 +1092,7 @@ static int mtip_exec_internal_command(st
 	struct mtip_cmd *int_cmd;
 	struct driver_data *dd = port->dd;
 	int rv = 0;
+	unsigned long start;
 
 	/* Make sure the buffer is 8 byte aligned. This is asic specific. */
 	if (buffer & 0x00000007) {
@@ -1155,6 +1156,8 @@ static int mtip_exec_internal_command(st
 	/* Populate the command header */
 	int_cmd->command_header->byte_count = 0;
 
+	start = jiffies;
+
 	/* Issue the command to the hardware */
 	mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL);
 
@@ -1165,8 +1168,9 @@ static int mtip_exec_internal_command(st
 				msecs_to_jiffies(timeout))) <= 0) {
 			if (rv == -ERESTARTSYS) { /* interrupted */
 				dev_err(&dd->pdev->dev,
-					"Internal command [%02X] was interrupted after %lu ms\n",
-					fis->command, timeout);
+					"Internal command [%02X] was interrupted after %u ms\n",
+					fis->command,
+					jiffies_to_msecs(jiffies - start));
 				rv = -EINTR;
 				goto exec_ic_exit;
 			} else if (rv == 0) /* timeout */
#120 lore raw

Re: [PATCH 4.5 109/238] mtip32xx: Print exact time when an internal command is interrupted

Quoted 9 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit 5b7e0a8ac85e2dfd83830dc9e0b3554d153a37e3 upstream.

Print exact time when an internal command is interrupted.

[...]

There's no way that's important enough for stable.

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#121 lore raw

Re: [PATCH 4.5 109/238] mtip32xx: Print exact time when an internal command is interrupted

Quoted 5 lines · Ben Hutchings
Quoted 4 lines · Greg Kroah-Hartman

4.5-stable review patch.��If anyone has any objections, please let me know.

------------------

Quoted 8 lines
Quoted 5 lines

From: Asai Thambi SP <[email protected]>

commit 5b7e0a8ac85e2dfd83830dc9e0b3554d153a37e3 upstream.

Print exact time when an internal command is interrupted.

[...]

There's no way that's important enough for stable.

I think one of the following patches needed it :(

#122 lore raw

Re: [PATCH 4.5 109/238] mtip32xx: Print exact time when an internal command is interrupted

Quoted 8 lines · Greg Kroah-Hartman
Quoted 7 lines · Ben Hutchings
Quoted 6 lines · Greg Kroah-Hartman

4.5-stable review patch.��If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

commit 5b7e0a8ac85e2dfd83830dc9e0b3554d153a37e3 upstream.

Print exact time when an internal command is interrupted.

[...]

There's no way that's important enough for stable.

I think one of the following patches needed it :(

Also in general I'd rather encourage maintainers to push their fixes into stable than give up early and leave bogus code behind them considering it's not their problem anymore once released. If someone cares enough to fix code in -stable and introduces a regression, 1) we know how to revert and 2) the same person will likely feel concerned by the issue and help fix it.

Just my 2 cents,
Willy

author maintainer
#123 lore raw

PATCH 110/238 mtip32xx: Fix for rmmod crash when drive is in FTL rebuild

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit 59cf70e236c96594d9f1e065755d8fce9df5356b upstream.

When FTL rebuild is in progress, alloc_disk() initializes the disk but device node will be created by add_disk() only after successful completion of FTL rebuild. So, skip deletion of device node in removal path when FTL rebuild is in progress.

---
 drivers/block/mtip32xx/mtip32xx.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +7 -7
@@ -2968,10 +2968,8 @@ restart_eh:
 		}
 
 		if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
-			if (mtip_ftl_rebuild_poll(dd) < 0)
-				set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
-							&dd->dd_flag);
-			clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
+			if (mtip_ftl_rebuild_poll(dd) == 0)
+				clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
 		}
 	}
 
@@ -3851,7 +3849,6 @@ static int mtip_block_initialize(struct
 
 	mtip_hw_debugfs_init(dd);
 
-skip_create_disk:
 	memset(&dd->tags, 0, sizeof(dd->tags));
 	dd->tags.ops = &mtip_mq_ops;
 	dd->tags.nr_hw_queues = 1;
@@ -3881,6 +3878,7 @@ skip_create_disk:
 	dd->disk->queue		= dd->queue;
 	dd->queue->queuedata	= dd;
 
+skip_create_disk:
 	/* Initialize the protocol layer. */
 	wait_for_rebuild = mtip_hw_get_identify(dd);
 	if (wait_for_rebuild < 0) {
@@ -4041,7 +4039,8 @@ static int mtip_block_remove(struct driv
 		dd->bdev = NULL;
 	}
 	if (dd->disk) {
-		del_gendisk(dd->disk);
+		if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
+			del_gendisk(dd->disk);
 		if (dd->disk->queue) {
 			blk_cleanup_queue(dd->queue);
 			blk_mq_free_tag_set(&dd->tags);
@@ -4082,7 +4081,8 @@ static int mtip_block_shutdown(struct dr
 		dev_info(&dd->pdev->dev,
 			"Shutting down %s ...\n", dd->disk->disk_name);
 
-		del_gendisk(dd->disk);
+		if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
+			del_gendisk(dd->disk);
 		if (dd->disk->queue) {
 			blk_cleanup_queue(dd->queue);
 			blk_mq_free_tag_set(&dd->tags);
author maintainer
#124 lore raw

PATCH 111/238 mtip32xx: Handle safe removal during IO

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit 51c6570eb922146470c2fe660c34585414679bd6 upstream.

Flush inflight IOs using fsync_bdev() when the device is safely removed. Also, block further IOs in device open function.

---
 drivers/block/mtip32xx/mtip32xx.c |   34 ++++++++++++++++++++++++++++++++--
 drivers/block/mtip32xx/mtip32xx.h |    1 +
 2 files changed, 33 insertions(+), 2 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +32 -2
@@ -3595,6 +3595,28 @@ static int mtip_block_getgeo(struct bloc
 	return 0;
 }
 
+static int mtip_block_open(struct block_device *dev, fmode_t mode)
+{
+	struct driver_data *dd;
+
+	if (dev && dev->bd_disk) {
+		dd = (struct driver_data *) dev->bd_disk->private_data;
+
+		if (dd) {
+			if (test_bit(MTIP_DDF_REMOVAL_BIT,
+							&dd->dd_flag)) {
+				return -ENODEV;
+			}
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+void mtip_block_release(struct gendisk *disk, fmode_t mode)
+{
+}
+
 /*
  * Block device operation function.
  *
@@ -3602,6 +3624,8 @@ static int mtip_block_getgeo(struct bloc
  * layer.
  */
 static const struct block_device_operations mtip_block_ops = {
+	.open		= mtip_block_open,
+	.release	= mtip_block_release,
 	.ioctl		= mtip_block_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= mtip_block_compat_ioctl,
@@ -4427,7 +4451,7 @@ static void mtip_pci_remove(struct pci_d
 	struct driver_data *dd = pci_get_drvdata(pdev);
 	unsigned long flags, to;
 
-	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+	set_bit(MTIP_DDF_REMOVAL_BIT, &dd->dd_flag);
 
 	spin_lock_irqsave(&dev_lock, flags);
 	list_del_init(&dd->online_list);
@@ -4444,12 +4468,18 @@ static void mtip_pci_remove(struct pci_d
 	} while (atomic_read(&dd->irq_workers_active) != 0 &&
 		time_before(jiffies, to));
 
+	fsync_bdev(dd->bdev);
+
 	if (atomic_read(&dd->irq_workers_active) != 0) {
 		dev_warn(&dd->pdev->dev,
 			"Completion workers still active!\n");
 	}
 
-	blk_mq_stop_hw_queues(dd->queue);
+	if (dd->sr)
+		blk_mq_stop_hw_queues(dd->queue);
+
+	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
 	/* Clean up the block layer. */
 	mtip_block_remove(dd);
 
drivers/block/mtip32xx/mtip32xx.h +1 -0
@@ -158,6 +158,7 @@ enum {
 	MTIP_DDF_RESUME_BIT         = 6,
 	MTIP_DDF_INIT_DONE_BIT      = 7,
 	MTIP_DDF_REBUILD_FAILED_BIT = 8,
+	MTIP_DDF_REMOVAL_BIT	    = 9,
 
 	MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) |
 				(1 << MTIP_DDF_SEC_LOCK_BIT) |
author maintainer
#125 lore raw

PATCH 112/238 mtip32xx: Handle FTL rebuild failure state during device initialization

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit aae4a033868c496adae86fc6f9c3e0c405bbf360 upstream.

Allow device initialization to finish gracefully when it is in FTL rebuild failure state. Also, recover device out of this state after successfully secure erasing it.

---
 drivers/block/mtip32xx/mtip32xx.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +6 -5
@@ -699,7 +699,7 @@ static void mtip_handle_tfe(struct drive
 			fail_reason = "thermal shutdown";
 		}
 		if (buf[288] == 0xBF) {
-			set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag);
+			set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
 			dev_info(&dd->pdev->dev,
 				"Drive indicates rebuild has failed. Secure erase required.\n");
 			fail_all_ncq_cmds = 1;
@@ -1000,6 +1000,7 @@ static bool mtip_pause_ncq(struct mtip_p
 			(fis->features == 0x27 || fis->features == 0x72 ||
 			 fis->features == 0x62 || fis->features == 0x26))) {
 		clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
+		clear_bit(MTIP_DDF_REBUILD_FAILED_BIT, &port->dd->dd_flag);
 		/* Com reset after secure erase or lowlevel format */
 		mtip_restart_port(port);
 		clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
@@ -1166,6 +1167,7 @@ static int mtip_exec_internal_command(st
 		if ((rv = wait_for_completion_interruptible_timeout(
 				&wait,
 				msecs_to_jiffies(timeout))) <= 0) {
+
 			if (rv == -ERESTARTSYS) { /* interrupted */
 				dev_err(&dd->pdev->dev,
 					"Internal command [%02X] was interrupted after %u ms\n",
@@ -3084,7 +3086,7 @@ static int mtip_hw_get_identify(struct d
 		if (buf[288] == 0xBF) {
 			dev_info(&dd->pdev->dev,
 				"Drive indicates rebuild has failed.\n");
-			/* TODO */
+			set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
 		}
 	}
 
@@ -3687,10 +3689,9 @@ static int mtip_submit_request(struct bl
 				rq_data_dir(rq))) {
 			return -ENODATA;
 		}
-		if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)))
+		if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag) ||
+			test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)))
 			return -ENODATA;
-		if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag))
-			return -ENXIO;
 	}
 
 	if (rq->cmd_flags & REQ_DISCARD) {
author maintainer
#126 lore raw

PATCH 113/238 mtip32xx: Implement timeout handler

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit abb0ccd185c9e31847709b86192e6c815d1f57ad upstream.

Added timeout handler. Replaced blk_mq_end_request() with blk_mq_complete_request() to avoid double completion of a request.

---
 drivers/block/mtip32xx/mtip32xx.c |   95 ++++++++++++++++++++++++++++++++++----
 drivers/block/mtip32xx/mtip32xx.h |    7 ++
 2 files changed, 92 insertions(+), 10 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +87 -8
@@ -233,15 +233,9 @@ static void mtip_async_complete(struct m
 			"Command tag %d failed due to TFE\n", tag);
 	}
 
-	/* Unmap the DMA scatter list entries */
-	dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents, cmd->direction);
-
 	rq = mtip_rq_from_tag(dd, tag);
 
-	if (unlikely(cmd->unaligned))
-		up(&port->cmd_slot_unal);
-
-	blk_mq_end_request(rq, status ? -EIO : 0);
+	blk_mq_complete_request(rq, status);
 }
 
 /*
@@ -2889,6 +2883,42 @@ static int mtip_ftl_rebuild_poll(struct
 	return -EFAULT;
 }
 
+static void mtip_softirq_done_fn(struct request *rq)
+{
+	struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
+	struct driver_data *dd = rq->q->queuedata;
+
+	/* Unmap the DMA scatter list entries */
+	dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents,
+							cmd->direction);
+
+	if (unlikely(cmd->unaligned))
+		up(&dd->port->cmd_slot_unal);
+
+	blk_mq_end_request(rq, rq->errors);
+}
+
+static void mtip_abort_cmd(struct request *req, void *data,
+							bool reserved)
+{
+	struct driver_data *dd = data;
+
+	dbg_printk(MTIP_DRV_NAME " Aborting request, tag = %d\n", req->tag);
+
+	clear_bit(req->tag, dd->port->cmds_to_issue);
+	req->errors = -EIO;
+	mtip_softirq_done_fn(req);
+}
+
+static void mtip_queue_cmd(struct request *req, void *data,
+							bool reserved)
+{
+	struct driver_data *dd = data;
+
+	set_bit(req->tag, dd->port->cmds_to_issue);
+	blk_abort_request(req);
+}
+
 /*
  * service thread to issue queued commands
  *
@@ -2901,7 +2931,7 @@ static int mtip_ftl_rebuild_poll(struct
 static int mtip_service_thread(void *data)
 {
 	struct driver_data *dd = (struct driver_data *)data;
-	unsigned long slot, slot_start, slot_wrap;
+	unsigned long slot, slot_start, slot_wrap, to;
 	unsigned int num_cmd_slots = dd->slot_groups * 32;
 	struct mtip_port *port = dd->port;
 
@@ -2938,6 +2968,32 @@ restart_eh:
 		if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags))
 			goto restart_eh;
 
+		if (test_bit(MTIP_PF_TO_ACTIVE_BIT, &port->flags)) {
+			to = jiffies + msecs_to_jiffies(5000);
+
+			do {
+				mdelay(100);
+			} while (atomic_read(&dd->irq_workers_active) != 0 &&
+				time_before(jiffies, to));
+
+			if (atomic_read(&dd->irq_workers_active) != 0)
+				dev_warn(&dd->pdev->dev,
+					"Completion workers still active!");
+
+			spin_lock(dd->queue->queue_lock);
+			blk_mq_all_tag_busy_iter(*dd->tags.tags,
+							mtip_queue_cmd, dd);
+			spin_unlock(dd->queue->queue_lock);
+
+			set_bit(MTIP_PF_ISSUE_CMDS_BIT, &dd->port->flags);
+
+			if (mtip_device_reset(dd))
+				blk_mq_all_tag_busy_iter(*dd->tags.tags,
+							mtip_abort_cmd, dd);
+
+			clear_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags);
+		}
+
 		if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
 			slot = 1;
 			/* used to restrict the loop to one iteration */
@@ -3803,11 +3859,33 @@ static int mtip_init_cmd(void *data, str
 	return 0;
 }
 
+static enum blk_eh_timer_return mtip_cmd_timeout(struct request *req,
+								bool reserved)
+{
+	struct driver_data *dd = req->q->queuedata;
+	int ret = BLK_EH_RESET_TIMER;
+
+	if (reserved)
+		goto exit_handler;
+
+	if (test_bit(req->tag, dd->port->cmds_to_issue))
+		goto exit_handler;
+
+	if (test_and_set_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags))
+		goto exit_handler;
+
+	wake_up_interruptible(&dd->port->svc_wait);
+exit_handler:
+	return ret;
+}
+
 static struct blk_mq_ops mtip_mq_ops = {
 	.queue_rq	= mtip_queue_rq,
 	.map_queue	= blk_mq_map_queue,
 	.init_request	= mtip_init_cmd,
 	.exit_request	= mtip_free_cmd,
+	.complete	= mtip_softirq_done_fn,
+	.timeout        = mtip_cmd_timeout,
 };
 
 /*
@@ -3883,6 +3961,7 @@ static int mtip_block_initialize(struct
 	dd->tags.numa_node = dd->numa_node;
 	dd->tags.flags = BLK_MQ_F_SHOULD_MERGE;
 	dd->tags.driver_data = dd;
+	dd->tags.timeout = MTIP_NCQ_CMD_TIMEOUT_MS;
 
 	rv = blk_mq_alloc_tag_set(&dd->tags);
 	if (rv) {
drivers/block/mtip32xx/mtip32xx.h +5 -2
@@ -134,10 +134,12 @@ enum {
 	MTIP_PF_EH_ACTIVE_BIT       = 1, /* error handling */
 	MTIP_PF_SE_ACTIVE_BIT       = 2, /* secure erase */
 	MTIP_PF_DM_ACTIVE_BIT       = 3, /* download microcde */
+	MTIP_PF_TO_ACTIVE_BIT       = 9, /* timeout handling */
 	MTIP_PF_PAUSE_IO      =	((1 << MTIP_PF_IC_ACTIVE_BIT) |
 				(1 << MTIP_PF_EH_ACTIVE_BIT) |
 				(1 << MTIP_PF_SE_ACTIVE_BIT) |
-				(1 << MTIP_PF_DM_ACTIVE_BIT)),
+				(1 << MTIP_PF_DM_ACTIVE_BIT) |
+				(1 << MTIP_PF_TO_ACTIVE_BIT)),
 
 	MTIP_PF_SVC_THD_ACTIVE_BIT  = 4,
 	MTIP_PF_ISSUE_CMDS_BIT      = 5,
@@ -147,7 +149,8 @@ enum {
 	MTIP_PF_SVC_THD_WORK	= ((1 << MTIP_PF_EH_ACTIVE_BIT) |
 				  (1 << MTIP_PF_ISSUE_CMDS_BIT) |
 				  (1 << MTIP_PF_REBUILD_BIT) |
-				  (1 << MTIP_PF_SVC_THD_STOP_BIT)),
+				  (1 << MTIP_PF_SVC_THD_STOP_BIT) |
+				  (1 << MTIP_PF_TO_ACTIVE_BIT)),
 
 	/* below are bit numbers in 'dd_flag' defined in driver_data */
 	MTIP_DDF_SEC_LOCK_BIT	    = 0,
#127 lore raw

Re: [PATCH 4.5 113/238] mtip32xx: Implement timeout handler

Quoted 17 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit abb0ccd185c9e31847709b86192e6c815d1f57ad upstream.

Added timeout handler. Replaced blk_mq_end_request() with blk_mq_complete_request() to avoid double completion of a request.

Quoted 4 lines

---
 drivers/block/mtip32xx/mtip32xx.c |   95 ++++++++++++++++++++++++++++++++++---- drivers/block/mtip32xx/mtip32xx.h |    7 ++

 2 files changed, 92 insertions(+), 10 deletions(-)

[...]

This is >100 lines (the rough limit for stable), and it's part of a whole series of complex and inadequately explained changes.

How thoroughly have these changes been tested against 4.4 and 4.5?

Ben.

Signature · 2 lines
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
author maintainer
#128 lore raw

PATCH 114/238 mtip32xx: Cleanup queued requests after surprise removal

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Asai Thambi SP <[email protected]>

commit 008e56d200225321371748d95908e6222436f06d upstream.

Fail all pending requests after surprise removal of a drive.

---
 drivers/block/mtip32xx/mtip32xx.c |   78 +++++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 18 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +60 -18
@@ -173,7 +173,13 @@ static struct mtip_cmd *mtip_get_int_com
 {
 	struct request *rq;
 
+	if (mtip_check_surprise_removal(dd->pdev))
+		return NULL;
+
 	rq = blk_mq_alloc_request(dd->queue, 0, BLK_MQ_REQ_RESERVED);
+	if (IS_ERR(rq))
+		return NULL;
+
 	return blk_mq_rq_to_pdu(rq);
 }
 
@@ -575,6 +581,8 @@ static void mtip_completion(struct mtip_
 		dev_warn(&port->dd->pdev->dev,
 			"Internal command %d completed with TFE\n", tag);
 
+	command->comp_func = NULL;
+	command->comp_data = NULL;
 	complete(waiting);
 }
 
@@ -1009,12 +1017,14 @@ static bool mtip_pause_ncq(struct mtip_p
  *
  * @port    Pointer to port data structure
  * @timeout Max duration to wait (ms)
+ * @atomic  gfp_t flag to indicate blockable context or not
  *
  * return value
  *	0	Success
  *	-EBUSY  Commands still active
  */
-static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
+static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout,
+								gfp_t atomic)
 {
 	unsigned long to;
 	unsigned int n;
@@ -1025,16 +1035,21 @@ static int mtip_quiesce_io(struct mtip_p
 	to = jiffies + msecs_to_jiffies(timeout);
 	do {
 		if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) &&
-			test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
+			test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags) &&
+			atomic == GFP_KERNEL) {
 			msleep(20);
 			continue; /* svc thd is actively issuing commands */
 		}
 
-		msleep(100);
+		if (atomic == GFP_KERNEL)
+			msleep(100);
+		else {
+			cpu_relax();
+			udelay(100);
+		}
+
 		if (mtip_check_surprise_removal(port->dd->pdev))
 			goto err_fault;
-		if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
-			goto err_fault;
 
 		/*
 		 * Ignore s_active bit 0 of array element 0.
@@ -1096,6 +1111,10 @@ static int mtip_exec_internal_command(st
 	}
 
 	int_cmd = mtip_get_int_command(dd);
+	if (!int_cmd) {
+		dbg_printk(MTIP_DRV_NAME "Unable to allocate tag for PIO cmd\n");
+		return -EFAULT;
+	}
 
 	set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
 
@@ -1108,7 +1127,7 @@ static int mtip_exec_internal_command(st
 		if (fis->command != ATA_CMD_STANDBYNOW1) {
 			/* wait for io to complete if non atomic */
 			if (mtip_quiesce_io(port,
-					MTIP_QUIESCE_IO_TIMEOUT_MS) < 0) {
+				MTIP_QUIESCE_IO_TIMEOUT_MS, atomic) < 0) {
 				dev_warn(&dd->pdev->dev,
 					"Failed to quiesce IO\n");
 				mtip_put_int_command(dd, int_cmd);
@@ -3347,10 +3366,6 @@ static int mtip_standby_drive(struct dri
  */
 static int mtip_hw_exit(struct driver_data *dd)
 {
-	/*
-	 * Send standby immediate (E0h) to the drive so that it
-	 * saves its state.
-	 */
 	if (!dd->sr) {
 		/* de-initialize the port. */
 		mtip_deinit_port(dd->port);
@@ -3967,7 +3982,7 @@ static int mtip_block_initialize(struct
 	if (rv) {
 		dev_err(&dd->pdev->dev,
 			"Unable to allocate request queue\n");
-		goto block_queue_alloc_init_error;
+		goto block_queue_alloc_tag_error;
 	}
 
 	/* Allocate the request queue. */
@@ -4079,8 +4094,9 @@ kthread_run_error:
 read_capacity_error:
 init_hw_cmds_error:
 	blk_cleanup_queue(dd->queue);
-	blk_mq_free_tag_set(&dd->tags);
 block_queue_alloc_init_error:
+	blk_mq_free_tag_set(&dd->tags);
+block_queue_alloc_tag_error:
 	mtip_hw_debugfs_exit(dd);
 disk_index_error:
 	spin_lock(&rssd_index_lock);
@@ -4097,6 +4113,22 @@ protocol_init_error:
 	return rv;
 }
 
+static void mtip_no_dev_cleanup(struct request *rq, void *data, bool reserv)
+{
+	struct driver_data *dd = (struct driver_data *)data;
+	struct mtip_cmd *cmd;
+
+	if (likely(!reserv))
+		blk_mq_complete_request(rq, -ENODEV);
+	else if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &dd->port->flags)) {
+
+		cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL);
+		if (cmd->comp_func)
+			cmd->comp_func(dd->port, MTIP_TAG_INTERNAL,
+					cmd, -ENODEV);
+	}
+}
+
 /*
  * Block layer deinitialization function.
  *
@@ -4128,12 +4160,23 @@ static int mtip_block_remove(struct driv
 		}
 	}
 
-	if (!dd->sr)
-		mtip_standby_drive(dd);
+	if (!dd->sr) {
+		/*
+		 * Explicitly wait here for IOs to quiesce,
+		 * as mtip_standby_drive usually won't wait for IOs.
+		 */
+		if (!mtip_quiesce_io(dd->port, MTIP_QUIESCE_IO_TIMEOUT_MS,
+								GFP_KERNEL))
+			mtip_standby_drive(dd);
+	}
 	else
 		dev_info(&dd->pdev->dev, "device %s surprise removal\n",
 						dd->disk->disk_name);
 
+	blk_mq_freeze_queue_start(dd->queue);
+	blk_mq_stop_hw_queues(dd->queue);
+	blk_mq_all_tag_busy_iter(dd->tags.tags[0], mtip_no_dev_cleanup, dd);
+
 	/*
 	 * Delete our gendisk structure. This also removes the device
 	 * from /dev
@@ -4548,16 +4591,15 @@ static void mtip_pci_remove(struct pci_d
 	} while (atomic_read(&dd->irq_workers_active) != 0 &&
 		time_before(jiffies, to));
 
-	fsync_bdev(dd->bdev);
+	if (!dd->sr)
+		fsync_bdev(dd->bdev);
 
 	if (atomic_read(&dd->irq_workers_active) != 0) {
 		dev_warn(&dd->pdev->dev,
 			"Completion workers still active!\n");
 	}
 
-	if (dd->sr)
-		blk_mq_stop_hw_queues(dd->queue);
-
+	blk_set_queue_dying(dd->queue);
 	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
 
 	/* Clean up the block layer. */
author maintainer
#129 lore raw

PATCH 115/238 ALSA: hda - Fix unexpected resume through regmap code path

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit fc4f000bf8c0cbf38f44de6bd5e225574e572ed4 upstream.

HD-audio driver has a mechanism to trigger the runtime resume automatically at accessing the verbs. This auto-resume, however, causes the mutex deadlock when invoked from the regmap handler since the regmap keeps the mutex while auto-resuming. For avoiding that, there is some tricky check in the HDA regmap handler to return -EAGAIN error to back-off when the codec is powered down. Then the caller of regmap r/w will retry after properly turning on the codec power.

This works in most cases, but there seems a slight race between the codec power check and the actual on-demand auto-resume trigger. This resulted in the lockdep splat, eventually leading to a real deadlock.

This patch tries to address the race window by getting the runtime PM refcount at the check time using pm_runtime_get_if_in_use(). With this call, we can keep the power on only when the codec has been already turned on, and back off if not.

For keeping the code consistency, the code touching the runtime PM is stored in hdac_device.c although it's used only locally in hdac_regmap.c.

---
 include/sound/hdaudio.h |    2 +
 sound/hda/hdac_device.c |   16 +++++++++++
 sound/hda/hdac_regmap.c |   69 ++++++++++++++++++++++++++++++++----------------
 3 files changed, 64 insertions(+), 23 deletions(-)
include/sound/hdaudio.h +2 -0
@@ -168,11 +168,13 @@ int snd_hdac_power_up(struct hdac_device
 int snd_hdac_power_down(struct hdac_device *codec);
 int snd_hdac_power_up_pm(struct hdac_device *codec);
 int snd_hdac_power_down_pm(struct hdac_device *codec);
+int snd_hdac_keep_power_up(struct hdac_device *codec);
 #else
 static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
 static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
 static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
 static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
 #endif
 
 /*
sound/hda/hdac_device.c +16 -0
@@ -611,6 +611,22 @@ int snd_hdac_power_up_pm(struct hdac_dev
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
 
+/* like snd_hdac_power_up_pm(), but only increment the pm count when
+ * already powered up.  Returns -1 if not powered up, 1 if incremented
+ * or 0 if unchanged.  Only used in hdac_regmap.c
+ */
+int snd_hdac_keep_power_up(struct hdac_device *codec)
+{
+	if (!atomic_inc_not_zero(&codec->in_pm)) {
+		int ret = pm_runtime_get_if_in_use(&codec->dev);
+		if (!ret)
+			return -1;
+		if (ret < 0)
+			return 0;
+	}
+	return 1;
+}
+
 /**
  * snd_hdac_power_down_pm - power down the codec
  * @codec: the codec object
sound/hda/hdac_regmap.c +46 -23

116 lines not on this page · raw message

author maintainer
#130 lore raw

PATCH 116/238 ALSA: hda - Apply reboot D3 fix for CX20724 codec, too

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 56dc66ff1c6d71f9a38c4a7c000b72b921fe4c89 upstream.

Just like CX20722, CX7024 codec also requires the power down at reboot in order to reduce the noise at reboot/shutdown.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=113511

---
 sound/pci/hda/patch_conexant.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
sound/pci/hda/patch_conexant.c +6 -1
@@ -204,8 +204,13 @@ static void cx_auto_reboot_notify(struct
 {
 	struct conexant_spec *spec = codec->spec;
 
-	if (codec->core.vendor_id != 0x14f150f2)
+	switch (codec->core.vendor_id) {
+	case 0x14f150f2: /* CX20722 */
+	case 0x14f150f4: /* CX20724 */
+		break;
+	default:
 		return;
+	}
 
 	/* Turn the CX20722 codec into D3 to avoid spurious noises
 	   from the internal speaker during (and after) reboot */
author maintainer
#131 lore raw

PATCH 117/238 ALSA: pcm: Avoid "BUG:" string for warnings again

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 0ab1ace856205d10cbc1924b2d931c01ffd216a6 upstream.

The commit [d507941beb1e: ALSA: pcm: Correct PCM BUG error message] made the warning prefix back to "BUG:" due to its previous wrong prefix. But a kernel message containing "BUG:" seems taken as an Oops message wrongly by some brain-dead daemons, and it annoys users in the end. Instead of teaching daemons, change the string again to a more reasonable one.

Fixes 507941beb1e ('ALSA: pcm: Correct PCM BUG error message')
---
 sound/core/pcm_lib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/core/pcm_lib.c +1 -1
@@ -322,7 +322,7 @@ static int snd_pcm_update_hw_ptr0(struct
 			char name[16];
 			snd_pcm_debug_name(substream, name, sizeof(name));
 			pcm_err(substream->pcm,
-				"BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
+				"invalid position: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
 				name, pos, runtime->buffer_size,
 				runtime->period_size);
 		}
author maintainer
#132 lore raw

PATCH 118/238 ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41.

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vittorio Gambaletta (VittGam) <[email protected]>

commit 4061db03dd71d195b9973ee466f6ed32f6a3fc16 upstream.

The clock measurement on the AC'97 audio card found in the IBM ThinkPad X41 will often fail, so add a quirk entry to fix it.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=441087

---
 sound/pci/intel8x0.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/intel8x0.c +1 -0
@@ -2879,6 +2879,7 @@ static void intel8x0_measure_ac97_clock(
 
 static struct snd_pci_quirk intel8x0_clock_list[] = {
 	SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
+	SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000),
 	SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
 	SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
 	SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
author maintainer
#133 lore raw

PATCH 119/238 ALSA: hda - Dont handle ELD notify from invalid port

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 4f8e4f3537cafc4de128e6bfdf83baa78bc60eb1 upstream.

The current Intel HDMI codec driver supports only three fixed ports from port B to port D. However, i915 driver may assign a DP on other ports, e.g. port A, when no eDP is used. This incompatibility is caught later at pin_nid_to_pin_index() and results in a warning message like "HDMI: pin nid 4 not registered" at each time.

This patch filters out such invalid events beforehand, so that the kernel won't be too grumbling.

---
 sound/pci/hda/patch_hdmi.c |    4 ++++
 1 file changed, 4 insertions(+)
sound/pci/hda/patch_hdmi.c +4 -0
@@ -2432,6 +2432,10 @@ static void intel_pin_eld_notify(void *a
 	struct hda_codec *codec = audio_ptr;
 	int pin_nid = port + 0x04;
 
+	/* we assume only from port-B to port-D */
+	if (port < 1 || port > 3)
+		return;
+
 	/* skip notification during system suspend (but not in runtime PM);
 	 * the state will be updated at resume
 	 */
author maintainer
#134 lore raw

PATCH 120/238 ALSA: hda - fix the mic mute button and led problem for a Lenovo AIO

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hui Wang <[email protected]>

commit 6ef2f68fa38bf415830f67903d87180d933e0f47 upstream.

This Lenovo ThinkCentre AIO also uses Line2 as mic mute button and uses GPIO2 to control the mic mute led, so applying this quirk can make both the button and led work.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -5556,6 +5556,7 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
 	SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+	SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
 	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
 	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
 	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
author maintainer
#135 lore raw

PATCH 121/238 ALSA: hda - Add new GPU codec ID 0x10de0082 to snd-hda

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaron Plattner <[email protected]>

commit 2d369c748c2ecc2a012ee85412a04007e67913ec upstream.

Vendor ID 0x10de0082 is used by a yet-to-be-named GPU chip.

This chip also has the 2-ch audio swapping bug, so patch_nvhdmi is appropriate here.

---
 sound/pci/hda/patch_hdmi.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -3663,6 +3663,7 @@ HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI
 HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI",	patch_nvhdmi_2ch),
 HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP",	patch_via_hdmi),
author maintainer
#136 lore raw

PATCH 122/238 ALSA: hda - Fix unconditional GPIO toggle via automute

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit 1f7c6658962fa1260c1658d681bd6bb0c746b99a upstream.

Cirrus HD-audio driver may adjust GPIO pins for EAPD dynamically depending on the jack plug state. This works fine for the auto-mute
mode where the speaker gets muted upon the HP jack plug. OTOH, when
the auto-mute mode is off, this turns off the EAPD unexpectedly depending on the jack state, which results in the silent speaker output.

This patch fixes the silent speaker output issue by setting GPIO bits constantly when the auto-mute mode is off.

---
 sound/pci/hda/patch_cirrus.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
sound/pci/hda/patch_cirrus.c +6 -2
@@ -174,8 +174,12 @@ static void cs_automute(struct hda_codec
 	snd_hda_gen_update_outputs(codec);
 
 	if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
-		spec->gpio_data = spec->gen.hp_jack_present ?
-			spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+		if (spec->gen.automute_speaker)
+			spec->gpio_data = spec->gen.hp_jack_present ?
+				spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+		else
+			spec->gpio_data =
+				spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
 		snd_hda_codec_write(codec, 0x01, 0,
 				    AC_VERB_SET_GPIO_DATA, spec->gpio_data);
 	}
author maintainer
#137 lore raw

PATCH 126/238 ALSA: hda - Fix forgotten HDMI monitor_present update

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit bd48128539ab89986b24ad08ecd3e027dd1993a1 upstream.

We forgot to copy monitor_present value when updating the ELD information. This won't change the ELD retrieval and the jack
notification behavior, but appears only in the proc output. In that
sense, it's no fatal error, but a bug is a bug is a bug.

---
 sound/pci/hda/patch_hdmi.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -1566,6 +1566,7 @@ static void update_eld(struct hda_codec
 			   eld->eld_size) != 0)
 			eld_changed = true;
 
+	pin_eld->monitor_present = eld->monitor_present;
 	pin_eld->eld_valid = eld->eld_valid;
 	pin_eld->eld_size = eld->eld_size;
 	if (eld->eld_valid)
author maintainer
#138 lore raw

PATCH 128/238 ALSA: hda - Fix missing ELD update at unplugging

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit c64c1437afb14ebc900e40910f31ffb20bf652ad upstream.

i915 get_eld ops may return an error when no encoder is connected, and currently we regard the error as fatal and skip the whole ELD handling. This ended up with the missing ELD update at unplugging.

This patch fixes the issue by treating the error as the unplugged state, instead of skipping the rest.

---
 sound/pci/hda/patch_hdmi.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
sound/pci/hda/patch_hdmi.c +1 -2
@@ -1670,11 +1670,10 @@ static void sync_eld_via_acomp(struct hd
 	int size;
 
 	mutex_lock(&per_pin->lock);
+	eld->monitor_present = false;
 	size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
 				      &eld->monitor_present, eld->eld_buffer,
 				      ELD_MAX_SIZE);
-	if (size < 0)
-		goto unlock;
 	if (size > 0) {
 		size = min(size, ELD_MAX_SIZE);
 		if (snd_hdmi_parse_eld(codec, &eld->info,
#139 lore raw

Re: [PATCH 4.5 128/238] ALSA: hda - Fix missing ELD update at unplugging

sound/pci/hda/patch_hdmi.c static void sync_eld_via_acomp(struct hd · line 1677

Quoted 12 lines · Greg Kroah-Hartman
sound/pci/hda/patch_hdmi.c +1 -2
@@ -1670,11 +1670,10 @@ static void sync_eld_via_acomp(struct hd
 	int size;
 
 	mutex_lock(&per_pin->lock);
+	eld->monitor_present = false;
 	size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
 				      &eld->monitor_present, eld->eld_buffer,
 				      ELD_MAX_SIZE);
-	if (size < 0)
-		goto unlock;

This hunk triggers an obviously correct warning:
sound/pci/hda/patch_hdmi.c: In function 'sync_eld_via_acomp':
sound/pci/hda/patch_hdmi.c:1695:2: warning: label 'unlock' defined but not used [-Wunused-label]
unlock:
^

It's trivial to silence this warning for the v4.5 stable build, of course. But I never saw this warning in my v4.6-rc builds, so it's possible another patch should also be included in the v4.5 stable tree. Takashi?

Thanks,

Paul Bolle

#140 lore raw

Re: [PATCH 4.5 128/238] ALSA: hda - Fix missing ELD update at unplugging

Quoted 21 lines · Paul Bolle

sound/pci/hda/patch_hdmi.c static void sync_eld_via_acomp(struct hd · line 1677

Quoted 12 lines · Greg Kroah-Hartman
sound/pci/hda/patch_hdmi.c +1 -2
@@ -1670,11 +1670,10 @@ static void sync_eld_via_acomp(struct hd
 	int size;
 
 	mutex_lock(&per_pin->lock);
+	eld->monitor_present = false;
 	size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
 				      &eld->monitor_present, eld->eld_buffer,
 				      ELD_MAX_SIZE);
-	if (size < 0)
-		goto unlock;

This hunk triggers an obviously correct warning:
sound/pci/hda/patch_hdmi.c: In function 'sync_eld_via_acomp':
sound/pci/hda/patch_hdmi.c:1695:2: warning: label 'unlock' defined but not used [-Wunused-label]
unlock:
^

Quoted 4 lines

It's trivial to silence this warning for the v4.5 stable build, of course. But I never saw this warning in my v4.6-rc builds, so it's possible another patch should also be included in the v4.5 stable tree. Takashi?

The newer kernel has more code jumping to unlock label, so it's a warning seen only on 4.5 kernel. If this really matters, we'd need a non-upstream fix to paper over it.

thanks,

Takashi

author maintainer
#141 lore raw

PATCH 129/238 tools/hv: Use include/uapi with __EXPORTED_HEADERS__

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kamal Mostafa <[email protected]>

commit 50fe6dd10069e7c062e27f29606f6e91ea979399 upstream.

Use the local uapi headers to keep in sync with "recently" added #define's (e.g. VSS_OP_REGISTER1).

Fixes 3eb2094c59e8 ("Adding makefile for tools/hv")
---
 tools/hv/Makefile |    2 ++
 1 file changed, 2 insertions(+)
tools/hv/Makefile +2 -0
@@ -5,6 +5,8 @@ PTHREAD_LIBS = -lpthread
 WARNINGS = -Wall -Wextra
 CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) $(shell getconf LFS_CFLAGS)
 
+CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
+
 all: hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
 %: %.c
 	$(CC) $(CFLAGS) -o $@ $^
author maintainer
#142 lore raw

PATCH 130/238 jbd2: fix FS corruption possibility in jbd2_journal_destroy() on umount path

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: OGAWA Hirofumi <[email protected]>

commit c0a2ad9b50dd80eeccd73d9ff962234590d5ec93 upstream.

On umount path, jbd2_journal_destroy() writes latest transaction ID (->j_tail_sequence) to be used at next mount.

The bug is that ->j_tail_sequence is not holding latest transaction ID in some cases. So, at next mount, there is chance to conflict with remaining (not overwritten yet) transactions.

mount (id=10)
write transaction (id=11)
write transaction (id=12)
umount (id=10) <= the bug doesn't write latest ID

mount (id=10)
write transaction (id=11)
crash

mount
[recovery process]
transaction (id=11)
transaction (id=12) <= valid transaction ID, but old commit
must not replay

Like above, this bug become the cause of recovery failure, or FS corruption.

So why ->j_tail_sequence doesn't point latest ID?

Because if checkpoint transactions was reclaimed by memory pressure (i.e. bdev_try_to_free_page()), then ->j_tail_sequence is not updated. (And another case is, __jbd2_journal_clean_checkpoint_list() is called with empty transaction.)

So in above cases, ->j_tail_sequence is not pointing latest transaction ID at umount path. Plus, REQ_FLUSH for checkpoint is not done too.

So, to fix this problem with minimum changes, this patch updates ->j_tail_sequence, and issue REQ_FLUSH. (With more complex changes, some optimizations would be possible to avoid unnecessary REQ_FLUSH for example though.)

BTW,

	journal->j_tail_sequence =
		++journal->j_transaction_sequence;

Increment of ->j_transaction_sequence seems to be unnecessary, but ext3 does this.

---
 fs/jbd2/journal.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
fs/jbd2/journal.c +12 -5
@@ -1408,11 +1408,12 @@ out:
 /**
  * jbd2_mark_journal_empty() - Mark on disk journal as empty.
  * @journal: The journal to update.
+ * @write_op: With which operation should we write the journal sb
  *
  * Update a journal's dynamic superblock fields to show that journal is empty.
  * Write updated superblock to disk waiting for IO to complete.
  */
-static void jbd2_mark_journal_empty(journal_t *journal)
+static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
 {
 	journal_superblock_t *sb = journal->j_superblock;
 
@@ -1430,7 +1431,7 @@ static void jbd2_mark_journal_empty(jour
 	sb->s_start    = cpu_to_be32(0);
 	read_unlock(&journal->j_state_lock);
 
-	jbd2_write_superblock(journal, WRITE_FUA);
+	jbd2_write_superblock(journal, write_op);
 
 	/* Log is no longer empty */
 	write_lock(&journal->j_state_lock);
@@ -1716,7 +1717,13 @@ int jbd2_journal_destroy(journal_t *jour
 	if (journal->j_sb_buffer) {
 		if (!is_journal_aborted(journal)) {
 			mutex_lock(&journal->j_checkpoint_mutex);
-			jbd2_mark_journal_empty(journal);
+
+			write_lock(&journal->j_state_lock);
+			journal->j_tail_sequence =
+				++journal->j_transaction_sequence;
+			write_unlock(&journal->j_state_lock);
+
+			jbd2_mark_journal_empty(journal, WRITE_FLUSH_FUA);
 			mutex_unlock(&journal->j_checkpoint_mutex);
 		} else
 			err = -EIO;
@@ -1975,7 +1982,7 @@ int jbd2_journal_flush(journal_t *journa
 	 * the magic code for a fully-recovered superblock.  Any future
 	 * commits of data to the journal will restore the current
 	 * s_start value. */
-	jbd2_mark_journal_empty(journal);
+	jbd2_mark_journal_empty(journal, WRITE_FUA);
 	mutex_unlock(&journal->j_checkpoint_mutex);
 	write_lock(&journal->j_state_lock);
 	J_ASSERT(!journal->j_running_transaction);
@@ -2021,7 +2028,7 @@ int jbd2_journal_wipe(journal_t *journal
 	if (write) {
 		/* Lock to make assertions happy... */
 		mutex_lock(&journal->j_checkpoint_mutex);
-		jbd2_mark_journal_empty(journal);
+		jbd2_mark_journal_empty(journal, WRITE_FUA);
 		mutex_unlock(&journal->j_checkpoint_mutex);
 	}
 
author maintainer
#143 lore raw

PATCH 131/238 gpio: pca953x: Fix pca953x_gpio_set_multiple() on 64-bit

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Geert Uytterhoeven <[email protected]>

commit e0a8604f1300cefab4aeafe214fc57954a7b4487 upstream.

pca953x_gpio_set_multiple() divides by 4 to convert from longs to bytes, which assumes a 32-bit platform, and is not correct on 64-bit platforms. Use "sizeof(...)" instead to fix this.

Fixes b4818afeacbd8182 ("gpio: pca953x: Add set_multiple to allow multiple bits to be set in one write.")
---
 drivers/gpio/gpio-pca953x.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpio/gpio-pca953x.c +4 -2
@@ -367,9 +367,11 @@ static void pca953x_gpio_set_multiple(st
 	memcpy(reg_val, chip->reg_output, NBANK(chip));
 	mutex_lock(&chip->i2c_lock);
 	for(bank=0; bank<NBANK(chip); bank++) {
-		unsigned bankmask = mask[bank/4] >> ((bank % 4) * 8);
+		unsigned bankmask = mask[bank / sizeof(*mask)] >>
+				    ((bank % sizeof(*mask)) * 8);
 		if(bankmask) {
-			unsigned bankval  = bits[bank/4] >> ((bank % 4) * 8);
+			unsigned bankval  = bits[bank / sizeof(*bits)] >>
+					    ((bank % sizeof(*bits)) * 8);
 			reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval;
 		}
 	}
author maintainer
#144 lore raw

PATCH 132/238 arm64: Update PTE_RDONLY in set_pte_at() for PROT_NONE permission

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Catalin Marinas <[email protected]>

commit fdc69e7df3cb24f18a93192641786e5b7ecd1dfe upstream.

The set_pte_at() function must update the hardware PTE_RDONLY bit depending on the state of the PTE_WRITE and PTE_DIRTY bits of the given entry value. However, it currently only performs this for pte_valid() entries, ignoring PTE_PROT_NONE. The side-effect is that PROT_NONE mappings would not have the PTE_RDONLY bit set. Without CONFIG_ARM64_HW_AFDBM, this is not an issue since such PROT_NONE pages are not accessible anyway.

With commit 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits"), the ptep_set_wrprotect() function was re-written to cope with automatic hardware updates of the dirty state. As an optimisation, only PTE_RDONLY is checked to assess the "dirty" status. Since set_pte_at() does not set this bit for PROT_NONE mappings, such pages may be considered "dirty" as a result of ptep_set_wrprotect().

This patch updates the pte_valid() check to pte_present() in set_pte_at(). It also adds PTE_PROT_NONE to the swap entry bits comment.

Fixes 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits")
---
 arch/arm64/include/asm/pgtable.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +2 -1
@@ -279,7 +279,7 @@ extern void __sync_icache_dcache(pte_t p
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep, pte_t pte)
 {
-	if (pte_valid(pte)) {
+	if (pte_present(pte)) {
 		if (pte_sw_dirty(pte) && pte_write(pte))
 			pte_val(pte) &= ~PTE_RDONLY;
 		else
@@ -649,6 +649,7 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
  *	bits 0-1:	present (must be zero)
  *	bits 2-7:	swap type
  *	bits 8-57:	swap offset
+ *	bit  58:	PTE_PROT_NONE (must be zero)
  */
 #define __SWP_TYPE_SHIFT	2
 #define __SWP_TYPE_BITS		6
author maintainer
#145 lore raw

PATCH 133/238 brd: Fix discard request processing

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

commit 5e4298be45e83ecdffaabb370eea9396889b07f1 upstream.

Avoid that discard requests with size => PAGE_SIZE fail with -EIO. Refuse discard requests if the discard size is not a multiple of the page size.

Fixes 2dbe54957636 ("brd: Refuse improperly aligned discard requests")
Cc Christoph Hellwig <[email protected]>
Cc Robert Elliot <[email protected]>
---
 drivers/block/brd.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/brd.c +1 -1
@@ -341,7 +341,7 @@ static blk_qc_t brd_make_request(struct
 
 	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
 		if (sector & ((PAGE_SIZE >> SECTOR_SHIFT) - 1) ||
-		    bio->bi_iter.bi_size & PAGE_MASK)
+		    bio->bi_iter.bi_size & ~PAGE_MASK)
 			goto io_error;
 		discard_from_brd(brd, sector, bio->bi_iter.bi_size);
 		goto out;
author maintainer
#146 lore raw

PATCH 134/238 IB/srpt: Simplify srpt_handle_tsk_mgmt()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

commit 51093254bf879bc9ce96590400a87897c7498463 upstream.

Let the target core check task existence instead of the SRP target driver. Additionally, let the target core check the validity of the task management request instead of the ib_srpt driver.

This patch fixes the following kernel crash:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
IP: [<ffffffffa0565f37>] srpt_handle_new_iu+0x6d7/0x790 [ib_srpt]
Oops: 0002 [#1] SMP
Call Trace:
 [<ffffffffa05660ce>] srpt_process_completion+0xde/0x570 [ib_srpt]
 [<ffffffffa056669f>] srpt_compl_thread+0x13f/0x160 [ib_srpt]
 [<ffffffff8109726f>] kthread+0xcf/0xe0
 [<ffffffff81613cfc>] ret_from_fork+0x7c/0xb0
Fixes 3e4f574857ee ("ib_srpt: Convert TMR path to target_submit_tmr")
Cc Nicholas Bellinger <[email protected]>
Cc Sagi Grimberg <[email protected]>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c |   59 ----------------------------------
 1 file changed, 1 insertion(+), 58 deletions(-)
drivers/infiniband/ulp/srpt/ib_srpt.c +1 -58
@@ -1670,47 +1670,6 @@ send_sense:
 	return -1;
 }
 
-/**
- * srpt_rx_mgmt_fn_tag() - Process a task management function by tag.
- * @ch: RDMA channel of the task management request.
- * @fn: Task management function to perform.
- * @req_tag: Tag of the SRP task management request.
- * @mgmt_ioctx: I/O context of the task management request.
- *
- * Returns zero if the target core will process the task management
- * request asynchronously.
- *
- * Note: It is assumed that the initiator serializes tag-based task management
- * requests.
- */
-static int srpt_rx_mgmt_fn_tag(struct srpt_send_ioctx *ioctx, u64 tag)
-{
-	struct srpt_device *sdev;
-	struct srpt_rdma_ch *ch;
-	struct srpt_send_ioctx *target;
-	int ret, i;
-
-	ret = -EINVAL;
-	ch = ioctx->ch;
-	BUG_ON(!ch);
-	BUG_ON(!ch->sport);
-	sdev = ch->sport->sdev;
-	BUG_ON(!sdev);
-	spin_lock_irq(&sdev->spinlock);
-	for (i = 0; i < ch->rq_size; ++i) {
-		target = ch->ioctx_ring[i];
-		if (target->cmd.se_lun == ioctx->cmd.se_lun &&
-		    target->cmd.tag == tag &&
-		    srpt_get_cmd_state(target) != SRPT_STATE_DONE) {
-			ret = 0;
-			/* now let the target core abort &target->cmd; */
-			break;
-		}
-	}
-	spin_unlock_irq(&sdev->spinlock);
-	return ret;
-}
-
 static int srp_tmr_to_tcm(int fn)
 {
 	switch (fn) {
@@ -1745,7 +1704,6 @@ static void srpt_handle_tsk_mgmt(struct
 	struct se_cmd *cmd;
 	struct se_session *sess = ch->sess;
 	uint64_t unpacked_lun;
-	uint32_t tag = 0;
 	int tcm_tmr;
 	int rc;
 
@@ -1761,25 +1719,10 @@ static void srpt_handle_tsk_mgmt(struct
 	srpt_set_cmd_state(send_ioctx, SRPT_STATE_MGMT);
 	send_ioctx->cmd.tag = srp_tsk->tag;
 	tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
-	if (tcm_tmr < 0) {
-		send_ioctx->cmd.se_tmr_req->response =
-			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
-		goto fail;
-	}
 	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
 				       sizeof(srp_tsk->lun));
-
-	if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) {
-		rc = srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
-		if (rc < 0) {
-			send_ioctx->cmd.se_tmr_req->response =
-					TMR_TASK_DOES_NOT_EXIST;
-			goto fail;
-		}
-		tag = srp_tsk->task_tag;
-	}
 	rc = target_submit_tmr(&send_ioctx->cmd, sess, NULL, unpacked_lun,
-				srp_tsk, tcm_tmr, GFP_KERNEL, tag,
+				srp_tsk, tcm_tmr, GFP_KERNEL, srp_tsk->task_tag,
 				TARGET_SCF_ACK_KREF);
 	if (rc != 0) {
 		send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
author maintainer
#147 lore raw

PATCH 135/238 bcache: cleaned up error handling around register_cache()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Wheeler <[email protected]>

commit 9b299728ed777428b3908ac72ace5f8f84b97789 upstream.

Fix null pointer dereference by changing register_cache() to return an int instead of being void. This allows it to return -ENOMEM or -ENODEV and enables upper layers to handle the OOM case without NULL pointer issues.

See this thread:
http://thread.gmane.org/gmane.linux.kernel.bcache.devel/3521

Fixes this error:

  gargamel:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register

bcache: register_cache() error opening sdh2: cannot allocate memory

  BUG: unable to handle kernel NULL pointer dereference at 00000000000009b8
  IP: [<ffffffffc05a7e8d>] cache_set_flush+0x102/0x15c [bcache]
  PGD 120dff067 PUD 1119a3067 PMD 0
  Oops: 0000 [#1] SMP
  Modules linked in: veth ip6table_filter ip6_tables
  (...)
  CPU: 4 PID: 3371 Comm: kworker/4:3 Not tainted 4.4.2-amd64-i915-volpreempt-20160213bc1 #3
  Hardware name: System manufacturer System Product Name/P8H67-M PRO, BIOS 3904 04/27/2013
  Workqueue: events cache_set_flush [bcache]
  task: ffff88020d5dc280 ti: ffff88020b6f8000 task.ti: ffff88020b6f8000
  RIP: 0010:[<ffffffffc05a7e8d>]  [<ffffffffc05a7e8d>] cache_set_flush+0x102/0x15c [bcache]
---
 drivers/md/bcache/super.c |   34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)
drivers/md/bcache/super.c +22 -12
@@ -1828,11 +1828,12 @@ static int cache_alloc(struct cache_sb *
 	return 0;
 }
 
-static void register_cache(struct cache_sb *sb, struct page *sb_page,
+static int register_cache(struct cache_sb *sb, struct page *sb_page,
 				struct block_device *bdev, struct cache *ca)
 {
 	char name[BDEVNAME_SIZE];
-	const char *err = "cannot allocate memory";
+	const char *err = NULL;
+	int ret = 0;
 
 	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
 	ca->bdev = bdev;
@@ -1847,27 +1848,35 @@ static void register_cache(struct cache_
 	if (blk_queue_discard(bdev_get_queue(ca->bdev)))
 		ca->discard = CACHE_DISCARD(&ca->sb);
 
-	if (cache_alloc(sb, ca) != 0)
+	ret = cache_alloc(sb, ca);
+	if (ret != 0)
 		goto err;
 
-	err = "error creating kobject";
-	if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache"))
-		goto err;
+	if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {
+		err = "error calling kobject_add";
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	mutex_lock(&bch_register_lock);
 	err = register_cache_set(ca);
 	mutex_unlock(&bch_register_lock);
 
-	if (err)
-		goto err;
+	if (err) {
+		ret = -ENODEV;
+		goto out;
+	}
 
 	pr_info("registered cache device %s", bdevname(bdev, name));
+
 out:
 	kobject_put(&ca->kobj);
-	return;
+
 err:
-	pr_notice("error opening %s: %s", bdevname(bdev, name), err);
-	goto out;
+	if (err)
+		pr_notice("error opening %s: %s", bdevname(bdev, name), err);
+
+	return ret;
 }
 
 /* Global interfaces/init */
@@ -1965,7 +1974,8 @@ static ssize_t register_bcache(struct ko
 		if (!ca)
 			goto err_close;
 
-		register_cache(sb, sb_page, bdev, ca);
+		if (register_cache(sb, sb_page, bdev, ca) != 0)
+			goto err_close;
 	}
 out:
 	if (sb_page)
author maintainer
#148 lore raw

PATCH 136/238 bcache: fix race of writeback thread starting before complete initialization

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Wheeler <[email protected]>

commit 07cc6ef8edc47f8b4fc1e276d31127a0a5863d4d upstream.

The bch_writeback_thread might BUG_ON in read_dirty() if dc->sb==BDEV_STATE_DIRTY and bch_sectors_dirty_init has not yet completed its related initialization. This patch downs the dc->writeback_lock until after initialization is complete, thus preventing bch_writeback_thread from proceeding prematurely.

See this thread:
http://thread.gmane.org/gmane.linux.kernel.bcache.devel/3453

---
 drivers/md/bcache/super.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/md/bcache/super.c +8 -1
@@ -1015,8 +1015,12 @@ int bch_cached_dev_attach(struct cached_
 	 */
 	atomic_set(&dc->count, 1);
 
-	if (bch_cached_dev_writeback_start(dc))
+	/* Block writeback thread, but spawn it */
+	down_write(&dc->writeback_lock);
+	if (bch_cached_dev_writeback_start(dc)) {
+		up_write(&dc->writeback_lock);
 		return -ENOMEM;
+	}
 
 	if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
 		bch_sectors_dirty_init(dc);
@@ -1028,6 +1032,9 @@ int bch_cached_dev_attach(struct cached_
 	bch_cached_dev_run(dc);
 	bcache_device_link(&dc->disk, c, "bdev");
 
+	/* Allow the writeback thread to proceed */
+	up_write(&dc->writeback_lock);
+
 	pr_info("Caching %s as %s on set %pU",
 		bdevname(dc->bdev, buf), dc->disk.disk->disk_name,
 		dc->disk.c->sb.set_uuid);
author maintainer
#149 lore raw

PATCH 137/238 bcache: fix cache_set_flush() NULL pointer dereference on OOM

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Wheeler <[email protected]>

commit f8b11260a445169989d01df75d35af0f56178f95 upstream.

When bch_cache_set_alloc() fails to kzalloc the cache_set, the asyncronous closure handling tries to dereference a cache_set that hadn't yet been allocated inside of cache_set_flush() which is called by __cache_set_unregister() during cleanup. This appears to happen only during an OOM condition on bcache_register.

---
 drivers/md/bcache/super.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/md/bcache/super.c +3 -0
@@ -1373,6 +1373,9 @@ static void cache_set_flush(struct closu
 	struct btree *b;
 	unsigned i;
 
+	if (!c)
+		closure_return(cl);
+
 	bch_cache_accounting_destroy(&c->accounting);
 
 	kobject_put(&c->internal);
author maintainer
#150 lore raw

PATCH 138/238 mm: memcontrol: reclaim when shrinking memory.high below usage

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Weiner <[email protected]>

commit 588083bb37a3cea8533c392370a554417c8f29cb upstream.

When setting memory.high below usage, nothing happens until the next charge comes along, and then it will only reclaim its own charge and not the now potentially huge excess of the new memory.high. This can cause groups to stay in excess of their memory.high indefinitely.

To fix that, when shrinking memory.high, kick off a reclaim cycle that goes after the delta.

---
 mm/memcontrol.c |    6 ++++++
 1 file changed, 6 insertions(+)
mm/memcontrol.c +6 -0
@@ -5051,6 +5051,7 @@ static ssize_t memory_high_write(struct
 				 char *buf, size_t nbytes, loff_t off)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+	unsigned long nr_pages;
 	unsigned long high;
 	int err;
 
@@ -5061,6 +5062,11 @@ static ssize_t memory_high_write(struct
 
 	memcg->high = high;
 
+	nr_pages = page_counter_read(&memcg->memory);
+	if (nr_pages > high)
+		try_to_free_mem_cgroup_pages(memcg, nr_pages - high,
+					     GFP_KERNEL, true);
+
 	memcg_wb_domain_size_changed(memcg);
 	return nbytes;
 }
author maintainer
#151 lore raw

PATCH 139/238 mm: memcontrol: reclaim and OOM kill when shrinking memory.max below usage

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Weiner <[email protected]>

commit b6e6edcfa40561e9c8abe5eecf1c96f8e5fd9c6f upstream.

Setting the original memory.limit_in_bytes hardlimit is subject to a race condition when the desired value is below the current usage. The code tries a few times to first reclaim and then see if the usage has dropped to where we would like it to be, but there is no locking, and the workload is free to continue making new charges up to the old limit. Thus, attempting to shrink a workload relies on pure luck and hope that the workload happens to cooperate.

To fix this in the cgroup2 memory.max knob, do it the other way round:
set the limit first, then try enforcement. And if reclaim is not able to succeed, trigger OOM kills in the group. Keep going until the new limit is met, we run out of OOM victims and there's only unreclaimable memory left, or the task writing to memory.max is killed. This allows users to shrink groups reliably, and the behavior is consistent with what happens when new charges are attempted in excess of memory.max.

---
 Documentation/cgroup-v2.txt |    6 ++++++
 mm/memcontrol.c             |   38 ++++++++++++++++++++++++++++++++++----
 2 files changed, 40 insertions(+), 4 deletions(-)
Documentation/cgroup-v2.txt +6 -0
@@ -1368,6 +1368,12 @@ system than killing the group.  Otherwis
 limit this type of spillover and ultimately contain buggy or even
 malicious applications.
 
+Setting the original memory.limit_in_bytes below the current usage was
+subject to a race condition, where concurrent charges could cause the
+limit setting to fail. memory.max on the other hand will first set the
+limit to prevent new charges, and then reclaim and OOM kill until the
+new limit is met - or the task writing to memory.max is killed.
+
 The combined memory+swap accounting and limiting is replaced by real
 control over swap space.
 
mm/memcontrol.c +34 -4
@@ -1262,7 +1262,7 @@ static unsigned long mem_cgroup_get_limi
 	return limit;
 }
 
-static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
+static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
 				     int order)
 {
 	struct oom_control oc = {
@@ -1340,6 +1340,7 @@ static void mem_cgroup_out_of_memory(str
 	}
 unlock:
 	mutex_unlock(&oom_lock);
+	return chosen;
 }
 
 #if MAX_NUMNODES > 1
@@ -5088,6 +5089,8 @@ static ssize_t memory_max_write(struct k
 				char *buf, size_t nbytes, loff_t off)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+	unsigned int nr_reclaims = MEM_CGROUP_RECLAIM_RETRIES;
+	bool drained = false;
 	unsigned long max;
 	int err;
 
@@ -5096,9 +5099,36 @@ static ssize_t memory_max_write(struct k
 	if (err)
 		return err;
 
-	err = mem_cgroup_resize_limit(memcg, max);
-	if (err)
-		return err;
+	xchg(&memcg->memory.limit, max);
+
+	for (;;) {
+		unsigned long nr_pages = page_counter_read(&memcg->memory);
+
+		if (nr_pages <= max)
+			break;
+
+		if (signal_pending(current)) {
+			err = -EINTR;
+			break;
+		}
+
+		if (!drained) {
+			drain_all_stock(memcg);
+			drained = true;
+			continue;
+		}
+
+		if (nr_reclaims) {
+			if (!try_to_free_mem_cgroup_pages(memcg, nr_pages - max,
+							  GFP_KERNEL, true))
+				nr_reclaims--;
+			continue;
+		}
+
+		mem_cgroup_events(memcg, MEMCG_OOM, 1);
+		if (!mem_cgroup_out_of_memory(memcg, GFP_KERNEL, 0))
+			break;
+	}
 
 	memcg_wb_domain_size_changed(memcg);
 	return nbytes;
author maintainer
#152 lore raw

PATCH 140/238 ia64: define ioremap_uc()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Luis R. Rodriguez <[email protected]>

commit b0f84ac352762ed02d7ea9f284942a8cab7f9077 upstream.

All architectures now need ioremap_uc(), ia64 seems defines this already through its ioremap_nocache() and it already ensures it *only* uses UC.

This is needed since v4.3 to complete an allyesconfig compile on ia64, there were others archs that needed this, and this one seems to have fallen through the cracks.

---
 arch/ia64/include/asm/io.h |    1 +
 1 file changed, 1 insertion(+)
arch/ia64/include/asm/io.h +1 -0
@@ -433,6 +433,7 @@ static inline void __iomem * ioremap_cac
 	return ioremap(phys_addr, size);
 }
 #define ioremap_cache ioremap_cache
+#define ioremap_uc ioremap_nocache
 
 
 /*
author maintainer
#153 lore raw

PATCH 141/238 drivers/firmware/broadcom/bcm47xx_nvram.c: fix incorrect __ioread32_copy

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaro Koskinen <[email protected]>

commit 4c11e554fb894b381a3dc47069259d87a2e6ffc9 upstream.

Commit 1f330c327900 ("drivers/firmware/broadcom/bcm47xx_nvram.c: use __ioread32_copy() instead of open-coding") switched to use a generic copy function, but failed to notice that the header pointer is updated between the two copies, resulting in bogus data being copied in the latter one. Fix by keeping the old header pointer.

The patch fixes totally broken networking on WRT54GL router (both LAN and WLAN interfaces fail to probe).

Fixes 1f330c327900 ("drivers/firmware/broadcom/bcm47xx_nvram.c: use __ioread32_copy() instead of open-coding")
Cc Rafal Milecki <[email protected]>
Cc Hauke Mehrtens <[email protected]>
---
 drivers/firmware/broadcom/bcm47xx_nvram.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/firmware/broadcom/bcm47xx_nvram.c +2 -3
@@ -94,15 +94,14 @@ static int nvram_find_and_copy(void __io
 
 found:
 	__ioread32_copy(nvram_buf, header, sizeof(*header) / 4);
-	header = (struct nvram_header *)nvram_buf;
-	nvram_len = header->len;
+	nvram_len = ((struct nvram_header *)(nvram_buf))->len;
 	if (nvram_len > size) {
 		pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
 		nvram_len = size;
 	}
 	if (nvram_len >= NVRAM_SPACE) {
 		pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
-		       header->len, NVRAM_SPACE - 1);
+		       nvram_len, NVRAM_SPACE - 1);
 		nvram_len = NVRAM_SPACE - 1;
 	}
 	/* proceed reading data after header */
author maintainer
#154 lore raw

PATCH 142/238 watchdog: dont run proc_watchdog_update if new value is same as old

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Hunt <[email protected]>

commit a1ee1932aa6bea0bb074f5e3ced112664e4637ed upstream.

While working on a script to restore all sysctl params before a series of tests I found that writing any value into the /proc/sys/kernel/{nmi_watchdog,soft_watchdog,watchdog,watchdog_thresh} causes them to call proc_watchdog_update().

NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter.

There doesn't appear to be a reason for doing this work every time a write occurs, so only do it when the values change.

---
 kernel/watchdog.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
kernel/watchdog.c +8 -1
@@ -923,6 +923,9 @@ static int proc_watchdog_common(int whic
 		 * both lockup detectors are disabled if proc_watchdog_update()
 		 * returns an error.
 		 */
+		if (old == new)
+			goto out;
+
 		err = proc_watchdog_update();
 	}
 out:
@@ -967,7 +970,7 @@ int proc_soft_watchdog(struct ctl_table
 int proc_watchdog_thresh(struct ctl_table *table, int write,
 			 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	int err, old;
+	int err, old, new;
 
 	get_online_cpus();
 	mutex_lock(&watchdog_proc_mutex);
@@ -987,6 +990,10 @@ int proc_watchdog_thresh(struct ctl_tabl
 	/*
 	 * Update the sample period. Restore on failure.
 	 */
+	new = ACCESS_ONCE(watchdog_thresh);
+	if (old == new)
+		goto out;
+
 	set_sample_period();
 	err = proc_watchdog_update();
 	if (err) {
#155 lore raw

Re: [PATCH 4.5 142/238] watchdog: dont run proc_watchdog_update if new value is same as old

Quoted 35 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joshua Hunt <[email protected]>

commit a1ee1932aa6bea0bb074f5e3ced112664e4637ed upstream.

While working on a script to restore all sysctl params before a series of tests I found that writing any value into the /proc/sys/kernel/{nmi_watchdog,soft_watchdog,watchdog,watchdog_thresh} causes them to call proc_watchdog_update().

  NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter.

There doesn't appear to be a reason for doing this work every time a write occurs, so only do it when the values change.

---
 kernel/watchdog.c |    9 ++++++++-

 1 file changed, 8 insertions(+), 1 deletion(-)
kernel/watchdog.c +0 -0

[...]

Quoted 10 lines
kernel/watchdog.c +1 -1
@@ -967,7 +970,7 @@ int proc_soft_watchdog(struct ctl_table
  int proc_watchdog_thresh(struct ctl_table *table, int write,
  			 void __user *buffer, size_t *lenp, loff_t *ppos)
  {
-	int err, old;
+	int err, old, new;


  get_online_cpus();
  mutex_lock(&watchdog_proc_mutex);

kernel/watchdog.c int proc_watchdog_thresh(struct ctl_tabl · line 993

Quoted 4 lines
kernel/watchdog.c +1 -0
@@ -987,6 +990,10 @@ int proc_watchdog_thresh(struct ctl_tabl
  	/*
  	 * Update the sample period. Restore on failure.
  	 */
+	new = ACCESS_ONCE(watchdog_thresh);

This ACCESS_ONCE() doesn't make any sense to me.  Isn't watchdog_thresh protected by watchdog_proc_mutex?  If a race on watchdog_thresh is still possible then the check for old == new isn't a valid optimisation, and if it isn't possible then ACCESS_ONCE() shouldn't be used here.

Ben.

kernel/watchdog.c int proc_watchdog_thresh(struct ctl_tabl · line 999

Quoted 6 lines
kernel/watchdog.c +3 -0
+	if (old == new)
+		goto out;
+
  	set_sample_period();
  	err = proc_watchdog_update();
  	if (err) {

--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.

#156 lore raw

Re: [PATCH 4.5 142/238] watchdog: dont run proc_watchdog_update if new value is same as old

Quoted 38 lines · Ben Hutchings
Quoted 35 lines · Greg Kroah-Hartman

4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joshua Hunt <[email protected]>

commit a1ee1932aa6bea0bb074f5e3ced112664e4637ed upstream.

While working on a script to restore all sysctl params before a series of tests I found that writing any value into the /proc/sys/kernel/{nmi_watchdog,soft_watchdog,watchdog,watchdog_thresh} causes them to call proc_watchdog_update().

  NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter. NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter.

There doesn't appear to be a reason for doing this work every time a write occurs, so only do it when the values change.

---
 kernel/watchdog.c |    9 ++++++++-

 1 file changed, 8 insertions(+), 1 deletion(-)
kernel/watchdog.c +0 -0

[...]

Quoted 15 lines
Quoted 10 lines
kernel/watchdog.c +1 -1
@@ -967,7 +970,7 @@ int proc_soft_watchdog(struct ctl_table
  int proc_watchdog_thresh(struct ctl_table *table, int write,
  			 void __user *buffer, size_t *lenp, loff_t *ppos)
  {
-	int err, old;
+	int err, old, new;


  get_online_cpus();
  mutex_lock(&watchdog_proc_mutex);

kernel/watchdog.c int proc_watchdog_thresh(struct ctl_tabl · line 993

Quoted 4 lines
kernel/watchdog.c +1 -0
@@ -987,6 +990,10 @@ int proc_watchdog_thresh(struct ctl_tabl
  	/*
  	 * Update the sample period. Restore on failure.
  	 */
+	new = ACCESS_ONCE(watchdog_thresh);

Hi Ben,

Quoted 2 lines

This ACCESS_ONCE() doesn't make any sense to me.  Isn't watchdog_thresh protected by watchdog_proc_mutex?  If a race on watchdog_thresh is

The write accesses are, but not all the reads.

Quoted 3 lines

still possible then the check for old == new isn't a valid optimisation, and if it isn't possible then ACCESS_ONCE() shouldn't be used here.

The irq and nmi handlers may read it, but not write. So there should not be any race of overwriting watchdog_thresh, just a race to read stale data.

I don't fully understand the use case for ACCESS_ONCE, so it is hard for me to comment on whether or not the code paths satisfy the use cases or not.

The check for 'old == new' is a needed optimization and should not race because of the mutex protection.

So, I don't have a good answer for you without understanding ACCESS_ONCE better.

Cheers,
Don

author maintainer
#157 lore raw

PATCH 143/238 watchdog: rc32434_wdt: fix ioctl error handling

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael S. Tsirkin <[email protected]>

commit 10e7ac22cdd4d211cef99afcb9371b70cb175be6 upstream.

Calling return copy_to_user(...) in an ioctl will not do the right thing if there's a pagefault: copy_to_user returns the number of bytes not copied in this case.

Fix up watchdog/rc32434_wdt to do

	return copy_to_user(...)) ?  -EFAULT : 0;

instead.

---
 drivers/watchdog/rc32434_wdt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/rc32434_wdt.c +1 -1
@@ -237,7 +237,7 @@ static long rc32434_wdt_ioctl(struct fil
 			return -EINVAL;
 		/* Fall through */
 	case WDIOC_GETTIMEOUT:
-		return copy_to_user(argp, &timeout, sizeof(int));
+		return copy_to_user(argp, &timeout, sizeof(int)) ? -EFAULT : 0;
 	default:
 		return -ENOTTY;
 	}
author maintainer
#158 lore raw

PATCH 144/238 Bluetooth: Add new AR3012 ID 0489:e095

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Tunin <[email protected]>

commit 28c971d82fb58ef7cba22e5308be6d2d2590473d upstream.

T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0489 ProdID=e095 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

This device requires ar3k/AthrBT_0x31010100.dfu and ar3k/ramps_0x31010100_40.dfu firmware files that are not in linux-firmware yet.

---
 drivers/bluetooth/ath3k.c |    2 ++
 drivers/bluetooth/btusb.c |    1 +
 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
@@ -82,6 +82,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0489, 0xe05f) },
 	{ USB_DEVICE(0x0489, 0xe076) },
 	{ USB_DEVICE(0x0489, 0xe078) },
+	{ USB_DEVICE(0x0489, 0xe095) },
 	{ USB_DEVICE(0x04c5, 0x1330) },
 	{ USB_DEVICE(0x04CA, 0x3004) },
 	{ USB_DEVICE(0x04CA, 0x3005) },
@@ -147,6 +148,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c +1 -0
@@ -196,6 +196,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
author maintainer
#159 lore raw

PATCH 145/238 Bluetooth: Fix potential buffer overflow with Add Advertising

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hedberg <[email protected]>

commit 6a0e78072c2ae7b20b14e0249d8108441ea928d2 upstream.

The Add Advertising command handler does the appropriate checks for the AD and Scan Response data, however fails to take into account the general length of the mgmt command itself, which could lead to potential buffer overflows. This patch adds the necessary check that the mgmt command length is consistent with the given ad and scan_rsp lengths.

---
 net/bluetooth/mgmt.c |    4 ++++
 1 file changed, 4 insertions(+)
net/bluetooth/mgmt.c +4 -0
@@ -5979,6 +5979,10 @@ static int add_advertising(struct sock *
 		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
 				       MGMT_STATUS_INVALID_PARAMS);
 
+	if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len)
+		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
+				       MGMT_STATUS_INVALID_PARAMS);
+
 	flags = __le32_to_cpu(cp->flags);
 	timeout = __le16_to_cpu(cp->timeout);
 	duration = __le16_to_cpu(cp->duration);
author maintainer
#160 lore raw

PATCH 146/238 cgroup: ignore css_sets associated with dead cgroups during migration

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

commit 2b021cbf3cb6208f0d40fd2f1869f237934340ed upstream.

Before 2e91fa7f6d45 ("cgroup: keep zombies associated with their original cgroups"), all dead tasks were associated with init_css_set. If a zombie task is requested for migration, while migration prep operations would still be performed on init_css_set, the actual migration would ignore zombie tasks. As init_css_set is always valid, this worked fine.

However, after 2e91fa7f6d45, zombie tasks stay with the css_set it was associated with at the time of death. Let's say a task T associated with cgroup A on hierarchy H-1 and cgroup B on hiearchy H-2. After T becomes a zombie, it would still remain associated with A and B. If A only contains zombie tasks, it can be removed. On removal, A gets marked offline but stays pinned until all zombies are drained. At this point, if migration is initiated on T to a cgroup C on hierarchy H-2, migration path would try to prepare T's css_set for migration and trigger the following.

 WARNING: CPU: 0 PID: 1576 at kernel/cgroup.c:474 cgroup_get+0x121/0x160()
 CPU: 0 PID: 1576 Comm: bash Not tainted 4.4.0-work+ #289
 ...
 Call Trace:
  [<ffffffff8127e63c>] dump_stack+0x4e/0x82
  [<ffffffff810445e8>] warn_slowpath_common+0x78/0xb0
  [<ffffffff810446d5>] warn_slowpath_null+0x15/0x20
  [<ffffffff810c33e1>] cgroup_get+0x121/0x160
  [<ffffffff810c349b>] link_css_set+0x7b/0x90
  [<ffffffff810c4fbc>] find_css_set+0x3bc/0x5e0
  [<ffffffff810c5269>] cgroup_migrate_prepare_dst+0x89/0x1f0
  [<ffffffff810c7547>] cgroup_attach_task+0x157/0x230
  [<ffffffff810c7a17>] __cgroup_procs_write+0x2b7/0x470
  [<ffffffff810c7bdc>] cgroup_tasks_write+0xc/0x10
  [<ffffffff810c4790>] cgroup_file_write+0x30/0x1b0
  [<ffffffff811c68fc>] kernfs_fop_write+0x13c/0x180
  [<ffffffff81151673>] __vfs_write+0x23/0xe0
  [<ffffffff81152494>] vfs_write+0xa4/0x1a0
  [<ffffffff811532d4>] SyS_write+0x44/0xa0
  [<ffffffff814af2d7>] entry_SYSCALL_64_fastpath+0x12/0x6f

It doesn't make sense to prepare migration for css_sets pointing to dead cgroups as they are guaranteed to contain only zombies which are ignored later during migration. This patch makes cgroup destruction path mark all affected css_sets as dead and updates the migration path to ignore them during preparation.

Fixes 2e91fa7f6d45 ("cgroup: keep zombies associated with their original cgroups")
---
 include/linux/cgroup-defs.h |    3 +++
 kernel/cgroup.c             |   20 ++++++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)
include/linux/cgroup-defs.h +3 -0
@@ -210,6 +210,9 @@ struct css_set {
 	/* all css_task_iters currently walking this cset */
 	struct list_head task_iters;
 
+	/* dead and being drained, ignore for migration */
+	bool dead;
+
 	/* For RCU-protected deletion */
 	struct rcu_head rcu_head;
 };
kernel/cgroup.c +18 -2
@@ -2474,6 +2474,14 @@ static void cgroup_migrate_add_src(struc
 	lockdep_assert_held(&cgroup_mutex);
 	lockdep_assert_held(&css_set_lock);
 
+	/*
+	 * If ->dead, @src_set is associated with one or more dead cgroups
+	 * and doesn't contain any migratable tasks.  Ignore it early so
+	 * that the rest of migration path doesn't get confused by it.
+	 */
+	if (src_cset->dead)
+		return;
+
 	src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root);
 
 	if (!list_empty(&src_cset->mg_preload_node))
@@ -5114,6 +5122,7 @@ static int cgroup_destroy_locked(struct
 	__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
 {
 	struct cgroup_subsys_state *css;
+	struct cgrp_cset_link *link;
 	int ssid;
 
 	lockdep_assert_held(&cgroup_mutex);
@@ -5134,11 +5143,18 @@ static int cgroup_destroy_locked(struct
 		return -EBUSY;
 
 	/*
-	 * Mark @cgrp dead.  This prevents further task migration and child
-	 * creation by disabling cgroup_lock_live_group().
+	 * Mark @cgrp and the associated csets dead.  The former prevents
+	 * further task migration and child creation by disabling
+	 * cgroup_lock_live_group().  The latter makes the csets ignored by
+	 * the migration path.
 	 */
 	cgrp->self.flags &= ~CSS_ONLINE;
 
+	spin_lock_bh(&css_set_lock);
+	list_for_each_entry(link, &cgrp->cset_links, cset_link)
+		link->cset->dead = true;
+	spin_unlock_bh(&css_set_lock);
+
 	/* initiate massacre of all css's */
 	for_each_css(css, ssid, cgrp)
 		kill_css(css);
author maintainer
#161 lore raw

PATCH 147/238 net: mvneta: enable change MAC address when interface is up

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitri Epshtein <[email protected]>

commit 928b6519afeb2a5e2dc61154380b545ed66c476a upstream.

Function eth_prepare_mac_addr_change() is called as part of MAC address change. This function check if interface is running. To enable change MAC address when interface is running:
IFF_LIVE_ADDR_CHANGE flag must be set to dev->priv_flags field

Fixes c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP

network unit")

---
 drivers/net/ethernet/marvell/mvneta.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvneta.c +1 -1
@@ -3720,7 +3720,7 @@ static int mvneta_probe(struct platform_
 	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 	dev->hw_features |= dev->features;
 	dev->vlan_features |= dev->features;
-	dev->priv_flags |= IFF_UNICAST_FLT;
+	dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
 	dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
 
 	err = register_netdev(dev);
author maintainer
#162 lore raw

PATCH 149/238 of: alloc anywhere from memblock if range not specified

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vinayak Menon <[email protected]>

commit e53b50c0cbe392c946807abf7d07615a3c588642 upstream.

early_init_dt_alloc_reserved_memory_arch passes end as 0 to __memblock_alloc_base, when limits are not specified. But __memblock_alloc_base takes end value of 0 as MEMBLOCK_ALLOC_ACCESSIBLE and limits the end to memblock.current_limit. This results in regions never being placed in HIGHMEM area, for e.g. CMA.
Let __memblock_alloc_base allocate from anywhere in memory if limits are not specified.

---
 drivers/of/of_reserved_mem.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/of/of_reserved_mem.c +3 -1
@@ -32,11 +32,13 @@ int __init __weak early_init_dt_alloc_re
 	phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
 	phys_addr_t *res_base)
 {
+	phys_addr_t base;
 	/*
 	 * We use __memblock_alloc_base() because memblock_alloc_base()
 	 * panic()s on allocation failure.
 	 */
-	phys_addr_t base = __memblock_alloc_base(size, align, end);
+	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
+	base = __memblock_alloc_base(size, align, end);
 	if (!base)
 		return -ENOMEM;
 
author maintainer
#163 lore raw

PATCH 150/238 vfs: show_vfsstat: do not ignore errors from show_devname method

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry V. Levin <[email protected]>

commit 5f8d498d4364f544fee17125787a47553db02afa upstream.

Explicitly check show_devname method return code and bail out in case of an error. This fixes regression introduced by commit 9d4d65748a5c.

---
 fs/proc_namespace.c |    2 ++
 1 file changed, 2 insertions(+)
fs/proc_namespace.c +2 -0
@@ -199,6 +199,8 @@ static int show_vfsstat(struct seq_file
 	if (sb->s_op->show_devname) {
 		seq_puts(m, "device ");
 		err = sb->s_op->show_devname(m, mnt_path.dentry);
+		if (err)
+			goto out;
 	} else {
 		if (r->mnt_devname) {
 			seq_puts(m, "device ");
author maintainer
#164 lore raw

PATCH 151/238 splice: handle zero nr_pages in splice_to_pipe()

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rabin Vincent <[email protected]>

commit d6785d9152147596f60234157da2b02540c3e60f upstream.

Running the following command:

busybox cat /sys/kernel/debug/tracing/trace_pipe > /dev/null

with any tracing enabled pretty very quickly leads to various NULL pointer dereferences and VM BUG_ON()s, such as these:

 BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
 IP: [<ffffffff8119df6c>] generic_pipe_buf_release+0xc/0x40
 Call Trace:
  [<ffffffff811c48a3>] splice_direct_to_actor+0x143/0x1e0
  [<ffffffff811c42e0>] ? generic_pipe_buf_nosteal+0x10/0x10
  [<ffffffff811c49cf>] do_splice_direct+0x8f/0xb0
  [<ffffffff81196869>] do_sendfile+0x199/0x380
  [<ffffffff81197600>] SyS_sendfile64+0x90/0xa0
  [<ffffffff8192cbee>] entry_SYSCALL_64_fastpath+0x12/0x6d

 page dumped because: VM_BUG_ON_PAGE(atomic_read(&page->_count) == 0)
 kernel BUG at include/linux/mm.h:367!
 invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
 RIP: [<ffffffff8119df9c>] generic_pipe_buf_release+0x3c/0x40
 Call Trace:
  [<ffffffff811c48a3>] splice_direct_to_actor+0x143/0x1e0
  [<ffffffff811c42e0>] ? generic_pipe_buf_nosteal+0x10/0x10
  [<ffffffff811c49cf>] do_splice_direct+0x8f/0xb0
  [<ffffffff81196869>] do_sendfile+0x199/0x380
  [<ffffffff81197600>] SyS_sendfile64+0x90/0xa0
  [<ffffffff8192cd1e>] tracesys_phase2+0x84/0x89

(busybox's cat uses sendfile(2), unlike the coreutils version)

This is because tracing_splice_read_pipe() can call splice_to_pipe() with spd->nr_pages == 0. spd_pages underflows in splice_to_pipe() and we fill the page pointers and the other fields of the pipe_buffers with garbage.

All other callers of splice_to_pipe() avoid calling it when nr_pages == 0, and we could make tracing_splice_read_pipe() do that too, but it seems reasonable to have splice_to_page() handle this condition gracefully.

---
 fs/splice.c |    3 +++
 1 file changed, 3 insertions(+)
fs/splice.c +3 -0
@@ -185,6 +185,9 @@ ssize_t splice_to_pipe(struct pipe_inode
 	unsigned int spd_pages = spd->nr_pages;
 	int ret, do_wakeup, page_nr;
 
+	if (!spd_pages)
+		return 0;
+
 	ret = 0;
 	do_wakeup = 0;
 	page_nr = 0;
author maintainer
#165 lore raw

PATCH 152/238 xtensa: ISS: dont hang if stdin EOF is reached

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Max Filippov <[email protected]>

commit 362014c8d9d51d504c167c44ac280169457732be upstream.

Simulator stdin may be connected to a file, when its end is reached kernel hangs in infinite loop inside rs_poll, because simc_poll always signals that descriptor 0 is readable and simc_read always returns 0. Check simc_read return value and exit loop if it's not positive. Also don't rewind polling timer if it's zero.

---
 arch/xtensa/platforms/iss/console.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
arch/xtensa/platforms/iss/console.c +6 -4
@@ -100,21 +100,23 @@ static void rs_poll(unsigned long priv)
 {
 	struct tty_port *port = (struct tty_port *)priv;
 	int i = 0;
+	int rd = 1;
 	unsigned char c;
 
 	spin_lock(&timer_lock);
 
 	while (simc_poll(0)) {
-		simc_read(0, &c, 1);
+		rd = simc_read(0, &c, 1);
+		if (rd <= 0)
+			break;
 		tty_insert_flip_char(port, c, TTY_NORMAL);
 		i++;
 	}
 
 	if (i)
 		tty_flip_buffer_push(port);
-
-
-	mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+	if (rd)
+		mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
 	spin_unlock(&timer_lock);
 }
 
author maintainer
#166 lore raw

PATCH 153/238 xtensa: fix preemption in {clear,copy}_user_highpage

In reply to Greg Kroah-Hartman

4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Max Filippov <[email protected]>

commit a67cc9aa2dfc6e66addf240bbd79e16e01565e81 upstream.

Disabling pagefault makes little sense there, preemption disabling is what was meant.

---
 arch/xtensa/mm/cache.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/xtensa/mm/cache.c +4 -4
@@ -97,11 +97,11 @@ void clear_user_highpage(struct page *pa
 	unsigned long paddr;
 	void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr);
 
-	pagefault_disable();
+	preempt_disable();
 	kmap_invalidate_coherent(page, vaddr);
 	set_bit(PG_arch_1, &page->flags);
 	clear_page_alias(kvaddr, paddr);
-	pagefault_enable();
+	preempt_enable();
 }
 
 void copy_user_highpage(struct page *dst, struct page *src,
@@ -113,11 +113,11 @@ void copy_user_highpage(struct page *dst
 	void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr,
 					  &src_paddr);
 
-	pagefault_disable();
+	preempt_disable();
 	kmap_invalidate_coherent(dst, vaddr);
 	set_bit(PG_arch_1, &dst->flags);
 	copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
-	pagefault_enable();
+	preempt_enable();
 }
 
 #endif /* DCACHE_WAY_SIZE > PAGE_SIZE */