This is the start of the stable review cycle for the 4.19.56 release. There are 90 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 Wed 26 Jun 2019 09:22:03 AM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.56-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.19.56-rc1
James Morse james.morse@arm.com x86/resctrl: Don't stop walking closids when a locksetup group is found
Jouni Malinen j@w1.fi mac80211: Do not use stack memory with scatterlist for GMAC
Andy Strohman andrew@andrewstrohman.com nl80211: fix station_info pertid memory leak
Yu Wang yyuwang@codeaurora.org mac80211: handle deauthentication/disassociation from TDLS peer
Manikanta Pubbisetty mpubbise@codeaurora.org {nl,mac}80211: allow 4addr AP operation on crypto controlled devices
Johannes Berg johannes.berg@intel.com mac80211: drop robust management frames from unknown TA
Eric Biggers ebiggers@google.com cfg80211: fix memory leak of wiphy device name
Steve French stfrench@microsoft.com SMB3: retry on STATUS_INSUFFICIENT_RESOURCES instead of failing write
Marcel Holtmann marcel@holtmann.org Bluetooth: Fix regression with minimum encryption key size alignment
Marcel Holtmann marcel@holtmann.org Bluetooth: Align minimum encryption key size for LE and BR/EDR connections
Gao Xiang gaoxiang25@huawei.com staging: erofs: add requirements field in superblock
Thomas Hellstrom thellstrom@vmware.com drm/vmwgfx: Use the backdoor port if the HB port is not available
Anisse Astier aastier@freebox.fr arm64: ssbd: explicitly depend on <linux/prctl.h>
Anisse Astier aastier@freebox.fr arm64/sve: <uapi/asm/ptrace.h> should not depend on <uapi/linux/prctl.h>
Faiz Abbas faiz_abbas@ti.com ARM: dts: am57xx-idk: Remove support for voltage switching for SD card
Faiz Abbas faiz_abbas@ti.com ARM: dts: dra76x: Update MMC2_HS200_MANUAL1 iodelay values
Fabio Estevam festevam@gmail.com ARM: imx: cpuidle-imx6sx: Restrict the SW2ISO increase to i.MX6SX
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com powerpc/bpf: use unsigned division instruction for 64-bit operations
ShihPo Hung shihpo.hung@sifive.com riscv: mm: synchronize MMU after pte change
Willem de Bruijn willemb@google.com can: purge socket error queue on sock destruct
Joakim Zhang qiangqing.zhang@nxp.com can: flexcan: fix timeout when set small bitrate
Anssi Hannula anssi.hannula@bitwise.fi can: xilinx_can: use correct bittiming_const for CAN FD core
Naohiro Aota naohiro.aota@wdc.com btrfs: start readahead also in seed devices
Jaesoo Lee jalee@purestorage.com nvme: Fix u32 overflow in the number of namespace list calculation
Dave Martin Dave.Martin@arm.com arm64: Silence gcc warnings about arch ABI drift
Robert Hancock hancock@sedsystems.ca hwmon: (pmbus/core) Treat parameters as paged if on multiple pages
Eduardo Valentin eduval@amazon.com hwmon: (core) add thermal sensors only if dev->of_node is present
Alexandra Winter wintera@linux.ibm.com s390/qeth: fix VLAN attribute in bridge_hostnotify udev event
Miaohe Lin linmiaohe@huawei.com net: ipvlan: Fix ipvlan device tso disabled while NETIF_F_IP_CSUM is set
Dan Carpenter dan.carpenter@oracle.com scsi: smartpqi: unlock on error in pqi_submit_raid_request_synchronous()
Avri Altman avri.altman@wdc.com scsi: ufs: Check that space was properly alloced in copy_query_response
George G. Davis george_davis@mentor.com scripts/checkstack.pl: Fix arm64 wrong or unknown architecture
Minwoo Im minwoo.im.dev@gmail.com nvmet: fix data_len to 0 for bdev-backed write_zeroes
Robin Murphy robin.murphy@arm.com drm/arm/hdlcd: Allow a bit of clock tolerance
Robin Murphy robin.murphy@arm.com drm/arm/hdlcd: Actually validate CRTC modes
Wen He wen.he_1@nxp.com drm/arm/mali-dp: Add a loop around the second set CVAL and try 5 times
Sean Wang sean.wang@mediatek.com net: ethernet: mediatek: Use NET_IP_ALIGN to judge if HW RX_2BYTE_OFFSET is enabled
Sean Wang sean.wang@mediatek.com net: ethernet: mediatek: Use hw_feature to judge if HWLRO is supported
Young Xiao 92siuyang@gmail.com sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD
Gen Zhang blackgod016574@gmail.com mdesc: fix a missing-check bug in get_vdev_port_node_info()
Yonglong Liu liuyonglong@huawei.com net: hns: Fix loopback test failed at copper ports
Nikita Yushchenko nikita.yoush@cogentembedded.com net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0
Naresh Kamboju naresh.kamboju@linaro.org selftests: vm: install test_vmalloc.sh for run_vmtests
Alex Shi alex.shi@linux.alibaba.com kselftest/cgroup: fix incorrect test_core skip
Alex Shi alex.shi@linux.alibaba.com kselftest/cgroup: fix unexpected testing failure on test_core
Alex Shi alex.shi@linux.alibaba.com kselftest/cgroup: fix unexpected testing failure on test_memcontrol
Guenter Roeck linux@roeck-us.net xtensa: Fix section mismatch between memblock_reserve and mem_reserve
YueHaibing yuehaibing@huawei.com MIPS: uprobes: remove set but not used variable 'epc'
Kamenee Arumugam kamenee.arumugam@intel.com IB/hfi1: Validate page aligned for a given virtual address
Mike Marciniszyn mike.marciniszyn@intel.com IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value
Mike Marciniszyn mike.marciniszyn@intel.com IB/hfi1: Insure freeze_work work_struct is canceled on shutdown
Mike Marciniszyn mike.marciniszyn@intel.com IB/rdmavt: Fix alloc_qpn() WARN_ON()
Helge Deller deller@gmx.de parisc: Fix compiler warnings in float emulation code
YueHaibing yuehaibing@huawei.com parport: Fix mem leak in parport_register_dev_model
Scott Wood swood@redhat.com fpga: dfl: Add lockdep classes for pdata->lock
Scott Wood swood@redhat.com fpga: dfl: afu: Pass the correct device to dma_mapping_error()
Jose Abreu joabreu@synopsys.com ARC: [plat-hsdk]: Add missing FIFO size entry in GMAC node
Jose Abreu joabreu@synopsys.com ARC: [plat-hsdk]: Add missing multicast filter bins number to GMAC node
Eric Long eric.long@unisoc.com dmaengine: sprd: Fix block length overflow
Colin Ian King colin.king@canonical.com dmaengine: dw-axi-dmac: fix null dereference when pointer first is null
Vineet Gupta vgupta@synopsys.com ARC: fix build warnings
Douglas Anderson dianders@chromium.org brcmfmac: sdio: Don't tune while the card is off
Douglas Anderson dianders@chromium.org brcmfmac: sdio: Disable auto-tuning around commands expected to fail
Jann Horn jannh@google.com apparmor: enforce nullbyte at end of tag string
John Johansen john.johansen@canonical.com apparmor: fix PROFILE_MEDIATES for untrusted input
Daniel Smith danct12@disroot.org Input: silead - add MSSL0017 to acpi_device_id
Andrey Smirnov andrew.smirnov@gmail.com Input: uinput - add compat ioctl number translation for UI_*_FF_UPLOAD
Alexander Mikhaylenko exalm7659@gmail.com Input: synaptics - enable SMBus on ThinkPad E480 and E580
Crt Mori cmo@melexis.com iio: temperature: mlx90632 Relax the compatibility check
Mike Marciniszyn mike.marciniszyn@intel.com IB/hfi1: Silence txreq allocation warnings
Kaike Wan kaike.wan@intel.com IB/hfi1: Validate fault injection opcode user input
Mathias Nyman mathias.nyman@linux.intel.com usb: xhci: Don't try to recover an endpoint if port is in error state.
Mathias Nyman mathias.nyman@linux.intel.com xhci: detect USB 3.2 capable host controllers correctly
Peter Chen peter.chen@nxp.com usb: chipidea: udc: workaround for endpoint conflict issue
Stanley Chu stanley.chu@mediatek.com scsi: ufs: Avoid runtime suspend possibly being blocked forever
Ulf Hansson ulf.hansson@linaro.org mmc: core: Prevent processing SDIO IRQs when the card is suspended
Douglas Anderson dianders@chromium.org mmc: core: Add sdio_retune_hold_now() and sdio_retune_release()
Douglas Anderson dianders@chromium.org mmc: core: API to temporarily disable retuning for SDIO CRC errors
Raul E Rangel rrangel@chromium.org mmc: sdhci: sdhci-pci-o2micro: Correctly set bus width when tuning
Harald Freudenberger freude@linux.ibm.com s390/ap: rework assembler functions to use unions for in/out register variables
Ilya Leoshkevich iii@linux.ibm.com s390/jump_label: Use "jdd" constraint on gcc9
Arnd Bergmann arnd@arndb.de ovl: fix bogus -Wmaybe-unitialized warning
Miklos Szeredi mszeredi@redhat.com ovl: don't fail with disconnected lower NFS
Amir Goldstein amir73il@gmail.com ovl: detect overlapping layers
Amir Goldstein amir73il@gmail.com ovl: make i_ino consistent with st_ino in more cases
Amir Goldstein amir73il@gmail.com ovl: fix wrong flags check in FS_IOC_FS[SG]ETXATTR ioctls
Amir Goldstein amir73il@gmail.com ovl: support the FS_IOC_FS[SG]ETXATTR ioctls
Linus Torvalds torvalds@linux-foundation.org gcc-9: silence 'address-of-packed-member' warning
Allan Xavier allan.x.xavier@oracle.com objtool: Support per-function rodata sections
Miguel Ojeda miguel.ojeda.sandonis@gmail.com tracing: Silence GCC 9 array bounds warning
-------------
Diffstat:
Makefile | 6 +- arch/arc/boot/dts/hsdk.dts | 4 + arch/arc/include/asm/cmpxchg.h | 14 +- arch/arc/mm/tlb.c | 13 +- arch/arm/boot/dts/am57xx-idk-common.dtsi | 1 + arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi | 40 ++--- arch/arm/mach-imx/cpuidle-imx6sx.c | 3 +- arch/arm64/Makefile | 1 + arch/arm64/include/uapi/asm/ptrace.h | 8 +- arch/arm64/kernel/ssbd.c | 1 + arch/mips/kernel/uprobes.c | 3 - arch/parisc/math-emu/cnv_float.h | 8 +- arch/powerpc/include/asm/ppc-opcode.h | 1 + arch/powerpc/net/bpf_jit.h | 2 +- arch/powerpc/net/bpf_jit_comp64.c | 8 +- arch/riscv/mm/fault.c | 13 ++ arch/s390/include/asm/ap.h | 28 ++-- arch/s390/include/asm/jump_label.h | 14 +- arch/sparc/kernel/mdesc.c | 2 + arch/sparc/kernel/perf_event.c | 4 + arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 2 +- arch/xtensa/kernel/setup.c | 3 +- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 3 +- drivers/dma/sprd-dma.c | 2 +- drivers/fpga/dfl-afu-dma-region.c | 2 +- drivers/fpga/dfl.c | 16 +- drivers/gpu/drm/arm/hdlcd_crtc.c | 14 +- drivers/gpu/drm/arm/malidp_drv.c | 13 +- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 146 +++++++++++++++---- drivers/hwmon/hwmon.c | 2 +- drivers/hwmon/pmbus/pmbus_core.c | 34 ++++- drivers/iio/temperature/mlx90632.c | 9 +- drivers/infiniband/hw/hfi1/chip.c | 1 + drivers/infiniband/hw/hfi1/fault.c | 5 + drivers/infiniband/hw/hfi1/user_exp_rcv.c | 3 + drivers/infiniband/hw/hfi1/verbs.c | 2 - drivers/infiniband/hw/hfi1/verbs_txreq.c | 2 +- drivers/infiniband/hw/hfi1/verbs_txreq.h | 3 +- drivers/infiniband/hw/qib/qib_verbs.c | 2 - drivers/infiniband/sw/rdmavt/mr.c | 2 + drivers/infiniband/sw/rdmavt/qp.c | 3 +- drivers/input/misc/uinput.c | 22 ++- drivers/input/mouse/synaptics.c | 2 + drivers/input/touchscreen/silead.c | 1 + drivers/mmc/core/core.c | 5 +- drivers/mmc/core/sdio.c | 13 +- drivers/mmc/core/sdio_io.c | 77 ++++++++++ drivers/mmc/core/sdio_irq.c | 4 + drivers/mmc/host/sdhci-pci-o2micro.c | 5 +- drivers/net/can/flexcan.c | 2 +- drivers/net/can/xilinx_can.c | 2 +- drivers/net/dsa/mv88e6xxx/chip.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 4 + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 +- drivers/net/ipvlan/ipvlan_main.c | 2 +- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 ++ drivers/nvme/host/core.c | 3 +- drivers/nvme/target/io-cmd-bdev.c | 1 + drivers/parport/share.c | 2 + drivers/s390/net/qeth_l2_main.c | 2 +- drivers/scsi/smartpqi/smartpqi_init.c | 6 +- drivers/scsi/ufs/ufshcd-pltfrm.c | 11 +- drivers/scsi/ufs/ufshcd.c | 3 +- drivers/staging/erofs/erofs_fs.h | 13 +- drivers/staging/erofs/internal.h | 2 + drivers/staging/erofs/super.c | 19 +++ drivers/usb/chipidea/udc.c | 20 +++ drivers/usb/host/xhci-ring.c | 15 +- drivers/usb/host/xhci.c | 25 +++- drivers/usb/host/xhci.h | 9 ++ fs/btrfs/reada.c | 5 + fs/cifs/smb2maperror.c | 2 +- fs/overlayfs/file.c | 96 ++++++++---- fs/overlayfs/inode.c | 60 +++++++- fs/overlayfs/namei.c | 8 + fs/overlayfs/overlayfs.h | 3 + fs/overlayfs/ovl_entry.h | 6 + fs/overlayfs/super.c | 161 ++++++++++++++++++--- fs/overlayfs/util.c | 12 ++ include/linux/mmc/host.h | 1 + include/linux/mmc/sdio_func.h | 6 + include/net/bluetooth/hci_core.h | 3 + include/net/cfg80211.h | 3 +- kernel/trace/trace.c | 6 +- kernel/trace/trace.h | 18 +++ kernel/trace/trace_kdb.c | 6 +- net/bluetooth/hci_conn.c | 10 +- net/bluetooth/l2cap_core.c | 33 ++++- net/can/af_can.c | 1 + net/mac80211/ieee80211_i.h | 3 + net/mac80211/mlme.c | 12 +- net/mac80211/rx.c | 2 + net/mac80211/tdls.c | 23 +++ net/mac80211/util.c | 4 +- net/mac80211/wpa.c | 7 +- net/wireless/core.c | 8 +- net/wireless/nl80211.c | 12 +- scripts/checkstack.pl | 2 +- security/apparmor/include/policy.h | 11 +- security/apparmor/policy_unpack.c | 2 +- tools/objtool/check.c | 38 ++++- tools/objtool/check.h | 4 +- tools/objtool/elf.c | 1 + tools/objtool/elf.h | 3 +- tools/testing/selftests/cgroup/test_core.c | 7 +- tools/testing/selftests/cgroup/test_memcontrol.c | 4 + tools/testing/selftests/vm/Makefile | 2 + 107 files changed, 1079 insertions(+), 247 deletions(-)
From: Miguel Ojeda miguel.ojeda.sandonis@gmail.com
commit 0c97bf863efce63d6ab7971dad811601e6171d2f upstream.
Starting with GCC 9, -Warray-bounds detects cases when memset is called starting on a member of a struct but the size to be cleared ends up writing over further members.
Such a call happens in the trace code to clear, at once, all members after and including `seq` on struct trace_iterator:
In function 'memset', inlined from 'ftrace_dump' at kernel/trace/trace.c:8914:3: ./include/linux/string.h:344:9: warning: '__builtin_memset' offset [8505, 8560] from the object at 'iter' is out of the bounds of referenced subobject 'seq' with type 'struct trace_seq' at offset 4368 [-Warray-bounds] 344 | return __builtin_memset(p, c, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to avoid GCC complaining about it, we compute the address ourselves by adding the offsetof distance instead of referring directly to the member.
Since there are two places doing this clear (trace.c and trace_kdb.c), take the chance to move the workaround into a single place in the internal header.
Link: http://lkml.kernel.org/r/20190523124535.GA12931@gmail.com
Signed-off-by: Miguel Ojeda miguel.ojeda.sandonis@gmail.com [ Removed unnecessary parenthesis around "iter" ] Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/trace/trace.c | 6 +----- kernel/trace/trace.h | 18 ++++++++++++++++++ kernel/trace/trace_kdb.c | 6 +----- 3 files changed, 20 insertions(+), 10 deletions(-)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8351,12 +8351,8 @@ void ftrace_dump(enum ftrace_dump_mode o
cnt++;
- /* reset all but tr, trace, and overruns */ - memset(&iter.seq, 0, - sizeof(struct trace_iterator) - - offsetof(struct trace_iterator, seq)); + trace_iterator_reset(&iter); iter.iter_flags |= TRACE_FILE_LAT_FMT; - iter.pos = -1;
if (trace_find_next_entry_inc(&iter) != NULL) { int ret; --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1895,4 +1895,22 @@ static inline void tracer_hardirqs_off(u
extern struct trace_iterator *tracepoint_print_iter;
+/* + * Reset the state of the trace_iterator so that it can read consumed data. + * Normally, the trace_iterator is used for reading the data when it is not + * consumed, and must retain state. + */ +static __always_inline void trace_iterator_reset(struct trace_iterator *iter) +{ + const size_t offset = offsetof(struct trace_iterator, seq); + + /* + * Keep gcc from complaining about overwriting more than just one + * member in the structure. + */ + memset((char *)iter + offset, 0, sizeof(struct trace_iterator) - offset); + + iter->pos = -1; +} + #endif /* _LINUX_KERNEL_TRACE_H */ --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -41,12 +41,8 @@ static void ftrace_dump_buf(int skip_lin
kdb_printf("Dumping ftrace buffer:\n");
- /* reset all but tr, trace, and overruns */ - memset(&iter.seq, 0, - sizeof(struct trace_iterator) - - offsetof(struct trace_iterator, seq)); + trace_iterator_reset(&iter); iter.iter_flags |= TRACE_FILE_LAT_FMT; - iter.pos = -1;
if (cpu_file == RING_BUFFER_ALL_CPUS) { for_each_tracing_cpu(cpu) {
From: Allan Xavier allan.x.xavier@oracle.com
commit 4a60aa05a0634241ce17f957bf9fb5ac1eed6576 upstream.
Add support for processing switch jump tables in objects with multiple .rodata sections, such as those created by '-ffunction-sections' and '-fdata-sections'. Currently, objtool always looks in .rodata for jump table information, which results in many "sibling call from callable instruction with modified stack frame" warnings with objects compiled using those flags.
The fix is comprised of three parts:
1. Flagging all .rodata sections when importing ELF information for easier checking later.
2. Keeping a reference to the section each relocation is from in order to get the list_head for the other relocations in that section.
3. Finding jump tables by following relocations to .rodata sections, rather than always referencing a single global .rodata section.
The patch has been tested without data sections enabled and no differences in the resulting orc unwind information were seen.
Note that as objtool adds terminators to end of each .text section the unwind information generated between a function+data sections build and a normal build aren't directly comparable. Manual inspection suggests that objtool is now generating the correct information, or at least making more of an effort to do so than it did previously.
Signed-off-by: Allan Xavier allan.x.xavier@oracle.com Signed-off-by: Josh Poimboeuf jpoimboe@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/099bdc375195c490dda04db777ee0b95d566ded1.153632591... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/objtool/check.c | 38 ++++++++++++++++++++++++++++++++------ tools/objtool/check.h | 4 ++-- tools/objtool/elf.c | 1 + tools/objtool/elf.h | 3 ++- 4 files changed, 37 insertions(+), 9 deletions(-)
--- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -839,7 +839,7 @@ static int add_switch_table(struct objto struct symbol *pfunc = insn->func->pfunc; unsigned int prev_offset = 0;
- list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { + list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) { if (rela == next_table) break;
@@ -929,6 +929,7 @@ static struct rela *find_switch_table(st { struct rela *text_rela, *rodata_rela; struct instruction *orig_insn = insn; + struct section *rodata_sec; unsigned long table_offset;
/* @@ -956,10 +957,13 @@ static struct rela *find_switch_table(st /* look for a relocation which references .rodata */ text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); - if (!text_rela || text_rela->sym != file->rodata->sym) + if (!text_rela || text_rela->sym->type != STT_SECTION || + !text_rela->sym->sec->rodata) continue;
table_offset = text_rela->addend; + rodata_sec = text_rela->sym->sec; + if (text_rela->type == R_X86_64_PC32) table_offset += 4;
@@ -967,10 +971,10 @@ static struct rela *find_switch_table(st * Make sure the .rodata address isn't associated with a * symbol. gcc jump tables are anonymous data. */ - if (find_symbol_containing(file->rodata, table_offset)) + if (find_symbol_containing(rodata_sec, table_offset)) continue;
- rodata_rela = find_rela_by_dest(file->rodata, table_offset); + rodata_rela = find_rela_by_dest(rodata_sec, table_offset); if (rodata_rela) { /* * Use of RIP-relative switch jumps is quite rare, and @@ -1055,7 +1059,7 @@ static int add_switch_table_alts(struct struct symbol *func; int ret;
- if (!file->rodata || !file->rodata->rela) + if (!file->rodata) return 0;
for_each_sec(file, sec) { @@ -1201,10 +1205,33 @@ static int read_retpoline_hints(struct o return 0; }
+static void mark_rodata(struct objtool_file *file) +{ + struct section *sec; + bool found = false; + + /* + * This searches for the .rodata section or multiple .rodata.func_name + * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8 + * rodata sections are ignored as they don't contain jump tables. + */ + for_each_sec(file, sec) { + if (!strncmp(sec->name, ".rodata", 7) && + !strstr(sec->name, ".str1.")) { + sec->rodata = true; + found = true; + } + } + + file->rodata = found; +} + static int decode_sections(struct objtool_file *file) { int ret;
+ mark_rodata(file); + ret = decode_instructions(file); if (ret) return ret; @@ -2176,7 +2203,6 @@ int check(const char *_objname, bool orc INIT_LIST_HEAD(&file.insn_list); hash_init(file.insn_hash); file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard"); - file.rodata = find_section_by_name(file.elf, ".rodata"); file.c_file = find_section_by_name(file.elf, ".comment"); file.ignore_unreachables = no_unreachable; file.hints = false; --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -60,8 +60,8 @@ struct objtool_file { struct elf *elf; struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); - struct section *rodata, *whitelist; - bool ignore_unreachables, c_file, hints; + struct section *whitelist; + bool ignore_unreachables, c_file, hints, rodata; };
int check(const char *objname, bool orc); --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -390,6 +390,7 @@ static int read_relas(struct elf *elf) rela->offset = rela->rela.r_offset; symndx = GELF_R_SYM(rela->rela.r_info); rela->sym = find_symbol_by_index(elf, symndx); + rela->rela_sec = sec; if (!rela->sym) { WARN("can't find rela entry symbol %d for %s", symndx, sec->name); --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h @@ -48,7 +48,7 @@ struct section { char *name; int idx; unsigned int len; - bool changed, text; + bool changed, text, rodata; };
struct symbol { @@ -68,6 +68,7 @@ struct rela { struct list_head list; struct hlist_node hash; GElf_Rela rela; + struct section *rela_sec; struct symbol *sym; unsigned int type; unsigned long offset;
From: Linus Torvalds torvalds@linux-foundation.org
commit 6f303d60534c46aa1a239f29c321f95c83dda748 upstream.
We already did this for clang, but now gcc has that warning too. Yes, yes, the address may be unaligned. And that's kind of the point.
Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Makefile +++ b/Makefile @@ -652,6 +652,7 @@ KBUILD_CFLAGS += $(call cc-disable-warni KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) +KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) @@ -696,7 +697,6 @@ ifeq ($(cc-name),clang) KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) -KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) # Quiet clang warning: comparison of unsigned expression < 0 is always false KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) # CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the
[ Upstream commit b21d9c435f935014d3e3fa6914f2e4fbabb0e94d ]
They are the extended version of FS_IOC_FS[SG]ETFLAGS ioctls. xfs_io -c "chattr <flags>" uses the new ioctls for setting flags.
This used to work in kernel pre v4.19, before stacked file ops introduced the ovl_ioctl whitelist.
Reported-by: Dave Chinner david@fromorbit.com Fixes: d1d04ef8572b ("ovl: stack file ops") Cc: stable@vger.kernel.org # v4.19 Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 00338b828f76..749532fd51d7 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -426,7 +426,8 @@ static unsigned int ovl_get_inode_flags(struct inode *inode) return ovl_iflags; }
-static long ovl_ioctl_set_flags(struct file *file, unsigned long arg) +static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd, + unsigned long arg) { long ret; struct inode *inode = file_inode(file); @@ -456,7 +457,7 @@ static long ovl_ioctl_set_flags(struct file *file, unsigned long arg) if (ret) goto unlock;
- ret = ovl_real_ioctl(file, FS_IOC_SETFLAGS, arg); + ret = ovl_real_ioctl(file, cmd, arg);
ovl_copyflags(ovl_inode_real(inode), inode); unlock: @@ -474,11 +475,13 @@ static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
switch (cmd) { case FS_IOC_GETFLAGS: + case FS_IOC_FSGETXATTR: ret = ovl_real_ioctl(file, cmd, arg); break;
case FS_IOC_SETFLAGS: - ret = ovl_ioctl_set_flags(file, arg); + case FS_IOC_FSSETXATTR: + ret = ovl_ioctl_set_flags(file, cmd, arg); break;
default:
[ Upstream commit 941d935ac7636911a3fd8fa80e758e52b0b11e20 ]
The ioctl argument was parsed as the wrong type.
Fixes: b21d9c435f93 ("ovl: support the FS_IOC_FS[SG]ETXATTR ioctls") Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/file.c | 91 ++++++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 26 deletions(-)
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 749532fd51d7..0bd276e4ccbe 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -409,37 +409,16 @@ static long ovl_real_ioctl(struct file *file, unsigned int cmd, return ret; }
-static unsigned int ovl_get_inode_flags(struct inode *inode) -{ - unsigned int flags = READ_ONCE(inode->i_flags); - unsigned int ovl_iflags = 0; - - if (flags & S_SYNC) - ovl_iflags |= FS_SYNC_FL; - if (flags & S_APPEND) - ovl_iflags |= FS_APPEND_FL; - if (flags & S_IMMUTABLE) - ovl_iflags |= FS_IMMUTABLE_FL; - if (flags & S_NOATIME) - ovl_iflags |= FS_NOATIME_FL; - - return ovl_iflags; -} - static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg, unsigned int iflags) { long ret; struct inode *inode = file_inode(file); - unsigned int flags; - unsigned int old_flags; + unsigned int old_iflags;
if (!inode_owner_or_capable(inode)) return -EACCES;
- if (get_user(flags, (int __user *) arg)) - return -EFAULT; - ret = mnt_want_write_file(file); if (ret) return ret; @@ -448,8 +427,8 @@ static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd,
/* Check the capability before cred override */ ret = -EPERM; - old_flags = ovl_get_inode_flags(inode); - if (((flags ^ old_flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) && + old_iflags = READ_ONCE(inode->i_flags); + if (((iflags ^ old_iflags) & (S_APPEND | S_IMMUTABLE)) && !capable(CAP_LINUX_IMMUTABLE)) goto unlock;
@@ -469,6 +448,63 @@ static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd,
}
+static unsigned int ovl_fsflags_to_iflags(unsigned int flags) +{ + unsigned int iflags = 0; + + if (flags & FS_SYNC_FL) + iflags |= S_SYNC; + if (flags & FS_APPEND_FL) + iflags |= S_APPEND; + if (flags & FS_IMMUTABLE_FL) + iflags |= S_IMMUTABLE; + if (flags & FS_NOATIME_FL) + iflags |= S_NOATIME; + + return iflags; +} + +static long ovl_ioctl_set_fsflags(struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned int flags; + + if (get_user(flags, (int __user *) arg)) + return -EFAULT; + + return ovl_ioctl_set_flags(file, cmd, arg, + ovl_fsflags_to_iflags(flags)); +} + +static unsigned int ovl_fsxflags_to_iflags(unsigned int xflags) +{ + unsigned int iflags = 0; + + if (xflags & FS_XFLAG_SYNC) + iflags |= S_SYNC; + if (xflags & FS_XFLAG_APPEND) + iflags |= S_APPEND; + if (xflags & FS_XFLAG_IMMUTABLE) + iflags |= S_IMMUTABLE; + if (xflags & FS_XFLAG_NOATIME) + iflags |= S_NOATIME; + + return iflags; +} + +static long ovl_ioctl_set_fsxflags(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct fsxattr fa; + + memset(&fa, 0, sizeof(fa)); + if (copy_from_user(&fa, (void __user *) arg, sizeof(fa))) + return -EFAULT; + + return ovl_ioctl_set_flags(file, cmd, arg, + ovl_fsxflags_to_iflags(fa.fsx_xflags)); +} + static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret; @@ -480,8 +516,11 @@ static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break;
case FS_IOC_SETFLAGS: + ret = ovl_ioctl_set_fsflags(file, cmd, arg); + break; + case FS_IOC_FSSETXATTR: - ret = ovl_ioctl_set_flags(file, cmd, arg); + ret = ovl_ioctl_set_fsxflags(file, cmd, arg); break;
default:
[ Upstream commit 6dde1e42f497b2d4e22466f23019016775607947 ]
Relax the condition that overlayfs supports nfs export, to require that i_ino is consistent with st_ino/d_ino.
It is enough to require that st_ino and d_ino are consistent.
This fixes the failure of xfstest generic/504, due to mismatch of st_ino to inode number in the output of /proc/locks.
Fixes: 12574a9f4c9c ("ovl: consistent i_ino for non-samefs with xino") Cc: stable@vger.kernel.org # v4.19 Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/inode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index b48273e846ad..373ccff9880c 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -553,15 +553,15 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev, int xinobits = ovl_xino_bits(inode->i_sb);
/* - * When NFS export is enabled and d_ino is consistent with st_ino - * (samefs or i_ino has enough bits to encode layer), set the same - * value used for d_ino to i_ino, because nfsd readdirplus compares - * d_ino values to i_ino values of child entries. When called from + * When d_ino is consistent with st_ino (samefs or i_ino has enough + * bits to encode layer), set the same value used for st_ino to i_ino, + * so inode number exposed via /proc/locks and a like will be + * consistent with d_ino and st_ino values. An i_ino value inconsistent + * with d_ino also causes nfsd readdirplus to fail. When called from * ovl_new_inode(), ino arg is 0, so i_ino will be updated to real * upper inode i_ino on ovl_inode_init() or ovl_inode_update(). */ - if (inode->i_sb->s_export_op && - (ovl_same_sb(inode->i_sb) || xinobits)) { + if (ovl_same_sb(inode->i_sb) || xinobits) { inode->i_ino = ino; if (xinobits && fsid && !(ino >> (64 - xinobits))) inode->i_ino |= (unsigned long)fsid << (64 - xinobits);
[ Upstream commit 146d62e5a5867fbf84490d82455718bfb10fe824 ]
Overlapping overlay layers are not supported and can cause unexpected behavior, but overlayfs does not currently check or warn about these configurations.
User is not supposed to specify the same directory for upper and lower dirs or for different lower layers and user is not supposed to specify directories that are descendants of each other for overlay layers, but that is exactly what this zysbot repro did:
https://syzkaller.appspot.com/x/repro.syz?x=12c7a94f400000
Moving layer root directories into other layers while overlayfs is mounted could also result in unexpected behavior.
This commit places "traps" in the overlay inode hash table. Those traps are dummy overlay inodes that are hashed by the layers root inodes.
On mount, the hash table trap entries are used to verify that overlay layers are not overlapping. While at it, we also verify that overlay layers are not overlapping with directories "in-use" by other overlay instances as upperdir/workdir.
On lookup, the trap entries are used to verify that overlay layers root inodes have not been moved into other layers after mount.
Some examples:
$ ./run --ov --samefs -s ... ( mkdir -p base/upper/0/u base/upper/0/w base/lower lower upper mnt mount -o bind base/lower lower mount -o bind base/upper upper mount -t overlay none mnt ... -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w)
$ umount mnt $ mount -t overlay none mnt ... -o lowerdir=base,upperdir=upper/0/u,workdir=upper/0/w
[ 94.434900] overlayfs: overlapping upperdir path mount: mount overlay on mnt failed: Too many levels of symbolic links
$ mount -t overlay none mnt ... -o lowerdir=upper/0/u,upperdir=upper/0/u,workdir=upper/0/w
[ 151.350132] overlayfs: conflicting lowerdir path mount: none is already mounted or mnt busy
$ mount -t overlay none mnt ... -o lowerdir=lower:lower/a,upperdir=upper/0/u,workdir=upper/0/w
[ 201.205045] overlayfs: overlapping lowerdir path mount: mount overlay on mnt failed: Too many levels of symbolic links
$ mount -t overlay none mnt ... -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w $ mv base/upper/0/ base/lower/ $ find mnt/0 mnt/0 mnt/0/w find: 'mnt/0/w/work': Too many levels of symbolic links find: 'mnt/0/u': Too many levels of symbolic links
Reported-by: syzbot+9c69c282adc4edd2b540@syzkaller.appspotmail.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/inode.c | 48 +++++++++++ fs/overlayfs/namei.c | 8 ++ fs/overlayfs/overlayfs.h | 3 + fs/overlayfs/ovl_entry.h | 6 ++ fs/overlayfs/super.c | 169 +++++++++++++++++++++++++++++++++++---- fs/overlayfs/util.c | 12 +++ 6 files changed, 229 insertions(+), 17 deletions(-)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 373ccff9880c..f0389849fd80 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -777,6 +777,54 @@ struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, return inode; }
+bool ovl_lookup_trap_inode(struct super_block *sb, struct dentry *dir) +{ + struct inode *key = d_inode(dir); + struct inode *trap; + bool res; + + trap = ilookup5(sb, (unsigned long) key, ovl_inode_test, key); + if (!trap) + return false; + + res = IS_DEADDIR(trap) && !ovl_inode_upper(trap) && + !ovl_inode_lower(trap); + + iput(trap); + return res; +} + +/* + * Create an inode cache entry for layer root dir, that will intentionally + * fail ovl_verify_inode(), so any lookup that will find some layer root + * will fail. + */ +struct inode *ovl_get_trap_inode(struct super_block *sb, struct dentry *dir) +{ + struct inode *key = d_inode(dir); + struct inode *trap; + + if (!d_is_dir(dir)) + return ERR_PTR(-ENOTDIR); + + trap = iget5_locked(sb, (unsigned long) key, ovl_inode_test, + ovl_inode_set, key); + if (!trap) + return ERR_PTR(-ENOMEM); + + if (!(trap->i_state & I_NEW)) { + /* Conflicting layer roots? */ + iput(trap); + return ERR_PTR(-ELOOP); + } + + trap->i_mode = S_IFDIR; + trap->i_flags = S_DEAD; + unlock_new_inode(trap); + + return trap; +} + /* * Does overlay inode need to be hashed by lower inode? */ diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index efd372312ef1..badf039267a2 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -18,6 +18,7 @@ #include "overlayfs.h"
struct ovl_lookup_data { + struct super_block *sb; struct qstr name; bool is_dir; bool opaque; @@ -244,6 +245,12 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, if (!d->metacopy || d->last) goto out; } else { + if (ovl_lookup_trap_inode(d->sb, this)) { + /* Caught in a trap of overlapping layers */ + err = -ELOOP; + goto out_err; + } + if (last_element) d->is_dir = true; if (d->last) @@ -819,6 +826,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, int err; bool metacopy = false; struct ovl_lookup_data d = { + .sb = dentry->d_sb, .name = dentry->d_name, .is_dir = false, .opaque = false, diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 80fb66426760..265bf9cfde08 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -270,6 +270,7 @@ void ovl_clear_flag(unsigned long flag, struct inode *inode); bool ovl_test_flag(unsigned long flag, struct inode *inode); bool ovl_inuse_trylock(struct dentry *dentry); void ovl_inuse_unlock(struct dentry *dentry); +bool ovl_is_inuse(struct dentry *dentry); bool ovl_need_index(struct dentry *dentry); int ovl_nlink_start(struct dentry *dentry, bool *locked); void ovl_nlink_end(struct dentry *dentry, bool locked); @@ -366,6 +367,8 @@ struct ovl_inode_params { struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev); struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, bool is_upper); +bool ovl_lookup_trap_inode(struct super_block *sb, struct dentry *dir); +struct inode *ovl_get_trap_inode(struct super_block *sb, struct dentry *dir); struct inode *ovl_get_inode(struct super_block *sb, struct ovl_inode_params *oip); static inline void ovl_copyattr(struct inode *from, struct inode *to) diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index ec237035333a..6ed1ace8f8b3 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -29,6 +29,8 @@ struct ovl_sb {
struct ovl_layer { struct vfsmount *mnt; + /* Trap in ovl inode cache */ + struct inode *trap; struct ovl_sb *fs; /* Index of this layer in fs root (upper idx == 0) */ int idx; @@ -65,6 +67,10 @@ struct ovl_fs { /* Did we take the inuse lock? */ bool upperdir_locked; bool workdir_locked; + /* Traps in ovl inode cache */ + struct inode *upperdir_trap; + struct inode *workdir_trap; + struct inode *indexdir_trap; /* Inode numbers in all layers do not use the high xino_bits */ unsigned int xino_bits; }; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 0fb0a59a5e5c..4e268f981b4d 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -217,6 +217,9 @@ static void ovl_free_fs(struct ovl_fs *ofs) { unsigned i;
+ iput(ofs->indexdir_trap); + iput(ofs->workdir_trap); + iput(ofs->upperdir_trap); dput(ofs->indexdir); dput(ofs->workdir); if (ofs->workdir_locked) @@ -225,8 +228,10 @@ static void ovl_free_fs(struct ovl_fs *ofs) if (ofs->upperdir_locked) ovl_inuse_unlock(ofs->upper_mnt->mnt_root); mntput(ofs->upper_mnt); - for (i = 0; i < ofs->numlower; i++) + for (i = 0; i < ofs->numlower; i++) { + iput(ofs->lower_layers[i].trap); mntput(ofs->lower_layers[i].mnt); + } for (i = 0; i < ofs->numlowerfs; i++) free_anon_bdev(ofs->lower_fs[i].pseudo_dev); kfree(ofs->lower_layers); @@ -984,7 +989,26 @@ static const struct xattr_handler *ovl_xattr_handlers[] = { NULL };
-static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath) +static int ovl_setup_trap(struct super_block *sb, struct dentry *dir, + struct inode **ptrap, const char *name) +{ + struct inode *trap; + int err; + + trap = ovl_get_trap_inode(sb, dir); + err = PTR_ERR(trap); + if (IS_ERR(trap)) { + if (err == -ELOOP) + pr_err("overlayfs: conflicting %s path\n", name); + return err; + } + + *ptrap = trap; + return 0; +} + +static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, + struct path *upperpath) { struct vfsmount *upper_mnt; int err; @@ -1004,6 +1028,11 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath) if (err) goto out;
+ err = ovl_setup_trap(sb, upperpath->dentry, &ofs->upperdir_trap, + "upperdir"); + if (err) + goto out; + upper_mnt = clone_private_mount(upperpath); err = PTR_ERR(upper_mnt); if (IS_ERR(upper_mnt)) { @@ -1030,7 +1059,8 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath) return err; }
-static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) +static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, + struct path *workpath) { struct vfsmount *mnt = ofs->upper_mnt; struct dentry *temp; @@ -1045,6 +1075,10 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) if (!ofs->workdir) goto out;
+ err = ovl_setup_trap(sb, ofs->workdir, &ofs->workdir_trap, "workdir"); + if (err) + goto out; + /* * Upper should support d_type, else whiteouts are visible. Given * workdir and upper are on same fs, we can do iterate_dir() on @@ -1105,7 +1139,8 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) return err; }
-static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath) +static int ovl_get_workdir(struct super_block *sb, struct ovl_fs *ofs, + struct path *upperpath) { int err; struct path workpath = { }; @@ -1136,19 +1171,16 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath) pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); }
- err = ovl_make_workdir(ofs, &workpath); - if (err) - goto out; + err = ovl_make_workdir(sb, ofs, &workpath);
- err = 0; out: path_put(&workpath);
return err; }
-static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe, - struct path *upperpath) +static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + struct ovl_entry *oe, struct path *upperpath) { struct vfsmount *mnt = ofs->upper_mnt; int err; @@ -1167,6 +1199,11 @@ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true); if (ofs->indexdir) { + err = ovl_setup_trap(sb, ofs->indexdir, &ofs->indexdir_trap, + "indexdir"); + if (err) + goto out; + /* * Verify upper root is exclusively associated with index dir. * Older kernels stored upper fh in "trusted.overlay.origin" @@ -1226,8 +1263,8 @@ static int ovl_get_fsid(struct ovl_fs *ofs, struct super_block *sb) return ofs->numlowerfs; }
-static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack, - unsigned int numlower) +static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs, + struct path *stack, unsigned int numlower) { int err; unsigned int i; @@ -1245,16 +1282,28 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack,
for (i = 0; i < numlower; i++) { struct vfsmount *mnt; + struct inode *trap; int fsid;
err = fsid = ovl_get_fsid(ofs, stack[i].mnt->mnt_sb); if (err < 0) goto out;
+ err = -EBUSY; + if (ovl_is_inuse(stack[i].dentry)) { + pr_err("overlayfs: lowerdir is in-use as upperdir/workdir\n"); + goto out; + } + + err = ovl_setup_trap(sb, stack[i].dentry, &trap, "lowerdir"); + if (err) + goto out; + mnt = clone_private_mount(&stack[i]); err = PTR_ERR(mnt); if (IS_ERR(mnt)) { pr_err("overlayfs: failed to clone lowerpath\n"); + iput(trap); goto out; }
@@ -1264,6 +1313,7 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack, */ mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
+ ofs->lower_layers[ofs->numlower].trap = trap; ofs->lower_layers[ofs->numlower].mnt = mnt; ofs->lower_layers[ofs->numlower].idx = i + 1; ofs->lower_layers[ofs->numlower].fsid = fsid; @@ -1358,7 +1408,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb, goto out_err; }
- err = ovl_get_lower_layers(ofs, stack, numlower); + err = ovl_get_lower_layers(sb, ofs, stack, numlower); if (err) goto out_err;
@@ -1390,6 +1440,85 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb, goto out; }
+/* + * Check if this layer root is a descendant of: + * - another layer of this overlayfs instance + * - upper/work dir of any overlayfs instance + * - a disconnected dentry (detached root) + */ +static int ovl_check_layer(struct super_block *sb, struct dentry *dentry, + const char *name) +{ + struct dentry *next, *parent; + bool is_root = false; + int err = 0; + + if (!dentry || dentry == dentry->d_sb->s_root) + return 0; + + next = dget(dentry); + /* Walk back ancestors to fs root (inclusive) looking for traps */ + do { + parent = dget_parent(next); + is_root = (parent == next); + if (ovl_is_inuse(parent)) { + err = -EBUSY; + pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n", + name); + } else if (ovl_lookup_trap_inode(sb, parent)) { + err = -ELOOP; + pr_err("overlayfs: overlapping %s path\n", name); + } + dput(next); + next = parent; + } while (!err && !is_root); + + /* Did we really walk to fs root or found a detached root? */ + if (!err && next != dentry->d_sb->s_root) { + err = -ESTALE; + pr_err("overlayfs: disconnected %s path\n", name); + } + + dput(next); + + return err; +} + +/* + * Check if any of the layers or work dirs overlap. + */ +static int ovl_check_overlapping_layers(struct super_block *sb, + struct ovl_fs *ofs) +{ + int i, err; + + if (ofs->upper_mnt) { + err = ovl_check_layer(sb, ofs->upper_mnt->mnt_root, "upperdir"); + if (err) + return err; + + /* + * Checking workbasedir avoids hitting ovl_is_inuse(parent) of + * this instance and covers overlapping work and index dirs, + * unless work or index dir have been moved since created inside + * workbasedir. In that case, we already have their traps in + * inode cache and we will catch that case on lookup. + */ + err = ovl_check_layer(sb, ofs->workbasedir, "workdir"); + if (err) + return err; + } + + for (i = 0; i < ofs->numlower; i++) { + err = ovl_check_layer(sb, ofs->lower_layers[i].mnt->mnt_root, + "lowerdir"); + if (err) + return err; + } + + return 0; +} + static int ovl_fill_super(struct super_block *sb, void *data, int silent) { struct path upperpath = { }; @@ -1429,17 +1558,20 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (ofs->config.xino != OVL_XINO_OFF) ofs->xino_bits = BITS_PER_LONG - 32;
+ /* alloc/destroy_inode needed for setting up traps in inode cache */ + sb->s_op = &ovl_super_operations; + if (ofs->config.upperdir) { if (!ofs->config.workdir) { pr_err("overlayfs: missing 'workdir'\n"); goto out_err; }
- err = ovl_get_upper(ofs, &upperpath); + err = ovl_get_upper(sb, ofs, &upperpath); if (err) goto out_err;
- err = ovl_get_workdir(ofs, &upperpath); + err = ovl_get_workdir(sb, ofs, &upperpath); if (err) goto out_err;
@@ -1460,7 +1592,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) sb->s_flags |= SB_RDONLY;
if (!(ovl_force_readonly(ofs)) && ofs->config.index) { - err = ovl_get_indexdir(ofs, oe, &upperpath); + err = ovl_get_indexdir(sb, ofs, oe, &upperpath); if (err) goto out_free_oe;
@@ -1473,6 +1605,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
}
+ err = ovl_check_overlapping_layers(sb, ofs); + if (err) + goto out_free_oe; + /* Show index=off in /proc/mounts for forced r/o mount */ if (!ofs->indexdir) { ofs->config.index = false; @@ -1494,7 +1630,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
sb->s_magic = OVERLAYFS_SUPER_MAGIC; - sb->s_op = &ovl_super_operations; sb->s_xattr = ovl_xattr_handlers; sb->s_fs_info = ofs; sb->s_flags |= SB_POSIXACL; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index c9a2e3c6d537..db8bdb29b320 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -653,6 +653,18 @@ void ovl_inuse_unlock(struct dentry *dentry) } }
+bool ovl_is_inuse(struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + bool inuse; + + spin_lock(&inode->i_lock); + inuse = (inode->i_state & I_OVL_INUSE); + spin_unlock(&inode->i_lock); + + return inuse; +} + /* * Does this overlay dentry need to be indexed on copy up? */
[ Upstream commit 9179c21dc6ed1c993caa5fe4da876a6765c26af7 ]
NFS mounts can be disconnected from fs root. Don't fail the overlapping layer check because of this.
The check is not authoritative anyway, since topology can change during or after the check.
Reported-by: Antti Antinoja antti@fennosys.fi Signed-off-by: Miklos Szeredi mszeredi@redhat.com Fixes: 146d62e5a586 ("ovl: detect overlapping layers") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/super.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 4e268f981b4d..d6e60a7156a1 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1444,23 +1444,20 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb, * Check if this layer root is a descendant of: * - another layer of this overlayfs instance * - upper/work dir of any overlayfs instance - * - a disconnected dentry (detached root) */ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry, const char *name) { - struct dentry *next, *parent; - bool is_root = false; + struct dentry *next = dentry, *parent; int err = 0;
- if (!dentry || dentry == dentry->d_sb->s_root) + if (!dentry) return 0;
- next = dget(dentry); - /* Walk back ancestors to fs root (inclusive) looking for traps */ - do { - parent = dget_parent(next); - is_root = (parent == next); + parent = dget_parent(next); + + /* Walk back ancestors to root (inclusive) looking for traps */ + while (!err && parent != next) { if (ovl_is_inuse(parent)) { err = -EBUSY; pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n", @@ -1469,17 +1466,12 @@ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry, err = -ELOOP; pr_err("overlayfs: overlapping %s path\n", name); } - dput(next); next = parent; - } while (!err && !is_root); - - /* Did we really walk to fs root or found a detached root? */ - if (!err && next != dentry->d_sb->s_root) { - err = -ESTALE; - pr_err("overlayfs: disconnected %s path\n", name); + parent = dget_parent(next); + dput(next); }
- dput(next); + dput(parent);
return err; }
[ Upstream commit 1dac6f5b0ed2601be21bb4e27a44b0c3e667b7f4 ]
gcc gets a bit confused by the logic in ovl_setup_trap() and can't figure out whether the local 'trap' variable in the caller was initialized or not:
fs/overlayfs/super.c: In function 'ovl_fill_super': fs/overlayfs/super.c:1333:4: error: 'trap' may be used uninitialized in this function [-Werror=maybe-uninitialized] iput(trap); ^~~~~~~~~~ fs/overlayfs/super.c:1312:17: note: 'trap' was declared here
Reword slightly to make it easier for the compiler to understand.
Fixes: 146d62e5a586 ("ovl: detect overlapping layers") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index d6e60a7156a1..2d028c02621f 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -996,8 +996,8 @@ static int ovl_setup_trap(struct super_block *sb, struct dentry *dir, int err;
trap = ovl_get_trap_inode(sb, dir); - err = PTR_ERR(trap); - if (IS_ERR(trap)) { + err = PTR_ERR_OR_ZERO(trap); + if (err) { if (err == -ELOOP) pr_err("overlayfs: conflicting %s path\n", name); return err;
[ Upstream commit 146448524bddbf6dfc62de31957e428de001cbda ]
[heiko.carstens@de.ibm.com]: ----- Laura Abbott reported that the kernel doesn't build anymore with gcc 9, due to the "X" constraint. Ilya provided the gcc 9 patch "S/390: Introduce jdd constraint" which introduces the new "jdd" constraint which fixes this. -----
The support for section anchors on S/390 introduced in gcc9 has changed the behavior of "X" constraint, which can now produce register references. Since existing constraints, in particular, "i", do not fit the intended use case on S/390, the new machine-specific "jdd" constraint was introduced. This patch makes jump labels use "jdd" constraint when building with gcc9.
Reported-by: Laura Abbott labbott@redhat.com Signed-off-by: Ilya Leoshkevich iii@linux.ibm.com Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/jump_label.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h index 40f651292aa7..9c7dc970e966 100644 --- a/arch/s390/include/asm/jump_label.h +++ b/arch/s390/include/asm/jump_label.h @@ -10,6 +10,12 @@ #define JUMP_LABEL_NOP_SIZE 6 #define JUMP_LABEL_NOP_OFFSET 2
+#if __GNUC__ < 9 +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "X" +#else +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "jdd" +#endif + /* * We use a brcl 0,2 instruction for jump labels at compile time so it * can be easily distinguished from a hotpatch generated instruction. @@ -19,9 +25,9 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran asm_volatile_goto("0: brcl 0,"__stringify(JUMP_LABEL_NOP_OFFSET)"\n" ".pushsection __jump_table, "aw"\n" ".balign 8\n" - ".quad 0b, %l[label], %0\n" + ".quad 0b, %l[label], %0+%1\n" ".popsection\n" - : : "X" (&((char *)key)[branch]) : : label); + : : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label);
return false; label: @@ -33,9 +39,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool asm_volatile_goto("0: brcl 15, %l[label]\n" ".pushsection __jump_table, "aw"\n" ".balign 8\n" - ".quad 0b, %l[label], %0\n" + ".quad 0b, %l[label], %0+%1\n" ".popsection\n" - : : "X" (&((char *)key)[branch]) : : label); + : : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label);
return false; label:
[ Upstream commit 159491f3b509bd8101199944dc7b0673b881c734 ]
The inline assembler functions ap_aqic() and ap_qact() used two variables declared on the very same register. One variable was for input only, the other for output. Looks like newer versions of the gcc don't like this. Anyway it is a better coding to use one variable (which may have a union data type) on one register for input and output. So this patch introduces unions and uses only one variable now for input and output for GR1 for the PQAP(QACT) and PQAP(QIC) invocation.
Signed-off-by: Harald Freudenberger freude@linux.ibm.com Acked-by: Ilya Leoshkevich iii@linux.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/ap.h | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h index 8c00fd509c45..1a6a7092d942 100644 --- a/arch/s390/include/asm/ap.h +++ b/arch/s390/include/asm/ap.h @@ -221,16 +221,22 @@ static inline struct ap_queue_status ap_aqic(ap_qid_t qid, void *ind) { register unsigned long reg0 asm ("0") = qid | (3UL << 24); - register struct ap_qirq_ctrl reg1_in asm ("1") = qirqctrl; - register struct ap_queue_status reg1_out asm ("1"); + register union { + unsigned long value; + struct ap_qirq_ctrl qirqctrl; + struct ap_queue_status status; + } reg1 asm ("1"); register void *reg2 asm ("2") = ind;
+ reg1.qirqctrl = qirqctrl; + asm volatile( ".long 0xb2af0000" /* PQAP(AQIC) */ - : "=d" (reg1_out) - : "d" (reg0), "d" (reg1_in), "d" (reg2) + : "+d" (reg1) + : "d" (reg0), "d" (reg2) : "cc"); - return reg1_out; + + return reg1.status; }
/* @@ -264,17 +270,21 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit, { register unsigned long reg0 asm ("0") = qid | (5UL << 24) | ((ifbit & 0x01) << 22); - register unsigned long reg1_in asm ("1") = apinfo->val; - register struct ap_queue_status reg1_out asm ("1"); + register union { + unsigned long value; + struct ap_queue_status status; + } reg1 asm ("1"); register unsigned long reg2 asm ("2");
+ reg1.value = apinfo->val; + asm volatile( ".long 0xb2af0000" /* PQAP(QACT) */ - : "+d" (reg1_in), "=d" (reg1_out), "=d" (reg2) + : "+d" (reg1), "=d" (reg2) : "d" (reg0) : "cc"); apinfo->val = reg2; - return reg1_out; + return reg1.status; }
/**
From: Raul E Rangel rrangel@chromium.org
commit 0f7b79a44e7d7dd3ef1f59758c1a341f217ff5e5 upstream.
The O2Micro controller only supports tuning at 4-bits. So the host driver needs to change the bus width while tuning and then set it back when done.
There was a bug in the original implementation in that mmc->ios.bus_width also wasn't updated. Thus setting the incorrect blocksize in sdhci_send_tuning which results in a tuning failure.
Signed-off-by: Raul E Rangel rrangel@chromium.org Fixes: 0086fc217d5d7 ("mmc: sdhci: Add support for O2 hardware tuning") Acked-by: Adrian Hunter adrian.hunter@intel.com Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/host/sdhci-pci-o2micro.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c @@ -117,6 +117,7 @@ static int sdhci_o2_execute_tuning(struc */ if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) { current_bus_width = mmc->ios.bus_width; + mmc->ios.bus_width = MMC_BUS_WIDTH_4; sdhci_set_bus_width(host, MMC_BUS_WIDTH_4); }
@@ -128,8 +129,10 @@ static int sdhci_o2_execute_tuning(struc
sdhci_end_tuning(host);
- if (current_bus_width == MMC_BUS_WIDTH_8) + if (current_bus_width == MMC_BUS_WIDTH_8) { + mmc->ios.bus_width = MMC_BUS_WIDTH_8; sdhci_set_bus_width(host, current_bus_width); + }
host->flags &= ~SDHCI_HS400_TUNING; return 0;
From: Douglas Anderson dianders@chromium.org
commit 0a55f4ab9678413a01e740c86e9367ba0c612b36 upstream.
Normally when the MMC core sees an "-EILSEQ" error returned by a host controller then it will trigger a retuning of the card. This is generally a good idea.
However, if a command is expected to sometimes cause transfer errors then these transfer errors shouldn't cause a re-tuning. This re-tuning will be a needless waste of time. One example case where a transfer is expected to cause errors is when transitioning between idle (sometimes referred to as "sleep" in Broadcom code) and active state on certain Broadcom WiFi SDIO cards. Specifically if the card was already transitioning between states when the command was sent it could cause an error on the SDIO bus.
Let's add an API that the SDIO function drivers can call that will temporarily disable the auto-tuning functionality. Then we can add a call to this in the Broadcom WiFi driver and any other driver that might have similar needs.
NOTE: this makes the assumption that the card is already tuned well enough that it's OK to disable the auto-retuning during one of these error-prone situations. Presumably the driver code performing the error-prone transfer knows how to recover / retry from errors. ...and after we can get back to a state where transfers are no longer error-prone then we can enable the auto-retuning again. If we truly find ourselves in a case where the card needs to be retuned sometimes to handle one of these error-prone transfers then we can always try a few transfers first without auto-retuning and then re-try with auto-retuning if the first few fail.
Without this change on rk3288-veyron-minnie I periodically see this in the logs of a machine just sitting there idle: dwmmc_rockchip ff0d0000.dwmmc: Successfully tuned phase to XYZ
Cc: stable@vger.kernel.org #v4.18+ Signed-off-by: Douglas Anderson dianders@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Acked-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/core/core.c | 5 +++-- drivers/mmc/core/sdio_io.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/mmc/host.h | 1 + include/linux/mmc/sdio_func.h | 3 +++ 4 files changed, 44 insertions(+), 2 deletions(-)
--- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -144,8 +144,9 @@ void mmc_request_done(struct mmc_host *h int err = cmd->error;
/* Flag re-tuning needed on CRC errors */ - if ((cmd->opcode != MMC_SEND_TUNING_BLOCK && - cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200) && + if (cmd->opcode != MMC_SEND_TUNING_BLOCK && + cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 && + !host->retune_crc_disable && (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) || (mrq->data && mrq->data->error == -EILSEQ) || (mrq->stop && mrq->stop->error == -EILSEQ))) --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -725,3 +725,40 @@ int sdio_set_host_pm_flags(struct sdio_f return 0; } EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags); + +/** + * sdio_retune_crc_disable - temporarily disable retuning on CRC errors + * @func: SDIO function attached to host + * + * If the SDIO card is known to be in a state where it might produce + * CRC errors on the bus in response to commands (like if we know it is + * transitioning between power states), an SDIO function driver can + * call this function to temporarily disable the SD/MMC core behavior of + * triggering an automatic retuning. + * + * This function should be called while the host is claimed and the host + * should remain claimed until sdio_retune_crc_enable() is called. + * Specifically, the expected sequence of calls is: + * - sdio_claim_host() + * - sdio_retune_crc_disable() + * - some number of calls like sdio_writeb() and sdio_readb() + * - sdio_retune_crc_enable() + * - sdio_release_host() + */ +void sdio_retune_crc_disable(struct sdio_func *func) +{ + func->card->host->retune_crc_disable = true; +} +EXPORT_SYMBOL_GPL(sdio_retune_crc_disable); + +/** + * sdio_retune_crc_enable - re-enable retuning on CRC errors + * @func: SDIO function attached to host + * + * This is the compement to sdio_retune_crc_disable(). + */ +void sdio_retune_crc_enable(struct sdio_func *func) +{ + func->card->host->retune_crc_disable = false; +} +EXPORT_SYMBOL_GPL(sdio_retune_crc_enable); --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -395,6 +395,7 @@ struct mmc_host { unsigned int retune_now:1; /* do re-tuning at next req */ unsigned int retune_paused:1; /* re-tuning is temporarily disabled */ unsigned int use_blk_mq:1; /* use blk-mq */ + unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */
int rescan_disable; /* disable card detection */ int rescan_entered; /* used with nonremovable devices */ --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -159,4 +159,7 @@ extern void sdio_f0_writeb(struct sdio_f extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func); extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
+extern void sdio_retune_crc_disable(struct sdio_func *func); +extern void sdio_retune_crc_enable(struct sdio_func *func); + #endif /* LINUX_MMC_SDIO_FUNC_H */
From: Douglas Anderson dianders@chromium.org
commit b4c9f938d542d5f88c501744d2d12fad4fd2915f upstream.
We want SDIO drivers to be able to temporarily stop retuning when the driver knows that the SDIO card is not in a state where retuning will work (maybe because the card is asleep). We'll move the relevant functions to a place where drivers can call them.
Cc: stable@vger.kernel.org #v4.18+ Signed-off-by: Douglas Anderson dianders@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Acked-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/core/sdio_io.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/sdio_func.h | 3 +++ 2 files changed, 43 insertions(+)
--- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -18,6 +18,7 @@ #include "sdio_ops.h" #include "core.h" #include "card.h" +#include "host.h"
/** * sdio_claim_host - exclusively claim a bus for a certain SDIO function @@ -762,3 +763,42 @@ void sdio_retune_crc_enable(struct sdio_ func->card->host->retune_crc_disable = false; } EXPORT_SYMBOL_GPL(sdio_retune_crc_enable); + +/** + * sdio_retune_hold_now - start deferring retuning requests till release + * @func: SDIO function attached to host + * + * This function can be called if it's currently a bad time to do + * a retune of the SDIO card. Retune requests made during this time + * will be held and we'll actually do the retune sometime after the + * release. + * + * This function could be useful if an SDIO card is in a power state + * where it can respond to a small subset of commands that doesn't + * include the retuning command. Care should be taken when using + * this function since (presumably) the retuning request we might be + * deferring was made for a good reason. + * + * This function should be called while the host is claimed. + */ +void sdio_retune_hold_now(struct sdio_func *func) +{ + mmc_retune_hold_now(func->card->host); +} +EXPORT_SYMBOL_GPL(sdio_retune_hold_now); + +/** + * sdio_retune_release - signal that it's OK to retune now + * @func: SDIO function attached to host + * + * This is the complement to sdio_retune_hold_now(). Calling this + * function won't make a retune happen right away but will allow + * them to be scheduled normally. + * + * This function should be called while the host is claimed. + */ +void sdio_retune_release(struct sdio_func *func) +{ + mmc_retune_release(func->card->host); +} +EXPORT_SYMBOL_GPL(sdio_retune_release); --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -162,4 +162,7 @@ extern int sdio_set_host_pm_flags(struct extern void sdio_retune_crc_disable(struct sdio_func *func); extern void sdio_retune_crc_enable(struct sdio_func *func);
+extern void sdio_retune_hold_now(struct sdio_func *func); +extern void sdio_retune_release(struct sdio_func *func); + #endif /* LINUX_MMC_SDIO_FUNC_H */
From: Ulf Hansson ulf.hansson@linaro.org
commit 83293386bc95cf5e9f0c0175794455835bd1cb4a upstream.
Processing of SDIO IRQs must obviously be prevented while the card is system suspended, otherwise we may end up trying to communicate with an uninitialized SDIO card.
Reports throughout the years shows that this is not only a theoretical problem, but a real issue. So, let's finally fix this problem, by keeping track of the state for the card and bail out before processing the SDIO IRQ, in case the card is suspended.
Cc: stable@vger.kernel.org Reported-by: Douglas Anderson dianders@chromium.org Tested-by: Douglas Anderson dianders@chromium.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/core/sdio.c | 13 ++++++++++++- drivers/mmc/core/sdio_irq.c | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-)
--- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -934,6 +934,10 @@ static int mmc_sdio_pre_suspend(struct m */ static int mmc_sdio_suspend(struct mmc_host *host) { + /* Prevent processing of SDIO IRQs in suspended state. */ + mmc_card_set_suspended(host->card); + cancel_delayed_work_sync(&host->sdio_irq_work); + mmc_claim_host(host);
if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) @@ -982,13 +986,20 @@ static int mmc_sdio_resume(struct mmc_ho err = sdio_enable_4bit_bus(host->card); }
- if (!err && host->sdio_irqs) { + if (err) + goto out; + + /* Allow SDIO IRQs to be processed again. */ + mmc_card_clr_suspended(host->card); + + if (host->sdio_irqs) { if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) wake_up_process(host->sdio_irq_thread); else if (host->caps & MMC_CAP_SDIO_IRQ) host->ops->enable_sdio_irq(host, 1); }
+out: mmc_release_host(host);
host->pm_flags &= ~MMC_PM_KEEP_POWER; --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -38,6 +38,10 @@ static int process_sdio_pending_irqs(str unsigned char pending; struct sdio_func *func;
+ /* Don't process SDIO IRQs if the card is suspended. */ + if (mmc_card_suspended(card)) + return 0; + /* * Optimization, if there is only 1 function interrupt registered * and we know an IRQ was signaled then call irq handler directly.
From: Stanley Chu stanley.chu@mediatek.com
commit 24e2e7a19f7e4b83d0d5189040d997bce3596473 upstream.
UFS runtime suspend can be triggered after pm_runtime_enable() is invoked in ufshcd_pltfrm_init(). However if the first runtime suspend is triggered before binding ufs_hba structure to ufs device structure via platform_set_drvdata(), then UFS runtime suspend will be no longer triggered in the future because its dev->power.runtime_error was set in the first triggering and does not have any chance to be cleared.
To be more clear, dev->power.runtime_error is set if hba is NULL in ufshcd_runtime_suspend() which returns -EINVAL to rpm_callback() where dev->power.runtime_error is set as -EINVAL. In this case, any future rpm_suspend() for UFS device fails because rpm_check_suspend_allowed() fails due to non-zero dev->power.runtime_error.
To resolve this issue, make sure the first UFS runtime suspend get valid "hba" in ufshcd_runtime_suspend(): Enable UFS runtime PM only after hba is successfully bound to UFS device structure.
Fixes: 62694735ca95 ([SCSI] ufs: Add runtime PM support for UFS host controller driver) Cc: stable@vger.kernel.org Signed-off-by: Stanley Chu stanley.chu@mediatek.com Reviewed-by: Avri Altman avri.altman@wdc.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/scsi/ufs/ufshcd-pltfrm.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -340,24 +340,21 @@ int ufshcd_pltfrm_init(struct platform_d goto dealloc_host; }
- pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - ufshcd_init_lanes_per_dir(hba);
err = ufshcd_init(hba, mmio_base, irq); if (err) { dev_err(dev, "Initialization failed\n"); - goto out_disable_rpm; + goto dealloc_host; }
platform_set_drvdata(pdev, hba);
+ pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0;
-out_disable_rpm: - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); dealloc_host: ufshcd_dealloc_host(hba); out:
From: Peter Chen peter.chen@nxp.com
commit c19dffc0a9511a7d7493ec21019aefd97e9a111b upstream.
An endpoint conflict occurs when the USB is working in device mode during an isochronous communication. When the endpointA IN direction is an isochronous IN endpoint, and the host sends an IN token to endpointA on another device, then the OUT transaction may be missed regardless the OUT endpoint number. Generally, this occurs when the device is connected to the host through a hub and other devices are connected to the same hub.
The affected OUT endpoint can be either control, bulk, isochronous, or an interrupt endpoint. After the OUT endpoint is primed, if an IN token to the same endpoint number on another device is received, then the OUT endpoint may be unprimed (cannot be detected by software), which causes this endpoint to no longer respond to the host OUT token, and thus, no corresponding interrupt occurs.
There is no good workaround for this issue, the only thing the software could do is numbering isochronous IN from the highest endpoint since we have observed most of device number endpoint from the lowest.
Cc: stable@vger.kernel.org #v3.14+ Cc: Fabio Estevam festevam@gmail.com Cc: Greg KH gregkh@linuxfoundation.org Cc: Sergei Shtylyov sergei.shtylyov@cogentembedded.com Cc: Jun Li jun.li@nxp.com Signed-off-by: Peter Chen peter.chen@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/chipidea/udc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
--- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1621,6 +1621,25 @@ static int ci_udc_pullup(struct usb_gadg static int ci_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); static int ci_udc_stop(struct usb_gadget *gadget); + +/* Match ISOC IN from the highest endpoint */ +static struct usb_ep *ci_udc_match_ep(struct usb_gadget *gadget, + struct usb_endpoint_descriptor *desc, + struct usb_ss_ep_comp_descriptor *comp_desc) +{ + struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); + struct usb_ep *ep; + + if (usb_endpoint_xfer_isoc(desc) && usb_endpoint_dir_in(desc)) { + list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) { + if (ep->caps.dir_in && !ep->claimed) + return ep; + } + } + + return NULL; +} + /** * Device operations part of the API to the USB controller hardware, * which don't involve endpoints (or i/o) @@ -1634,6 +1653,7 @@ static const struct usb_gadget_ops usb_g .vbus_draw = ci_udc_vbus_draw, .udc_start = ci_udc_start, .udc_stop = ci_udc_stop, + .match_ep = ci_udc_match_ep, };
static int init_eps(struct ci_hdrc *ci)
From: Mathias Nyman mathias.nyman@linux.intel.com
commit ddd57980a0fde30f7b5d14b888a2cc84d01610e8 upstream.
USB 3.2 capability in a host can be detected from the xHCI Supported Protocol Capability major and minor revision fields.
If major is 0x3 and minor 0x20 then the host is USB 3.2 capable.
For USB 3.2 capable hosts set the root hub lane count to 2.
The Major Revision and Minor Revision fields contain a BCD version number. The value of the Major Revision field is JJh and the value of the Minor Revision field is MNh for version JJ.M.N, where JJ = major revision number, M - minor version number, N = sub-minor version number, e.g. version 3.1 is represented with a value of 0310h.
Also fix the extra whitespace printed out when announcing regular SuperSpeed hosts.
Cc: stable@vger.kernel.org # v4.18+ Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
--- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5030,16 +5030,26 @@ int xhci_gen_setup(struct usb_hcd *hcd, } else { /* * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol - * minor revision instead of sbrn + * minor revision instead of sbrn. Minor revision is a two digit + * BCD containing minor and sub-minor numbers, only show minor. */ - minor_rev = xhci->usb3_rhub.min_rev; - if (minor_rev) { + minor_rev = xhci->usb3_rhub.min_rev / 0x10; + + switch (minor_rev) { + case 2: + hcd->speed = HCD_USB32; + hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; + hcd->self.root_hub->rx_lanes = 2; + hcd->self.root_hub->tx_lanes = 2; + break; + case 1: hcd->speed = HCD_USB31; hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; + break; } - xhci_info(xhci, "Host supports USB 3.%x %s SuperSpeed\n", + xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n", minor_rev, - minor_rev ? "Enhanced" : ""); + minor_rev ? "Enhanced " : "");
xhci->usb3_rhub.hcd = hcd; /* xHCI private pointer was set in xhci_pci_probe for the second
From: Mathias Nyman mathias.nyman@linux.intel.com
commit b8c3b718087bf7c3c8e388eb1f72ac1108a4926e upstream.
A USB3 device needs to be reset and re-enumarated if the port it connects to goes to a error state, with link state inactive.
There is no use in trying to recover failed transactions by resetting endpoints at this stage. Tests show that in rare cases, after multiple endpoint resets of a roothub port the whole host controller might stop completely.
Several retries to recover from transaction error can happen as it can take a long time before the hub thread discovers the USB3 port error and inactive link.
We can't reliably detect the port error from slot or endpoint context due to a limitation in xhci, see xhci specs section 4.8.3: "There are several cases where the EP State field in the Output Endpoint Context may not reflect the current state of an endpoint" and "Software should maintain an accurate value for EP State, by tracking it with an internal variable that is driven by Events and Doorbell accesses"
Same appears to be true for slot state.
set a flag to the corresponding slot if a USB3 roothub port link goes inactive to prevent both queueing new URBs and resetting endpoints.
Reported-by: Rapolu Chiranjeevi chiranjeevi.rapolu@intel.com Tested-by: Rapolu Chiranjeevi chiranjeevi.rapolu@intel.com Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci-ring.c | 15 ++++++++++++++- drivers/usb/host/xhci.c | 5 +++++ drivers/usb/host/xhci.h | 9 +++++++++ 3 files changed, 28 insertions(+), 1 deletion(-)
--- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1604,8 +1604,13 @@ static void handle_port_status(struct xh usb_hcd_resume_root_hub(hcd); }
- if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) + if (hcd->speed >= HCD_USB3 && + (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) { + slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1); + if (slot_id && xhci->devs[slot_id]) + xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR; bus_state->port_remote_wakeup &= ~(1 << hcd_portnum); + }
if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { xhci_dbg(xhci, "port resume event for port %d\n", port_id); @@ -1793,6 +1798,14 @@ static void xhci_cleanup_halted_endpoint { struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; struct xhci_command *command; + + /* + * Avoid resetting endpoint if link is inactive. Can cause host hang. + * Device will be reset soon to recover the link so don't do anything + */ + if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) + return; + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); if (!command) return; --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1441,6 +1441,10 @@ static int xhci_urb_enqueue(struct usb_h xhci_dbg(xhci, "urb submitted during PCI suspend\n"); return -ESHUTDOWN; } + if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) { + xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n"); + return -ENODEV; + }
if (usb_endpoint_xfer_isoc(&urb->ep->desc)) num_tds = urb->number_of_packets; @@ -3724,6 +3728,7 @@ static int xhci_discover_or_reset_device } /* If necessary, update the number of active TTs on this root port */ xhci_update_tt_active_eps(xhci, virt_dev, old_active_eps); + virt_dev->flags = 0; ret = 0;
command_cleanup: --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1010,6 +1010,15 @@ struct xhci_virt_device { u8 real_port; struct xhci_interval_bw_table *bw_table; struct xhci_tt_bw_info *tt_info; + /* + * flags for state tracking based on events and issued commands. + * Software can not rely on states from output contexts because of + * latency between events and xHC updating output context values. + * See xhci 1.1 section 4.8.3 for more details + */ + unsigned long flags; +#define VDEV_PORT_ERROR BIT(0) /* Port error, link inactive */ + /* The current max exit latency for the enabled USB3 link states. */ u16 current_mel; /* Used for the debugfs interfaces. */
From: Kaike Wan kaike.wan@intel.com
commit 5f90677ed31963abb184ee08ebee4a4a68225dd8 upstream.
The opcode range for fault injection from user should be validated before it is applied to the fault->opcodes[] bitmap to avoid out-of-bound error.
Cc: stable@vger.kernel.org Fixes: a74d5307caba ("IB/hfi1: Rework fault injection machinery") Reported-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Kaike Wan kaike.wan@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/hw/hfi1/fault.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/infiniband/hw/hfi1/fault.c +++ b/drivers/infiniband/hw/hfi1/fault.c @@ -153,6 +153,7 @@ static ssize_t fault_opcodes_write(struc char *dash; unsigned long range_start, range_end, i; bool remove = false; + unsigned long bound = 1U << BITS_PER_BYTE;
end = strchr(ptr, ','); if (end) @@ -178,6 +179,10 @@ static ssize_t fault_opcodes_write(struc BITS_PER_BYTE); break; } + /* Check the inputs */ + if (range_start >= bound || range_end >= bound) + break; + for (i = range_start; i <= range_end; i++) { if (remove) clear_bit(i, fault->opcodes);
From: Mike Marciniszyn mike.marciniszyn@intel.com
commit 3230f4a8d44e4a0bb7afea814b280b5129521f52 upstream.
The following warning can happen when a memory shortage occurs during txreq allocation:
[10220.939246] SLUB: Unable to allocate memory on node -1, gfp=0xa20(GFP_ATOMIC) [10220.939246] Hardware name: Intel Corporation S2600WT2R/S2600WT2R, BIOS SE5C610.86B.01.01.0018.C4.072020161249 07/20/2016 [10220.939247] cache: mnt_cache, object size: 384, buffer size: 384, default order: 2, min order: 0 [10220.939260] Workqueue: hfi0_0 _hfi1_do_send [hfi1] [10220.939261] node 0: slabs: 1026568, objs: 43115856, free: 0 [10220.939262] Call Trace: [10220.939262] node 1: slabs: 820872, objs: 34476624, free: 0 [10220.939263] dump_stack+0x5a/0x73 [10220.939265] warn_alloc+0x103/0x190 [10220.939267] ? wake_all_kswapds+0x54/0x8b [10220.939268] __alloc_pages_slowpath+0x86c/0xa2e [10220.939270] ? __alloc_pages_nodemask+0x2fe/0x320 [10220.939271] __alloc_pages_nodemask+0x2fe/0x320 [10220.939273] new_slab+0x475/0x550 [10220.939275] ___slab_alloc+0x36c/0x520 [10220.939287] ? hfi1_make_rc_req+0x90/0x18b0 [hfi1] [10220.939299] ? __get_txreq+0x54/0x160 [hfi1] [10220.939310] ? hfi1_make_rc_req+0x90/0x18b0 [hfi1] [10220.939312] __slab_alloc+0x40/0x61 [10220.939323] ? hfi1_make_rc_req+0x90/0x18b0 [hfi1] [10220.939325] kmem_cache_alloc+0x181/0x1b0 [10220.939336] hfi1_make_rc_req+0x90/0x18b0 [hfi1] [10220.939348] ? hfi1_verbs_send_dma+0x386/0xa10 [hfi1] [10220.939359] ? find_prev_entry+0xb0/0xb0 [hfi1] [10220.939371] hfi1_do_send+0x1d9/0x3f0 [hfi1] [10220.939372] process_one_work+0x171/0x380 [10220.939374] worker_thread+0x49/0x3f0 [10220.939375] kthread+0xf8/0x130 [10220.939377] ? max_active_store+0x80/0x80 [10220.939378] ? kthread_bind+0x10/0x10 [10220.939379] ret_from_fork+0x35/0x40 [10220.939381] SLUB: Unable to allocate memory on node -1, gfp=0xa20(GFP_ATOMIC)
The shortage is handled properly so the message isn't needed. Silence by adding the no warn option to the slab allocation.
Fixes: 45842abbb292 ("staging/rdma/hfi1: move txreq header code") Cc: stable@vger.kernel.org Reviewed-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/hw/hfi1/verbs_txreq.c | 2 +- drivers/infiniband/hw/hfi1/verbs_txreq.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.c +++ b/drivers/infiniband/hw/hfi1/verbs_txreq.c @@ -100,7 +100,7 @@ struct verbs_txreq *__get_txreq(struct h if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) { struct hfi1_qp_priv *priv;
- tx = kmem_cache_alloc(dev->verbs_txreq_cache, GFP_ATOMIC); + tx = kmem_cache_alloc(dev->verbs_txreq_cache, VERBS_TXREQ_GFP); if (tx) goto out; priv = qp->priv; --- a/drivers/infiniband/hw/hfi1/verbs_txreq.h +++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h @@ -72,6 +72,7 @@ struct hfi1_ibdev; struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev, struct rvt_qp *qp);
+#define VERBS_TXREQ_GFP (GFP_ATOMIC | __GFP_NOWARN) static inline struct verbs_txreq *get_txreq(struct hfi1_ibdev *dev, struct rvt_qp *qp) __must_hold(&qp->slock) @@ -79,7 +80,7 @@ static inline struct verbs_txreq *get_tx struct verbs_txreq *tx; struct hfi1_qp_priv *priv = qp->priv;
- tx = kmem_cache_alloc(dev->verbs_txreq_cache, GFP_ATOMIC); + tx = kmem_cache_alloc(dev->verbs_txreq_cache, VERBS_TXREQ_GFP); if (unlikely(!tx)) { /* call slow path to get the lock */ tx = __get_txreq(dev, qp);
From: Crt Mori cmo@melexis.com
commit 389fc70b60f534d679aea9a3f05146040ce20d77 upstream.
Register EE_VERSION contains mixture of calibration information and DSP version. So far, because calibrations were definite, the driver compatibility depended on whole contents, but in the newer production process the calibration part changes. Because of that, value in EE_VERSION will be changed and to avoid that calibration value is same as DSP version the MSB in calibration part was fixed to 1. That means existing calibrations (medical and consumer) will now have hex values (bits 8 to 15) of 83 and 84 respectively. Driver compatibility should be based only on DSP version part of the EE_VERSION (bits 0 to 7) register.
Signed-off-by: Crt Mori cmo@melexis.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/temperature/mlx90632.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -81,6 +81,8 @@ /* Magic constants */ #define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */ #define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */ +#define MLX90632_DSP_VERSION 5 /* DSP version */ +#define MLX90632_DSP_MASK GENMASK(7, 0) /* DSP version in EE_VERSION */ #define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */ #define MLX90632_REF_12 12LL /**< ResCtrlRef value of Ch 1 or Ch 2 */ #define MLX90632_REF_3 12LL /**< ResCtrlRef value of Channel 3 */ @@ -666,10 +668,13 @@ static int mlx90632_probe(struct i2c_cli } else if (read == MLX90632_ID_CONSUMER) { dev_dbg(&client->dev, "Detected Consumer EEPROM calibration %x\n", read); + } else if ((read & MLX90632_DSP_MASK) == MLX90632_DSP_VERSION) { + dev_dbg(&client->dev, + "Detected Unknown EEPROM calibration %x\n", read); } else { dev_err(&client->dev, - "EEPROM version mismatch %x (expected %x or %x)\n", - read, MLX90632_ID_CONSUMER, MLX90632_ID_MEDICAL); + "Wrong DSP version %x (expected %x)\n", + read, MLX90632_DSP_VERSION); return -EPROTONOSUPPORT; }
From: Alexander Mikhaylenko exalm7659@gmail.com
commit 9843f3e08e2144724be7148e08d77a195dea257a upstream.
They are capable of using intertouch and it works well with psmouse.synaptics_intertouch=1, so add them to the list.
Without it, scrolling and gestures are jumpy, three-finger pinch gesture doesn't work and three- or four-finger swipes sometimes get stuck.
Signed-off-by: Alexander Mikhaylenko exalm7659@gmail.com Reviewed-by: Benjamin Tissoires benjamin.tissoires@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/input/mouse/synaptics.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -179,6 +179,8 @@ static const char * const smbus_pnp_ids[ "LEN0096", /* X280 */ "LEN0097", /* X280 -> ALPS trackpoint */ "LEN200f", /* T450s */ + "LEN2054", /* E480 */ + "LEN2055", /* E580 */ "SYN3052", /* HP EliteBook 840 G4 */ "SYN3221", /* HP 15-ay000 */ NULL
From: Andrey Smirnov andrew.smirnov@gmail.com
commit 7c7da40da1640ce6814dab1e8031b44e19e5a3f6 upstream.
In the case of compat syscall ioctl numbers for UI_BEGIN_FF_UPLOAD and UI_END_FF_UPLOAD need to be adjusted before being passed on uinput_ioctl_handler() since code built with -m32 will be passing slightly different values. Extend the code already covering UI_SET_PHYS to cover UI_BEGIN_FF_UPLOAD and UI_END_FF_UPLOAD as well.
Reported-by: Pierre-Loup A. Griffais pgriffais@valvesoftware.com Signed-off-by: Andrey Smirnov andrew.smirnov@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/input/misc/uinput.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
--- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -1051,13 +1051,31 @@ static long uinput_ioctl(struct file *fi
#ifdef CONFIG_COMPAT
-#define UI_SET_PHYS_COMPAT _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t) +/* + * These IOCTLs change their size and thus their numbers between + * 32 and 64 bits. + */ +#define UI_SET_PHYS_COMPAT \ + _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t) +#define UI_BEGIN_FF_UPLOAD_COMPAT \ + _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload_compat) +#define UI_END_FF_UPLOAD_COMPAT \ + _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload_compat)
static long uinput_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - if (cmd == UI_SET_PHYS_COMPAT) + switch (cmd) { + case UI_SET_PHYS_COMPAT: cmd = UI_SET_PHYS; + break; + case UI_BEGIN_FF_UPLOAD_COMPAT: + cmd = UI_BEGIN_FF_UPLOAD; + break; + case UI_END_FF_UPLOAD_COMPAT: + cmd = UI_END_FF_UPLOAD; + break; + }
return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg)); }
From: Daniel Smith danct12@disroot.org
commit 0e658060e5fc50dc282885dc424a94b5d95547e5 upstream.
On Chuwi Hi10 Plus, the Silead device id is MSSL0017.
Signed-off-by: Daniel Smith danct12@disroot.org Reviewed-by: Hans de Goede hdegoede@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/input/touchscreen/silead.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -604,6 +604,7 @@ static const struct acpi_device_id silea { "MSSL1680", 0 }, { "MSSL0001", 0 }, { "MSSL0002", 0 }, + { "MSSL0017", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match);
From: John Johansen john.johansen@canonical.com
commit 23375b13f98c5464c2b4d15f983cc062940f1f4e upstream.
While commit 11c236b89d7c2 ("apparmor: add a default null dfa") ensure every profile has a policy.dfa it does not resize the policy.start[] to have entries for every possible start value. Which means PROFILE_MEDIATES is not safe to use on untrusted input. Unforunately commit b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE") did not take into account the start value usage.
The input string in profile_query_cb() is user controlled and is not properly checked to be within the limited start[] entries, even worse it can't be as userspace policy is allowed to make us of entries types the kernel does not know about. This mean usespace can currently cause the kernel to access memory up to 240 entries beyond the start array bounds.
Cc: stable@vger.kernel.org Fixes: b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE") Signed-off-by: John Johansen john.johansen@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- security/apparmor/include/policy.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -214,7 +214,16 @@ static inline struct aa_profile *aa_get_ return labels_profile(aa_get_newest_label(&p->label)); }
-#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(unsigned char) (T)]) +static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile, + unsigned char class) +{ + if (class <= AA_CLASS_LAST) + return profile->policy.start[class]; + else + return aa_dfa_match_len(profile->policy.dfa, + profile->policy.start[0], &class, 1); +} + static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile, u16 AF) { unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
From: Jann Horn jannh@google.com
commit 8404d7a674c49278607d19726e0acc0cae299357 upstream.
A packed AppArmor policy contains null-terminated tag strings that are read by unpack_nameX(). However, unpack_nameX() uses string functions on them without ensuring that they are actually null-terminated, potentially leading to out-of-bounds accesses.
Make sure that the tag string is null-terminated before passing it to strcmp().
Cc: stable@vger.kernel.org Fixes: 736ec752d95e ("AppArmor: policy routines for loading and unpacking policy") Signed-off-by: Jann Horn jannh@google.com Signed-off-by: John Johansen john.johansen@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- security/apparmor/policy_unpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -276,7 +276,7 @@ static bool unpack_nameX(struct aa_ext * char *tag = NULL; size_t size = unpack_u16_chunk(e, &tag); /* if a name is specified it must match. otherwise skip tag */ - if (name && (!size || strcmp(name, tag))) + if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag))) goto fail; } else if (name) { /* if a name is specified and there is no name tag fail */
From: Douglas Anderson dianders@chromium.org
commit 2de0b42da263c97d330d276f5ccf7c4470e3324f upstream.
There are certain cases, notably when transitioning between sleep and active state, when Broadcom SDIO WiFi cards will produce errors on the SDIO bus. This is evident from the source code where you can see that we try commands in a loop until we either get success or we've tried too many times. The comment in the code reinforces this by saying "just one write attempt may fail"
Unfortunately these failures sometimes end up causing an "-EILSEQ" back to the core which triggers a retuning of the SDIO card and that blocks all traffic to the card until it's done.
Let's disable retuning around the commands we expect might fail.
Cc: stable@vger.kernel.org #v4.18+ Signed-off-by: Douglas Anderson dianders@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Arend van Spriel arend.vanspriel@broadcom.com Acked-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -667,6 +667,8 @@ brcmf_sdio_kso_control(struct brcmf_sdio
brcmf_dbg(TRACE, "Enter: on=%d\n", on);
+ sdio_retune_crc_disable(bus->sdiodev->func1); + wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); /* 1st KSO write goes to AOS wake up core if device is asleep */ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); @@ -719,6 +721,8 @@ brcmf_sdio_kso_control(struct brcmf_sdio if (try_cnt > MAX_KSO_ATTEMPTS) brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
+ sdio_retune_crc_enable(bus->sdiodev->func1); + return err; }
From: Douglas Anderson dianders@chromium.org
commit 65dade6044079a5c206fd1803642ff420061417a upstream.
When Broadcom SDIO cards are idled they go to sleep and a whole separate subsystem takes over their SDIO communication. This is the Always-On-Subsystem (AOS) and it can't handle tuning requests.
Specifically, as tested on rk3288-veyron-minnie (which reports having BCM4354/1 in dmesg), if I force a retune in brcmf_sdio_kso_control() when "on = 1" (aka we're transition from sleep to wake) by whacking: bus->sdiodev->func1->card->host->need_retune = 1 ...then I can often see tuning fail. In this case dw_mmc reports "All phases bad!"). Note that I don't get 100% failure, presumably because sometimes the card itself has already transitioned away from the AOS itself by the time we try to wake it up. If I force retuning when "on = 0" (AKA force retuning right before sending the command to go to sleep) then retuning is always OK.
NOTE: we need _both_ this patch and the patch to avoid triggering tuning due to CRC errors in the sleep/wake transition, AKA ("brcmfmac: sdio: Disable auto-tuning around commands expected to fail"). Though both patches handle issues with Broadcom's AOS, the problems are distinct: 1. We want to defer (but not ignore) asynchronous (like timer-requested) tuning requests till the card is awake. However, we want to ignore CRC errors during the transition, we don't want to queue deferred tuning request. 2. You could imagine that the AOS could implement retuning but we could still get errors while transitioning in and out of the AOS. Similarly you could imagine a seamless transition into and out of the AOS (with no CRC errors) even if the AOS couldn't handle tuning.
ALSO NOTE: presumably there is never a desperate need to retune in order to wake up the card, since doing so is impossible. Luckily the only way the card can get into sleep state is if we had a good enough tuning to send it the command to put it into sleep, so presumably that "good enough" tuning is enough to wake us up, at least with a few retries.
Cc: stable@vger.kernel.org #v4.18+ Signed-off-by: Douglas Anderson dianders@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Arend van Spriel arend.vanspriel@broadcom.com Acked-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -669,6 +669,10 @@ brcmf_sdio_kso_control(struct brcmf_sdio
sdio_retune_crc_disable(bus->sdiodev->func1);
+ /* Cannot re-tune if device is asleep; defer till we're awake */ + if (on) + sdio_retune_hold_now(bus->sdiodev->func1); + wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); /* 1st KSO write goes to AOS wake up core if device is asleep */ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); @@ -721,6 +725,9 @@ brcmf_sdio_kso_control(struct brcmf_sdio if (try_cnt > MAX_KSO_ATTEMPTS) brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
+ if (on) + sdio_retune_release(bus->sdiodev->func1); + sdio_retune_crc_enable(bus->sdiodev->func1);
return err;
[ Upstream commit 89c92142f75eb80064f5b9f1111484b1b4d81790 ]
| arch/arc/mm/tlb.c:914:2: warning: variable length array 'pd0' is used [-Wvla] | arch/arc/include/asm/cmpxchg.h:95:29: warning: value computed is not used [-Wunused-value]
Signed-off-by: Vineet Gupta vgupta@synopsys.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arc/include/asm/cmpxchg.h | 14 ++++++++++---- arch/arc/mm/tlb.c | 13 ++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index d819de1c5d10..3ea4112c8302 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -92,8 +92,11 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
#endif /* CONFIG_ARC_HAS_LLSC */
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ - (unsigned long)(o), (unsigned long)(n))) +#define cmpxchg(ptr, o, n) ({ \ + (typeof(*(ptr)))__cmpxchg((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n)); \ +})
/* * atomic_cmpxchg is same as cmpxchg @@ -198,8 +201,11 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, return __xchg_bad_pointer(); }
-#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \ - sizeof(*(ptr)))) +#define xchg(ptr, with) ({ \ + (typeof(*(ptr)))__xchg((unsigned long)(with), \ + (ptr), \ + sizeof(*(ptr))); \ +})
#endif /* CONFIG_ARC_PLAT_EZNPS */
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 4097764fea23..fa18c00b0cfd 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -911,9 +911,11 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, struct pt_regs *regs) { struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; - unsigned int pd0[mmu->ways]; unsigned long flags; - int set; + int set, n_ways = mmu->ways; + + n_ways = min(n_ways, 4); + BUG_ON(mmu->ways > 4);
local_irq_save(flags);
@@ -921,9 +923,10 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, for (set = 0; set < mmu->sets; set++) {
int is_valid, way; + unsigned int pd0[4];
/* read out all the ways of current set */ - for (way = 0, is_valid = 0; way < mmu->ways; way++) { + for (way = 0, is_valid = 0; way < n_ways; way++) { write_aux_reg(ARC_REG_TLBINDEX, SET_WAY_TO_IDX(mmu, set, way)); write_aux_reg(ARC_REG_TLBCOMMAND, TLBRead); @@ -937,14 +940,14 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, continue;
/* Scan the set for duplicate ways: needs a nested loop */ - for (way = 0; way < mmu->ways - 1; way++) { + for (way = 0; way < n_ways - 1; way++) {
int n;
if (!pd0[way]) continue;
- for (n = way + 1; n < mmu->ways; n++) { + for (n = way + 1; n < n_ways; n++) { if (pd0[way] != pd0[n]) continue;
[ Upstream commit 0788611c9a0925c607de536b2449de5ed98ef8df ]
In the unlikely event that axi_desc_get returns a null desc in the very first iteration of the while-loop the error exit path ends up calling axi_desc_put on a null pointer 'first' and this causes a null pointer dereference. Fix this by adding a null check on pointer 'first' before calling axi_desc_put.
Addresses-Coverity: ("Explicit null dereference") Fixes: 1fe20f1b8454 ("dmaengine: Introduce DW AXI DMAC driver") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index c4eb55e3011c..c05ef7f1d7b6 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -512,7 +512,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, return vchan_tx_prep(&chan->vc, &first->vd, flags);
err_desc_get: - axi_desc_put(first); + if (first) + axi_desc_put(first); return NULL; }
[ Upstream commit 89d03b3c126d683f7b2cd5b07178493993d12448 ]
The maximum value of block length is 0xffff, so if the configured transfer length is more than 0xffff, that will cause block length overflow to lead a configuration error.
Thus we can set block length as the maximum burst length to avoid this issue, since the maximum burst length will not be a big value which is more than 0xffff.
Signed-off-by: Eric Long eric.long@unisoc.com Signed-off-by: Baolin Wang baolin.wang@linaro.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/sprd-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 55df0d41355b..1ed1c7efa288 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -663,7 +663,7 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, temp |= slave_cfg->src_maxburst & SPRD_DMA_FRG_LEN_MASK; hw->frg_len = temp;
- hw->blk_len = len & SPRD_DMA_BLK_LEN_MASK; + hw->blk_len = slave_cfg->src_maxburst & SPRD_DMA_BLK_LEN_MASK; hw->trsc_len = len & SPRD_DMA_TRSC_LEN_MASK;
temp = (dst_step & SPRD_DMA_TRSF_STEP_MASK) << SPRD_DMA_DEST_TRSF_STEP_OFFSET;
[ Upstream commit ecc906a11c2a0940e1a380debd8bd5bc09faf454 ]
GMAC controller on HSDK boards supports 256 Hash Table size so we need to add the multicast filter bins property. This allows for the Hash filter to work properly using stmmac driver.
Cc: Joao Pinto jpinto@synopsys.com Cc: Rob Herring robh+dt@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Acked-by: Alexey Brodkin abrodkin@synopsys.com Signed-off-by: Jose Abreu joabreu@synopsys.com Signed-off-by: Vineet Gupta vgupta@synopsys.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arc/boot/dts/hsdk.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts index ef149f59929a..f67f614ccb0e 100644 --- a/arch/arc/boot/dts/hsdk.dts +++ b/arch/arc/boot/dts/hsdk.dts @@ -175,6 +175,7 @@ interrupt-names = "macirq"; phy-mode = "rgmii"; snps,pbl = <32>; + snps,multicast-filter-bins = <256>; clocks = <&gmacclk>; clock-names = "stmmaceth"; phy-handle = <&phy0>;
[ Upstream commit 4c70850aeb2e40016722cd1abd43c679666d3ca0 ]
Add the binding for RX/TX fifo size of GMAC node.
Cc: Joao Pinto jpinto@synopsys.com Cc: Rob Herring robh+dt@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Vineet Gupta vgupta@synopsys.com Tested-by: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Acked-by: Alexey Brodkin abrodkin@synopsys.com Signed-off-by: Jose Abreu joabreu@synopsys.com Signed-off-by: Vineet Gupta vgupta@synopsys.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arc/boot/dts/hsdk.dts | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts index f67f614ccb0e..d131c54acd3e 100644 --- a/arch/arc/boot/dts/hsdk.dts +++ b/arch/arc/boot/dts/hsdk.dts @@ -184,6 +184,9 @@ mac-address = [00 00 00 00 00 00]; /* Filled in by U-Boot */ dma-coherent;
+ tx-fifo-depth = <4096>; + rx-fifo-depth = <4096>; + mdio { #address-cells = <1>; #size-cells = <0>;
[ Upstream commit 13069847a475b60069918dc9971f5adb42811ce3 ]
dma_mapping_error() was being called on a different device struct than what was passed to map/unmap. Besides rendering the error checking ineffective, it caused a debug splat with CONFIG_DMA_API_DEBUG.
Signed-off-by: Scott Wood swood@redhat.com Acked-by: Wu Hao hao.wu@intel.com Acked-by: Moritz Fischer mdf@kernel.org Acked-by: Alan Tull atull@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fpga/dfl-afu-dma-region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c index 0e81d33af856..c9a613dc9eb7 100644 --- a/drivers/fpga/dfl-afu-dma-region.c +++ b/drivers/fpga/dfl-afu-dma-region.c @@ -399,7 +399,7 @@ int afu_dma_map_region(struct dfl_feature_platform_data *pdata, region->pages[0], 0, region->length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(&pdata->dev->dev, region->iova)) { + if (dma_mapping_error(dfl_fpga_pdata_to_parent(pdata), region->iova)) { dev_err(&pdata->dev->dev, "failed to map for dma\n"); ret = -EFAULT; goto unpin_pages;
[ Upstream commit dfe3de8d397bf878b31864d4e489d41118ec475f ]
struct dfl_feature_platform_data (and it's mutex) is used by both fme and port devices, and when lockdep is enabled it complains about nesting between these locks. Tell lockdep about the difference so it can track each class separately.
Here's the lockdep complaint: [ 409.680668] WARNING: possible recursive locking detected [ 409.685983] 5.1.0-rc3.fpga+ #1 Tainted: G E [ 409.691469] -------------------------------------------- [ 409.696779] fpgaconf/9348 is trying to acquire lock: [ 409.701746] 00000000a443fe2e (&pdata->lock){+.+.}, at: port_enable_set+0x24/0x60 [dfl_afu] [ 409.710006] [ 409.710006] but task is already holding lock: [ 409.715837] 0000000063b78782 (&pdata->lock){+.+.}, at: fme_pr_ioctl+0x21d/0x330 [dfl_fme] [ 409.724012] [ 409.724012] other info that might help us debug this: [ 409.730535] Possible unsafe locking scenario: [ 409.730535] [ 409.736457] CPU0 [ 409.738910] ---- [ 409.741360] lock(&pdata->lock); [ 409.744679] lock(&pdata->lock); [ 409.747999] [ 409.747999] *** DEADLOCK *** [ 409.747999] [ 409.753920] May be due to missing lock nesting notation [ 409.753920] [ 409.760704] 4 locks held by fpgaconf/9348: [ 409.764805] #0: 0000000063b78782 (&pdata->lock){+.+.}, at: fme_pr_ioctl+0x21d/0x330 [dfl_fme] [ 409.773408] #1: 00000000213c8a66 (®ion->mutex){+.+.}, at: fpga_region_program_fpga+0x24/0x200 [fpga_region] [ 409.783489] #2: 00000000fe63afb9 (&mgr->ref_mutex){+.+.}, at: fpga_mgr_lock+0x15/0x40 [fpga_mgr] [ 409.792354] #3: 000000000b2285c5 (&bridge->mutex){+.+.}, at: __fpga_bridge_get+0x26/0xa0 [fpga_bridge] [ 409.801740] [ 409.801740] stack backtrace: [ 409.806102] CPU: 45 PID: 9348 Comm: fpgaconf Kdump: loaded Tainted: G E 5.1.0-rc3.fpga+ #1 [ 409.815658] Hardware name: Intel Corporation S2600BT/S2600BT, BIOS SE5C620.86B.01.00.0763.022420181017 02/24/2018 [ 409.825911] Call Trace: [ 409.828369] dump_stack+0x5e/0x8b [ 409.831686] __lock_acquire+0xf3d/0x10e0 [ 409.835612] ? find_held_lock+0x3c/0xa0 [ 409.839451] lock_acquire+0xbc/0x1d0 [ 409.843030] ? port_enable_set+0x24/0x60 [dfl_afu] [ 409.847823] ? port_enable_set+0x24/0x60 [dfl_afu] [ 409.852616] __mutex_lock+0x86/0x970 [ 409.856195] ? port_enable_set+0x24/0x60 [dfl_afu] [ 409.860989] ? port_enable_set+0x24/0x60 [dfl_afu] [ 409.865777] ? __mutex_unlock_slowpath+0x4b/0x290 [ 409.870486] port_enable_set+0x24/0x60 [dfl_afu] [ 409.875106] fpga_bridges_disable+0x36/0x50 [fpga_bridge] [ 409.880502] fpga_region_program_fpga+0xea/0x200 [fpga_region] [ 409.886338] fme_pr_ioctl+0x13e/0x330 [dfl_fme] [ 409.890870] fme_ioctl+0x66/0xe0 [dfl_fme] [ 409.894973] do_vfs_ioctl+0xa9/0x720 [ 409.898548] ? lockdep_hardirqs_on+0xf0/0x1a0 [ 409.902907] ksys_ioctl+0x60/0x90 [ 409.906225] __x64_sys_ioctl+0x16/0x20 [ 409.909981] do_syscall_64+0x5a/0x220 [ 409.913644] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 409.918698] RIP: 0033:0x7f9d31b9b8d7 [ 409.922276] Code: 44 00 00 48 8b 05 b9 15 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 89 15 2d 00 f7 d8 64 89 01 48 [ 409.941020] RSP: 002b:00007ffe4cae0d68 EFLAGS: 00000202 ORIG_RAX: 0000000000000010 [ 409.948588] RAX: ffffffffffffffda RBX: 00007f9d32ade6a0 RCX: 00007f9d31b9b8d7 [ 409.955719] RDX: 00007ffe4cae0df0 RSI: 000000000000b680 RDI: 0000000000000003 [ 409.962852] RBP: 0000000000000003 R08: 00007f9d2b70a177 R09: 00007ffe4cae0e40 [ 409.969984] R10: 00007ffe4cae0160 R11: 0000000000000202 R12: 00007ffe4cae0df0 [ 409.977115] R13: 000000000000b680 R14: 0000000000000000 R15: 00007ffe4cae0f60
Signed-off-by: Scott Wood swood@redhat.com Acked-by: Wu Hao hao.wu@intel.com Acked-by: Alan Tull atull@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fpga/dfl.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index a9b521bccb06..ab361ec78df4 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -40,6 +40,13 @@ enum dfl_fpga_devt_type { DFL_FPGA_DEVT_MAX, };
+static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX]; + +static const char *dfl_pdata_key_strings[DFL_ID_MAX] = { + "dfl-fme-pdata", + "dfl-port-pdata", +}; + /** * dfl_dev_info - dfl feature device information. * @name: name string of the feature platform device. @@ -443,11 +450,16 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) struct platform_device *fdev = binfo->feature_dev; struct dfl_feature_platform_data *pdata; struct dfl_feature_info *finfo, *p; + enum dfl_id_type type; int ret, index = 0;
if (!fdev) return 0;
+ type = feature_dev_id_type(fdev); + if (WARN_ON_ONCE(type >= DFL_ID_MAX)) + return -EINVAL; + /* * we do not need to care for the memory which is associated with * the platform device. After calling platform_device_unregister(), @@ -463,6 +475,8 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) pdata->num = binfo->feature_num; pdata->dfl_cdev = binfo->cdev; mutex_init(&pdata->lock); + lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type], + dfl_pdata_key_strings[type]);
/* * the count should be initialized to 0 to make sure @@ -497,7 +511,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
ret = platform_device_add(binfo->feature_dev); if (!ret) { - if (feature_dev_id_type(binfo->feature_dev) == PORT_ID) + if (type == PORT_ID) dfl_fpga_cdev_add_port_dev(binfo->cdev, binfo->feature_dev); else
[ Upstream commit 1c7ebeabc9e5ee12e42075a597de40fdb9059530 ]
BUG: memory leak unreferenced object 0xffff8881df48cda0 (size 16): comm "syz-executor.0", pid 5077, jiffies 4295994670 (age 22.280s) hex dump (first 16 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000d2d0d5fe>] parport_register_dev_model+0x141/0x6e0 [parport] [<00000000782f6dab>] 0xffffffffc15d1196 [<00000000d2ca6ae4>] platform_drv_probe+0x7e/0x100 [<00000000628c2a94>] really_probe+0x342/0x4d0 [<000000006874f5da>] driver_probe_device+0x8c/0x170 [<00000000424de37a>] __device_attach_driver+0xda/0x100 [<000000002acab09a>] bus_for_each_drv+0xfe/0x170 [<000000003d9e5f31>] __device_attach+0x190/0x230 [<0000000035d32f80>] bus_probe_device+0x123/0x140 [<00000000a05ba627>] device_add+0x7cc/0xce0 [<000000003f7560bf>] platform_device_add+0x230/0x3c0 [<000000002a0be07d>] 0xffffffffc15d0949 [<000000007361d8d2>] port_check+0x3b/0x50 [parport] [<000000004d67200f>] bus_for_each_dev+0x115/0x180 [<000000003ccfd11c>] __parport_register_driver+0x1f0/0x210 [parport] [<00000000987f06fc>] 0xffffffffc15d803e
After commit 4e5a74f1db8d ("parport: Revert "parport: fix memory leak""), free_pardevice do not free par_dev->state, we should free it in error path of parport_register_dev_model before return.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: 4e5a74f1db8d ("parport: Revert "parport: fix memory leak"") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/parport/share.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 5dc53d420ca8..7b4ee33c1935 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -895,6 +895,7 @@ parport_register_dev_model(struct parport *port, const char *name, par_dev->devmodel = true; ret = device_register(&par_dev->dev); if (ret) { + kfree(par_dev->state); put_device(&par_dev->dev); goto err_put_port; } @@ -912,6 +913,7 @@ parport_register_dev_model(struct parport *port, const char *name, spin_unlock(&port->physport->pardevice_lock); pr_debug("%s: cannot grant exclusive access for device %s\n", port->name, name); + kfree(par_dev->state); device_unregister(&par_dev->dev); goto err_put_port; }
[ Upstream commit 6b98d9134e14f5ef4bcf64b27eedf484ed19a1ec ]
Avoid such compiler warnings: arch/parisc/math-emu/cnv_float.h:71:27: warning: ‘<<’ in boolean context, did you mean ‘<’ ? [-Wint-in-bool-context] ((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) || Dintp2(dint_valueB)) arch/parisc/math-emu/fcnvxf.c:257:6: note: in expansion of macro ‘Dint_isinexact_to_sgl’ if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/math-emu/cnv_float.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/parisc/math-emu/cnv_float.h b/arch/parisc/math-emu/cnv_float.h index 933423fa5144..b0db61188a61 100644 --- a/arch/parisc/math-emu/cnv_float.h +++ b/arch/parisc/math-emu/cnv_float.h @@ -60,19 +60,19 @@ ((exponent < (SGL_P - 1)) ? \ (Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
-#define Int_isinexact_to_sgl(int_value) (int_value << 33 - SGL_EXP_LENGTH) +#define Int_isinexact_to_sgl(int_value) ((int_value << 33 - SGL_EXP_LENGTH) != 0)
#define Sgl_roundnearest_from_int(int_value,sgl_value) \ if (int_value & 1<<(SGL_EXP_LENGTH - 2)) /* round bit */ \ - if ((int_value << 34 - SGL_EXP_LENGTH) || Slow(sgl_value)) \ + if (((int_value << 34 - SGL_EXP_LENGTH) != 0) || Slow(sgl_value)) \ Sall(sgl_value)++
#define Dint_isinexact_to_sgl(dint_valueA,dint_valueB) \ - ((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) || Dintp2(dint_valueB)) + (((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) != 0) || Dintp2(dint_valueB))
#define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value) \ if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2)) \ - if ((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) || \ + if (((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) != 0) || \ Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
#define Dint_isinexact_to_dbl(dint_value) \
[ Upstream commit 2abae62a26a265129b364d8c1ef3be55e2c01309 ]
The qpn allocation logic has a WARN_ON() that intends to detect the use of an index that will introduce bits in the lower order bits of the QOS bits in the QPN.
Unfortunately, it has the following bugs: - it misfires when wrapping QPN allocation for non-QOS - it doesn't correctly detect low order QOS bits (despite the comment)
The WARN_ON() should not be applied to non-QOS (qos_shift == 1).
Additionally, it SHOULD test the qpn bits per the table below:
2 data VLs: [qp7, qp6, qp5, qp4, qp3, qp2, qp1] ^ [ 0, 0, 0, 0, 0, 0, sc0], qp bit 1 always 0* 3-4 data VLs: [qp7, qp6, qp5, qp4, qp3, qp2, qp1] ^ [ 0, 0, 0, 0, 0, sc1, sc0], qp bits [21] always 0 5-8 data VLs: [qp7, qp6, qp5, qp4, qp3, qp2, qp1] ^ [ 0, 0, 0, 0, sc2, sc1, sc0] qp bits [321] always 0
Fix by qualifying the warning for qos_shift > 1 and producing the correct mask to insure the above bits are zero without generating a superfluous warning.
Fixes: 501edc42446e ("IB/rdmavt: Correct warning during QPN allocation") Reviewed-by: Kaike Wan kaike.wan@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rdmavt/qp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 5ce403c6cddb..7d03680afd91 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -412,7 +412,8 @@ static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, offset = qpt->incr | ((offset & 1) ^ 1); } /* there can be no set bits in low-order QoS bits */ - WARN_ON(offset & (BIT(rdi->dparms.qos_shift) - 1)); + WARN_ON(rdi->dparms.qos_shift > 1 && + offset & ((BIT(rdi->dparms.qos_shift - 1) - 1) << 1)); qpn = mk_qpn(qpt, map, offset); }
[ Upstream commit 6d517353c70bb0818b691ca003afdcb5ee5ea44e ]
By code inspection, the freeze_work is never canceled.
Fix by adding a cancel_work_sync in the shutdown path to insure it is no longer running.
Fixes: 7724105686e7 ("IB/hfi1: add driver files") Reviewed-by: Michael J. Ruhl michael.j.ruhl@intel.com Reviewed-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/chip.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index b12c8ff8ed66..d8eb4dc04d69 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -9849,6 +9849,7 @@ void hfi1_quiet_serdes(struct hfi1_pportdata *ppd)
/* disable the port */ clear_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK); + cancel_work_sync(&ppd->freeze_work); }
static inline int init_cpu_counters(struct hfi1_devdata *dd)
[ Upstream commit 35164f5259a47ea756fa1deb3e463ac2a4f10dc9 ]
The command 'ibv_devinfo -v' reports 0 for max_mr.
Fix by assigning the query values after the mr lkey_table has been built rather than early on in the driver.
Fixes: 7b1e2099adc8 ("IB/rdmavt: Move memory registration into rdmavt") Reviewed-by: Josh Collier josh.d.collier@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/verbs.c | 2 -- drivers/infiniband/hw/qib/qib_verbs.c | 2 -- drivers/infiniband/sw/rdmavt/mr.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c index 48692adbe811..27d9c4cefdc7 100644 --- a/drivers/infiniband/hw/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c @@ -1418,8 +1418,6 @@ static void hfi1_fill_device_attr(struct hfi1_devdata *dd) rdi->dparms.props.max_cq = hfi1_max_cqs; rdi->dparms.props.max_ah = hfi1_max_ahs; rdi->dparms.props.max_cqe = hfi1_max_cqes; - rdi->dparms.props.max_mr = rdi->lkey_table.max; - rdi->dparms.props.max_fmr = rdi->lkey_table.max; rdi->dparms.props.max_map_per_fmr = 32767; rdi->dparms.props.max_pd = hfi1_max_pds; rdi->dparms.props.max_qp_rd_atom = HFI1_MAX_RDMA_ATOMIC; diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c index 41babbc0db58..803c3544c75b 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.c +++ b/drivers/infiniband/hw/qib/qib_verbs.c @@ -1495,8 +1495,6 @@ static void qib_fill_device_attr(struct qib_devdata *dd) rdi->dparms.props.max_cq = ib_qib_max_cqs; rdi->dparms.props.max_cqe = ib_qib_max_cqes; rdi->dparms.props.max_ah = ib_qib_max_ahs; - rdi->dparms.props.max_mr = rdi->lkey_table.max; - rdi->dparms.props.max_fmr = rdi->lkey_table.max; rdi->dparms.props.max_map_per_fmr = 32767; rdi->dparms.props.max_qp_rd_atom = QIB_MAX_RDMA_ATOMIC; rdi->dparms.props.max_qp_init_rd_atom = 255; diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 5819c9d6ffdc..39d101df229d 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c @@ -96,6 +96,8 @@ int rvt_driver_mr_init(struct rvt_dev_info *rdi) for (i = 0; i < rdi->lkey_table.max; i++) RCU_INIT_POINTER(rdi->lkey_table.table[i], NULL);
+ rdi->dparms.props.max_mr = rdi->lkey_table.max; + rdi->dparms.props.max_fmr = rdi->lkey_table.max; return 0; }
[ Upstream commit 97736f36dbebf2cda2799db3b54717ba5b388255 ]
User applications can register memory regions for TID buffers that are not aligned on page boundaries. Hfi1 is expected to pin those pages in memory and cache the pages with mmu_rb. The rb tree will fail to insert pages that are not aligned correctly.
Validate whether a given virtual address is page aligned before pinning.
Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body") Reviewed-by: Michael J. Ruhl michael.j.ruhl@intel.com Signed-off-by: Kamenee Arumugam kamenee.arumugam@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index dbe7d14a5c76..4e986ca4dd35 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -324,6 +324,9 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, u32 *tidlist = NULL; struct tid_user_buf *tidbuf;
+ if (!PAGE_ALIGNED(tinfo->vaddr)) + return -EINVAL; + tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL); if (!tidbuf) return -ENOMEM;
[ Upstream commit f532beeeff0c0a3586cc15538bc52d249eb19e7c ]
Fixes gcc '-Wunused-but-set-variable' warning:
arch/mips/kernel/uprobes.c: In function 'arch_uprobe_pre_xol': arch/mips/kernel/uprobes.c:115:17: warning: variable 'epc' set but not used [-Wunused-but-set-variable]
It's never used since introduction in commit 40e084a506eb ("MIPS: Add uprobes support.")
Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: ralf@linux-mips.org Cc: jhogan@kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-mips@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kernel/uprobes.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 4aaff3b3175c..6dbe4eab0a0e 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -112,9 +112,6 @@ int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs) */ aup->resume_epc = regs->cp0_epc + 4; if (insn_has_delay_slot((union mips_instruction) aup->insn[0])) { - unsigned long epc; - - epc = regs->cp0_epc; __compute_return_epc_for_insn(regs, (union mips_instruction) aup->insn[0]); aup->resume_epc = regs->cp0_epc;
[ Upstream commit adefd051a6707a6ca0ebad278d3c1c05c960fc3b ]
Since commit 9012d011660ea5cf2 ("compiler: allow all arches to enable CONFIG_OPTIMIZE_INLINING"), xtensa:tinyconfig fails to build with section mismatch errors.
WARNING: vmlinux.o(.text.unlikely+0x68): Section mismatch in reference from the function ___pa() to the function .meminit.text:memblock_reserve() WARNING: vmlinux.o(.text.unlikely+0x74): Section mismatch in reference from the function mem_reserve() to the function .meminit.text:memblock_reserve() FATAL: modpost: Section mismatches detected.
This was not seen prior to the above mentioned commit because mem_reserve() was always inlined.
Mark mem_reserve(() as __init_memblock to have it reside in the same section as memblock_reserve().
Signed-off-by: Guenter Roeck linux@roeck-us.net Message-Id: 1559220098-9955-1-git-send-email-linux@roeck-us.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/xtensa/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 351283b60df6..a285fbd0fd9b 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -310,7 +310,8 @@ extern char _SecondaryResetVector_text_start; extern char _SecondaryResetVector_text_end; #endif
-static inline int mem_reserve(unsigned long start, unsigned long end) +static inline int __init_memblock mem_reserve(unsigned long start, + unsigned long end) { return memblock_reserve(start, end - start); }
[ Upstream commit f6131f28057d4fd8922599339e701a2504e0f23d ]
The cgroup testing relies on the root cgroup's subtree_control setting, If the 'memory' controller isn't set, all test cases will be failed as following:
$ sudo ./test_memcontrol not ok 1 test_memcg_subtree_control not ok 2 test_memcg_current ok 3 # skip test_memcg_min not ok 4 test_memcg_low not ok 5 test_memcg_high not ok 6 test_memcg_max not ok 7 test_memcg_oom_events ok 8 # skip test_memcg_swap_max not ok 9 test_memcg_sock not ok 10 test_memcg_oom_group_leaf_events not ok 11 test_memcg_oom_group_parent_events not ok 12 test_memcg_oom_group_score_events
To correct this unexpected failure, this patch write the 'memory' to subtree_control of root to get a right result.
Signed-off-by: Alex Shi alex.shi@linux.alibaba.com Cc: Shuah Khan shuah@kernel.org Cc: Roman Gushchin guro@fb.com Cc: Tejun Heo tj@kernel.org Cc: Mike Rapoport rppt@linux.vnet.ibm.com Cc: Jay Kamat jgkamat@fb.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Roman Gushchin guro@fb.com Acked-by: Tejun Heo tj@kernel.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/cgroup/test_memcontrol.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c index 6f339882a6ca..c19a97dd02d4 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c @@ -1205,6 +1205,10 @@ int main(int argc, char **argv) if (cg_read_strstr(root, "cgroup.controllers", "memory")) ksft_exit_skip("memory controller isn't available\n");
+ if (cg_read_strstr(root, "cgroup.subtree_control", "memory")) + if (cg_write(root, "cgroup.subtree_control", "+memory")) + ksft_exit_skip("Failed to set memory controller\n"); + for (i = 0; i < ARRAY_SIZE(tests); i++) { switch (tests[i].fn(root)) { case KSFT_PASS:
[ Upstream commit 00e38a5d753d7788852f81703db804a60a84c26e ]
The cgroup testing relys on the root cgroup's subtree_control setting, If the 'memory' controller isn't set, some test cases will be failed as following:
$sudo ./test_core not ok 1 test_cgcore_internal_process_constraint ok 2 test_cgcore_top_down_constraint_enable not ok 3 test_cgcore_top_down_constraint_disable ...
To correct this unexpected failure, this patch write the 'memory' to subtree_control of root to get a right result.
Signed-off-by: Alex Shi alex.shi@linux.alibaba.com Cc: Shuah Khan shuah@kernel.org Cc: Tejun Heo tj@kernel.org Cc: Roman Gushchin guro@fb.com Cc: Claudio Zumbo claudioz@fb.com Cc: Claudio claudiozumbo@gmail.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Roman Gushchin guro@fb.com Acked-by: Tejun Heo tj@kernel.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/cgroup/test_core.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c index be59f9c34ea2..d78f1c5366d3 100644 --- a/tools/testing/selftests/cgroup/test_core.c +++ b/tools/testing/selftests/cgroup/test_core.c @@ -376,6 +376,11 @@ int main(int argc, char *argv[])
if (cg_find_unified_root(root, sizeof(root))) ksft_exit_skip("cgroup v2 isn't mounted\n"); + + if (cg_read_strstr(root, "cgroup.subtree_control", "memory")) + if (cg_write(root, "cgroup.subtree_control", "+memory")) + ksft_exit_skip("Failed to set memory controller\n"); + for (i = 0; i < ARRAY_SIZE(tests); i++) { switch (tests[i].fn(root)) { case KSFT_PASS:
[ Upstream commit f97f3f8839eb9de5843066d80819884f7722c8c5 ]
The test_core will skip the test_cgcore_no_internal_process_constraint_on_threads test case if the 'cpu' controller missing in root's subtree_control. In fact we need to set the 'cpu' in subtree_control, to make the testing meaningful.
./test_core ... ok 4 # skip test_cgcore_no_internal_process_constraint_on_threads ...
Signed-off-by: Alex Shi alex.shi@linux.alibaba.com Cc: Shuah Khan shuah@kernel.org Cc: Tejun Heo tj@kernel.org Cc: Roman Gushchin guro@fb.com Cc: Claudio Zumbo claudioz@fb.com Cc: Claudio claudiozumbo@gmail.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Roman Gushchin guro@fb.com Acked-by: Tejun Heo tj@kernel.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/cgroup/test_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c index d78f1c5366d3..79053a4f4783 100644 --- a/tools/testing/selftests/cgroup/test_core.c +++ b/tools/testing/selftests/cgroup/test_core.c @@ -198,7 +198,7 @@ static int test_cgcore_no_internal_process_constraint_on_threads(const char *roo char *parent = NULL, *child = NULL;
if (cg_read_strstr(root, "cgroup.controllers", "cpu") || - cg_read_strstr(root, "cgroup.subtree_control", "cpu")) { + cg_write(root, "cgroup.subtree_control", "+cpu")) { ret = KSFT_SKIP; goto cleanup; }
[ Upstream commit bc2cce3f2ebcae02aa4bb29e3436bf75ee674c32 ]
Add test_vmalloc.sh to TEST_FILES to make sure it gets installed for run_vmtests.
Fixed below error: ./run_vmtests: line 217: ./test_vmalloc.sh: No such file or directory
Tested with: make TARGETS=vm install INSTALL_PATH=$PWD/x
Signed-off-by: Naresh Kamboju naresh.kamboju@linaro.org Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vm/Makefile | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index dc68340a6a96..2cf3dc49bd03 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -24,6 +24,8 @@ TEST_GEN_FILES += virtual_address_range
TEST_PROGS := run_vmtests
+TEST_FILES := test_vmalloc.sh + KSFT_KHDR_INSTALL := 1 include ../lib.mk
[ Upstream commit 62394708f3e01c9f2be6be74eb6305bae1ed924f ]
When non-bridged, non-vlan'ed mv88e6xxx port is moving down, error message is logged:
failed to kill vid 0081/0 for device eth_cu_1000_4
This is caused by call from __vlan_vid_del() with vin set to zero, over call chain this results into _mv88e6xxx_port_vlan_del() called with vid=0, and mv88e6xxx_vtu_get() called from there returns -EINVAL.
On symmetric path moving port up, call goes through mv88e6xxx_port_vlan_prepare() that calls mv88e6xxx_port_check_hw_vlan() that returns -EOPNOTSUPP for zero vid.
This patch changes mv88e6xxx_vtu_get() to also return -EOPNOTSUPP for zero vid, then this error code is explicitly cleared in dsa_slave_vlan_rx_kill_vid() and error message is no longer logged.
Signed-off-by: Nikita Yushchenko nikita.yoush@cogentembedded.com Reviewed-by: Vivien Didelot vivien.didelot@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index dfaad1c2c2b8..411cfb806459 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1484,7 +1484,7 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid, int err;
if (!vid) - return -EINVAL; + return -EOPNOTSUPP;
entry->vid = vid - 1; entry->valid = false;
[ Upstream commit 2e1f164861e500f4e068a9d909bbd3fcc7841483 ]
When doing a loopback test at copper ports, the serdes loopback and the phy loopback will fail, because of the adjust link had not finished, and phy not ready.
Adds sleep between adjust link and test process to fix it.
Signed-off-by: Yonglong Liu liuyonglong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index e2710ff48fb0..1fa0cd527ead 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -339,6 +339,7 @@ static int __lb_setup(struct net_device *ndev, static int __lb_up(struct net_device *ndev, enum hnae_loop loop_mode) { +#define NIC_LB_TEST_WAIT_PHY_LINK_TIME 300 struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_handle *h = priv->ae_handle; int speed, duplex; @@ -365,6 +366,9 @@ static int __lb_up(struct net_device *ndev,
h->dev->ops->adjust_link(h, speed, duplex);
+ /* wait adjust link done and phy ready */ + msleep(NIC_LB_TEST_WAIT_PHY_LINK_TIME); + return 0; }
[ Upstream commit 80caf43549e7e41a695c6d1e11066286538b336f ]
In get_vdev_port_node_info(), 'node_info->vdev_port.name' is allcoated by kstrdup_const(), and it returns NULL when fails. So 'node_info->vdev_port.name' should be checked.
Signed-off-by: Gen Zhang blackgod016574@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sparc/kernel/mdesc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 39a2503fa3e1..51028abe5e90 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -357,6 +357,8 @@ static int get_vdev_port_node_info(struct mdesc_handle *md, u64 node,
node_info->vdev_port.id = *idp; node_info->vdev_port.name = kstrdup_const(name, GFP_KERNEL); + if (!node_info->vdev_port.name) + return -1; node_info->vdev_port.parent_cfg_hdl = *parent_cfg_hdlp;
return 0;
[ Upstream commit 56cd0aefa475079e9613085b14a0f05037518fed ]
The PERF_EVENT_IOC_PERIOD ioctl command can be used to change the sample period of a running perf_event. Consequently, when calculating the next event period, the new period will only be considered after the previous one has overflowed.
This patch changes the calculation of the remaining event ticks so that they are offset if the period has changed.
See commit 3581fe0ef37c ("ARM: 7556/1: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD") for details.
Signed-off-by: Young Xiao 92siuyang@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sparc/kernel/perf_event.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 67b3e6b3ce5d..1ad5911f62b4 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -891,6 +891,10 @@ static int sparc_perf_event_set_period(struct perf_event *event, s64 period = hwc->sample_period; int ret = 0;
+ /* The period may have been changed by PERF_EVENT_IOC_PERIOD */ + if (unlikely(period != hwc->last_period)) + left = period - (hwc->last_period - left); + if (unlikely(left <= -period)) { left = period; local64_set(&hwc->period_left, left);
[ Upstream commit 9e4f56f1a7f3287718d0083b5cb85298dc05a5fd ]
Should hw_feature as hardware capability flags to check if hardware LRO got support.
Signed-off-by: Mark Lee mark-mc.lee@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 6e6abdc399de..0c70fb345f83 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -2304,13 +2304,13 @@ static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - if (dev->features & NETIF_F_LRO) { + if (dev->hw_features & NETIF_F_LRO) { cmd->data = MTK_MAX_RX_RING_NUM; ret = 0; } break; case ETHTOOL_GRXCLSRLCNT: - if (dev->features & NETIF_F_LRO) { + if (dev->hw_features & NETIF_F_LRO) { struct mtk_mac *mac = netdev_priv(dev);
cmd->rule_cnt = mac->hwlro_ip_cnt; @@ -2318,11 +2318,11 @@ static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, } break; case ETHTOOL_GRXCLSRULE: - if (dev->features & NETIF_F_LRO) + if (dev->hw_features & NETIF_F_LRO) ret = mtk_hwlro_get_fdir_entry(dev, cmd); break; case ETHTOOL_GRXCLSRLALL: - if (dev->features & NETIF_F_LRO) + if (dev->hw_features & NETIF_F_LRO) ret = mtk_hwlro_get_fdir_all(dev, cmd, rule_locs); break; @@ -2339,11 +2339,11 @@ static int mtk_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
switch (cmd->cmd) { case ETHTOOL_SRXCLSRLINS: - if (dev->features & NETIF_F_LRO) + if (dev->hw_features & NETIF_F_LRO) ret = mtk_hwlro_add_ipaddr(dev, cmd); break; case ETHTOOL_SRXCLSRLDEL: - if (dev->features & NETIF_F_LRO) + if (dev->hw_features & NETIF_F_LRO) ret = mtk_hwlro_del_ipaddr(dev, cmd); break; default:
[ Upstream commit 880c2d4b2fdfd580ebcd6bb7240a8027a1d34751 ]
Should only enable HW RX_2BYTE_OFFSET function in the case NET_IP_ALIGN equals to 2.
Signed-off-by: Mark Lee mark-mc.lee@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 0c70fb345f83..1d55f014725e 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -1784,6 +1784,7 @@ static void mtk_poll_controller(struct net_device *dev)
static int mtk_start_dma(struct mtk_eth *eth) { + u32 rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0; int err;
err = mtk_dma_init(eth); @@ -1800,7 +1801,7 @@ static int mtk_start_dma(struct mtk_eth *eth) MTK_QDMA_GLO_CFG);
mtk_w32(eth, - MTK_RX_DMA_EN | MTK_RX_2B_OFFSET | + MTK_RX_DMA_EN | rx_2b_offset | MTK_RX_BT_32DWORDS | MTK_MULTI_EN, MTK_PDMA_GLO_CFG);
[ Upstream commit 6a88e0c14813d00f8520d0e16cd4136c6cf8b4d4 ]
This patch trying to fix monitor freeze issue caused by drm error 'flip_done timed out' on LS1028A platform. this set try is make a loop around the second setting CVAL and try like 5 times before giveing up.
Signed-off-by: Wen He wen.he_1@nxp.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/malidp_drv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 94d6dabec2dc..1ab511e33243 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -190,6 +190,7 @@ static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state) { struct drm_device *drm = state->dev; struct malidp_drm *malidp = drm->dev_private; + int loop = 5;
malidp->event = malidp->crtc.state->event; malidp->crtc.state->event = NULL; @@ -204,8 +205,18 @@ static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state) drm_crtc_vblank_get(&malidp->crtc);
/* only set config_valid if the CRTC is enabled */ - if (malidp_set_and_wait_config_valid(drm) < 0) + if (malidp_set_and_wait_config_valid(drm) < 0) { + /* + * make a loop around the second CVAL setting and + * try 5 times before giving up. + */ + while (loop--) { + if (!malidp_set_and_wait_config_valid(drm)) + break; + } DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n"); + } + } else if (malidp->event) { /* CRTC inactive means vblank IRQ is disabled, send event directly */ spin_lock_irq(&drm->event_lock);
[ Upstream commit b96151edced4edb6a18aa89a5fa02c7066efff45 ]
Rather than allowing any old mode through, then subsequently refusing unmatchable clock rates in atomic_check when it's too late to back out and pick a different mode, let's do that validation up-front where it will cause unsupported modes to be correctly pruned in the first place.
This also eliminates an issue whereby a perceived clock rate of 0 would cause atomic disable to fail and prevent the module from being unloaded.
Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/hdlcd_crtc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index e4d67b70244d..d5c1a0b1f01a 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -186,20 +186,19 @@ static void hdlcd_crtc_atomic_disable(struct drm_crtc *crtc, clk_disable_unprepare(hdlcd->clk); }
-static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) +static enum drm_mode_status hdlcd_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); - struct drm_display_mode *mode = &state->adjusted_mode; long rate, clk_rate = mode->clock * 1000;
rate = clk_round_rate(hdlcd->clk, clk_rate); if (rate != clk_rate) { /* clock required by mode not supported by hardware */ - return -EINVAL; + return MODE_NOCLOCK; }
- return 0; + return MODE_OK; }
static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, @@ -220,7 +219,7 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, }
static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { - .atomic_check = hdlcd_crtc_atomic_check, + .mode_valid = hdlcd_crtc_mode_valid, .atomic_begin = hdlcd_crtc_atomic_begin, .atomic_enable = hdlcd_crtc_atomic_enable, .atomic_disable = hdlcd_crtc_atomic_disable,
[ Upstream commit 1c810739097fdeb31b393b67a0a1e3d7ffdd9f63 ]
On the Arm Juno platform, the HDLCD pixel clock is constrained to 250KHz resolution in order to avoid the tiny System Control Processor spending aeons trying to calculate exact PLL coefficients. This means that modes like my oddball 1600x1200 with 130.89MHz clock get rejected since the rate cannot be matched exactly. In practice, though, this mode works quite happily with the clock at 131MHz, so let's relax the check to allow a little bit of slop.
Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/hdlcd_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index d5c1a0b1f01a..e69d996eabad 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -193,7 +193,8 @@ static enum drm_mode_status hdlcd_crtc_mode_valid(struct drm_crtc *crtc, long rate, clk_rate = mode->clock * 1000;
rate = clk_round_rate(hdlcd->clk, clk_rate); - if (rate != clk_rate) { + /* 0.1% seems a close enough tolerance for the TDA19988 on Juno */ + if (abs(rate - clk_rate) * 1000 > clk_rate) { /* clock required by mode not supported by hardware */ return MODE_NOCLOCK; }
[ Upstream commit 3562f5d9f21e7779ae442a45197fed6cb247fd22 ]
The WRITE ZEROES command has no data transfer so that we need to initialize the struct (nvmet_req *req)->data_len to 0x0. While (nvmet_req *req)->transfer_len is initialized in nvmet_req_init(), data_len will be initialized by nowhere which might cause the failure with status code NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR randomly. It's because nvmet_req_execute() checks like:
if (unlikely(req->data_len != req->transfer_len)) { req->error_loc = offsetof(struct nvme_common_command, dptr); nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR); } else req->execute(req);
This patch fixes req->data_len not to be a randomly assigned by initializing it to 0x0 when preparing the command in nvmet_bdev_parse_io_cmd().
nvmet_file_parse_io_cmd() which is for file-backed I/O has already initialized the data_len field to 0x0, though.
Cc: Christoph Hellwig hch@lst.de Cc: Sagi Grimberg sagi@grimberg.me Cc: Chaitanya Kulkarni Chaitanya.Kulkarni@wdc.com Signed-off-by: Minwoo Im minwoo.im.dev@gmail.com Reviewed-by: Chaitanya Kulkarni chaitanya.kulkarni@wdc.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/io-cmd-bdev.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 7bc9f6240432..1096dd01ca22 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -239,6 +239,7 @@ u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req) return 0; case nvme_cmd_write_zeroes: req->execute = nvmet_bdev_execute_write_zeroes; + req->data_len = 0; return 0; default: pr_err("unhandled cmd %d on qid %d\n", cmd->common.opcode,
[ Upstream commit 4f45d62a52297b10ded963412a158685647ecdec ]
The following error occurs for the `make ARCH=arm64 checkstack` case:
aarch64-linux-gnu-objdump -d vmlinux $(find . -name '*.ko') | \ perl ./scripts/checkstack.pl arm64 wrong or unknown architecture "arm64"
As suggested by Masahiro Yamada, fix the above error using regular expressions in the same way it was fixed for the `ARCH=x86` case via commit fda9f9903be6 ("scripts/checkstack.pl: automatically handle 32-bit and 64-bit mode for ARCH=x86").
Suggested-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: George G. Davis george_davis@mentor.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/checkstack.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 34414c6efad6..a2c9e7f98e06 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -46,7 +46,7 @@ my (@stack, $re, $dre, $x, $xs, $funcre); $x = "[0-9a-f]"; # hex character $xs = "[0-9a-f ]"; # hex character or space $funcre = qr/^$x* <(.*)>:$/; - if ($arch eq 'aarch64') { + if ($arch =~ '^(aarch|arm)64$') { #ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp, #-80]! $re = qr/^.*stp.*sp, #-([0-9]{1,8})]!/o; } elsif ($arch eq 'arm') {
[ Upstream commit 1c90836f70f9a8ef7b7ad9e1fdd8961903e6ced6 ]
struct ufs_dev_cmd is the main container that supports device management commands. In the case of a read descriptor request, we assume that the proper space was allocated in dev_cmd to hold the returning descriptor.
This is no longer true, as there are flows that doesn't use dev_cmd for device management requests, and was wrong in the first place.
Fixes: d44a5f98bb49 (ufs: query descriptor API) Signed-off-by: Avri Altman avri.altman@wdc.com Reviewed-by: Alim Akhtar alim.akhtar@samsung.com Acked-by: Bean Huo beanhuo@micron.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3183fa8c5857..b8b59cfeacd1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1914,7 +1914,8 @@ int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) memcpy(&query_res->upiu_res, &lrbp->ucd_rsp_ptr->qr, QUERY_OSF_SIZE);
/* Get the descriptor */ - if (lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) { + if (hba->dev_cmd.query.descriptor && + lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) { u8 *descp = (u8 *)lrbp->ucd_rsp_ptr + GENERAL_UPIU_REQUEST_SIZE; u16 resp_len;
[ Upstream commit cc8f52609bb4177febade24d11713e20c0893b0a ]
We need to drop the "ctrl_info->sync_request_sem" lock before returning.
Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Don Brace don.brace@microsemi.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 411d656f2530..98f2d076f938 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -3697,8 +3697,10 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, return -ETIMEDOUT; msecs_blocked = jiffies_to_msecs(jiffies - start_jiffies); - if (msecs_blocked >= timeout_msecs) - return -ETIMEDOUT; + if (msecs_blocked >= timeout_msecs) { + rc = -ETIMEDOUT; + goto out; + } timeout_msecs -= msecs_blocked; } }
[ Upstream commit ceae266bf0ae6564ac16d086bf749a096fa90ded ]
There's some NICs, such as hinic, with NETIF_F_IP_CSUM and NETIF_F_TSO on but NETIF_F_HW_CSUM off. And ipvlan device features will be NETIF_F_TSO on with NETIF_F_IP_CSUM and NETIF_F_IP_CSUM both off as IPVLAN_FEATURES only care about NETIF_F_HW_CSUM. So TSO will be disabled in netdev_fix_features. For example: Features for enp129s0f0: rx-checksumming: on tx-checksumming: on tx-checksum-ipv4: on tx-checksum-ip-generic: off [fixed] tx-checksum-ipv6: on
Fixes: a188222b6ed2 ("net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipvlan/ipvlan_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 68b8007da82b..0115a2868933 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -178,7 +178,7 @@ static void ipvlan_port_destroy(struct net_device *dev) }
#define IPVLAN_FEATURES \ - (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ + (NETIF_F_SG | NETIF_F_CSUM_MASK | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ NETIF_F_GSO | NETIF_F_TSO | NETIF_F_GSO_ROBUST | \ NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \ NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
[ Upstream commit 335726195e460cb6b3f795b695bfd31f0ea70ef0 ]
Enabling sysfs attribute bridge_hostnotify triggers a series of udev events for the MAC addresses of all currently connected peers. In case no VLAN is set for a peer, the device reports the corresponding MAC addresses with VLAN ID 4096. This currently results in attribute VLAN=4096 for all non-VLAN interfaces in the initial series of events after host-notify is enabled.
Instead, no VLAN attribute should be reported in the udev event for non-VLAN interfaces.
Only the initial events face this issue. For dynamic changes that are reported later, the device uses a validity flag.
This also changes the code so that it now sets the VLAN attribute for MAC addresses with VID 0. On Linux, no qeth interface will ever be registered with VID 0: Linux kernel registers VID 0 on all network interfaces initially, but qeth will drop .ndo_vlan_rx_add_vid for VID 0. Peers with other OSs could register MACs with VID 0.
Fixes: 9f48b9db9a22 ("qeth: bridgeport support - address notifications") Signed-off-by: Alexandra Winter wintera@linux.ibm.com Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_l2_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index b7513c5848cf..c1c35eccd5b6 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1901,7 +1901,7 @@ static void qeth_bridgeport_an_set_cb(void *priv,
l2entry = (struct qdio_brinfo_entry_l2 *)entry; code = IPA_ADDR_CHANGE_CODE_MACADDR; - if (l2entry->addr_lnid.lnid) + if (l2entry->addr_lnid.lnid < VLAN_N_VID) code |= IPA_ADDR_CHANGE_CODE_VLANID; qeth_bridge_emit_host_event(card, anev_reg_unreg, code, (struct net_if_token *)&l2entry->nit,
[ Upstream commit c41dd48e21fae3e55b3670ccf2eb562fc1f6a67d ]
Drivers may register to hwmon and request for also registering with the thermal subsystem (HWMON_C_REGISTER_TZ). However, some of these driver, e.g. marvell phy, may be probed from Device Tree or being dynamically allocated, and in the later case, it will not have a dev->of_node entry.
Registering with hwmon without the dev->of_node may result in different outcomes depending on the device tree, which may be a bit misleading. If the device tree blob has no 'thermal-zones' node, the *hwmon_device_register*() family functions are going to gracefully succeed, because of-thermal, *thermal_zone_of_sensor_register() return -ENODEV in this case, and the hwmon error path handles this error code as success to cover for the case where CONFIG_THERMAL_OF is not set. However, if the device tree blob has the 'thermal-zones' entry, the *hwmon_device_register*() will always fail on callers with no dev->of_node, propagating -EINVAL.
If dev->of_node is not present, calling of-thermal does not make sense. For this reason, this patch checks first if the device has a of_node before going over the process of registering with the thermal subsystem of-thermal interface. And in this case, when a caller of *hwmon_device_register*() with HWMON_C_REGISTER_TZ and no dev->of_node will still register with hwmon, but not with the thermal subsystem. If all the hwmon part bits are in place, the registration will succeed.
Fixes: d560168b5d0f ("hwmon: (core) New hwmon registration API") Cc: Jean Delvare jdelvare@suse.com Cc: Guenter Roeck linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Eduardo Valentin eduval@amazon.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/hwmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index fcdbac4a56e3..6b3559f58b67 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -619,7 +619,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, if (err) goto free_hwmon;
- if (dev && chip && chip->ops->read && + if (dev && dev->of_node && chip && chip->ops->read && chip->info[0]->type == hwmon_chip && (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) { const struct hwmon_channel_info **info = chip->info;
[ Upstream commit 4a60570dce658e3f8885bbcf852430b99f65aca5 ]
Some chips have attributes which exist on more than one page but the attribute is not presently marked as paged. This causes the attributes to be generated with the same label, which makes it impossible for userspace to tell them apart.
Marking all such attributes as paged would result in the page suffix being added regardless of whether they were present on more than one page or not, which might break existing setups. Therefore, we add a second check which treats the attribute as paged, even if not marked as such, if it is present on multiple pages.
Fixes: b4ce237b7f7d ("hwmon: (pmbus) Introduce infrastructure to detect sensors and limit registers") Signed-off-by: Robert Hancock hancock@sedsystems.ca Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/pmbus_core.c | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 2e2b5851139c..cd24b375df1e 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -1230,7 +1230,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, const struct pmbus_driver_info *info, const char *name, int index, int page, - const struct pmbus_sensor_attr *attr) + const struct pmbus_sensor_attr *attr, + bool paged) { struct pmbus_sensor *base; bool upper = !!(attr->gbit & 0xff00); /* need to check STATUS_WORD */ @@ -1238,7 +1239,7 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
if (attr->label) { ret = pmbus_add_label(data, name, index, attr->label, - attr->paged ? page + 1 : 0); + paged ? page + 1 : 0); if (ret) return ret; } @@ -1271,6 +1272,30 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, return 0; }
+static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info, + const struct pmbus_sensor_attr *attr) +{ + int p; + + if (attr->paged) + return true; + + /* + * Some attributes may be present on more than one page despite + * not being marked with the paged attribute. If that is the case, + * then treat the sensor as being paged and add the page suffix to the + * attribute name. + * We don't just add the paged attribute to all such attributes, in + * order to maintain the un-suffixed labels in the case where the + * attribute is only on page 0. + */ + for (p = 1; p < info->pages; p++) { + if (info->func[p] & attr->func) + return true; + } + return false; +} + static int pmbus_add_sensor_attrs(struct i2c_client *client, struct pmbus_data *data, const char *name, @@ -1284,14 +1309,15 @@ static int pmbus_add_sensor_attrs(struct i2c_client *client, index = 1; for (i = 0; i < nattrs; i++) { int page, pages; + bool paged = pmbus_sensor_is_paged(info, attrs);
- pages = attrs->paged ? info->pages : 1; + pages = paged ? info->pages : 1; for (page = 0; page < pages; page++) { if (!(info->func[page] & attrs->func)) continue; ret = pmbus_add_sensor_attrs_one(client, data, info, name, index, page, - attrs); + attrs, paged); if (ret) return ret; index++;
[ Upstream commit ebcc5928c5d925b1c8d968d9c89cdb0d0186db17 ]
Since GCC 9, the compiler warns about evolution of the platform-specific ABI, in particular relating for the marshaling of certain structures involving bitfields.
The kernel is a standalone binary, and of course nobody would be so stupid as to expose structs containing bitfields as function arguments in ABI. (Passing a pointer to such a struct, however inadvisable, should be unaffected by this change. perf and various drivers rely on that.)
So these warnings do more harm than good: turn them off.
We may miss warnings about future ABI drift, but that's too bad. Future ABI breaks of this class will have to be debugged and fixed the traditional way unless the compiler evolves finer-grained diagnostics.
Signed-off-by: Dave Martin Dave.Martin@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 35649ee8ad56..c12ff63265a9 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -51,6 +51,7 @@ endif
KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables +KBUILD_CFLAGS += -Wno-psabi KBUILD_AFLAGS += $(lseinstr) $(brokengasinst)
KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
[ Upstream commit c8e8c77b3bdbade6e26e8e76595f141ede12b692 ]
The Number of Namespaces (nn) field in the identify controller data structure is defined as u32 and the maximum allowed value in NVMe specification is 0xFFFFFFFEUL. This change fixes the possible overflow of the DIV_ROUND_UP() operation used in nvme_scan_ns_list() by casting the nn to u64.
Signed-off-by: Jaesoo Lee jalee@purestorage.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a867a139bb35..d8869d978c34 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3228,7 +3228,8 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn) { struct nvme_ns *ns; __le32 *ns_list; - unsigned i, j, nsid, prev = 0, num_lists = DIV_ROUND_UP(nn, 1024); + unsigned i, j, nsid, prev = 0; + unsigned num_lists = DIV_ROUND_UP_ULL((u64)nn, 1024); int ret = 0;
ns_list = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
From: Naohiro Aota naohiro.aota@wdc.com
commit c4e0540d0ad49c8ceab06cceed1de27c4fe29f6e upstream.
Currently, btrfs does not consult seed devices to start readahead. As a result, if readahead zone is added to the seed devices, btrfs_reada_wait() indefinitely wait for the reada_ctl to finish.
You can reproduce the hung by modifying btrfs/163 to have larger initial file size (e.g. xfs_io pwrite 4M instead of current 256K).
Fixes: 7414a03fbf9e ("btrfs: initial readahead code and prototypes") Cc: stable@vger.kernel.org # 3.2+: ce7791ffee1e: Btrfs: fix race between readahead and device replace/removal Cc: stable@vger.kernel.org # 3.2+ Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/reada.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -745,6 +745,7 @@ static void __reada_start_machine(struct u64 total = 0; int i;
+again: do { enqueued = 0; mutex_lock(&fs_devices->device_list_mutex); @@ -756,6 +757,10 @@ static void __reada_start_machine(struct mutex_unlock(&fs_devices->device_list_mutex); total += enqueued; } while (enqueued && total < 10000); + if (fs_devices->seed) { + fs_devices = fs_devices->seed; + goto again; + }
if (enqueued == 0) return;
From: Anssi Hannula anssi.hannula@bitwise.fi
commit 904044dd8fff43e289c11a2f90fa532e946a1d8b upstream.
Commit 9e5f1b273e6a ("can: xilinx_can: add support for Xilinx CAN FD core") added a new can_bittiming_const structure for CAN FD cores that support larger values for tseg1, tseg2, and sjw than previous Xilinx CAN cores, but the commit did not actually take that into use.
Fix that.
Tested with CAN FD core on a ZynqMP board.
Fixes: 9e5f1b273e6a ("can: xilinx_can: add support for Xilinx CAN FD core") Reported-by: Shubhrajyoti Datta shubhrajyoti.datta@gmail.com Signed-off-by: Anssi Hannula anssi.hannula@bitwise.fi Cc: Michal Simek michal.simek@xilinx.com Reviewed-by: Shubhrajyoti Datta shubhrajyoti.datta@gmail.com Cc: linux-stable stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/can/xilinx_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -1424,7 +1424,7 @@ static const struct xcan_devtype_data xc XCAN_FLAG_RXMNF | XCAN_FLAG_TX_MAILBOXES | XCAN_FLAG_RX_FIFO_MULTI, - .bittiming_const = &xcan_bittiming_const, + .bittiming_const = &xcan_bittiming_const_canfd, .btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD, .btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD, .bus_clk_name = "s_axi_aclk",
From: Joakim Zhang qiangqing.zhang@nxp.com
commit 247e5356a709eb49a0d95ff2a7f07dac05c8252c upstream.
Current we can meet timeout issue when setting a small bitrate like 10000 as follows on i.MX6UL EVK board (ipg clock = 66MHZ, per clock = 30MHZ):
| root@imx6ul7d:~# ip link set can0 up type can bitrate 10000
A link change request failed with some changes committed already. Interface can0 may have been left with an inconsistent configuration, please check.
| RTNETLINK answers: Connection timed out
It is caused by calling of flexcan_chip_unfreeze() timeout.
Originally the code is using usleep_range(10, 20) for unfreeze operation, but the patch (8badd65 can: flexcan: avoid calling usleep_range from interrupt context) changed it into udelay(10) which is only a half delay of before, there're also some other delay changes.
After double to FLEXCAN_TIMEOUT_US to 100 can fix the issue.
Meanwhile, Rasmus Villemoes reported that even with a timeout of 100, flexcan_probe() fails on the MPC8309, which requires a value of at least 140 to work reliably. 250 works for everyone.
Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Reviewed-by: Dong Aisheng aisheng.dong@nxp.com Cc: linux-stable stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/can/flexcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -165,7 +165,7 @@ #define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) #define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
-#define FLEXCAN_TIMEOUT_US (50) +#define FLEXCAN_TIMEOUT_US (250)
/* FLEXCAN hardware feature flags *
From: Willem de Bruijn willemb@google.com
commit fd704bd5ee749d560e86c4f1fd2ef486d8abf7cf upstream.
CAN supports software tx timestamps as of the below commit. Purge any queued timestamp packets on socket destroy.
Fixes: 51f31cabe3ce ("ip: support for TX timestamps on UDP and RAW sockets") Reported-by: syzbot+a90604060cb40f5bdd16@syzkaller.appspotmail.com Signed-off-by: Willem de Bruijn willemb@google.com Cc: linux-stable stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/can/af_can.c | 1 + 1 file changed, 1 insertion(+)
--- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -105,6 +105,7 @@ EXPORT_SYMBOL(can_ioctl); static void can_sock_destruct(struct sock *sk) { skb_queue_purge(&sk->sk_receive_queue); + skb_queue_purge(&sk->sk_error_queue); }
static const struct can_proto *can_get_proto(int protocol)
From: ShihPo Hung shihpo.hung@sifive.com
commit bf587caae305ae3b4393077fb22c98478ee55755 upstream.
Because RISC-V compliant implementations can cache invalid entries in TLB, an SFENCE.VMA is necessary after changes to the page table. This patch adds an SFENCE.vma for the vmalloc_fault path.
Signed-off-by: ShihPo Hung shihpo.hung@sifive.com [paul.walmsley@sifive.com: reversed tab->whitespace conversion, wrapped comment lines] Signed-off-by: Paul Walmsley paul.walmsley@sifive.com Cc: Palmer Dabbelt palmer@sifive.com Cc: Albert Ou aou@eecs.berkeley.edu Cc: Paul Walmsley paul.walmsley@sifive.com Cc: linux-riscv@lists.infradead.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/riscv/mm/fault.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -29,6 +29,7 @@
#include <asm/pgalloc.h> #include <asm/ptrace.h> +#include <asm/tlbflush.h>
/* * This routine handles page faults. It determines the address and the @@ -281,6 +282,18 @@ vmalloc_fault: pte_k = pte_offset_kernel(pmd_k, addr); if (!pte_present(*pte_k)) goto no_context; + + /* + * The kernel assumes that TLBs don't cache invalid + * entries, but in RISC-V, SFENCE.VMA specifies an + * ordering constraint, not a cache flush; it is + * necessary even after writing invalid entries. + * Relying on flush_tlb_fix_spurious_fault would + * suffice, but the extra traps reduce + * performance. So, eagerly SFENCE.VMA. + */ + local_flush_tlb_page(addr); + return; } }
From: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com
commit 758f2046ea040773ae8ea7f72dd3bbd8fa984501 upstream.
BPF_ALU64 div/mod operations are currently using signed division, unlike BPF_ALU32 operations. Fix the same. DIV64 and MOD64 overflow tests pass with this fix.
Fixes: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/include/asm/ppc-opcode.h | 1 + arch/powerpc/net/bpf_jit.h | 2 +- arch/powerpc/net/bpf_jit_comp64.c | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-)
--- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -336,6 +336,7 @@ #define PPC_INST_MULLI 0x1c000000 #define PPC_INST_DIVWU 0x7c000396 #define PPC_INST_DIVD 0x7c0003d2 +#define PPC_INST_DIVDU 0x7c000392 #define PPC_INST_RLWINM 0x54000000 #define PPC_INST_RLWIMI 0x50000000 #define PPC_INST_RLDICL 0x78000000 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -116,7 +116,7 @@ ___PPC_RA(a) | IMM_L(i)) #define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \ +#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \ ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \ ___PPC_RS(a) | ___PPC_RB(b)) --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -372,12 +372,12 @@ static int bpf_jit_build_body(struct bpf case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */ case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */ if (BPF_OP(code) == BPF_MOD) { - PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg); + PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg); PPC_MULD(b2p[TMP_REG_1], src_reg, b2p[TMP_REG_1]); PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); } else - PPC_DIVD(dst_reg, dst_reg, src_reg); + PPC_DIVDU(dst_reg, dst_reg, src_reg); break; case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */ case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */ @@ -405,7 +405,7 @@ static int bpf_jit_build_body(struct bpf break; case BPF_ALU64: if (BPF_OP(code) == BPF_MOD) { - PPC_DIVD(b2p[TMP_REG_2], dst_reg, + PPC_DIVDU(b2p[TMP_REG_2], dst_reg, b2p[TMP_REG_1]); PPC_MULD(b2p[TMP_REG_1], b2p[TMP_REG_1], @@ -413,7 +413,7 @@ static int bpf_jit_build_body(struct bpf PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); } else - PPC_DIVD(dst_reg, dst_reg, + PPC_DIVDU(dst_reg, dst_reg, b2p[TMP_REG_1]); break; }
From: Fabio Estevam festevam@gmail.com
commit b25af2ff7c07bd19af74e3f64ff82e2880d13d81 upstream.
Since commit 1e434b703248 ("ARM: imx: update the cpu power up timing setting on i.mx6sx") some characters loss is noticed on i.MX6ULL UART as reported by Christoph Niedermaier.
The intention of such commit was to increase the SW2ISO field for i.MX6SX only, but since cpuidle-imx6sx is also used on i.MX6UL/i.MX6ULL this caused unintended side effects on other SoCs.
Fix this problem by keeping the original SW2ISO value for i.MX6UL/i.MX6ULL and only increase SW2ISO in the i.MX6SX case.
Cc: stable@vger.kernel.org Fixes: 1e434b703248 ("ARM: imx: update the cpu power up timing setting on i.mx6sx") Reported-by: Christoph Niedermaier cniedermaier@dh-electronics.com Signed-off-by: Fabio Estevam festevam@gmail.com Tested-by: Sébastien Szymanski sebastien.szymanski@armadeus.com Tested-by: Christoph Niedermaier cniedermaier@dh-electronics.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/mach-imx/cpuidle-imx6sx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -15,6 +15,7 @@
#include "common.h" #include "cpuidle.h" +#include "hardware.h"
static int imx6sx_idle_finish(unsigned long val) { @@ -110,7 +111,7 @@ int __init imx6sx_cpuidle_init(void) * except for power up sw2iso which need to be * larger than LDO ramp up time. */ - imx_gpc_set_arm_power_up_timing(0xf, 1); + imx_gpc_set_arm_power_up_timing(cpu_is_imx6sx() ? 0xf : 0x2, 1); imx_gpc_set_arm_power_down_timing(1, 1);
return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
From: Faiz Abbas faiz_abbas@ti.com
commit c3c0b70cd3f801bded7a548198ee1c9851a0ca82 upstream.
Update the MMC2_HS200_MANUAL1 iodelay values to match with the latest dra76x data manual[1]. The new iodelay values will have better marginality and should prevent issues in corner cases.
Also this particular pinctrl-array is using spaces instead of tabs for spacing between the values and the comments. Fix this as well.
[1] http://www.ti.com/lit/ds/symlink/dra76p.pdf
Cc: stable@vger.kernel.org Signed-off-by: Faiz Abbas faiz_abbas@ti.com [tony@atomide.com: updated description with a bit more info] Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-)
--- a/arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi +++ b/arch/arm/boot/dts/dra76x-mmc-iodelay.dtsi @@ -22,7 +22,7 @@ * * Datamanual Revisions: * - * DRA76x Silicon Revision 1.0: SPRS993A, Revised July 2017 + * DRA76x Silicon Revision 1.0: SPRS993E, Revised December 2018 * */
@@ -169,25 +169,25 @@ /* Corresponds to MMC2_HS200_MANUAL1 in datamanual */ mmc2_iodelay_hs200_conf: mmc2_iodelay_hs200_conf { pinctrl-pin-array = < - 0x190 A_DELAY_PS(384) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ - 0x194 A_DELAY_PS(0) G_DELAY_PS(174) /* CFG_GPMC_A19_OUT */ - 0x1a8 A_DELAY_PS(410) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ - 0x1ac A_DELAY_PS(85) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ - 0x1b4 A_DELAY_PS(468) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ - 0x1b8 A_DELAY_PS(139) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ - 0x1c0 A_DELAY_PS(676) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ - 0x1c4 A_DELAY_PS(69) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ - 0x1d0 A_DELAY_PS(1062) G_DELAY_PS(154) /* CFG_GPMC_A23_OUT */ - 0x1d8 A_DELAY_PS(640) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ - 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ - 0x1e4 A_DELAY_PS(356) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ - 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ - 0x1f0 A_DELAY_PS(579) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ - 0x1f4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ - 0x1fc A_DELAY_PS(435) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ - 0x200 A_DELAY_PS(36) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ - 0x364 A_DELAY_PS(759) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ - 0x368 A_DELAY_PS(72) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(384) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(350) G_DELAY_PS(174) /* CFG_GPMC_A19_OUT */ + 0x1a8 A_DELAY_PS(410) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(335) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b4 A_DELAY_PS(468) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(339) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c0 A_DELAY_PS(676) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(219) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(1062) G_DELAY_PS(154) /* CFG_GPMC_A23_OUT */ + 0x1d8 A_DELAY_PS(640) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(150) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e4 A_DELAY_PS(356) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(150) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f0 A_DELAY_PS(579) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(200) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1fc A_DELAY_PS(435) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(236) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x364 A_DELAY_PS(759) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(372) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ >; };
From: Faiz Abbas faiz_abbas@ti.com
commit 88a748419b84187fd1da05637b8e5928b04a1e06 upstream.
If UHS speed modes are enabled, a compatible SD card switches down to 1.8V during enumeration. If after this a software reboot/crash takes place and on-chip ROM tries to enumerate the SD card, the difference in IO voltages (host @ 3.3V and card @ 1.8V) may end up damaging the card.
The fix for this is to have support for power cycling the card in hardware (with a PORz/soft-reset line causing a power cycle of the card). Since am571x-, am572x- and am574x-idk don't have this capability, disable voltage switching for these boards.
The major effect of this is that the maximum supported speed mode is now high speed(50 MHz) down from SDR104(200 MHz).
Cc: stable@vger.kernel.org Signed-off-by: Faiz Abbas faiz_abbas@ti.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/am57xx-idk-common.dtsi | 1 + 1 file changed, 1 insertion(+)
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -410,6 +410,7 @@ vqmmc-supply = <&ldo1_reg>; bus-width = <4>; cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */ + no-1-8-v; };
&mmc2 {
From: Anisse Astier aastier@freebox.fr
commit 35341ca0614ab13e1ef34ad4f29a39e15ef31fa8 upstream.
Pulling linux/prctl.h into asm/ptrace.h in the arm64 UAPI headers causes userspace build issues for any program (e.g. strace and qemu) that includes both <sys/prctl.h> and <linux/ptrace.h> when using musl libc:
| error: redefinition of 'struct prctl_mm_map' | struct prctl_mm_map {
See https://github.com/foundriesio/meta-lmp/commit/6d4a106e191b5d79c41b9ac78fd32... for a public example of people working around this issue.
Although it's a bit grotty, fix this breakage by duplicating the prctl constant definitions. Since these are part of the kernel ABI, they cannot be changed in future and so it's not the end of the world to have them open-coded.
Fixes: 43d4da2c45b2 ("arm64/sve: ptrace and ELF coredump support") Cc: stable@vger.kernel.org Acked-by: Dave Martin Dave.Martin@arm.com Signed-off-by: Anisse Astier aastier@freebox.fr Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/include/uapi/asm/ptrace.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
--- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -64,8 +64,6 @@
#ifndef __ASSEMBLY__
-#include <linux/prctl.h> - /* * User structures for general purpose, floating point and debug registers. */ @@ -112,10 +110,10 @@ struct user_sve_header {
/* * Common SVE_PT_* flags: - * These must be kept in sync with prctl interface in <linux/ptrace.h> + * These must be kept in sync with prctl interface in <linux/prctl.h> */ -#define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16) -#define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16) +#define SVE_PT_VL_INHERIT ((1 << 17) /* PR_SVE_VL_INHERIT */ >> 16) +#define SVE_PT_VL_ONEXEC ((1 << 18) /* PR_SVE_SET_VL_ONEXEC */ >> 16)
/*
From: Anisse Astier aastier@freebox.fr
commit adeaa21a4b6954e878f3f7d1c5659ed9c1fe567a upstream.
Fix ssbd.c which depends implicitly on asm/ptrace.h including linux/prctl.h (through for example linux/compat.h, then linux/time.h, linux/seqlock.h, linux/spinlock.h and linux/irqflags.h), and uses PR_SPEC* defines.
This is an issue since we'll soon be removing the include from asm/ptrace.h.
Fixes: 9cdc0108baa8 ("arm64: ssbd: Add prctl interface for per-thread mitigation") Cc: stable@vger.kernel.org Signed-off-by: Anisse Astier aastier@freebox.fr Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/kernel/ssbd.c | 1 + 1 file changed, 1 insertion(+)
--- a/arch/arm64/kernel/ssbd.c +++ b/arch/arm64/kernel/ssbd.c @@ -4,6 +4,7 @@ */
#include <linux/errno.h> +#include <linux/prctl.h> #include <linux/sched.h> #include <linux/thread_info.h>
From: Thomas Hellstrom thellstrom@vmware.com
commit cc0ba0d8624f210995924bb57a8b181ce8976606 upstream.
The HB port may not be available for various reasons. Either it has been disabled by a config option or by the hypervisor for other reasons. In that case, make sure we have a backup plan and use the backdoor port instead with a performance penalty.
Cc: stable@vger.kernel.org Fixes: 89da76fde68d ("drm/vmwgfx: Add VMWare host messaging capability") Signed-off-by: Thomas Hellstrom thellstrom@vmware.com Reviewed-by: Deepak Rawat drawat@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 146 ++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 29 deletions(-)
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -136,6 +136,114 @@ static int vmw_close_channel(struct rpc_ return 0; }
+/** + * vmw_port_hb_out - Send the message payload either through the + * high-bandwidth port if available, or through the backdoor otherwise. + * @channel: The rpc channel. + * @msg: NULL-terminated message. + * @hb: Whether the high-bandwidth port is available. + * + * Return: The port status. + */ +static unsigned long vmw_port_hb_out(struct rpc_channel *channel, + const char *msg, bool hb) +{ + unsigned long si, di, eax, ebx, ecx, edx; + unsigned long msg_len = strlen(msg); + + if (hb) { + unsigned long bp = channel->cookie_high; + + si = (uintptr_t) msg; + di = channel->cookie_low; + + VMW_PORT_HB_OUT( + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, + msg_len, si, di, + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, bp, + eax, ebx, ecx, edx, si, di); + + return ebx; + } + + /* HB port not available. Send the message 4 bytes at a time. */ + ecx = MESSAGE_STATUS_SUCCESS << 16; + while (msg_len && (HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS)) { + unsigned int bytes = min_t(size_t, msg_len, 4); + unsigned long word = 0; + + memcpy(&word, msg, bytes); + msg_len -= bytes; + msg += bytes; + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16), + word, si, di, + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + } + + return ecx; +} + +/** + * vmw_port_hb_in - Receive the message payload either through the + * high-bandwidth port if available, or through the backdoor otherwise. + * @channel: The rpc channel. + * @reply: Pointer to buffer holding reply. + * @reply_len: Length of the reply. + * @hb: Whether the high-bandwidth port is available. + * + * Return: The port status. + */ +static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, + unsigned long reply_len, bool hb) +{ + unsigned long si, di, eax, ebx, ecx, edx; + + if (hb) { + unsigned long bp = channel->cookie_low; + + si = channel->cookie_high; + di = (uintptr_t) reply; + + VMW_PORT_HB_IN( + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, + reply_len, si, di, + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, bp, + eax, ebx, ecx, edx, si, di); + + return ebx; + } + + /* HB port not available. Retrieve the message 4 bytes at a time. */ + ecx = MESSAGE_STATUS_SUCCESS << 16; + while (reply_len) { + unsigned int bytes = min_t(unsigned long, reply_len, 4); + + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16), + MESSAGE_STATUS_SUCCESS, si, di, + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) + break; + + memcpy(reply, &ebx, bytes); + reply_len -= bytes; + reply += bytes; + } + + return ecx; +}
/** @@ -148,11 +256,10 @@ static int vmw_close_channel(struct rpc_ */ static int vmw_send_msg(struct rpc_channel *channel, const char *msg) { - unsigned long eax, ebx, ecx, edx, si, di, bp; + unsigned long eax, ebx, ecx, edx, si, di; size_t msg_len = strlen(msg); int retries = 0;
- while (retries < RETRIES) { retries++;
@@ -166,23 +273,14 @@ static int vmw_send_msg(struct rpc_chann VMW_HYPERVISOR_MAGIC, eax, ebx, ecx, edx, si, di);
- if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || - (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { - /* Expected success + high-bandwidth. Give up. */ + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { + /* Expected success. Give up. */ return -EINVAL; }
/* Send msg */ - si = (uintptr_t) msg; - di = channel->cookie_low; - bp = channel->cookie_high; - - VMW_PORT_HB_OUT( - (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, - msg_len, si, di, - VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), - VMW_HYPERVISOR_MAGIC, bp, - eax, ebx, ecx, edx, si, di); + ebx = vmw_port_hb_out(channel, msg, + !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) { return 0; @@ -211,7 +309,7 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg); static int vmw_recv_msg(struct rpc_channel *channel, void **msg, size_t *msg_len) { - unsigned long eax, ebx, ecx, edx, si, di, bp; + unsigned long eax, ebx, ecx, edx, si, di; char *reply; size_t reply_len; int retries = 0; @@ -233,8 +331,7 @@ static int vmw_recv_msg(struct rpc_chann VMW_HYPERVISOR_MAGIC, eax, ebx, ecx, edx, si, di);
- if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || - (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { DRM_ERROR("Failed to get reply size for host message.\n"); return -EINVAL; } @@ -252,17 +349,8 @@ static int vmw_recv_msg(struct rpc_chann
/* Receive buffer */ - si = channel->cookie_high; - di = (uintptr_t) reply; - bp = channel->cookie_low; - - VMW_PORT_HB_IN( - (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, - reply_len, si, di, - VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), - VMW_HYPERVISOR_MAGIC, bp, - eax, ebx, ecx, edx, si, di); - + ebx = vmw_port_hb_in(channel, reply, reply_len, + !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { kfree(reply);
From: Gao Xiang gaoxiang25@huawei.com
commit 5efe5137f05bbb4688890620934538c005e7d1d6 upstream.
There are some backward incompatible features pending for months, mainly due to on-disk format expensions.
However, we should ensure that it cannot be mounted with old kernels. Otherwise, it will causes unexpected behaviors.
Fixes: ba2b77a82022 ("staging: erofs: add super block operations") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Gao Xiang gaoxiang25@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/erofs/erofs_fs.h | 13 ++++++++++--- drivers/staging/erofs/internal.h | 2 ++ drivers/staging/erofs/super.c | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-)
--- a/drivers/staging/erofs/erofs_fs.h +++ b/drivers/staging/erofs/erofs_fs.h @@ -17,10 +17,16 @@ #define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2 #define EROFS_SUPER_OFFSET 1024
+/* + * Any bits that aren't in EROFS_ALL_REQUIREMENTS should be + * incompatible with this kernel version. + */ +#define EROFS_ALL_REQUIREMENTS 0 + struct erofs_super_block { /* 0 */__le32 magic; /* in the little endian */ /* 4 */__le32 checksum; /* crc32c(super_block) */ -/* 8 */__le32 features; +/* 8 */__le32 features; /* (aka. feature_compat) */ /* 12 */__u8 blkszbits; /* support block_size == PAGE_SIZE only */ /* 13 */__u8 reserved;
@@ -34,9 +40,10 @@ struct erofs_super_block { /* 44 */__le32 xattr_blkaddr; /* 48 */__u8 uuid[16]; /* 128-bit uuid for volume */ /* 64 */__u8 volume_name[16]; /* volume name */ +/* 80 */__le32 requirements; /* (aka. feature_incompat) */
-/* 80 */__u8 reserved2[48]; /* 128 bytes */ -} __packed; +/* 84 */__u8 reserved2[44]; +} __packed; /* 128 bytes */
#define __EROFS_BIT(_prefix, _cur, _pre) enum { \ _prefix ## _cur ## _BIT = _prefix ## _pre ## _BIT + \ --- a/drivers/staging/erofs/internal.h +++ b/drivers/staging/erofs/internal.h @@ -111,6 +111,8 @@ struct erofs_sb_info {
u8 uuid[16]; /* 128-bit uuid for volume */ u8 volume_name[16]; /* volume name */ + u32 requirements; + char *dev_name;
unsigned int mount_opt; --- a/drivers/staging/erofs/super.c +++ b/drivers/staging/erofs/super.c @@ -75,6 +75,22 @@ static void destroy_inode(struct inode * call_rcu(&inode->i_rcu, i_callback); }
+static bool check_layout_compatibility(struct super_block *sb, + struct erofs_super_block *layout) +{ + const unsigned int requirements = le32_to_cpu(layout->requirements); + + EROFS_SB(sb)->requirements = requirements; + + /* check if current kernel meets all mandatory requirements */ + if (requirements & (~EROFS_ALL_REQUIREMENTS)) { + errln("unidentified requirements %x, please upgrade kernel version", + requirements & ~EROFS_ALL_REQUIREMENTS); + return false; + } + return true; +} + static int superblock_read(struct super_block *sb) { struct erofs_sb_info *sbi; @@ -108,6 +124,9 @@ static int superblock_read(struct super_ goto out; }
+ if (!check_layout_compatibility(sb, layout)) + goto out; + sbi->blocks = le32_to_cpu(layout->blocks); sbi->meta_blkaddr = le32_to_cpu(layout->meta_blkaddr); #ifdef CONFIG_EROFS_FS_XATTR
From: Marcel Holtmann marcel@holtmann.org
commit d5bb334a8e171b262e48f378bd2096c0ea458265 upstream.
The minimum encryption key size for LE connections is 56 bits and to align LE with BR/EDR, enforce 56 bits of minimum encryption key size for BR/EDR connections as well.
Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Johan Hedberg johan.hedberg@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/net/bluetooth/hci_core.h | 3 +++ net/bluetooth/hci_conn.c | 8 ++++++++ 2 files changed, 11 insertions(+)
--- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -182,6 +182,9 @@ struct adv_info {
#define HCI_MAX_SHORT_NAME_LENGTH 10
+/* Min encryption key size to match with SMP */ +#define HCI_MIN_ENC_KEY_SIZE 7 + /* Default LE RPA expiry time, 15 minutes */ #define HCI_DEFAULT_RPA_TIMEOUT (15 * 60)
--- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1276,6 +1276,14 @@ int hci_conn_check_link_mode(struct hci_ !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) return 0;
+ /* The minimum encryption key size needs to be enforced by the + * host stack before establishing any L2CAP connections. The + * specification in theory allows a minimum of 1, but to align + * BR/EDR and LE transports, a minimum of 7 is chosen. + */ + if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE) + return 0; + return 1; }
From: Marcel Holtmann marcel@holtmann.org
commit 693cd8ce3f882524a5d06f7800dd8492411877b3 upstream.
When trying to align the minimum encryption key size requirement for Bluetooth connections, it turns out doing this in a central location in the HCI connection handling code is not possible.
Original Bluetooth version up to 2.0 used a security model where the L2CAP service would enforce authentication and encryption. Starting with Bluetooth 2.1 and Secure Simple Pairing that model has changed into that the connection initiator is responsible for providing an encrypted ACL link before any L2CAP communication can happen.
Now connecting Bluetooth 2.1 or later devices with Bluetooth 2.0 and before devices are causing a regression. The encryption key size check needs to be moved out of the HCI connection handling into the L2CAP channel setup.
To achieve this, the current check inside hci_conn_security() has been moved into l2cap_check_enc_key_size() helper function and then called from four decisions point inside L2CAP to cover all combinations of Secure Simple Pairing enabled devices and device using legacy pairing and legacy service security model.
Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203643 Signed-off-by: Marcel Holtmann marcel@holtmann.org Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/bluetooth/hci_conn.c | 18 +++++++++--------- net/bluetooth/l2cap_core.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-)
--- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1276,14 +1276,6 @@ int hci_conn_check_link_mode(struct hci_ !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) return 0;
- /* The minimum encryption key size needs to be enforced by the - * host stack before establishing any L2CAP connections. The - * specification in theory allows a minimum of 1, but to align - * BR/EDR and LE transports, a minimum of 7 is chosen. - */ - if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE) - return 0; - return 1; }
@@ -1400,8 +1392,16 @@ auth: return 0;
encrypt: - if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) + if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) { + /* Ensure that the encryption key size has been read, + * otherwise stall the upper layer responses. + */ + if (!conn->enc_key_size) + return 0; + + /* Nothing else needed, all requirements are met */ return 1; + }
hci_conn_encrypt(conn); return 0; --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1340,6 +1340,21 @@ static void l2cap_request_info(struct l2 sizeof(req), &req); }
+static bool l2cap_check_enc_key_size(struct hci_conn *hcon) +{ + /* The minimum encryption key size needs to be enforced by the + * host stack before establishing any L2CAP connections. The + * specification in theory allows a minimum of 1, but to align + * BR/EDR and LE transports, a minimum of 7 is chosen. + * + * This check might also be called for unencrypted connections + * that have no key size requirements. Ensure that the link is + * actually encrypted before enforcing a key size. + */ + return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || + hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE); +} + static void l2cap_do_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1357,9 +1372,14 @@ static void l2cap_do_start(struct l2cap_ if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) return;
- if (l2cap_chan_check_security(chan, true) && - __l2cap_no_conn_pending(chan)) + if (!l2cap_chan_check_security(chan, true) || + !__l2cap_no_conn_pending(chan)) + return; + + if (l2cap_check_enc_key_size(conn->hcon)) l2cap_start_connection(chan); + else + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); }
static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) @@ -1438,7 +1458,10 @@ static void l2cap_conn_start(struct l2ca continue; }
- l2cap_start_connection(chan); + if (l2cap_check_enc_key_size(conn->hcon)) + l2cap_start_connection(chan); + else + l2cap_chan_close(chan, ECONNREFUSED);
} else if (chan->state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; @@ -7455,7 +7478,7 @@ static void l2cap_security_cfm(struct hc }
if (chan->state == BT_CONNECT) { - if (!status) + if (!status && l2cap_check_enc_key_size(hcon)) l2cap_start_connection(chan); else __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); @@ -7464,7 +7487,7 @@ static void l2cap_security_cfm(struct hc struct l2cap_conn_rsp rsp; __u16 res, stat;
- if (!status) { + if (!status && l2cap_check_enc_key_size(hcon)) { if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { res = L2CAP_CR_PEND; stat = L2CAP_CS_AUTHOR_PEND;
From: Steve French stfrench@microsoft.com
commit 8d526d62db907e786fd88948c75d1833d82bd80e upstream.
Some servers such as Windows 10 will return STATUS_INSUFFICIENT_RESOURCES as the number of simultaneous SMB3 requests grows (even though the client has sufficient credits). Return EAGAIN on STATUS_INSUFFICIENT_RESOURCES so that we can retry writes which fail with this status code.
This (for example) fixes large file copies to Windows 10 on fast networks.
Signed-off-by: Steve French stfrench@microsoft.com CC: Stable stable@vger.kernel.org Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Reviewed-by: Pavel Shilovsky pshilov@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2maperror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c @@ -457,7 +457,7 @@ static const struct status_to_posix_erro {STATUS_FILE_INVALID, -EIO, "STATUS_FILE_INVALID"}, {STATUS_ALLOTTED_SPACE_EXCEEDED, -EIO, "STATUS_ALLOTTED_SPACE_EXCEEDED"}, - {STATUS_INSUFFICIENT_RESOURCES, -EREMOTEIO, + {STATUS_INSUFFICIENT_RESOURCES, -EAGAIN, "STATUS_INSUFFICIENT_RESOURCES"}, {STATUS_DFS_EXIT_PATH_FOUND, -EIO, "STATUS_DFS_EXIT_PATH_FOUND"}, {STATUS_DEVICE_DATA_ERROR, -EIO, "STATUS_DEVICE_DATA_ERROR"},
From: Eric Biggers ebiggers@google.com
commit 4f488fbca2a86cc7714a128952eead92cac279ab upstream.
In wiphy_new_nm(), if an error occurs after dev_set_name() and device_initialize() have already been called, it's necessary to call put_device() (via wiphy_free()) to avoid a memory leak.
Reported-by: syzbot+7fddca22578bc67c3fe4@syzkaller.appspotmail.com Fixes: 1f87f7d3a3b4 ("cfg80211: add rfkill support") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/wireless/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -498,7 +498,7 @@ use_default_name: &rdev->rfkill_ops, rdev);
if (!rdev->rfkill) { - kfree(rdev); + wiphy_free(&rdev->wiphy); return NULL; }
Hi!
From: Eric Biggers ebiggers@google.com
commit 4f488fbca2a86cc7714a128952eead92cac279ab upstream.
In wiphy_new_nm(), if an error occurs after dev_set_name() and device_initialize() have already been called, it's necessary to call put_device() (via wiphy_free()) to avoid a memory leak.
....
--- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -498,7 +498,7 @@ use_default_name: &rdev->rfkill_ops, rdev); if (!rdev->rfkill) {
kfree(rdev);
return NULL; }wiphy_free(&rdev->wiphy);
Is kfree(rdev) still neccessary? drivers/net/wireless/marvell/libertas/cfg.c seems to suggest so.
Best regards, Pavel
On Tue, Jun 25, 2019 at 11:51:36PM +0200, Pavel Machek wrote:
Hi!
From: Eric Biggers ebiggers@google.com
commit 4f488fbca2a86cc7714a128952eead92cac279ab upstream.
In wiphy_new_nm(), if an error occurs after dev_set_name() and device_initialize() have already been called, it's necessary to call put_device() (via wiphy_free()) to avoid a memory leak.
....
--- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -498,7 +498,7 @@ use_default_name: &rdev->rfkill_ops, rdev); if (!rdev->rfkill) {
kfree(rdev);
return NULL; }wiphy_free(&rdev->wiphy);
Is kfree(rdev) still neccessary? drivers/net/wireless/marvell/libertas/cfg.c seems to suggest so.
No, because it's freed by:
wiphy_free() => put_device() => wiphy_dev_release() => cfg80211_dev_free() => kfree(rdev)
drivers/net/wireless/marvell/libertas/cfg.c is different because there the struct wiphy is separately allocated from the struct wireless_dev that's being freed afterwards.
- Eric
From: Johannes Berg johannes.berg@intel.com
commit 588f7d39b3592a36fb7702ae3b8bdd9be4621e2f upstream.
When receiving a robust management frame, drop it if we don't have rx->sta since then we don't have a security association and thus couldn't possibly validate the frame.
Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/mac80211/rx.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3752,6 +3752,8 @@ static bool ieee80211_accept_frame(struc case NL80211_IFTYPE_STATION: if (!bssid && !sdata->u.mgd.use_4addr) return false; + if (ieee80211_is_robust_mgmt_frame(skb) && !rx->sta) + return false; if (multicast) return true; return ether_addr_equal(sdata->vif.addr, hdr->addr1);
From: Manikanta Pubbisetty mpubbise@codeaurora.org
commit 33d915d9e8ce811d8958915ccd18d71a66c7c495 upstream.
As per the current design, in the case of sw crypto controlled devices, it is the device which advertises the support for AP/VLAN iftype based on it's ability to tranmsit packets encrypted in software (In VLAN functionality, group traffic generated for a specific VLAN group is always encrypted in software). Commit db3bdcb9c3ff ("mac80211: allow AP_VLAN operation on crypto controlled devices") has introduced this change.
Since 4addr AP operation also uses AP/VLAN iftype, this conditional way of advertising AP/VLAN support has broken 4addr AP mode operation on crypto controlled devices which do not support VLAN functionality.
In the case of ath10k driver, not all firmwares have support for VLAN functionality but all can support 4addr AP operation. Because AP/VLAN support is not advertised for these devices, 4addr AP operations are also blocked.
Fix this by allowing 4addr operation on devices which do not support AP/VLAN iftype but can support 4addr AP operation (decision is based on the wiphy flag WIPHY_FLAG_4ADDR_AP).
Cc: stable@vger.kernel.org Fixes: db3bdcb9c3ff ("mac80211: allow AP_VLAN operation on crypto controlled devices") Signed-off-by: Manikanta Pubbisetty mpubbise@codeaurora.org Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/net/cfg80211.h | 3 ++- net/mac80211/util.c | 4 +++- net/wireless/core.c | 6 +++++- net/wireless/nl80211.c | 8 ++++++-- 4 files changed, 16 insertions(+), 5 deletions(-)
--- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3448,7 +3448,8 @@ struct cfg80211_ops { * on wiphy_new(), but can be changed by the driver if it has a good * reason to override the default * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station - * on a VLAN interface) + * on a VLAN interface). This flag also serves an extra purpose of + * supporting 4ADDR AP mode on devices which do not support AP/VLAN iftype. * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the * control port protocol ethertype. The device also honours the --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3523,7 +3523,9 @@ int ieee80211_check_combinations(struct }
/* Always allow software iftypes */ - if (local->hw.wiphy->software_iftypes & BIT(iftype)) { + if (local->hw.wiphy->software_iftypes & BIT(iftype) || + (iftype == NL80211_IFTYPE_AP_VLAN && + local->hw.wiphy->flags & WIPHY_FLAG_4ADDR_AP)) { if (radar_detect) return -EINVAL; return 0; --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1335,8 +1335,12 @@ static int cfg80211_netdev_notifier_call } break; case NETDEV_PRE_UP: - if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) + if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)) && + !(wdev->iftype == NL80211_IFTYPE_AP_VLAN && + rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP && + wdev->use_4addr)) return notifier_from_errno(-EOPNOTSUPP); + if (rfkill_blocked(rdev->rfkill)) return notifier_from_errno(-ERFKILL); break; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3191,8 +3191,7 @@ static int nl80211_new_interface(struct return -EINVAL; }
- if (!rdev->ops->add_virtual_intf || - !(rdev->wiphy.interface_modes & (1 << type))) + if (!rdev->ops->add_virtual_intf) return -EOPNOTSUPP;
if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN || @@ -3211,6 +3210,11 @@ static int nl80211_new_interface(struct return err; }
+ if (!(rdev->wiphy.interface_modes & (1 << type)) && + !(type == NL80211_IFTYPE_AP_VLAN && params.use_4addr && + rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)) + return -EOPNOTSUPP; + err = nl80211_parse_mon_options(rdev, type, info, ¶ms); if (err < 0) return err;
From: Yu Wang yyuwang@codeaurora.org
commit 79c92ca42b5a3e0ea172ea2ce8df8e125af237da upstream.
When receiving a deauthentication/disassociation frame from a TDLS peer, a station should not disconnect the current AP, but only disable the current TDLS link if it's enabled.
Without this change, a TDLS issue can be reproduced by following the steps as below:
1. STA-1 and STA-2 are connected to AP, bidirection traffic is running between STA-1 and STA-2. 2. Set up TDLS link between STA-1 and STA-2, stay for a while, then teardown TDLS link. 3. Repeat step #2 and monitor the connection between STA and AP.
During the test, one STA may send a deauthentication/disassociation frame to another, after TDLS teardown, with reason code 6/7, which means: Class 2/3 frame received from nonassociated STA.
On receive this frame, the receiver STA will disconnect the current AP and then reconnect. It's not a expected behavior, purpose of this frame should be disabling the TDLS link, not the link with AP.
Cc: stable@vger.kernel.org Signed-off-by: Yu Wang yyuwang@codeaurora.org Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/mlme.c | 12 +++++++++++- net/mac80211/tdls.c | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-)
--- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2183,6 +2183,9 @@ void ieee80211_tdls_cancel_channel_switc const u8 *addr); void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata); void ieee80211_tdls_chsw_work(struct work_struct *wk); +void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, + const u8 *peer, u16 reason); +const char *ieee80211_get_reason_code_string(u16 reason_code);
extern const struct ethtool_ops ieee80211_ethtool_ops;
--- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2868,7 +2868,7 @@ static void ieee80211_rx_mgmt_auth(struc #define case_WLAN(type) \ case WLAN_REASON_##type: return #type
-static const char *ieee80211_get_reason_code_string(u16 reason_code) +const char *ieee80211_get_reason_code_string(u16 reason_code) { switch (reason_code) { case_WLAN(UNSPECIFIED); @@ -2933,6 +2933,11 @@ static void ieee80211_rx_mgmt_deauth(str if (len < 24 + 2) return;
+ if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) { + ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code); + return; + } + if (ifmgd->associated && ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) { const u8 *bssid = ifmgd->associated->bssid; @@ -2982,6 +2987,11 @@ static void ieee80211_rx_mgmt_disassoc(s
reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
+ if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) { + ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code); + return; + } + sdata_info(sdata, "disassociated from %pM (Reason: %u=%s)\n", mgmt->sa, reason_code, ieee80211_get_reason_code_string(reason_code)); --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -1992,3 +1992,26 @@ void ieee80211_tdls_chsw_work(struct wor } rtnl_unlock(); } + +void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, + const u8 *peer, u16 reason) +{ + struct ieee80211_sta *sta; + + rcu_read_lock(); + sta = ieee80211_find_sta(&sdata->vif, peer); + if (!sta || !sta->tdls) { + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + + tdls_dbg(sdata, "disconnected from TDLS peer %pM (Reason: %u=%s)\n", + peer, reason, + ieee80211_get_reason_code_string(reason)); + + ieee80211_tdls_oper_request(&sdata->vif, peer, + NL80211_TDLS_TEARDOWN, + WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, + GFP_ATOMIC); +}
From: Andy Strohman andrew@andrewstrohman.com
commit f77bf4863dc2218362f4227d56af4a5f3f08830c upstream.
When dumping stations, memory allocated for station_info's pertid member will leak if the nl80211 header cannot be added to the sk_buff due to insufficient tail room.
I noticed this leak in the kmalloc-2048 cache.
Cc: stable@vger.kernel.org Fixes: 8689c051a201 ("cfg80211: dynamically allocate per-tid stats for station info") Signed-off-by: Andy Strohman andy@uplevelsystems.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/wireless/nl80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4611,8 +4611,10 @@ static int nl80211_send_station(struct s struct nlattr *sinfoattr, *bss_param;
hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); - if (!hdr) + if (!hdr) { + cfg80211_sinfo_release_content(sinfo); return -1; + }
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
From: Jouni Malinen j@w1.fi
commit a71fd9dac23613d96ba3c05619a8ef4fd6cdf9b9 upstream.
ieee80211_aes_gmac() uses the mic argument directly in sg_set_buf() and that does not allow use of stack memory (e.g., BUG_ON() is hit in sg_set_buf() with CONFIG_DEBUG_SG). BIP GMAC TX side is fine for this since it can use the skb data buffer, but the RX side was using a stack variable for deriving the local MIC value to compare against the received one.
Fix this by allocating heap memory for the mic buffer.
This was found with hwsim test case ap_cipher_bip_gmac_128 hitting that BUG_ON() and kernel panic.
Cc: stable@vger.kernel.org Signed-off-by: Jouni Malinen j@w1.fi Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/mac80211/wpa.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -1175,7 +1175,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_key *key = rx->key; struct ieee80211_mmie_16 *mmie; - u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; + u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (!ieee80211_is_mgmt(hdr->frame_control)) @@ -1206,13 +1206,18 @@ ieee80211_crypto_aes_gmac_decrypt(struct memcpy(nonce, hdr->addr2, ETH_ALEN); memcpy(nonce + ETH_ALEN, ipn, 6);
+ mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC); + if (!mic) + return RX_DROP_UNUSABLE; if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, skb->data + 24, skb->len - 24, mic) < 0 || crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { key->u.aes_gmac.icverrors++; + kfree(mic); return RX_DROP_UNUSABLE; } + kfree(mic); }
memcpy(key->u.aes_gmac.rx_pn, ipn, 6);
From: James Morse james.morse@arm.com
commit 87d3aa28f345bea77c396855fa5d5fec4c24461f upstream.
When a new control group is created __init_one_rdt_domain() walks all the other closids to calculate the sets of used and unused bits.
If it discovers a pseudo_locksetup group, it breaks out of the loop. This means any later closid doesn't get its used bits added to used_b. These bits will then get set in unused_b, and added to the new control group's configuration, even if they were marked as exclusive for a later closid.
When encountering a pseudo_locksetup group, we should continue. This is because "a resource group enters 'pseudo-locked' mode after the schemata is written while the resource group is in 'pseudo-locksetup' mode." When we find a pseudo_locksetup group, its configuration is expected to be overwritten, we can skip it.
Fixes: dfe9674b04ff6 ("x86/intel_rdt: Enable entering of pseudo-locksetup mode") Signed-off-by: James Morse james.morse@arm.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Acked-by: Reinette Chatre reinette.chatre@intel.com Cc: Fenghua Yu fenghua.yu@intel.com Cc: Borislav Petkov bp@alien8.de Cc: H Peter Avin hpa@zytor.com Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190603172531.178830-1-james.morse@arm.com [Dropped comment due to lack of space] Signed-off-by: James Morse james.morse@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -2379,7 +2379,7 @@ static int rdtgroup_init_alloc(struct rd if (closid_allocated(i) && i != closid) { mode = rdtgroup_mode_by_closid(i); if (mode == RDT_MODE_PSEUDO_LOCKSETUP) - break; + continue; used_b |= *ctrl; if (mode == RDT_MODE_SHAREABLE) d->new_ctrl |= *ctrl;
stable-rc/linux-4.19.y boot: 120 boots: 0 failed, 113 passed with 7 offline (v4.19.55-91-gc491b02eb03a)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.19.y/kernel/v4.19... Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.19.y/kernel/v4.19.55-91-...
Tree: stable-rc Branch: linux-4.19.y Git Describe: v4.19.55-91-gc491b02eb03a Git Commit: c491b02eb03a59e32d78bb8d4ee00c154a694267 Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git Tested: 67 unique boards, 24 SoC families, 15 builds out of 205
Offline Platforms:
arm:
qcom_defconfig: gcc-8 qcom-apq8064-cm-qs600: 1 offline lab qcom-apq8064-ifc6410: 1 offline lab
sunxi_defconfig: gcc-8 sun5i-r8-chip: 1 offline lab
multi_v7_defconfig: gcc-8 qcom-apq8064-cm-qs600: 1 offline lab qcom-apq8064-ifc6410: 1 offline lab sun5i-r8-chip: 1 offline lab
arm64:
defconfig: gcc-8 apq8016-sbc: 1 offline lab
--- For more info write to info@kernelci.org
On 6/24/19 2:55 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.19.56 release. There are 90 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 Wed 26 Jun 2019 09:22:03 AM UTC. Anything received after that time might be too late.
For v4.19.55-92-gd8e5ade617e9:
Build results: total: 156 pass: 156 fail: 0 Qemu test results: total: 364 pass: 364 fail: 0
Guenter
On Mon, 24 Jun 2019 at 15:33, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.19.56 release. There are 90 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 Wed 26 Jun 2019 09:22:03 AM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.56-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Summary ------------------------------------------------------------------------
kernel: 4.19.56-rc2 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.19.y git commit: d8e5ade617e917a499d5d59b24e19e71f80886a8 git describe: v4.19.55-92-gd8e5ade617e9 Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.19-oe/build/v4.19.55-92...
No regressions (compared to build v4.19.55)
No fixes (compared to build v4.19.55)
Ran 25252 total tests in the following environments and test suites.
Environments -------------- - dragonboard-410c - arm64 - hi6220-hikey - arm64 - i386 - juno-r2 - arm64 - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - arm - x86_64
Test Suites ----------- * build * install-android-platform-tools-r2600 * kselftest * libgpiod * libhugetlbfs * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-timers-tests * perf * spectre-meltdown-checker-test * v4l2-compliance * network-basic-tests * ltp-open-posix-tests * kvm-unit-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none
On 24/06/2019 10:55, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.19.56 release. There are 90 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 Wed 26 Jun 2019 09:22:03 AM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.56-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v4.19: 12 builds: 12 pass, 0 fail 22 boots: 22 pass, 0 fail 32 tests: 32 pass, 0 fail
Linux version: 4.19.56-rc1-gc491b02eb03a Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Cheers Jon
linux-stable-mirror@lists.linaro.org