From 87f911ceb8ff76c9100cd67e2bdc292994fe7102 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 13 Apr 2021 00:19:18 +0200 Subject: [PATCH] add upstream patches (#2743) * add upstream patches * Add more patches Co-authored-by: Igor Pecovnik --- .../archive/sunxi-5.10/patch-5.10.21-22.patch | 1550 ++ .../archive/sunxi-5.10/patch-5.10.22-23.patch | 2146 +++ .../archive/sunxi-5.10/patch-5.10.23-24.patch | 11590 ++++++++++++++ .../archive/sunxi-5.10/patch-5.10.24-25.patch | 1108 ++ .../archive/sunxi-5.10/patch-5.10.25-26.patch | 12913 ++++++++++++++++ .../archive/sunxi-5.10/patch-5.10.26-27.patch | 8926 +++++++++++ .../archive/sunxi-5.10/patch-5.10.27-28.patch | 7730 +++++++++ .../archive/sunxi-5.10/patch-5.10.28-29.patch | 1006 ++ 8 files changed, 46969 insertions(+) create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.21-22.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.22-23.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.23-24.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.24-25.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.25-26.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.26-27.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.27-28.patch create mode 100644 patch/kernel/archive/sunxi-5.10/patch-5.10.28-29.patch diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.21-22.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.21-22.patch new file mode 100644 index 0000000000..cb507f769c --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.21-22.patch @@ -0,0 +1,1550 @@ +diff --git a/Makefile b/Makefile +index 98ae9007e8a52..12a2a7271fcb0 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 21 ++SUBLEVEL = 22 + EXTRAVERSION = + NAME = Dare mighty things + +diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +index 724ee179b316e..fae48efae83e9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +@@ -227,8 +227,6 @@ + "timing-adjustment"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; +- resets = <&reset RESET_ETHERNET>; +- reset-names = "stmmaceth"; + status = "disabled"; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +index a6127002573bd..959b299344e54 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +@@ -224,8 +224,6 @@ + "timing-adjustment"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; +- resets = <&reset RESET_ETHERNET>; +- reset-names = "stmmaceth"; + status = "disabled"; + + mdio0: mdio { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 726b91d3a905a..0edd137151f89 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -13,7 +13,6 @@ + #include + #include + #include +-#include + #include + + / { +@@ -576,8 +575,6 @@ + interrupt-names = "macirq"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; +- resets = <&reset RESET_ETHERNET>; +- reset-names = "stmmaceth"; + power-domains = <&pwrc PWRC_GXBB_ETHERNET_MEM_ID>; + status = "disabled"; + }; +diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c +index 00576a960f11f..b913844ab7404 100644 +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -42,8 +43,6 @@ + #include + #include + +-#define ARM64_ZONE_DMA_BITS 30 +- + /* + * We need to be able to catch inadvertent references to memstart_addr + * that occur (potentially in generic code) before arm64_memblock_init() +@@ -188,8 +187,14 @@ static phys_addr_t __init max_zone_phys(unsigned int zone_bits) + static void __init zone_sizes_init(unsigned long min, unsigned long max) + { + unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; ++ unsigned int __maybe_unused acpi_zone_dma_bits; ++ unsigned int __maybe_unused dt_zone_dma_bits; + + #ifdef CONFIG_ZONE_DMA ++ acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); ++ dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL)); ++ zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits); ++ arm64_dma_phys_limit = max_zone_phys(zone_dma_bits); + max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); + #endif + #ifdef CONFIG_ZONE_DMA32 +@@ -376,18 +381,11 @@ void __init arm64_memblock_init(void) + + early_init_fdt_scan_reserved_mem(); + +- if (IS_ENABLED(CONFIG_ZONE_DMA)) { +- zone_dma_bits = ARM64_ZONE_DMA_BITS; +- arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS); +- } +- + if (IS_ENABLED(CONFIG_ZONE_DMA32)) + arm64_dma32_phys_limit = max_zone_phys(32); + else + arm64_dma32_phys_limit = PHYS_MASK + 1; + +- reserve_crashkernel(); +- + reserve_elfcorehdr(); + + high_memory = __va(memblock_end_of_DRAM() - 1) + 1; +@@ -427,6 +425,12 @@ void __init bootmem_init(void) + sparse_init(); + zone_sizes_init(min, max); + ++ /* ++ * request_standard_resources() depends on crashkernel's memory being ++ * reserved, so do it here. ++ */ ++ reserve_crashkernel(); ++ + memblock_dump_all(); + } + +diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c +index 94f34109695c9..2494138a6905e 100644 +--- a/drivers/acpi/arm64/iort.c ++++ b/drivers/acpi/arm64/iort.c +@@ -1730,3 +1730,58 @@ void __init acpi_iort_init(void) + + iort_init_platform_devices(); + } ++ ++#ifdef CONFIG_ZONE_DMA ++/* ++ * Extract the highest CPU physical address accessible to all DMA masters in ++ * the system. PHYS_ADDR_MAX is returned when no constrained device is found. ++ */ ++phys_addr_t __init acpi_iort_dma_get_max_cpu_address(void) ++{ ++ phys_addr_t limit = PHYS_ADDR_MAX; ++ struct acpi_iort_node *node, *end; ++ struct acpi_table_iort *iort; ++ acpi_status status; ++ int i; ++ ++ if (acpi_disabled) ++ return limit; ++ ++ status = acpi_get_table(ACPI_SIG_IORT, 0, ++ (struct acpi_table_header **)&iort); ++ if (ACPI_FAILURE(status)) ++ return limit; ++ ++ node = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset); ++ end = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length); ++ ++ for (i = 0; i < iort->node_count; i++) { ++ if (node >= end) ++ break; ++ ++ switch (node->type) { ++ struct acpi_iort_named_component *ncomp; ++ struct acpi_iort_root_complex *rc; ++ phys_addr_t local_limit; ++ ++ case ACPI_IORT_NODE_NAMED_COMPONENT: ++ ncomp = (struct acpi_iort_named_component *)node->node_data; ++ local_limit = DMA_BIT_MASK(ncomp->memory_address_limit); ++ limit = min_not_zero(limit, local_limit); ++ break; ++ ++ case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: ++ if (node->revision < 1) ++ break; ++ ++ rc = (struct acpi_iort_root_complex *)node->node_data; ++ local_limit = DMA_BIT_MASK(rc->memory_address_limit); ++ limit = min_not_zero(limit, local_limit); ++ break; ++ } ++ node = ACPI_ADD_PTR(struct acpi_iort_node, node, node->length); ++ } ++ acpi_put_table(&iort->header); ++ return limit; ++} ++#endif +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index bfda153b1a41d..87682dcb64ec3 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct device *dev) + static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + __releases(&dev->power.lock) __acquires(&dev->power.lock) + { +- int retval, idx; + bool use_links = dev->power.links_count > 0; ++ bool get = false; ++ int retval, idx; ++ bool put; + + if (dev->power.irq_safe) { + spin_unlock(&dev->power.lock); ++ } else if (!use_links) { ++ spin_unlock_irq(&dev->power.lock); + } else { ++ get = dev->power.runtime_status == RPM_RESUMING; ++ + spin_unlock_irq(&dev->power.lock); + +- /* +- * Resume suppliers if necessary. +- * +- * The device's runtime PM status cannot change until this +- * routine returns, so it is safe to read the status outside of +- * the lock. +- */ +- if (use_links && dev->power.runtime_status == RPM_RESUMING) { ++ /* Resume suppliers if necessary. */ ++ if (get) { + idx = device_links_read_lock(); + + retval = rpm_get_suppliers(dev); +@@ -355,24 +355,36 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + + if (dev->power.irq_safe) { + spin_lock(&dev->power.lock); +- } else { +- /* +- * If the device is suspending and the callback has returned +- * success, drop the usage counters of the suppliers that have +- * been reference counted on its resume. +- * +- * Do that if resume fails too. +- */ +- if (use_links +- && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) +- || (dev->power.runtime_status == RPM_RESUMING && retval))) { +- idx = device_links_read_lock(); ++ return retval; ++ } + +- fail: +- rpm_put_suppliers(dev); ++ spin_lock_irq(&dev->power.lock); + +- device_links_read_unlock(idx); +- } ++ if (!use_links) ++ return retval; ++ ++ /* ++ * If the device is suspending and the callback has returned success, ++ * drop the usage counters of the suppliers that have been reference ++ * counted on its resume. ++ * ++ * Do that if the resume fails too. ++ */ ++ put = dev->power.runtime_status == RPM_SUSPENDING && !retval; ++ if (put) ++ __update_runtime_status(dev, RPM_SUSPENDED); ++ else ++ put = get && retval; ++ ++ if (put) { ++ spin_unlock_irq(&dev->power.lock); ++ ++ idx = device_links_read_lock(); ++ ++fail: ++ rpm_put_suppliers(dev); ++ ++ device_links_read_unlock(idx); + + spin_lock_irq(&dev->power.lock); + } +diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c +index 63f549889f875..5ac1881396afb 100644 +--- a/drivers/block/rsxx/core.c ++++ b/drivers/block/rsxx/core.c +@@ -165,15 +165,17 @@ static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf, + { + struct rsxx_cardinfo *card = file_inode(fp)->i_private; + char *buf; +- ssize_t st; ++ int st; + + buf = kzalloc(cnt, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + st = rsxx_creg_read(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1); +- if (!st) +- st = copy_to_user(ubuf, buf, cnt); ++ if (!st) { ++ if (copy_to_user(ubuf, buf, cnt)) ++ st = -EFAULT; ++ } + kfree(buf); + if (st) + return st; +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index 431919d5f48af..a2e0395cbe618 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -707,12 +707,22 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip) + const char *desc = "attempting to generate an interrupt"; + u32 cap2; + cap_t cap; ++ int ret; + ++ /* TPM 2.0 */ + if (chip->flags & TPM_CHIP_FLAG_TPM2) + return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); +- else +- return tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, +- 0); ++ ++ /* TPM 1.2 */ ++ ret = request_locality(chip, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); ++ ++ release_locality(chip, 0); ++ ++ return ret; + } + + /* Register the IRQ and issue a command that will cause an interrupt. If an +@@ -1019,11 +1029,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, + init_waitqueue_head(&priv->read_queue); + init_waitqueue_head(&priv->int_queue); + if (irq != -1) { +- /* Before doing irq testing issue a command to the TPM in polling mode ++ /* ++ * Before doing irq testing issue a command to the TPM in polling mode + * to make sure it works. May as well use that command to set the + * proper timeouts for the driver. + */ +- if (tpm_get_timeouts(chip)) { ++ ++ rc = request_locality(chip, 0); ++ if (rc < 0) ++ goto out_err; ++ ++ rc = tpm_get_timeouts(chip); ++ ++ release_locality(chip, 0); ++ ++ if (rc) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index 2d125b8b15ee1..00a190929b55c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -355,7 +355,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, + while (size) { + uint32_t value; + +- value = RREG32_PCIE(*pos >> 2); ++ value = RREG32_PCIE(*pos); + r = put_user(value, (uint32_t *)buf); + if (r) { + pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); +@@ -422,7 +422,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user + return r; + } + +- WREG32_PCIE(*pos >> 2, value); ++ WREG32_PCIE(*pos, value); + + result += 4; + buf += 4; +diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c +index 8eeba8096493b..0af4774ddd613 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/nv.c +@@ -459,7 +459,8 @@ static bool nv_is_headless_sku(struct pci_dev *pdev) + { + if ((pdev->device == 0x731E && + (pdev->revision == 0xC6 || pdev->revision == 0xC7)) || +- (pdev->device == 0x7340 && pdev->revision == 0xC9)) ++ (pdev->device == 0x7340 && pdev->revision == 0xC9) || ++ (pdev->device == 0x7360 && pdev->revision == 0xC7)) + return true; + return false; + } +@@ -524,7 +525,8 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && + !amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); +- amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); ++ if (!nv_is_headless_sku(adev->pdev)) ++ amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); + if (!amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); + break; +diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c +index 8e578f73a074c..bbba0cd42c89b 100644 +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -3650,6 +3650,7 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, + struct ib_cm_sidr_rep_param *param) + { + struct ib_mad_send_buf *msg; ++ unsigned long flags; + int ret; + + lockdep_assert_held(&cm_id_priv->lock); +@@ -3675,12 +3676,12 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, + return ret; + } + cm_id_priv->id.state = IB_CM_IDLE; +- spin_lock_irq(&cm.lock); ++ spin_lock_irqsave(&cm.lock, flags); + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) { + rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); + RB_CLEAR_NODE(&cm_id_priv->sidr_id_node); + } +- spin_unlock_irq(&cm.lock); ++ spin_unlock_irqrestore(&cm.lock, flags); + return 0; + } + +diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c +index 26564e7d34572..efb9ec99b68bd 100644 +--- a/drivers/infiniband/hw/mlx5/devx.c ++++ b/drivers/infiniband/hw/mlx5/devx.c +@@ -1973,8 +1973,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_SUBSCRIBE_EVENT)( + + num_alloc_xa_entries++; + event_sub = kzalloc(sizeof(*event_sub), GFP_KERNEL); +- if (!event_sub) ++ if (!event_sub) { ++ err = -ENOMEM; + goto err; ++ } + + list_add_tail(&event_sub->event_list, &sub_list); + uverbs_uobject_get(&ev_file->uobj); +diff --git a/drivers/infiniband/sw/rxe/Kconfig b/drivers/infiniband/sw/rxe/Kconfig +index 4521490667925..06b8dc5093f77 100644 +--- a/drivers/infiniband/sw/rxe/Kconfig ++++ b/drivers/infiniband/sw/rxe/Kconfig +@@ -4,6 +4,7 @@ config RDMA_RXE + depends on INET && PCI && INFINIBAND + depends on INFINIBAND_VIRT_DMA + select NET_UDP_TUNNEL ++ select CRYPTO + select CRYPTO_CRC32 + help + This driver implements the InfiniBand RDMA transport over +diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h +index 97dfcffbf495a..444c0bec221a4 100644 +--- a/drivers/iommu/intel/pasid.h ++++ b/drivers/iommu/intel/pasid.h +@@ -30,8 +30,8 @@ + #define VCMD_VRSP_IP 0x1 + #define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3) + #define VCMD_VRSP_SC_SUCCESS 0 +-#define VCMD_VRSP_SC_NO_PASID_AVAIL 1 +-#define VCMD_VRSP_SC_INVALID_PASID 1 ++#define VCMD_VRSP_SC_NO_PASID_AVAIL 2 ++#define VCMD_VRSP_SC_INVALID_PASID 2 + #define VCMD_VRSP_RESULT_PASID(e) (((e) >> 8) & 0xfffff) + #define VCMD_CMD_OPERAND(e) ((e) << 8) + /* +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index fce4cbf9529d6..50f3e673729c3 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1526,6 +1526,10 @@ EXPORT_SYMBOL_GPL(dm_bufio_get_block_size); + sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) + { + sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT; ++ if (s >= c->start) ++ s -= c->start; ++ else ++ s = 0; + if (likely(c->sectors_per_block_bits >= 0)) + s >>= c->sectors_per_block_bits; + else +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index fb41b4f23c489..66f4c6398f670 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -61,19 +61,18 @@ static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio, + static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, + unsigned *offset, struct dm_buffer **buf) + { +- u64 position, block; ++ u64 position, block, rem; + u8 *res; + + position = (index + rsb) * v->fec->roots; +- block = position >> v->data_dev_block_bits; +- *offset = (unsigned)(position - (block << v->data_dev_block_bits)); ++ block = div64_u64_rem(position, v->fec->roots << SECTOR_SHIFT, &rem); ++ *offset = (unsigned)rem; + +- res = dm_bufio_read(v->fec->bufio, v->fec->start + block, buf); ++ res = dm_bufio_read(v->fec->bufio, block, buf); + if (IS_ERR(res)) { + DMERR("%s: FEC %llu: parity read failed (block %llu): %ld", + v->data_dev->name, (unsigned long long)rsb, +- (unsigned long long)(v->fec->start + block), +- PTR_ERR(res)); ++ (unsigned long long)block, PTR_ERR(res)); + *buf = NULL; + } + +@@ -155,7 +154,7 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + + /* read the next block when we run out of parity bytes */ + offset += v->fec->roots; +- if (offset >= 1 << v->data_dev_block_bits) { ++ if (offset >= v->fec->roots << SECTOR_SHIFT) { + dm_bufio_release(buf); + + par = fec_read_parity(v, rsb, block_offset, &offset, &buf); +@@ -674,7 +673,7 @@ int verity_fec_ctr(struct dm_verity *v) + { + struct dm_verity_fec *f = v->fec; + struct dm_target *ti = v->ti; +- u64 hash_blocks; ++ u64 hash_blocks, fec_blocks; + int ret; + + if (!verity_fec_is_enabled(v)) { +@@ -744,15 +743,17 @@ int verity_fec_ctr(struct dm_verity *v) + } + + f->bufio = dm_bufio_client_create(f->dev->bdev, +- 1 << v->data_dev_block_bits, ++ f->roots << SECTOR_SHIFT, + 1, 0, NULL, NULL); + if (IS_ERR(f->bufio)) { + ti->error = "Cannot initialize FEC bufio client"; + return PTR_ERR(f->bufio); + } + +- if (dm_bufio_get_device_size(f->bufio) < +- ((f->start + f->rounds * f->roots) >> v->data_dev_block_bits)) { ++ dm_bufio_set_sector_offset(f->bufio, f->start << (v->data_dev_block_bits - SECTOR_SHIFT)); ++ ++ fec_blocks = div64_u64(f->rounds * f->roots, v->fec->roots << SECTOR_SHIFT); ++ if (dm_bufio_get_device_size(f->bufio) < fec_blocks) { + ti->error = "FEC device is too small"; + return -E2BIG; + } +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index cfcc3ac613189..b7d5eaa70a67b 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -2244,6 +2244,7 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: +@@ -2271,6 +2272,7 @@ static void rtl_pll_power_up(struct rtl8169_private *tp) + { + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: +diff --git a/drivers/of/address.c b/drivers/of/address.c +index 1c3257a2d4e37..73ddf2540f3fe 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -1024,6 +1024,48 @@ out: + } + #endif /* CONFIG_HAS_DMA */ + ++/** ++ * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA ++ * @np: The node to start searching from or NULL to start from the root ++ * ++ * Gets the highest CPU physical address that is addressable by all DMA masters ++ * in the sub-tree pointed by np, or the whole tree if NULL is passed. If no ++ * DMA constrained device is found, it returns PHYS_ADDR_MAX. ++ */ ++phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np) ++{ ++ phys_addr_t max_cpu_addr = PHYS_ADDR_MAX; ++ struct of_range_parser parser; ++ phys_addr_t subtree_max_addr; ++ struct device_node *child; ++ struct of_range range; ++ const __be32 *ranges; ++ u64 cpu_end = 0; ++ int len; ++ ++ if (!np) ++ np = of_root; ++ ++ ranges = of_get_property(np, "dma-ranges", &len); ++ if (ranges && len) { ++ of_dma_range_parser_init(&parser, np); ++ for_each_of_range(&parser, &range) ++ if (range.cpu_addr + range.size > cpu_end) ++ cpu_end = range.cpu_addr + range.size - 1; ++ ++ if (max_cpu_addr > cpu_end) ++ max_cpu_addr = cpu_end; ++ } ++ ++ for_each_available_child_of_node(np, child) { ++ subtree_max_addr = of_dma_get_max_cpu_address(child); ++ if (max_cpu_addr > subtree_max_addr) ++ max_cpu_addr = subtree_max_addr; ++ } ++ ++ return max_cpu_addr; ++} ++ + /** + * of_dma_is_coherent - Check if device is coherent + * @np: device node +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index 06cc988faf78b..eb51bc1474401 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -869,6 +869,26 @@ static void __init of_unittest_changeset(void) + #endif + } + ++static void __init of_unittest_dma_get_max_cpu_address(void) ++{ ++ struct device_node *np; ++ phys_addr_t cpu_addr; ++ ++ if (!IS_ENABLED(CONFIG_OF_ADDRESS)) ++ return; ++ ++ np = of_find_node_by_path("/testcase-data/address-tests"); ++ if (!np) { ++ pr_err("missing testcase data\n"); ++ return; ++ } ++ ++ cpu_addr = of_dma_get_max_cpu_address(np); ++ unittest(cpu_addr == 0x4fffffff, ++ "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %x)\n", ++ &cpu_addr, 0x4fffffff); ++} ++ + static void __init of_unittest_dma_ranges_one(const char *path, + u64 expect_dma_addr, u64 expect_paddr) + { +@@ -3266,6 +3286,7 @@ static int __init of_unittest(void) + of_unittest_changeset(); + of_unittest_parse_interrupts(); + of_unittest_parse_interrupts_extended(); ++ of_unittest_dma_get_max_cpu_address(); + of_unittest_parse_dma_ranges(); + of_unittest_pci_dma_ranges(); + of_unittest_match_node(); +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 9a5d652c1672e..c99e293b50f54 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -1229,6 +1229,11 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force) + spin_lock(&sinfo->lock); + spin_lock(&cache->lock); + ++ if (cache->swap_extents) { ++ ret = -ETXTBSY; ++ goto out; ++ } ++ + if (cache->ro) { + cache->ro++; + ret = 0; +@@ -2274,7 +2279,7 @@ again: + } + + ret = inc_block_group_ro(cache, 0); +- if (!do_chunk_alloc) ++ if (!do_chunk_alloc || ret == -ETXTBSY) + goto unlock_out; + if (!ret) + goto out; +@@ -2283,6 +2288,8 @@ again: + if (ret < 0) + goto out; + ret = inc_block_group_ro(cache, 0); ++ if (ret == -ETXTBSY) ++ goto unlock_out; + out: + if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) { + alloc_flags = btrfs_get_alloc_profile(fs_info, cache->flags); +@@ -3363,6 +3370,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) + ASSERT(list_empty(&block_group->io_list)); + ASSERT(list_empty(&block_group->bg_list)); + ASSERT(refcount_read(&block_group->refs) == 1); ++ ASSERT(block_group->swap_extents == 0); + btrfs_put_block_group(block_group); + + spin_lock(&info->block_group_cache_lock); +@@ -3429,3 +3437,26 @@ void btrfs_unfreeze_block_group(struct btrfs_block_group *block_group) + __btrfs_remove_free_space_cache(block_group->free_space_ctl); + } + } ++ ++bool btrfs_inc_block_group_swap_extents(struct btrfs_block_group *bg) ++{ ++ bool ret = true; ++ ++ spin_lock(&bg->lock); ++ if (bg->ro) ++ ret = false; ++ else ++ bg->swap_extents++; ++ spin_unlock(&bg->lock); ++ ++ return ret; ++} ++ ++void btrfs_dec_block_group_swap_extents(struct btrfs_block_group *bg, int amount) ++{ ++ spin_lock(&bg->lock); ++ ASSERT(!bg->ro); ++ ASSERT(bg->swap_extents >= amount); ++ bg->swap_extents -= amount; ++ spin_unlock(&bg->lock); ++} +diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h +index adfd7583a17b8..4c7614346f724 100644 +--- a/fs/btrfs/block-group.h ++++ b/fs/btrfs/block-group.h +@@ -181,6 +181,12 @@ struct btrfs_block_group { + */ + int needs_free_space; + ++ /* ++ * Number of extents in this block group used for swap files. ++ * All accesses protected by the spinlock 'lock'. ++ */ ++ int swap_extents; ++ + /* Record locked full stripes for RAID5/6 block group */ + struct btrfs_full_stripe_locks_tree full_stripe_locks_root; + }; +@@ -299,4 +305,7 @@ int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, + u64 physical, u64 **logical, int *naddrs, int *stripe_len); + #endif + ++bool btrfs_inc_block_group_swap_extents(struct btrfs_block_group *bg); ++void btrfs_dec_block_group_swap_extents(struct btrfs_block_group *bg, int amount); ++ + #endif /* BTRFS_BLOCK_GROUP_H */ +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index b6884eda9ff67..bcc6848bb6d6a 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -522,6 +522,11 @@ struct btrfs_swapfile_pin { + * points to a struct btrfs_device. + */ + bool is_block_group; ++ /* ++ * Only used when 'is_block_group' is true and it is the number of ++ * extents used by a swapfile for this block group ('ptr' field). ++ */ ++ int bg_extent_count; + }; + + bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr); +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 5aba81e161132..36e0de34ec68b 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -649,7 +649,7 @@ static int btrfs_delayed_inode_reserve_metadata( + btrfs_ino(inode), + num_bytes, 1); + } else { +- btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize); ++ btrfs_qgroup_free_meta_prealloc(root, num_bytes); + } + return ret; + } +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index 4373da7bcc0d5..c81a20cc10dc8 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -3236,8 +3236,11 @@ reserve_space: + goto out; + ret = btrfs_qgroup_reserve_data(BTRFS_I(inode), &data_reserved, + alloc_start, bytes_to_reserve); +- if (ret) ++ if (ret) { ++ unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, ++ lockend, &cached_state); + goto out; ++ } + ret = btrfs_prealloc_file_range(inode, mode, alloc_start, + alloc_end - alloc_start, + i_blocksize(inode), +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index ae4059ce2f84c..ba280707d5ec2 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -2714,8 +2714,10 @@ static void __btrfs_return_cluster_to_free_space( + struct rb_node *node; + + spin_lock(&cluster->lock); +- if (cluster->block_group != block_group) +- goto out; ++ if (cluster->block_group != block_group) { ++ spin_unlock(&cluster->lock); ++ return; ++ } + + cluster->block_group = NULL; + cluster->window_start = 0; +@@ -2753,8 +2755,6 @@ static void __btrfs_return_cluster_to_free_space( + entry->offset, &entry->offset_index, bitmap); + } + cluster->root = RB_ROOT; +- +-out: + spin_unlock(&cluster->lock); + btrfs_put_block_group(block_group); + } +@@ -3034,8 +3034,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group, + entry->bytes -= bytes; + } + +- if (entry->bytes == 0) +- rb_erase(&entry->offset_index, &cluster->root); + break; + } + out: +@@ -3052,7 +3050,10 @@ out: + ctl->free_space -= bytes; + if (!entry->bitmap && !btrfs_free_space_trimmed(entry)) + ctl->discardable_bytes[BTRFS_STAT_CURR] -= bytes; ++ ++ spin_lock(&cluster->lock); + if (entry->bytes == 0) { ++ rb_erase(&entry->offset_index, &cluster->root); + ctl->free_extents--; + if (entry->bitmap) { + kmem_cache_free(btrfs_free_space_bitmap_cachep, +@@ -3065,6 +3066,7 @@ out: + kmem_cache_free(btrfs_free_space_cachep, entry); + } + ++ spin_unlock(&cluster->lock); + spin_unlock(&ctl->tree_lock); + + return ret; +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 4d85f3a6695d1..9b3df72ceffbb 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -9993,6 +9993,7 @@ static int btrfs_add_swapfile_pin(struct inode *inode, void *ptr, + sp->ptr = ptr; + sp->inode = inode; + sp->is_block_group = is_block_group; ++ sp->bg_extent_count = 1; + + spin_lock(&fs_info->swapfile_pins_lock); + p = &fs_info->swapfile_pins.rb_node; +@@ -10006,6 +10007,8 @@ static int btrfs_add_swapfile_pin(struct inode *inode, void *ptr, + (sp->ptr == entry->ptr && sp->inode > entry->inode)) { + p = &(*p)->rb_right; + } else { ++ if (is_block_group) ++ entry->bg_extent_count++; + spin_unlock(&fs_info->swapfile_pins_lock); + kfree(sp); + return 1; +@@ -10031,8 +10034,11 @@ static void btrfs_free_swapfile_pins(struct inode *inode) + sp = rb_entry(node, struct btrfs_swapfile_pin, node); + if (sp->inode == inode) { + rb_erase(&sp->node, &fs_info->swapfile_pins); +- if (sp->is_block_group) ++ if (sp->is_block_group) { ++ btrfs_dec_block_group_swap_extents(sp->ptr, ++ sp->bg_extent_count); + btrfs_put_block_group(sp->ptr); ++ } + kfree(sp); + } + node = next; +@@ -10093,7 +10099,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, + sector_t *span) + { + struct inode *inode = file_inode(file); +- struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; ++ struct btrfs_root *root = BTRFS_I(inode)->root; ++ struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + struct extent_state *cached_state = NULL; + struct extent_map *em = NULL; +@@ -10144,13 +10151,27 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, + "cannot activate swapfile while exclusive operation is running"); + return -EBUSY; + } ++ ++ /* ++ * Prevent snapshot creation while we are activating the swap file. ++ * We do not want to race with snapshot creation. If snapshot creation ++ * already started before we bumped nr_swapfiles from 0 to 1 and ++ * completes before the first write into the swap file after it is ++ * activated, than that write would fallback to COW. ++ */ ++ if (!btrfs_drew_try_write_lock(&root->snapshot_lock)) { ++ btrfs_exclop_finish(fs_info); ++ btrfs_warn(fs_info, ++ "cannot activate swapfile because snapshot creation is in progress"); ++ return -EINVAL; ++ } + /* + * Snapshots can create extents which require COW even if NODATACOW is + * set. We use this counter to prevent snapshots. We must increment it + * before walking the extents because we don't want a concurrent + * snapshot to run after we've already checked the extents. + */ +- atomic_inc(&BTRFS_I(inode)->root->nr_swapfiles); ++ atomic_inc(&root->nr_swapfiles); + + isize = ALIGN_DOWN(inode->i_size, fs_info->sectorsize); + +@@ -10247,6 +10268,17 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, + goto out; + } + ++ if (!btrfs_inc_block_group_swap_extents(bg)) { ++ btrfs_warn(fs_info, ++ "block group for swapfile at %llu is read-only%s", ++ bg->start, ++ atomic_read(&fs_info->scrubs_running) ? ++ " (scrub running)" : ""); ++ btrfs_put_block_group(bg); ++ ret = -EINVAL; ++ goto out; ++ } ++ + ret = btrfs_add_swapfile_pin(inode, bg, true); + if (ret) { + btrfs_put_block_group(bg); +@@ -10285,6 +10317,8 @@ out: + if (ret) + btrfs_swap_deactivate(file); + ++ btrfs_drew_write_unlock(&root->snapshot_lock); ++ + btrfs_exclop_finish(fs_info); + + if (ret) +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index bd46e107f955e..f5135314e4b39 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -1914,7 +1914,10 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, + if (vol_args->flags & BTRFS_SUBVOL_RDONLY) + readonly = true; + if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { +- if (vol_args->size > PAGE_SIZE) { ++ u64 nums; ++ ++ if (vol_args->size < sizeof(*inherit) || ++ vol_args->size > PAGE_SIZE) { + ret = -EINVAL; + goto free_args; + } +@@ -1923,6 +1926,20 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, + ret = PTR_ERR(inherit); + goto free_args; + } ++ ++ if (inherit->num_qgroups > PAGE_SIZE || ++ inherit->num_ref_copies > PAGE_SIZE || ++ inherit->num_excl_copies > PAGE_SIZE) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } ++ ++ nums = inherit->num_qgroups + 2 * inherit->num_ref_copies + ++ 2 * inherit->num_excl_copies; ++ if (vol_args->size != struct_size(inherit, qgroups, nums)) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } + } + + ret = __btrfs_ioctl_snap_create(file, vol_args->name, vol_args->fd, +diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c +index 255490f42b5d5..9d33bf0154abf 100644 +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -2363,16 +2363,21 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + SetPageUptodate(p_page); + + if (has_qstripe) { ++ /* RAID6, allocate and map temp space for the Q stripe */ + q_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (!q_page) { + __free_page(p_page); + goto cleanup; + } + SetPageUptodate(q_page); ++ pointers[rbio->real_stripes - 1] = kmap(q_page); + } + + atomic_set(&rbio->error, 0); + ++ /* Map the parity stripe just once */ ++ pointers[nr_data] = kmap(p_page); ++ + for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { + struct page *p; + void *parity; +@@ -2382,16 +2387,8 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + pointers[stripe] = kmap(p); + } + +- /* then add the parity stripe */ +- pointers[stripe++] = kmap(p_page); +- + if (has_qstripe) { +- /* +- * raid6, add the qstripe and call the +- * library function to fill in our p/q +- */ +- pointers[stripe++] = kmap(q_page); +- ++ /* RAID6, call the library function to fill in our P/Q */ + raid6_call.gen_syndrome(rbio->real_stripes, PAGE_SIZE, + pointers); + } else { +@@ -2412,12 +2409,14 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, + + for (stripe = 0; stripe < nr_data; stripe++) + kunmap(page_in_rbio(rbio, stripe, pagenr, 0)); +- kunmap(p_page); + } + ++ kunmap(p_page); + __free_page(p_page); +- if (q_page) ++ if (q_page) { ++ kunmap(q_page); + __free_page(q_page); ++ } + + writeback: + /* +diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c +index a646af95dd100..c4f87df532833 100644 +--- a/fs/btrfs/reflink.c ++++ b/fs/btrfs/reflink.c +@@ -548,6 +548,24 @@ process_slot: + btrfs_release_path(path); + path->leave_spinning = 0; + ++ /* ++ * When using NO_HOLES and we are cloning a range that covers ++ * only a hole (no extents) into a range beyond the current ++ * i_size, punching a hole in the target range will not create ++ * an extent map defining a hole, because the range starts at or ++ * beyond current i_size. If the file previously had an i_size ++ * greater than the new i_size set by this clone operation, we ++ * need to make sure the next fsync is a full fsync, so that it ++ * detects and logs a hole covering a range from the current ++ * i_size to the new i_size. If the clone range covers extents, ++ * besides a hole, then we know the full sync flag was already ++ * set by previous calls to btrfs_replace_file_extents() that ++ * replaced file extent items. ++ */ ++ if (last_dest_end >= i_size_read(inode)) ++ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, ++ &BTRFS_I(inode)->runtime_flags); ++ + ret = btrfs_replace_file_extents(inode, path, last_dest_end, + destoff + len - 1, NULL, &trans); + if (ret) +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index e71e7586e9eb0..0392c556af601 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -3568,6 +3568,13 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, + * commit_transactions. + */ + ro_set = 0; ++ } else if (ret == -ETXTBSY) { ++ btrfs_warn(fs_info, ++ "skipping scrub of block group %llu due to active swapfile", ++ cache->start); ++ scrub_pause_off(fs_info); ++ ret = 0; ++ goto skip_unfreeze; + } else { + btrfs_warn(fs_info, + "failed setting block group ro: %d", ret); +@@ -3657,7 +3664,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, + } else { + spin_unlock(&cache->lock); + } +- ++skip_unfreeze: + btrfs_unfreeze_block_group(cache); + btrfs_put_block_group(cache); + if (ret) +diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c +index e51774201d53b..f1a60bcdb3db8 100644 +--- a/fs/btrfs/xattr.c ++++ b/fs/btrfs/xattr.c +@@ -229,11 +229,33 @@ int btrfs_setxattr_trans(struct inode *inode, const char *name, + { + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; ++ const bool start_trans = (current->journal_info == NULL); + int ret; + +- trans = btrfs_start_transaction(root, 2); +- if (IS_ERR(trans)) +- return PTR_ERR(trans); ++ if (start_trans) { ++ /* ++ * 1 unit for inserting/updating/deleting the xattr ++ * 1 unit for the inode item update ++ */ ++ trans = btrfs_start_transaction(root, 2); ++ if (IS_ERR(trans)) ++ return PTR_ERR(trans); ++ } else { ++ /* ++ * This can happen when smack is enabled and a directory is being ++ * created. It happens through d_instantiate_new(), which calls ++ * smack_d_instantiate(), which in turn calls __vfs_setxattr() to ++ * set the transmute xattr (XATTR_NAME_SMACKTRANSMUTE) on the ++ * inode. We have already reserved space for the xattr and inode ++ * update at btrfs_mkdir(), so just use the transaction handle. ++ * We don't join or start a transaction, as that will reset the ++ * block_rsv of the handle and trigger a warning for the start ++ * case. ++ */ ++ ASSERT(strncmp(name, XATTR_SECURITY_PREFIX, ++ XATTR_SECURITY_PREFIX_LEN) == 0); ++ trans = current->journal_info; ++ } + + ret = btrfs_setxattr(trans, inode, name, value, size, flags); + if (ret) +@@ -244,7 +266,8 @@ int btrfs_setxattr_trans(struct inode *inode, const char *name, + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + out: +- btrfs_end_transaction(trans); ++ if (start_trans) ++ btrfs_end_transaction(trans); + return ret; + } + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index d0172cc4f6427..691c998691439 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -5083,6 +5083,9 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, + pt->error = -EINVAL; + return; + } ++ /* double add on the same waitqueue head, ignore */ ++ if (poll->head == head) ++ return; + poll = kmalloc(sizeof(*poll), GFP_ATOMIC); + if (!poll) { + pt->error = -ENOMEM; +diff --git a/include/crypto/hash.h b/include/crypto/hash.h +index af2ff31ff619f..13f8a6a54ca87 100644 +--- a/include/crypto/hash.h ++++ b/include/crypto/hash.h +@@ -149,7 +149,7 @@ struct ahash_alg { + + struct shash_desc { + struct crypto_shash *tfm; +- void *__ctx[] CRYPTO_MINALIGN_ATTR; ++ void *__ctx[] __aligned(ARCH_SLAB_MINALIGN); + }; + + #define HASH_MAX_DIGESTSIZE 64 +@@ -162,9 +162,9 @@ struct shash_desc { + + #define HASH_MAX_STATESIZE 512 + +-#define SHASH_DESC_ON_STACK(shash, ctx) \ +- char __##shash##_desc[sizeof(struct shash_desc) + \ +- HASH_MAX_DESCSIZE] CRYPTO_MINALIGN_ATTR; \ ++#define SHASH_DESC_ON_STACK(shash, ctx) \ ++ char __##shash##_desc[sizeof(struct shash_desc) + HASH_MAX_DESCSIZE] \ ++ __aligned(__alignof__(struct shash_desc)); \ + struct shash_desc *shash = (struct shash_desc *)__##shash##_desc + + /** +diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h +index 20a32120bb880..1a12baa58e409 100644 +--- a/include/linux/acpi_iort.h ++++ b/include/linux/acpi_iort.h +@@ -38,6 +38,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size); + const struct iommu_ops *iort_iommu_configure_id(struct device *dev, + const u32 *id_in); + int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head); ++phys_addr_t acpi_iort_dma_get_max_cpu_address(void); + #else + static inline void acpi_iort_init(void) { } + static inline u32 iort_msi_map_id(struct device *dev, u32 id) +@@ -55,6 +56,9 @@ static inline const struct iommu_ops *iort_iommu_configure_id( + static inline + int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) + { return 0; } ++ ++static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void) ++{ return PHYS_ADDR_MAX; } + #endif + + #endif /* __ACPI_IORT_H__ */ +diff --git a/include/linux/crypto.h b/include/linux/crypto.h +index ef90e07c9635c..e3abd1f8646a1 100644 +--- a/include/linux/crypto.h ++++ b/include/linux/crypto.h +@@ -151,9 +151,12 @@ + * The macro CRYPTO_MINALIGN_ATTR (along with the void * type in the actual + * declaration) is used to ensure that the crypto_tfm context structure is + * aligned correctly for the given architecture so that there are no alignment +- * faults for C data types. In particular, this is required on platforms such +- * as arm where pointers are 32-bit aligned but there are data types such as +- * u64 which require 64-bit alignment. ++ * faults for C data types. On architectures that support non-cache coherent ++ * DMA, such as ARM or arm64, it also takes into account the minimal alignment ++ * that is required to ensure that the context struct member does not share any ++ * cachelines with the rest of the struct. This is needed to ensure that cache ++ * maintenance for non-coherent DMA (cache invalidation in particular) does not ++ * affect data that may be accessed by the CPU concurrently. + */ + #define CRYPTO_MINALIGN ARCH_KMALLOC_MINALIGN + +diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h +index fb3bf696c05e8..9d0c454d23cd6 100644 +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -354,26 +354,6 @@ enum zone_type { + * DMA mask is assumed when ZONE_DMA32 is defined. Some 64-bit + * platforms may need both zones as they support peripherals with + * different DMA addressing limitations. +- * +- * Some examples: +- * +- * - i386 and x86_64 have a fixed 16M ZONE_DMA and ZONE_DMA32 for the +- * rest of the lower 4G. +- * +- * - arm only uses ZONE_DMA, the size, up to 4G, may vary depending on +- * the specific device. +- * +- * - arm64 has a fixed 1G ZONE_DMA and ZONE_DMA32 for the rest of the +- * lower 4G. +- * +- * - powerpc only uses ZONE_DMA, the size, up to 2G, may vary +- * depending on the specific device. +- * +- * - s390 uses ZONE_DMA fixed to the lower 2G. +- * +- * - ia64 and riscv only use ZONE_DMA32. +- * +- * - parisc uses neither. + */ + #ifdef CONFIG_ZONE_DMA + ZONE_DMA, +diff --git a/include/linux/of.h b/include/linux/of.h +index af655d264f10f..0f4e81e6fb232 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -558,6 +558,8 @@ int of_map_id(struct device_node *np, u32 id, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out); + ++phys_addr_t of_dma_get_max_cpu_address(struct device_node *np); ++ + #else /* CONFIG_OF */ + + static inline void of_core_init(void) +@@ -995,6 +997,11 @@ static inline int of_map_id(struct device_node *np, u32 id, + return -EINVAL; + } + ++static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np) ++{ ++ return PHYS_ADDR_MAX; ++} ++ + #define of_match_ptr(_ptr) NULL + #define of_match_node(_matches, _node) NULL + #endif /* CONFIG_OF */ +diff --git a/include/sound/intel-nhlt.h b/include/sound/intel-nhlt.h +index 743c2f4422806..d0574805865f9 100644 +--- a/include/sound/intel-nhlt.h ++++ b/include/sound/intel-nhlt.h +@@ -112,6 +112,11 @@ struct nhlt_vendor_dmic_array_config { + /* TODO add vendor mic config */ + } __packed; + ++enum { ++ NHLT_CONFIG_TYPE_GENERIC = 0, ++ NHLT_CONFIG_TYPE_MIC_ARRAY = 1 ++}; ++ + enum { + NHLT_MIC_ARRAY_2CH_SMALL = 0xa, + NHLT_MIC_ARRAY_2CH_BIG = 0xb, +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index ddeb865706ba4..b12e5f4721ca7 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -2836,6 +2836,17 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, + write_stamp, write_stamp - delta)) + return 0; + ++ /* ++ * It's possible that the event time delta is zero ++ * (has the same time stamp as the previous event) ++ * in which case write_stamp and before_stamp could ++ * be the same. In such a case, force before_stamp ++ * to be different than write_stamp. It doesn't ++ * matter what it is, as long as its different. ++ */ ++ if (!delta) ++ rb_time_set(&cpu_buffer->before_stamp, 0); ++ + /* + * If an event were to come in now, it would see that the + * write_stamp and the before_stamp are different, and assume +diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c +index b9c2ee7ab43fa..cce12e1971d85 100644 +--- a/scripts/recordmcount.c ++++ b/scripts/recordmcount.c +@@ -438,7 +438,7 @@ static int arm_is_fake_mcount(Elf32_Rel const *rp) + + static int arm64_is_fake_mcount(Elf64_Rel const *rp) + { +- return ELF64_R_TYPE(w(rp->r_info)) != R_AARCH64_CALL26; ++ return ELF64_R_TYPE(w8(rp->r_info)) != R_AARCH64_CALL26; + } + + /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. +diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c +index a89ed55d85d41..478f757ff8435 100644 +--- a/security/tomoyo/network.c ++++ b/security/tomoyo/network.c +@@ -613,7 +613,7 @@ static int tomoyo_check_unix_address(struct sockaddr *addr, + static bool tomoyo_kernel_service(void) + { + /* Nothing to do if I am a kernel service. */ +- return uaccess_kernel(); ++ return (current->flags & (PF_KTHREAD | PF_IO_WORKER)) == PF_KTHREAD; + } + + /** +diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c +index 059aaf04f536a..d053beccfaec3 100644 +--- a/sound/hda/intel-nhlt.c ++++ b/sound/hda/intel-nhlt.c +@@ -31,18 +31,44 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt) + struct nhlt_endpoint *epnt; + struct nhlt_dmic_array_config *cfg; + struct nhlt_vendor_dmic_array_config *cfg_vendor; ++ struct nhlt_fmt *fmt_configs; + unsigned int dmic_geo = 0; +- u8 j; ++ u16 max_ch = 0; ++ u8 i, j; + + if (!nhlt) + return 0; + +- epnt = (struct nhlt_endpoint *)nhlt->desc; ++ for (j = 0, epnt = nhlt->desc; j < nhlt->endpoint_count; j++, ++ epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length)) { + +- for (j = 0; j < nhlt->endpoint_count; j++) { +- if (epnt->linktype == NHLT_LINK_DMIC) { +- cfg = (struct nhlt_dmic_array_config *) +- (epnt->config.caps); ++ if (epnt->linktype != NHLT_LINK_DMIC) ++ continue; ++ ++ cfg = (struct nhlt_dmic_array_config *)(epnt->config.caps); ++ fmt_configs = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); ++ ++ /* find max number of channels based on format_configuration */ ++ if (fmt_configs->fmt_count) { ++ dev_dbg(dev, "%s: found %d format definitions\n", ++ __func__, fmt_configs->fmt_count); ++ ++ for (i = 0; i < fmt_configs->fmt_count; i++) { ++ struct wav_fmt_ext *fmt_ext; ++ ++ fmt_ext = &fmt_configs->fmt_config[i].fmt_ext; ++ ++ if (fmt_ext->fmt.channels > max_ch) ++ max_ch = fmt_ext->fmt.channels; ++ } ++ dev_dbg(dev, "%s: max channels found %d\n", __func__, max_ch); ++ } else { ++ dev_dbg(dev, "%s: No format information found\n", __func__); ++ } ++ ++ if (cfg->device_config.config_type != NHLT_CONFIG_TYPE_MIC_ARRAY) { ++ dmic_geo = max_ch; ++ } else { + switch (cfg->array_type) { + case NHLT_MIC_ARRAY_2CH_SMALL: + case NHLT_MIC_ARRAY_2CH_BIG: +@@ -59,13 +85,23 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt) + dmic_geo = cfg_vendor->nb_mics; + break; + default: +- dev_warn(dev, "undefined DMIC array_type 0x%0x\n", +- cfg->array_type); ++ dev_warn(dev, "%s: undefined DMIC array_type 0x%0x\n", ++ __func__, cfg->array_type); ++ } ++ ++ if (dmic_geo > 0) { ++ dev_dbg(dev, "%s: Array with %d dmics\n", __func__, dmic_geo); ++ } ++ if (max_ch > dmic_geo) { ++ dev_dbg(dev, "%s: max channels %d exceed dmic number %d\n", ++ __func__, max_ch, dmic_geo); + } + } +- epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); + } + ++ dev_dbg(dev, "%s: dmic number %d max_ch %d\n", ++ __func__, dmic_geo, max_ch); ++ + return dmic_geo; + } + EXPORT_SYMBOL_GPL(intel_nhlt_get_dmic_geo); +diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c +index fc1bc18caee98..85d1fc76f59e1 100644 +--- a/sound/pci/ctxfi/cthw20k2.c ++++ b/sound/pci/ctxfi/cthw20k2.c +@@ -991,7 +991,7 @@ static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf) + + if (idx < 4) { + /* S/PDIF output */ +- switch ((conf & 0x7)) { ++ switch ((conf & 0xf)) { + case 1: + set_field(&ctl->txctl[idx], ATXCTL_NUC, 0); + break; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5f4f8c2d760f0..b47504fa8dfd0 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6408,6 +6408,7 @@ enum { + ALC236_FIXUP_DELL_AIO_HEADSET_MIC, + ALC282_FIXUP_ACER_DISABLE_LINEOUT, + ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST, ++ ALC256_FIXUP_ACER_HEADSET_MIC, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -7864,6 +7865,16 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, + }, ++ [ALC256_FIXUP_ACER_HEADSET_MIC] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x19, 0x02a1113c }, /* use as headset mic, without its own jack detect */ ++ { 0x1a, 0x90a1092f }, /* use as internal mic */ ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -7890,9 +7901,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK), + SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS), + SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1025, 0x1269, "Acer SWIFT SF314-54", ALC256_FIXUP_ACER_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1025, 0x129c, "Acer SWIFT SF314-55", ALC256_FIXUP_ACER_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 81e987eaf0637..375cfb9c9ab7e 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1301,6 +1301,17 @@ no_res_check: + /* totally crap, return an error */ + return -EINVAL; + } ++ } else { ++ /* if the max volume is too low, it's likely a bogus range; ++ * here we use -96dB as the threshold ++ */ ++ if (cval->dBmax <= -9600) { ++ usb_audio_info(cval->head.mixer->chip, ++ "%d:%d: bogus dB values (%d/%d), disabling dB reporting\n", ++ cval->head.id, mixer_ctrl_intf(cval->head.mixer), ++ cval->dBmin, cval->dBmax); ++ cval->dBmin = cval->dBmax = 0; ++ } + } + + return 0; +diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c +index a7212f16660ec..646deb6244b15 100644 +--- a/sound/usb/mixer_maps.c ++++ b/sound/usb/mixer_maps.c +@@ -536,6 +536,16 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { + .id = USB_ID(0x05a7, 0x1020), + .map = bose_companion5_map, + }, ++ { ++ /* Corsair Virtuoso SE (wired mode) */ ++ .id = USB_ID(0x1b1c, 0x0a3d), ++ .map = corsair_virtuoso_map, ++ }, ++ { ++ /* Corsair Virtuoso SE (wireless mode) */ ++ .id = USB_ID(0x1b1c, 0x0a3e), ++ .map = corsair_virtuoso_map, ++ }, + { + /* Corsair Virtuoso (wired mode) */ + .id = USB_ID(0x1b1c, 0x0a41), diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.22-23.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.22-23.patch new file mode 100644 index 0000000000..975a160e9c --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.22-23.patch @@ -0,0 +1,2146 @@ +diff --git a/Makefile b/Makefile +index 12a2a7271fcb0..7fdb78b48f556 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 22 ++SUBLEVEL = 23 + EXTRAVERSION = + NAME = Dare mighty things + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index afe4bc55d4eba..c1be64228327c 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -950,8 +950,9 @@ choice + that is selected here. + + config CPU_BIG_ENDIAN +- bool "Build big-endian kernel" +- help ++ bool "Build big-endian kernel" ++ depends on !LD_IS_LLD || LLD_VERSION >= 130000 ++ help + Say Y if you plan on running a kernel with a big-endian userspace. + + config CPU_LITTLE_ENDIAN +diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig +index 04dc17d52ac2d..14f3252f2da03 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -201,9 +201,12 @@ config PREFETCH + def_bool y + depends on PA8X00 || PA7200 + ++config PARISC_HUGE_KERNEL ++ def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST ++ + config MLONGCALLS +- def_bool y if !MODULES || UBSAN || FTRACE +- bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE ++ def_bool y if PARISC_HUGE_KERNEL ++ bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL + depends on PA8X00 + help + If you configure the kernel to include many drivers built-in instead +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 76ab1ee0784ae..642f0da31ac4f 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -1192,6 +1192,7 @@ static void init_vmcb(struct vcpu_svm *svm) + init_sys_seg(&save->ldtr, SEG_TYPE_LDT); + init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); + ++ svm_set_cr4(&svm->vcpu, 0); + svm_set_efer(&svm->vcpu, 0); + save->dr6 = 0xffff0ff0; + kvm_set_rflags(&svm->vcpu, 2); +diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h +index e7ca622a468f5..2249a7d7ca27f 100644 +--- a/arch/x86/kvm/x86.h ++++ b/arch/x86/kvm/x86.h +@@ -404,6 +404,8 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); + __reserved_bits |= X86_CR4_UMIP; \ + if (!__cpu_has(__c, X86_FEATURE_VMX)) \ + __reserved_bits |= X86_CR4_VMXE; \ ++ if (!__cpu_has(__c, X86_FEATURE_PCID)) \ ++ __reserved_bits |= X86_CR4_PCIDE; \ + __reserved_bits; \ + }) + +diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h +index 9f0219a8cb985..dd7efafcb1034 100644 +--- a/drivers/acpi/acpica/acobject.h ++++ b/drivers/acpi/acpica/acobject.h +@@ -284,6 +284,7 @@ struct acpi_object_addr_handler { + acpi_adr_space_handler handler; + struct acpi_namespace_node *node; /* Parent device */ + void *context; ++ acpi_mutex context_mutex; + acpi_adr_space_setup setup; + union acpi_operand_object *region_list; /* Regions using this handler */ + union acpi_operand_object *next; +diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c +index 5884eba047f73..3438dc187efb6 100644 +--- a/drivers/acpi/acpica/evhandler.c ++++ b/drivers/acpi/acpica/evhandler.c +@@ -489,6 +489,13 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node, + + /* Init handler obj */ + ++ status = ++ acpi_os_create_mutex(&handler_obj->address_space.context_mutex); ++ if (ACPI_FAILURE(status)) { ++ acpi_ut_remove_reference(handler_obj); ++ goto unlock_and_exit; ++ } ++ + handler_obj->address_space.space_id = (u8)space_id; + handler_obj->address_space.handler_flags = flags; + handler_obj->address_space.region_list = NULL; +diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c +index 738d4b231f34a..980efc9bd5ee7 100644 +--- a/drivers/acpi/acpica/evregion.c ++++ b/drivers/acpi/acpica/evregion.c +@@ -111,6 +111,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + union acpi_operand_object *region_obj2; + void *region_context = NULL; + struct acpi_connection_info *context; ++ acpi_mutex context_mutex; ++ u8 context_locked; + acpi_physical_address address; + + ACPI_FUNCTION_TRACE(ev_address_space_dispatch); +@@ -135,6 +137,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + } + + context = handler_desc->address_space.context; ++ context_mutex = handler_desc->address_space.context_mutex; ++ context_locked = FALSE; + + /* + * It may be the case that the region has never been initialized. +@@ -203,6 +207,23 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + handler = handler_desc->address_space.handler; + address = (region_obj->region.address + region_offset); + ++ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, ++ "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ++ ®ion_obj->region.handler->address_space, handler, ++ ACPI_FORMAT_UINT64(address), ++ acpi_ut_get_region_name(region_obj->region. ++ space_id))); ++ ++ if (!(handler_desc->address_space.handler_flags & ++ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { ++ /* ++ * For handlers other than the default (supplied) handlers, we must ++ * exit the interpreter because the handler *might* block -- we don't ++ * know what it will do, so we can't hold the lock on the interpreter. ++ */ ++ acpi_ex_exit_interpreter(); ++ } ++ + /* + * Special handling for generic_serial_bus and general_purpose_io: + * There are three extra parameters that must be passed to the +@@ -211,6 +232,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + * 2) Length of the above buffer + * 3) Actual access length from the access_as() op + * ++ * Since we pass these extra parameters via the context, which is ++ * shared between threads, we must lock the context to avoid these ++ * parameters being changed from another thread before the handler ++ * has completed running. ++ * + * In addition, for general_purpose_io, the Address and bit_width fields + * are defined as follows: + * 1) Address is the pin number index of the field (bit offset from +@@ -220,6 +246,14 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && + context && field_obj) { + ++ status = ++ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); ++ if (ACPI_FAILURE(status)) { ++ goto re_enter_interpreter; ++ } ++ ++ context_locked = TRUE; ++ + /* Get the Connection (resource_template) buffer */ + + context->connection = field_obj->field.resource_buffer; +@@ -229,6 +263,14 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && + context && field_obj) { + ++ status = ++ acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); ++ if (ACPI_FAILURE(status)) { ++ goto re_enter_interpreter; ++ } ++ ++ context_locked = TRUE; ++ + /* Get the Connection (resource_template) buffer */ + + context->connection = field_obj->field.resource_buffer; +@@ -238,28 +280,15 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + bit_width = field_obj->field.bit_length; + } + +- ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, +- "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", +- ®ion_obj->region.handler->address_space, handler, +- ACPI_FORMAT_UINT64(address), +- acpi_ut_get_region_name(region_obj->region. +- space_id))); +- +- if (!(handler_desc->address_space.handler_flags & +- ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { +- /* +- * For handlers other than the default (supplied) handlers, we must +- * exit the interpreter because the handler *might* block -- we don't +- * know what it will do, so we can't hold the lock on the interpreter. +- */ +- acpi_ex_exit_interpreter(); +- } +- + /* Call the handler */ + + status = handler(function, address, bit_width, value, context, + region_obj2->extra.region_context); + ++ if (context_locked) { ++ acpi_os_release_mutex(context_mutex); ++ } ++ + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", + acpi_ut_get_region_name(region_obj->region. +@@ -276,6 +305,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, + } + } + ++re_enter_interpreter: + if (!(handler_desc->address_space.handler_flags & + ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + /* +diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c +index da97fd0c6b51e..3bb06f17a18b6 100644 +--- a/drivers/acpi/acpica/evxfregn.c ++++ b/drivers/acpi/acpica/evxfregn.c +@@ -201,6 +201,8 @@ acpi_remove_address_space_handler(acpi_handle device, + + /* Now we can delete the handler object */ + ++ acpi_os_release_mutex(handler_obj->address_space. ++ context_mutex); + acpi_ut_remove_reference(handler_obj); + goto unlock_and_exit; + } +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index 4f5463b2a2178..811d298637cb2 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -140,6 +140,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + }, + { + .callback = video_detect_force_vendor, ++ .ident = "GIGABYTE GB-BXBT-2807", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), ++ }, ++ }, ++ { + .ident = "Sony VPCEH3U1E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 5c26c7d941731..ad47ff0d55c2e 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -78,6 +78,7 @@ enum qca_flags { + + enum qca_capabilities { + QCA_CAP_WIDEBAND_SPEECH = BIT(0), ++ QCA_CAP_VALID_LE_STATES = BIT(1), + }; + + /* HCI_IBS transmit side sleep protocol states */ +@@ -1782,7 +1783,7 @@ static const struct qca_device_data qca_soc_data_wcn3991 = { + { "vddch0", 450000 }, + }, + .num_vregs = 4, +- .capabilities = QCA_CAP_WIDEBAND_SPEECH, ++ .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + }; + + static const struct qca_device_data qca_soc_data_wcn3998 = { +@@ -2019,11 +2020,17 @@ static int qca_serdev_probe(struct serdev_device *serdev) + hdev->shutdown = qca_power_off; + } + +- /* Wideband speech support must be set per driver since it can't be +- * queried via hci. +- */ +- if (data && (data->capabilities & QCA_CAP_WIDEBAND_SPEECH)) +- set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); ++ if (data) { ++ /* Wideband speech support must be set per driver since it can't ++ * be queried via hci. Same with the valid le states quirk. ++ */ ++ if (data->capabilities & QCA_CAP_WIDEBAND_SPEECH) ++ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, ++ &hdev->quirks); ++ ++ if (data->capabilities & QCA_CAP_VALID_LE_STATES) ++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); ++ } + + return 0; + } +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 92ecf1a78ec73..45f5530666d3f 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -1379,6 +1379,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), ++ SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff, ++ SYSC_QUIRK_GPMC_DEBUG), + SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, + SYSC_QUIRK_OPT_CLKS_NEEDED), + SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, +@@ -1814,6 +1816,14 @@ static void sysc_init_module_quirks(struct sysc *ddata) + return; + } + ++#ifdef CONFIG_OMAP_GPMC_DEBUG ++ if (ddata->cfg.quirks & SYSC_QUIRK_GPMC_DEBUG) { ++ ddata->cfg.quirks |= SYSC_QUIRK_NO_RESET_ON_INIT; ++ ++ return; ++ } ++#endif ++ + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) { + ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c; + ddata->post_reset_quirk = sysc_post_reset_quirk_i2c; +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +index 69ed2c6094665..5e11cdb207d83 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +@@ -626,8 +626,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu) + if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) + gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); + +- gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); +- + /* Enable USE_RETENTION_FLOPS */ + gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 94180c63571ed..06813f297dcca 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -359,6 +359,7 @@ + #define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 + #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843 + #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844 ++#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846 + + #define USB_VENDOR_ID_DWAV 0x0eef + #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 +@@ -638,6 +639,8 @@ + #define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 + + #define USB_VENDOR_ID_ITE 0x048d ++#define I2C_VENDOR_ID_ITE 0x103c ++#define I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 0x184f + #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 + #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 + #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a +diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c +index fc75f30f537c9..92d7ecd41a78f 100644 +--- a/drivers/hid/hid-mf.c ++++ b/drivers/hid/hid-mf.c +@@ -153,6 +153,8 @@ static const struct hid_device_id mf_devices[] = { + .driver_data = HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2), + .driver_data = 0 }, /* No quirk required */ ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), ++ .driver_data = HID_QUIRK_MULTI_INPUT }, + { } + }; + MODULE_DEVICE_TABLE(hid, mf_devices); +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index bf7ecab5d9e5e..2e38340e19dfb 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -72,6 +72,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, +@@ -484,6 +485,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) }, + #endif + #if IS_ENABLED(CONFIG_HID_MICROSOFT) + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, +diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c +index aeff1ffb0c8b3..cb7758d59014e 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-core.c ++++ b/drivers/hid/i2c-hid/i2c-hid-core.c +@@ -171,6 +171,8 @@ static const struct i2c_hid_quirks { + I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, + { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, ++ { I2C_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15, ++ I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { USB_VENDOR_ID_ELAN, HID_ANY_ID, +diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c +index b9cf59443843b..5f1195791cb18 100644 +--- a/drivers/iommu/amd/iommu.c ++++ b/drivers/iommu/amd/iommu.c +@@ -1503,6 +1503,10 @@ static bool increase_address_space(struct protection_domain *domain, + bool ret = true; + u64 *pte; + ++ pte = (void *)get_zeroed_page(gfp); ++ if (!pte) ++ return false; ++ + spin_lock_irqsave(&domain->lock, flags); + + amd_iommu_domain_get_pgtable(domain, &pgtable); +@@ -1514,10 +1518,6 @@ static bool increase_address_space(struct protection_domain *domain, + if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) + goto out; + +- pte = (void *)get_zeroed_page(gfp); +- if (!pte) +- goto out; +- + *pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); + + pgtable.root = pte; +@@ -1531,10 +1531,12 @@ static bool increase_address_space(struct protection_domain *domain, + */ + amd_iommu_domain_set_pgtable(domain, pte, pgtable.mode); + ++ pte = NULL; + ret = true; + + out: + spin_unlock_irqrestore(&domain->lock, flags); ++ free_page((unsigned long)pte); + + return ret; + } +diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c +index 4b0c53f61fb7c..4e8132d4b2dfa 100644 +--- a/drivers/media/pci/cx23885/cx23885-core.c ++++ b/drivers/media/pci/cx23885/cx23885-core.c +@@ -2074,6 +2074,10 @@ static struct { + * 0x1451 is PCI ID for the IOMMU found on Ryzen + */ + { PCI_VENDOR_ID_AMD, 0x1451 }, ++ /* According to sudo lspci -nn, ++ * 0x1423 is the PCI ID for the IOMMU found on Kaveri ++ */ ++ { PCI_VENDOR_ID_AMD, 0x1423 }, + }; + + static bool cx23885_does_need_dma_reset(void) +diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c +index d92c4d2c521a3..6e5f544c9c737 100644 +--- a/drivers/misc/eeprom/eeprom_93xx46.c ++++ b/drivers/misc/eeprom/eeprom_93xx46.c +@@ -35,6 +35,10 @@ static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = { + EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, + }; + ++static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = { ++ .quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE, ++}; ++ + struct eeprom_93xx46_dev { + struct spi_device *spi; + struct eeprom_93xx46_platform_data *pdata; +@@ -55,6 +59,11 @@ static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; + } + ++static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev) ++{ ++ return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; ++} ++ + static int eeprom_93xx46_read(void *priv, unsigned int off, + void *val, size_t count) + { +@@ -96,6 +105,11 @@ static int eeprom_93xx46_read(void *priv, unsigned int off, + dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", + cmd_addr, edev->spi->max_speed_hz); + ++ if (has_quirk_extra_read_cycle(edev)) { ++ cmd_addr <<= 1; ++ bits += 1; ++ } ++ + spi_message_init(&m); + + t[0].tx_buf = (char *)&cmd_addr; +@@ -363,6 +377,7 @@ static void select_deassert(void *context) + static const struct of_device_id eeprom_93xx46_of_table[] = { + { .compatible = "eeprom-93xx46", }, + { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, ++ { .compatible = "microchip,93lc46b", .data = µchip_93lc46b_data, }, + {} + }; + MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); +diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c +index d90020ed36227..59d8d96ce206b 100644 +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -112,6 +112,7 @@ static const struct sdhci_ops sdhci_dwcmshc_ops = { + static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }; + + static int dwcmshc_probe(struct platform_device *pdev) +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c +index 6a10ff0377a24..33cf952cc01d3 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c +@@ -526,6 +526,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev) + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); + mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); ++ ++ card->pci_reset_ongoing = true; + } + + /* +@@ -554,6 +556,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev) + dev_err(&pdev->dev, "reinit failed: %d\n", ret); + else + mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); ++ ++ card->pci_reset_ongoing = false; + } + + static const struct pci_error_handlers mwifiex_pcie_err_handler = { +@@ -3142,7 +3146,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) + int ret; + u32 fw_status; + +- cancel_work_sync(&card->work); ++ /* Perform the cancel_work_sync() only when we're not resetting ++ * the card. It's because that function never returns if we're ++ * in reset path. If we're here when resetting the card, it means ++ * that we failed to reset the card (reset failure path). ++ */ ++ if (!card->pci_reset_ongoing) { ++ mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n"); ++ cancel_work_sync(&card->work); ++ mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n"); ++ } else { ++ mwifiex_dbg(adapter, MSG, ++ "skipped cancel_work_sync() because we're in card reset failure path\n"); ++ } + + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); + if (fw_status == FIRMWARE_READY_PCIE) { +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h +index 843d57eda8201..5ed613d657094 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.h ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.h +@@ -242,6 +242,8 @@ struct pcie_service_card { + struct mwifiex_msix_context share_irq_ctx; + struct work_struct work; + unsigned long work_flags; ++ ++ bool pci_reset_ongoing; + }; + + static inline int +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 4a33287371bda..99c59f93a0641 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3235,7 +3235,8 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_DEVICE(0x126f, 0x2263), /* Silicon Motion unidentified */ + .driver_data = NVME_QUIRK_NO_NS_DESC_LIST, }, + { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ +- .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, ++ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | ++ NVME_QUIRK_NO_NS_DESC_LIST, }, + { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + { PCI_DEVICE(0x1c58, 0x0023), /* WDC SN200 adapter */ +@@ -3249,6 +3250,9 @@ static const struct pci_device_id nvme_id_table[] = { + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, ++ { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ ++ .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | ++ NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ + .driver_data = NVME_QUIRK_LIGHTNVM, }, + { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ +@@ -3264,6 +3268,8 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, ++ { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ ++ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), +diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c +index 586b9d69fa5e2..d34ca0fda0f66 100644 +--- a/drivers/pci/controller/cadence/pci-j721e.c ++++ b/drivers/pci/controller/cadence/pci-j721e.c +@@ -63,6 +63,7 @@ enum j721e_pcie_mode { + + struct j721e_pcie_data { + enum j721e_pcie_mode mode; ++ bool quirk_retrain_flag; + }; + + static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) +@@ -270,6 +271,7 @@ static struct pci_ops cdns_ti_pcie_host_ops = { + + static const struct j721e_pcie_data j721e_pcie_rc_data = { + .mode = PCI_MODE_RC, ++ .quirk_retrain_flag = true, + }; + + static const struct j721e_pcie_data j721e_pcie_ep_data = { +@@ -378,6 +380,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) + + bridge->ops = &cdns_ti_pcie_host_ops; + rc = pci_host_bridge_priv(bridge); ++ rc->quirk_retrain_flag = data->quirk_retrain_flag; + + cdns_pcie = &rc->pcie; + cdns_pcie->dev = dev; +diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c +index 1cb7cfc75d6e4..73dcf8cf98fbf 100644 +--- a/drivers/pci/controller/cadence/pcie-cadence-host.c ++++ b/drivers/pci/controller/cadence/pcie-cadence-host.c +@@ -77,6 +77,68 @@ static struct pci_ops cdns_pcie_host_ops = { + .write = pci_generic_config_write, + }; + ++static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ int retries; ++ ++ /* Check if the link is up or not */ ++ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { ++ if (cdns_pcie_link_up(pcie)) { ++ dev_info(dev, "Link up\n"); ++ return 0; ++ } ++ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); ++ } ++ ++ return -ETIMEDOUT; ++} ++ ++static int cdns_pcie_retrain(struct cdns_pcie *pcie) ++{ ++ u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET; ++ u16 lnk_stat, lnk_ctl; ++ int ret = 0; ++ ++ /* ++ * Set retrain bit if current speed is 2.5 GB/s, ++ * but the PCIe root port support is > 2.5 GB/s. ++ */ ++ ++ lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off + ++ PCI_EXP_LNKCAP)); ++ if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB) ++ return ret; ++ ++ lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA); ++ if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { ++ lnk_ctl = cdns_pcie_rp_readw(pcie, ++ pcie_cap_off + PCI_EXP_LNKCTL); ++ lnk_ctl |= PCI_EXP_LNKCTL_RL; ++ cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, ++ lnk_ctl); ++ ++ ret = cdns_pcie_host_wait_for_link(pcie); ++ } ++ return ret; ++} ++ ++static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc) ++{ ++ struct cdns_pcie *pcie = &rc->pcie; ++ int ret; ++ ++ ret = cdns_pcie_host_wait_for_link(pcie); ++ ++ /* ++ * Retrain link for Gen2 training defect ++ * if quirk flag is set. ++ */ ++ if (!ret && rc->quirk_retrain_flag) ++ ret = cdns_pcie_retrain(pcie); ++ ++ return ret; ++} + + static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc) + { +@@ -399,23 +461,6 @@ static int cdns_pcie_host_init(struct device *dev, + return cdns_pcie_host_init_address_translation(rc); + } + +-static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) +-{ +- struct device *dev = pcie->dev; +- int retries; +- +- /* Check if the link is up or not */ +- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { +- if (cdns_pcie_link_up(pcie)) { +- dev_info(dev, "Link up\n"); +- return 0; +- } +- usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); +- } +- +- return -ETIMEDOUT; +-} +- + int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) + { + struct device *dev = rc->pcie.dev; +@@ -458,7 +503,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) + return ret; + } + +- ret = cdns_pcie_host_wait_for_link(pcie); ++ ret = cdns_pcie_host_start_link(rc); + if (ret) + dev_dbg(dev, "PCIe link never came up\n"); + +diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h +index feed1e3038f45..6705a5fedfbb0 100644 +--- a/drivers/pci/controller/cadence/pcie-cadence.h ++++ b/drivers/pci/controller/cadence/pcie-cadence.h +@@ -119,7 +119,7 @@ + * Root Port Registers (PCI configuration space for the root port function) + */ + #define CDNS_PCIE_RP_BASE 0x00200000 +- ++#define CDNS_PCIE_RP_CAP_OFFSET 0xc0 + + /* + * Address Translation Registers +@@ -290,6 +290,7 @@ struct cdns_pcie { + * @device_id: PCI device ID + * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and RP_NO_BAR if it's free or + * available ++ * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2 + */ + struct cdns_pcie_rc { + struct cdns_pcie pcie; +@@ -298,6 +299,7 @@ struct cdns_pcie_rc { + u32 vendor_id; + u32 device_id; + bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB]; ++ bool quirk_retrain_flag; + }; + + /** +@@ -413,6 +415,13 @@ static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie, + cdns_pcie_write_sz(addr, 0x2, value); + } + ++static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg) ++{ ++ void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg; ++ ++ return cdns_pcie_read_sz(addr, 0x2); ++} ++ + /* Endpoint Function register access */ + static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn, + u32 reg, u8 value) +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index fb1dc11e7cc52..b570f297e3ec1 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3998,6 +3998,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9183, + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, + quirk_dma_func1_alias); ++/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9215, ++ quirk_dma_func1_alias); + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, + quirk_dma_func1_alias); +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 5592a929b5935..80983f9dfcd55 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -30,6 +30,7 @@ + #include + #include + ++ACPI_MODULE_NAME(KBUILD_MODNAME); + MODULE_AUTHOR("Carlos Corbacho"); + MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); + MODULE_LICENSE("GPL"); +@@ -80,7 +81,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); + + enum acer_wmi_event_ids { + WMID_HOTKEY_EVENT = 0x1, +- WMID_ACCEL_EVENT = 0x5, ++ WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, + }; + + static const struct key_entry acer_wmi_keymap[] __initconst = { +@@ -128,7 +129,9 @@ struct event_return_value { + u8 function; + u8 key_num; + u16 device_state; +- u32 reserved; ++ u16 reserved1; ++ u8 kbd_dock_state; ++ u8 reserved2; + } __attribute__((packed)); + + /* +@@ -206,14 +209,13 @@ struct hotkey_function_type_aa { + /* + * Interface capability flags + */ +-#define ACER_CAP_MAILLED (1<<0) +-#define ACER_CAP_WIRELESS (1<<1) +-#define ACER_CAP_BLUETOOTH (1<<2) +-#define ACER_CAP_BRIGHTNESS (1<<3) +-#define ACER_CAP_THREEG (1<<4) +-#define ACER_CAP_ACCEL (1<<5) +-#define ACER_CAP_RFBTN (1<<6) +-#define ACER_CAP_ANY (0xFFFFFFFF) ++#define ACER_CAP_MAILLED BIT(0) ++#define ACER_CAP_WIRELESS BIT(1) ++#define ACER_CAP_BLUETOOTH BIT(2) ++#define ACER_CAP_BRIGHTNESS BIT(3) ++#define ACER_CAP_THREEG BIT(4) ++#define ACER_CAP_SET_FUNCTION_MODE BIT(5) ++#define ACER_CAP_KBD_DOCK BIT(6) + + /* + * Interface type flags +@@ -236,6 +238,7 @@ static int mailled = -1; + static int brightness = -1; + static int threeg = -1; + static int force_series; ++static int force_caps = -1; + static bool ec_raw_mode; + static bool has_type_aa; + static u16 commun_func_bitmap; +@@ -245,11 +248,13 @@ module_param(mailled, int, 0444); + module_param(brightness, int, 0444); + module_param(threeg, int, 0444); + module_param(force_series, int, 0444); ++module_param(force_caps, int, 0444); + module_param(ec_raw_mode, bool, 0444); + MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); + MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); + MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); + MODULE_PARM_DESC(force_series, "Force a different laptop series"); ++MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value"); + MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); + + struct acer_data { +@@ -319,6 +324,15 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) + return 1; + } + ++static int __init set_force_caps(const struct dmi_system_id *dmi) ++{ ++ if (force_caps == -1) { ++ force_caps = (uintptr_t)dmi->driver_data; ++ pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps); ++ } ++ return 1; ++} ++ + static struct quirk_entry quirk_unknown = { + }; + +@@ -497,6 +511,33 @@ static const struct dmi_system_id acer_quirks[] __initconst = { + }, + .driver_data = &quirk_acer_travelmate_2490, + }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer Aspire Switch 10E SW3-016", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer Aspire Switch 10 SW5-012", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, ++ { ++ .callback = set_force_caps, ++ .ident = "Acer One 10 (S1003)", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), ++ }, ++ .driver_data = (void *)ACER_CAP_KBD_DOCK, ++ }, + {} + }; + +@@ -1253,10 +1294,8 @@ static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) + interface->capability |= ACER_CAP_THREEG; + if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) + interface->capability |= ACER_CAP_BLUETOOTH; +- if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { +- interface->capability |= ACER_CAP_RFBTN; ++ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) + commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; +- } + + commun_fn_key_number = type_aa->commun_fn_key_number; + } +@@ -1520,7 +1559,7 @@ static int acer_gsensor_event(void) + struct acpi_buffer output; + union acpi_object out_obj[5]; + +- if (!has_cap(ACER_CAP_ACCEL)) ++ if (!acer_wmi_accel_dev) + return -1; + + output.length = sizeof(out_obj); +@@ -1543,6 +1582,71 @@ static int acer_gsensor_event(void) + return 0; + } + ++/* ++ * Switch series keyboard dock status ++ */ ++static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state) ++{ ++ switch (kbd_dock_state) { ++ case 0x01: /* Docked, traditional clamshell laptop mode */ ++ return 0; ++ case 0x04: /* Stand-alone tablet */ ++ case 0x40: /* Docked, tent mode, keyboard not usable */ ++ return 1; ++ default: ++ pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state); ++ } ++ ++ return 0; ++} ++ ++static void acer_kbd_dock_get_initial_state(void) ++{ ++ u8 *output, input[8] = { 0x05, 0x00, }; ++ struct acpi_buffer input_buf = { sizeof(input), input }; ++ struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL }; ++ union acpi_object *obj; ++ acpi_status status; ++ int sw_tablet_mode; ++ ++ status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf); ++ if (ACPI_FAILURE(status)) { ++ ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status")); ++ return; ++ } ++ ++ obj = output_buf.pointer; ++ if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { ++ pr_err("Unexpected output format getting keyboard-dock initial status\n"); ++ goto out_free_obj; ++ } ++ ++ output = obj->buffer.pointer; ++ if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) { ++ pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n", ++ output[0], output[3]); ++ goto out_free_obj; ++ } ++ ++ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]); ++ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); ++ ++out_free_obj: ++ kfree(obj); ++} ++ ++static void acer_kbd_dock_event(const struct event_return_value *event) ++{ ++ int sw_tablet_mode; ++ ++ if (!has_cap(ACER_CAP_KBD_DOCK)) ++ return; ++ ++ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state); ++ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); ++ input_sync(acer_wmi_input_dev); ++} ++ + /* + * Rfkill devices + */ +@@ -1770,8 +1874,9 @@ static void acer_wmi_notify(u32 value, void *context) + sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); + } + break; +- case WMID_ACCEL_EVENT: ++ case WMID_ACCEL_OR_KBD_DOCK_EVENT: + acer_gsensor_event(); ++ acer_kbd_dock_event(&return_value); + break; + default: + pr_warn("Unknown function number - %d - %d\n", +@@ -1894,8 +1999,6 @@ static int __init acer_wmi_accel_setup(void) + gsensor_handle = acpi_device_handle(adev); + acpi_dev_put(adev); + +- interface->capability |= ACER_CAP_ACCEL; +- + acer_wmi_accel_dev = input_allocate_device(); + if (!acer_wmi_accel_dev) + return -ENOMEM; +@@ -1921,11 +2024,6 @@ err_free_dev: + return err; + } + +-static void acer_wmi_accel_destroy(void) +-{ +- input_unregister_device(acer_wmi_accel_dev); +-} +- + static int __init acer_wmi_input_setup(void) + { + acpi_status status; +@@ -1943,6 +2041,9 @@ static int __init acer_wmi_input_setup(void) + if (err) + goto err_free_dev; + ++ if (has_cap(ACER_CAP_KBD_DOCK)) ++ input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE); ++ + status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, + acer_wmi_notify, NULL); + if (ACPI_FAILURE(status)) { +@@ -1950,6 +2051,9 @@ static int __init acer_wmi_input_setup(void) + goto err_free_dev; + } + ++ if (has_cap(ACER_CAP_KBD_DOCK)) ++ acer_kbd_dock_get_initial_state(); ++ + err = input_register_device(acer_wmi_input_dev); + if (err) + goto err_uninstall_notifier; +@@ -2080,7 +2184,7 @@ static int acer_resume(struct device *dev) + if (has_cap(ACER_CAP_BRIGHTNESS)) + set_u32(data->brightness, ACER_CAP_BRIGHTNESS); + +- if (has_cap(ACER_CAP_ACCEL)) ++ if (acer_wmi_accel_dev) + acer_gsensor_init(); + + return 0; +@@ -2181,7 +2285,7 @@ static int __init acer_wmi_init(void) + } + /* WMID always provides brightness methods */ + interface->capability |= ACER_CAP_BRIGHTNESS; +- } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { ++ } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) { + pr_err("No WMID device detection method found\n"); + return -ENODEV; + } +@@ -2211,7 +2315,14 @@ static int __init acer_wmi_init(void) + if (acpi_video_get_backlight_type() != acpi_backlight_vendor) + interface->capability &= ~ACER_CAP_BRIGHTNESS; + +- if (wmi_has_guid(WMID_GUID3)) { ++ if (wmi_has_guid(WMID_GUID3)) ++ interface->capability |= ACER_CAP_SET_FUNCTION_MODE; ++ ++ if (force_caps != -1) ++ interface->capability = force_caps; ++ ++ if (wmi_has_guid(WMID_GUID3) && ++ (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) { + if (ACPI_FAILURE(acer_wmi_enable_rf_button())) + pr_warn("Cannot enable RF Button Driver\n"); + +@@ -2270,8 +2381,8 @@ error_device_alloc: + error_platform_register: + if (wmi_has_guid(ACERWMID_EVENT_GUID)) + acer_wmi_input_destroy(); +- if (has_cap(ACER_CAP_ACCEL)) +- acer_wmi_accel_destroy(); ++ if (acer_wmi_accel_dev) ++ input_unregister_device(acer_wmi_accel_dev); + + return err; + } +@@ -2281,8 +2392,8 @@ static void __exit acer_wmi_exit(void) + if (wmi_has_guid(ACERWMID_EVENT_GUID)) + acer_wmi_input_destroy(); + +- if (has_cap(ACER_CAP_ACCEL)) +- acer_wmi_accel_destroy(); ++ if (acer_wmi_accel_dev) ++ input_unregister_device(acer_wmi_accel_dev); + + remove_debugfs(); + platform_device_unregister(acer_platform_device); +diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c +index 5e6b95dbb578f..f54b494ca4486 100644 +--- a/drivers/scsi/ufs/ufs-exynos.c ++++ b/drivers/scsi/ufs/ufs-exynos.c +@@ -653,6 +653,11 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba, + } + } + ++ /* setting for three timeout values for traffic class #0 */ ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 8064); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 28224); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 20160); ++ + return 0; + out: + return ret; +@@ -1249,7 +1254,9 @@ struct exynos_ufs_drv_data exynos_ufs_drvs = { + UFSHCI_QUIRK_BROKEN_HCE | + UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR | + UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR | +- UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL, ++ UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL | ++ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING | ++ UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE, + .opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL | + EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL | + EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX | +diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c +index 914a827a93ee8..934713472ebce 100644 +--- a/drivers/scsi/ufs/ufs-mediatek.c ++++ b/drivers/scsi/ufs/ufs-mediatek.c +@@ -566,6 +566,7 @@ static int ufs_mtk_init(struct ufs_hba *hba) + + /* Enable WriteBooster */ + hba->caps |= UFSHCD_CAP_WB_EN; ++ hba->quirks |= UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL; + hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80); + + /* +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 8132893284670..5a7cc2e42ffdf 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -4153,25 +4153,27 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba, + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES), + pwr_mode->hs_rate); + +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), +- DL_FC0ProtectionTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), +- DL_TC0ReplayTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), +- DL_AFC0ReqTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3), +- DL_FC1ProtectionTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4), +- DL_TC1ReplayTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5), +- DL_AFC1ReqTimeOutVal_Default); +- +- ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal), +- DL_FC0ProtectionTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal), +- DL_TC0ReplayTimeOutVal_Default); +- ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal), +- DL_AFC0ReqTimeOutVal_Default); ++ if (!(hba->quirks & UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING)) { ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), ++ DL_FC0ProtectionTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), ++ DL_TC0ReplayTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), ++ DL_AFC0ReqTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3), ++ DL_FC1ProtectionTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4), ++ DL_TC1ReplayTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5), ++ DL_AFC1ReqTimeOutVal_Default); ++ ++ ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal), ++ DL_FC0ProtectionTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal), ++ DL_TC0ReplayTimeOutVal_Default); ++ ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal), ++ DL_AFC0ReqTimeOutVal_Default); ++ } + + ret = ufshcd_uic_change_pwr_mode(hba, pwr_mode->pwr_rx << 4 + | pwr_mode->pwr_tx); +@@ -4746,6 +4748,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) + struct request_queue *q = sdev->request_queue; + + blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); ++ if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) ++ blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); + + if (ufshcd_is_rpm_autosuspend_allowed(hba)) + sdev->rpm_autosuspend = 1; +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index 6c62a281c8631..812aa348751eb 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -544,6 +544,16 @@ enum ufshcd_quirks { + */ + UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 12, + ++ /* ++ * This quirk needs to disable unipro timeout values ++ * before power mode change ++ */ ++ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, ++ ++ /* ++ * This quirk allows only sg entries aligned with page size. ++ */ ++ UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, + }; + + enum ufshcd_caps { +diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c +index 039ab5d2435eb..6eeb7ed8e91f3 100644 +--- a/drivers/usb/cdns3/core.c ++++ b/drivers/usb/cdns3/core.c +@@ -569,7 +569,8 @@ static int cdns3_probe(struct platform_device *pdev) + device_set_wakeup_capable(dev, true); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); +- pm_runtime_forbid(dev); ++ if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW))) ++ pm_runtime_forbid(dev); + + /* + * The controller needs less time between bus and controller suspend, +diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h +index 8a40d53d5edeb..3176f924293a1 100644 +--- a/drivers/usb/cdns3/core.h ++++ b/drivers/usb/cdns3/core.h +@@ -42,6 +42,8 @@ struct cdns3_role_driver { + struct cdns3_platform_data { + int (*platform_suspend)(struct device *dev, + bool suspend, bool wakeup); ++ unsigned long quirks; ++#define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0) + }; + + /** +@@ -73,6 +75,7 @@ struct cdns3_platform_data { + * @wakeup_pending: wakeup interrupt pending + * @pdata: platform data from glue layer + * @lock: spinlock structure ++ * @xhci_plat_data: xhci private data structure pointer + */ + struct cdns3 { + struct device *dev; +@@ -106,6 +109,7 @@ struct cdns3 { + bool wakeup_pending; + struct cdns3_platform_data *pdata; + spinlock_t lock; ++ struct xhci_plat_priv *xhci_plat_data; + }; + + int cdns3_hw_role_switch(struct cdns3 *cdns); +diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h +index ae11810f88261..26041718a086c 100644 +--- a/drivers/usb/cdns3/host-export.h ++++ b/drivers/usb/cdns3/host-export.h +@@ -9,9 +9,11 @@ + #ifndef __LINUX_CDNS3_HOST_EXPORT + #define __LINUX_CDNS3_HOST_EXPORT + ++struct usb_hcd; + #ifdef CONFIG_USB_CDNS3_HOST + + int cdns3_host_init(struct cdns3 *cdns); ++int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd); + + #else + +@@ -21,6 +23,10 @@ static inline int cdns3_host_init(struct cdns3 *cdns) + } + + static inline void cdns3_host_exit(struct cdns3 *cdns) { } ++static inline int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) ++{ ++ return 0; ++} + + #endif /* CONFIG_USB_CDNS3_HOST */ + +diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c +index b3e2cb69762cc..102977790d606 100644 +--- a/drivers/usb/cdns3/host.c ++++ b/drivers/usb/cdns3/host.c +@@ -14,6 +14,19 @@ + #include "drd.h" + #include "host-export.h" + #include ++#include "../host/xhci.h" ++#include "../host/xhci-plat.h" ++ ++#define XECP_PORT_CAP_REG 0x8000 ++#define XECP_AUX_CTRL_REG1 0x8120 ++ ++#define CFG_RXDET_P3_EN BIT(15) ++#define LPM_2_STB_SWITCH_EN BIT(25) ++ ++static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { ++ .quirks = XHCI_SKIP_PHY_INIT, ++ .suspend_quirk = xhci_cdns3_suspend_quirk, ++}; + + static int __cdns3_host_init(struct cdns3 *cdns) + { +@@ -39,10 +52,25 @@ static int __cdns3_host_init(struct cdns3 *cdns) + goto err1; + } + ++ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, ++ sizeof(struct xhci_plat_priv), GFP_KERNEL); ++ if (!cdns->xhci_plat_data) { ++ ret = -ENOMEM; ++ goto err1; ++ } ++ ++ if (cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)) ++ cdns->xhci_plat_data->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; ++ ++ ret = platform_device_add_data(xhci, cdns->xhci_plat_data, ++ sizeof(struct xhci_plat_priv)); ++ if (ret) ++ goto free_memory; ++ + ret = platform_device_add(xhci); + if (ret) { + dev_err(cdns->dev, "failed to register xHCI device\n"); +- goto err1; ++ goto free_memory; + } + + /* Glue needs to access xHCI region register for Power management */ +@@ -51,13 +79,43 @@ static int __cdns3_host_init(struct cdns3 *cdns) + cdns->xhci_regs = hcd->regs; + + return 0; ++ ++free_memory: ++ kfree(cdns->xhci_plat_data); + err1: + platform_device_put(xhci); + return ret; + } + ++int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) ++{ ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ u32 value; ++ ++ if (pm_runtime_status_suspended(hcd->self.controller)) ++ return 0; ++ ++ /* set usbcmd.EU3S */ ++ value = readl(&xhci->op_regs->command); ++ value |= CMD_PM_INDEX; ++ writel(value, &xhci->op_regs->command); ++ ++ if (hcd->regs) { ++ value = readl(hcd->regs + XECP_AUX_CTRL_REG1); ++ value |= CFG_RXDET_P3_EN; ++ writel(value, hcd->regs + XECP_AUX_CTRL_REG1); ++ ++ value = readl(hcd->regs + XECP_PORT_CAP_REG); ++ value |= LPM_2_STB_SWITCH_EN; ++ writel(value, hcd->regs + XECP_PORT_CAP_REG); ++ } ++ ++ return 0; ++} ++ + static void cdns3_host_exit(struct cdns3 *cdns) + { ++ kfree(cdns->xhci_plat_data); + platform_device_unregister(cdns->host_dev); + cdns->host_dev = NULL; + cdns3_drd_host_off(cdns); +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 36e0de34ec68b..4e2cce5ca7f6a 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -627,7 +627,8 @@ static int btrfs_delayed_inode_reserve_metadata( + */ + if (!src_rsv || (!trans->bytes_reserved && + src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) { +- ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true); ++ ret = btrfs_qgroup_reserve_meta(root, num_bytes, ++ BTRFS_QGROUP_RSV_META_PREALLOC, true); + if (ret < 0) + return ret; + ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 9b3df72ceffbb..cbeb0cdaca7af 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -5798,7 +5798,7 @@ static int btrfs_dirty_inode(struct inode *inode) + return PTR_ERR(trans); + + ret = btrfs_update_inode(trans, root, inode); +- if (ret && ret == -ENOSPC) { ++ if (ret && (ret == -ENOSPC || ret == -EDQUOT)) { + /* whoops, lets try again with the full transaction */ + btrfs_end_transaction(trans); + trans = btrfs_start_transaction(root, 1); +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index d504a9a207515..cd9b1a16489b4 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -3875,8 +3875,8 @@ static int sub_root_meta_rsv(struct btrfs_root *root, int num_bytes, + return num_bytes; + } + +-static int qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, +- enum btrfs_qgroup_rsv_type type, bool enforce) ++int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, ++ enum btrfs_qgroup_rsv_type type, bool enforce) + { + struct btrfs_fs_info *fs_info = root->fs_info; + int ret; +@@ -3907,14 +3907,14 @@ int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, + { + int ret; + +- ret = qgroup_reserve_meta(root, num_bytes, type, enforce); ++ ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); + if (ret <= 0 && ret != -EDQUOT) + return ret; + + ret = try_flush_qgroup(root); + if (ret < 0) + return ret; +- return qgroup_reserve_meta(root, num_bytes, type, enforce); ++ return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); + } + + void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root) +diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h +index 50dea9a2d8fbd..7283e4f549af7 100644 +--- a/fs/btrfs/qgroup.h ++++ b/fs/btrfs/qgroup.h +@@ -361,6 +361,8 @@ int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len); + int btrfs_qgroup_free_data(struct btrfs_inode *inode, + struct extent_changeset *reserved, u64 start, + u64 len); ++int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, ++ enum btrfs_qgroup_rsv_type type, bool enforce); + int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, + enum btrfs_qgroup_rsv_type type, bool enforce); + /* Reserve metadata space for pertrans and prealloc type */ +diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h +index eec7928ff8fe0..99580c22f91a4 100644 +--- a/include/linux/eeprom_93xx46.h ++++ b/include/linux/eeprom_93xx46.h +@@ -16,6 +16,8 @@ struct eeprom_93xx46_platform_data { + #define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ (1 << 0) + /* Instructions such as EWEN are (addrlen + 2) in length. */ + #define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH (1 << 1) ++/* Add extra cycle after address during a read */ ++#define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE BIT(2) + + /* + * optional hooks to control additional logic +diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h +index 240dce553a0bd..fafc1beea504a 100644 +--- a/include/linux/platform_data/ti-sysc.h ++++ b/include/linux/platform_data/ti-sysc.h +@@ -50,6 +50,7 @@ struct sysc_regbits { + s8 emufree_shift; + }; + ++#define SYSC_QUIRK_GPMC_DEBUG BIT(26) + #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25) + #define SYSC_MODULE_QUIRK_PRUSS BIT(24) + #define SYSC_MODULE_QUIRK_DSS_RESET BIT(23) +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 3af4cb87032ce..d56db9f34373e 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -437,6 +437,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, ++ { ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), ++ }, ++ .driver_data = (void *)(BYT_RT5640_IN1_MAP | ++ BYT_RT5640_JD_SRC_JD2_IN4N | ++ BYT_RT5640_OVCD_TH_2000UA | ++ BYT_RT5640_OVCD_SF_0P75 | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index 0f1d845a0ccad..1d7677376e742 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -48,26 +48,14 @@ static int sof_sdw_quirk_cb(const struct dmi_system_id *id) + } + + static const struct dmi_system_id sof_sdw_quirk_table[] = { ++ /* CometLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), +- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") +- }, +- .driver_data = (void *)(SOF_SDW_TGL_HDMI | +- SOF_RT711_JD_SRC_JD2 | +- SOF_RT715_DAI_ID_FIX), +- }, +- { +- .callback = sof_sdw_quirk_cb, +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), +- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), + }, +- .driver_data = (void *)(SOF_SDW_TGL_HDMI | +- SOF_RT711_JD_SRC_JD2 | +- SOF_RT715_DAI_ID_FIX | +- SOF_SDW_FOUR_SPK), ++ .driver_data = (void *)SOF_SDW_PCH_DMIC, + }, + { + .callback = sof_sdw_quirk_cb, +@@ -98,7 +86,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), + }, +- { ++ { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), +@@ -108,6 +96,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), + }, ++ /* IceLake devices */ ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), ++ }, ++ .driver_data = (void *)SOF_SDW_PCH_DMIC, ++ }, ++ /* TigerLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { +@@ -123,18 +121,23 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + { + .callback = sof_sdw_quirk_cb, + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") + }, +- .driver_data = (void *)SOF_SDW_PCH_DMIC, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ SOF_RT711_JD_SRC_JD2 | ++ SOF_RT715_DAI_ID_FIX), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") + }, +- .driver_data = (void *)SOF_SDW_PCH_DMIC, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ SOF_RT711_JD_SRC_JD2 | ++ SOF_RT715_DAI_ID_FIX | ++ SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, +@@ -156,7 +159,34 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + SOF_SDW_PCH_DMIC | + SOF_SDW_FOUR_SPK), + }, +- ++ { ++ /* ++ * this entry covers multiple HP SKUs. The family name ++ * does not seem robust enough, so we use a partial ++ * match that ignores the product name suffix ++ * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) ++ */ ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), ++ }, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ SOF_SDW_PCH_DMIC | ++ SOF_RT711_JD_SRC_JD2), ++ }, ++ /* TigerLake-SDCA devices */ ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") ++ }, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ SOF_RT711_JD_SRC_JD2 | ++ SOF_RT715_DAI_ID_FIX | ++ SOF_SDW_FOUR_SPK), ++ }, + {} + }; + +diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig +index de7ff2d097ab9..6708a2c5a8381 100644 +--- a/sound/soc/sof/intel/Kconfig ++++ b/sound/soc/sof/intel/Kconfig +@@ -84,7 +84,7 @@ config SND_SOC_SOF_BAYTRAIL + + config SND_SOC_SOF_BROADWELL_SUPPORT + bool "SOF support for Broadwell" +- depends on SND_SOC_INTEL_HASWELL=n ++ depends on SND_SOC_INTEL_CATPT=n + help + This adds support for Sound Open Firmware for Intel(R) platforms + using the Broadwell processors. +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index df036a359f2fc..448de77f43fd8 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -2603,141 +2603,251 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) + } + + /* +- * Pioneer DJ DJM-250MK2 and maybe other DJM models ++ * Pioneer DJ DJM Mixers + * +- * For playback, no duplicate mapping should be set. +- * There are three mixer stereo channels (CH1, CH2, AUX) +- * and three stereo sources (Playback 1-2, Playback 3-4, Playback 5-6). +- * Each channel should be mapped just once to one source. +- * If mapped multiple times, only one source will play on given channel +- * (sources are not mixed together). ++ * These devices generally have options for soft-switching the playback and ++ * capture sources in addition to the recording level. Although different ++ * devices have different configurations, there seems to be canonical values ++ * for specific capture/playback types: See the definitions of these below. + * +- * For recording, duplicate mapping is OK. We will get the same signal multiple times. +- * +- * Channels 7-8 are in both directions fixed to FX SEND / FX RETURN. +- * +- * See also notes in the quirks-table.h file. ++ * The wValue is masked with the stereo channel number. e.g. Setting Ch2 to ++ * capture phono would be 0x0203. Capture, playback and capture level have ++ * different wIndexes. + */ + +-struct snd_pioneer_djm_option { +- const u16 wIndex; +- const u16 wValue; ++// Capture types ++#define SND_DJM_CAP_LINE 0x00 ++#define SND_DJM_CAP_CDLINE 0x01 ++#define SND_DJM_CAP_DIGITAL 0x02 ++#define SND_DJM_CAP_PHONO 0x03 ++#define SND_DJM_CAP_PFADER 0x06 ++#define SND_DJM_CAP_XFADERA 0x07 ++#define SND_DJM_CAP_XFADERB 0x08 ++#define SND_DJM_CAP_MIC 0x09 ++#define SND_DJM_CAP_AUX 0x0d ++#define SND_DJM_CAP_RECOUT 0x0a ++#define SND_DJM_CAP_NONE 0x0f ++#define SND_DJM_CAP_CH1PFADER 0x11 ++#define SND_DJM_CAP_CH2PFADER 0x12 ++#define SND_DJM_CAP_CH3PFADER 0x13 ++#define SND_DJM_CAP_CH4PFADER 0x14 ++ ++// Playback types ++#define SND_DJM_PB_CH1 0x00 ++#define SND_DJM_PB_CH2 0x01 ++#define SND_DJM_PB_AUX 0x04 ++ ++#define SND_DJM_WINDEX_CAP 0x8002 ++#define SND_DJM_WINDEX_CAPLVL 0x8003 ++#define SND_DJM_WINDEX_PB 0x8016 ++ ++// kcontrol->private_value layout ++#define SND_DJM_VALUE_MASK 0x0000ffff ++#define SND_DJM_GROUP_MASK 0x00ff0000 ++#define SND_DJM_DEVICE_MASK 0xff000000 ++#define SND_DJM_GROUP_SHIFT 16 ++#define SND_DJM_DEVICE_SHIFT 24 ++ ++// device table index ++#define SND_DJM_250MK2_IDX 0x0 ++#define SND_DJM_750_IDX 0x1 ++#define SND_DJM_900NXS2_IDX 0x2 ++ ++ ++#define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ ++ .name = _name, \ ++ .options = snd_djm_opts_##suffix, \ ++ .noptions = ARRAY_SIZE(snd_djm_opts_##suffix), \ ++ .default_value = _default_value, \ ++ .wIndex = _windex } ++ ++#define SND_DJM_DEVICE(suffix) { \ ++ .controls = snd_djm_ctls_##suffix, \ ++ .ncontrols = ARRAY_SIZE(snd_djm_ctls_##suffix) } ++ ++ ++struct snd_djm_device { + const char *name; ++ const struct snd_djm_ctl *controls; ++ size_t ncontrols; + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_level[] = { +- { .name = "-5 dB", .wValue = 0x0300, .wIndex = 0x8003 }, +- { .name = "-10 dB", .wValue = 0x0200, .wIndex = 0x8003 }, +- { .name = "-15 dB", .wValue = 0x0100, .wIndex = 0x8003 }, +- { .name = "-19 dB", .wValue = 0x0000, .wIndex = 0x8003 } ++struct snd_djm_ctl { ++ const char *name; ++ const u16 *options; ++ size_t noptions; ++ u16 default_value; ++ u16 wIndex; + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch12[] = { +- { .name = "CH1 Control Tone PHONO", .wValue = 0x0103, .wIndex = 0x8002 }, +- { .name = "CH1 Control Tone LINE", .wValue = 0x0100, .wIndex = 0x8002 }, +- { .name = "Post CH1 Fader", .wValue = 0x0106, .wIndex = 0x8002 }, +- { .name = "Cross Fader A", .wValue = 0x0107, .wIndex = 0x8002 }, +- { .name = "Cross Fader B", .wValue = 0x0108, .wIndex = 0x8002 }, +- { .name = "MIC", .wValue = 0x0109, .wIndex = 0x8002 }, +- { .name = "AUX", .wValue = 0x010d, .wIndex = 0x8002 }, +- { .name = "REC OUT", .wValue = 0x010a, .wIndex = 0x8002 } ++static const char *snd_djm_get_label_caplevel(u16 wvalue) ++{ ++ switch (wvalue) { ++ case 0x0000: return "-19dB"; ++ case 0x0100: return "-15dB"; ++ case 0x0200: return "-10dB"; ++ case 0x0300: return "-5dB"; ++ default: return NULL; ++ } + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch34[] = { +- { .name = "CH2 Control Tone PHONO", .wValue = 0x0203, .wIndex = 0x8002 }, +- { .name = "CH2 Control Tone LINE", .wValue = 0x0200, .wIndex = 0x8002 }, +- { .name = "Post CH2 Fader", .wValue = 0x0206, .wIndex = 0x8002 }, +- { .name = "Cross Fader A", .wValue = 0x0207, .wIndex = 0x8002 }, +- { .name = "Cross Fader B", .wValue = 0x0208, .wIndex = 0x8002 }, +- { .name = "MIC", .wValue = 0x0209, .wIndex = 0x8002 }, +- { .name = "AUX", .wValue = 0x020d, .wIndex = 0x8002 }, +- { .name = "REC OUT", .wValue = 0x020a, .wIndex = 0x8002 } ++static const char *snd_djm_get_label_cap(u16 wvalue) ++{ ++ switch (wvalue & 0x00ff) { ++ case SND_DJM_CAP_LINE: return "Control Tone LINE"; ++ case SND_DJM_CAP_CDLINE: return "Control Tone CD/LINE"; ++ case SND_DJM_CAP_DIGITAL: return "Control Tone DIGITAL"; ++ case SND_DJM_CAP_PHONO: return "Control Tone PHONO"; ++ case SND_DJM_CAP_PFADER: return "Post Fader"; ++ case SND_DJM_CAP_XFADERA: return "Cross Fader A"; ++ case SND_DJM_CAP_XFADERB: return "Cross Fader B"; ++ case SND_DJM_CAP_MIC: return "Mic"; ++ case SND_DJM_CAP_RECOUT: return "Rec Out"; ++ case SND_DJM_CAP_AUX: return "Aux"; ++ case SND_DJM_CAP_NONE: return "None"; ++ case SND_DJM_CAP_CH1PFADER: return "Post Fader Ch1"; ++ case SND_DJM_CAP_CH2PFADER: return "Post Fader Ch2"; ++ case SND_DJM_CAP_CH3PFADER: return "Post Fader Ch3"; ++ case SND_DJM_CAP_CH4PFADER: return "Post Fader Ch4"; ++ default: return NULL; ++ } + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch56[] = { +- { .name = "REC OUT", .wValue = 0x030a, .wIndex = 0x8002 }, +- { .name = "Post CH1 Fader", .wValue = 0x0311, .wIndex = 0x8002 }, +- { .name = "Post CH2 Fader", .wValue = 0x0312, .wIndex = 0x8002 }, +- { .name = "Cross Fader A", .wValue = 0x0307, .wIndex = 0x8002 }, +- { .name = "Cross Fader B", .wValue = 0x0308, .wIndex = 0x8002 }, +- { .name = "MIC", .wValue = 0x0309, .wIndex = 0x8002 }, +- { .name = "AUX", .wValue = 0x030d, .wIndex = 0x8002 } ++static const char *snd_djm_get_label_pb(u16 wvalue) ++{ ++ switch (wvalue & 0x00ff) { ++ case SND_DJM_PB_CH1: return "Ch1"; ++ case SND_DJM_PB_CH2: return "Ch2"; ++ case SND_DJM_PB_AUX: return "Aux"; ++ default: return NULL; ++ } + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_12[] = { +- { .name = "CH1", .wValue = 0x0100, .wIndex = 0x8016 }, +- { .name = "CH2", .wValue = 0x0101, .wIndex = 0x8016 }, +- { .name = "AUX", .wValue = 0x0104, .wIndex = 0x8016 } ++static const char *snd_djm_get_label(u16 wvalue, u16 windex) ++{ ++ switch (windex) { ++ case SND_DJM_WINDEX_CAPLVL: return snd_djm_get_label_caplevel(wvalue); ++ case SND_DJM_WINDEX_CAP: return snd_djm_get_label_cap(wvalue); ++ case SND_DJM_WINDEX_PB: return snd_djm_get_label_pb(wvalue); ++ default: return NULL; ++ } + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_34[] = { +- { .name = "CH1", .wValue = 0x0200, .wIndex = 0x8016 }, +- { .name = "CH2", .wValue = 0x0201, .wIndex = 0x8016 }, +- { .name = "AUX", .wValue = 0x0204, .wIndex = 0x8016 } ++ ++// DJM-250MK2 ++static const u16 snd_djm_opts_cap_level[] = { ++ 0x0000, 0x0100, 0x0200, 0x0300 }; ++ ++static const u16 snd_djm_opts_250mk2_cap1[] = { ++ 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a }; ++ ++static const u16 snd_djm_opts_250mk2_cap2[] = { ++ 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a }; ++ ++static const u16 snd_djm_opts_250mk2_cap3[] = { ++ 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d }; ++ ++static const u16 snd_djm_opts_250mk2_pb1[] = { 0x0100, 0x0101, 0x0104 }; ++static const u16 snd_djm_opts_250mk2_pb2[] = { 0x0200, 0x0201, 0x0204 }; ++static const u16 snd_djm_opts_250mk2_pb3[] = { 0x0300, 0x0301, 0x0304 }; ++ ++static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = { ++ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), ++ SND_DJM_CTL("Ch1 Input", 250mk2_cap1, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch2 Input", 250mk2_cap2, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch3 Input", 250mk2_cap3, 0, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch1 Output", 250mk2_pb1, 0, SND_DJM_WINDEX_PB), ++ SND_DJM_CTL("Ch2 Output", 250mk2_pb2, 1, SND_DJM_WINDEX_PB), ++ SND_DJM_CTL("Ch3 Output", 250mk2_pb3, 2, SND_DJM_WINDEX_PB) + }; + +-static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_56[] = { +- { .name = "CH1", .wValue = 0x0300, .wIndex = 0x8016 }, +- { .name = "CH2", .wValue = 0x0301, .wIndex = 0x8016 }, +- { .name = "AUX", .wValue = 0x0304, .wIndex = 0x8016 } ++ ++// DJM-750 ++static const u16 snd_djm_opts_750_cap1[] = { ++ 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f }; ++static const u16 snd_djm_opts_750_cap2[] = { ++ 0x0200, 0x0201, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020f }; ++static const u16 snd_djm_opts_750_cap3[] = { ++ 0x0300, 0x0301, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a, 0x030f }; ++static const u16 snd_djm_opts_750_cap4[] = { ++ 0x0401, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040f }; ++ ++static const struct snd_djm_ctl snd_djm_ctls_750[] = { ++ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), ++ SND_DJM_CTL("Ch1 Input", 750_cap1, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch2 Input", 750_cap2, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch3 Input", 750_cap3, 0, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch4 Input", 750_cap4, 0, SND_DJM_WINDEX_CAP) + }; + +-struct snd_pioneer_djm_option_group { +- const char *name; +- const struct snd_pioneer_djm_option *options; +- const size_t count; +- const u16 default_value; ++ ++// DJM-900NXS2 ++static const u16 snd_djm_opts_900nxs2_cap1[] = { ++ 0x0100, 0x0102, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a }; ++static const u16 snd_djm_opts_900nxs2_cap2[] = { ++ 0x0200, 0x0202, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a }; ++static const u16 snd_djm_opts_900nxs2_cap3[] = { ++ 0x0300, 0x0302, 0x0303, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a }; ++static const u16 snd_djm_opts_900nxs2_cap4[] = { ++ 0x0400, 0x0402, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a }; ++static const u16 snd_djm_opts_900nxs2_cap5[] = { ++ 0x0507, 0x0508, 0x0509, 0x050a, 0x0511, 0x0512, 0x0513, 0x0514 }; ++ ++static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] = { ++ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), ++ SND_DJM_CTL("Ch1 Input", 900nxs2_cap1, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch2 Input", 900nxs2_cap2, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch3 Input", 900nxs2_cap3, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch4 Input", 900nxs2_cap4, 2, SND_DJM_WINDEX_CAP), ++ SND_DJM_CTL("Ch5 Input", 900nxs2_cap5, 3, SND_DJM_WINDEX_CAP) + }; + +-#define snd_pioneer_djm_option_group_item(_name, suffix, _default_value) { \ +- .name = _name, \ +- .options = snd_pioneer_djm_options_##suffix, \ +- .count = ARRAY_SIZE(snd_pioneer_djm_options_##suffix), \ +- .default_value = _default_value } +- +-static const struct snd_pioneer_djm_option_group snd_pioneer_djm_option_groups[] = { +- snd_pioneer_djm_option_group_item("Master Capture Level Capture Switch", capture_level, 0), +- snd_pioneer_djm_option_group_item("Capture 1-2 Capture Switch", capture_ch12, 2), +- snd_pioneer_djm_option_group_item("Capture 3-4 Capture Switch", capture_ch34, 2), +- snd_pioneer_djm_option_group_item("Capture 5-6 Capture Switch", capture_ch56, 0), +- snd_pioneer_djm_option_group_item("Playback 1-2 Playback Switch", playback_12, 0), +- snd_pioneer_djm_option_group_item("Playback 3-4 Playback Switch", playback_34, 1), +- snd_pioneer_djm_option_group_item("Playback 5-6 Playback Switch", playback_56, 2) ++ ++static const struct snd_djm_device snd_djm_devices[] = { ++ SND_DJM_DEVICE(250mk2), ++ SND_DJM_DEVICE(750), ++ SND_DJM_DEVICE(900nxs2) + }; + +-// layout of the kcontrol->private_value: +-#define SND_PIONEER_DJM_VALUE_MASK 0x0000ffff +-#define SND_PIONEER_DJM_GROUP_MASK 0xffff0000 +-#define SND_PIONEER_DJM_GROUP_SHIFT 16 + +-static int snd_pioneer_djm_controls_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *info) ++static int snd_djm_controls_info(struct snd_kcontrol *kctl, ++ struct snd_ctl_elem_info *info) + { +- u16 group_index = kctl->private_value >> SND_PIONEER_DJM_GROUP_SHIFT; +- size_t count; ++ unsigned long private_value = kctl->private_value; ++ u8 device_idx = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; ++ u8 ctl_idx = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; ++ const struct snd_djm_device *device = &snd_djm_devices[device_idx]; + const char *name; +- const struct snd_pioneer_djm_option_group *group; ++ const struct snd_djm_ctl *ctl; ++ size_t noptions; + +- if (group_index >= ARRAY_SIZE(snd_pioneer_djm_option_groups)) ++ if (ctl_idx >= device->ncontrols) ++ return -EINVAL; ++ ++ ctl = &device->controls[ctl_idx]; ++ noptions = ctl->noptions; ++ if (info->value.enumerated.item >= noptions) ++ info->value.enumerated.item = noptions - 1; ++ ++ name = snd_djm_get_label(ctl->options[info->value.enumerated.item], ++ ctl->wIndex); ++ if (!name) + return -EINVAL; + +- group = &snd_pioneer_djm_option_groups[group_index]; +- count = group->count; +- if (info->value.enumerated.item >= count) +- info->value.enumerated.item = count - 1; +- name = group->options[info->value.enumerated.item].name; + strlcpy(info->value.enumerated.name, name, sizeof(info->value.enumerated.name)); + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; +- info->value.enumerated.items = count; ++ info->value.enumerated.items = noptions; + return 0; + } + +-static int snd_pioneer_djm_controls_update(struct usb_mixer_interface *mixer, u16 group, u16 value) ++static int snd_djm_controls_update(struct usb_mixer_interface *mixer, ++ u8 device_idx, u8 group, u16 value) + { + int err; ++ const struct snd_djm_device *device = &snd_djm_devices[device_idx]; + +- if (group >= ARRAY_SIZE(snd_pioneer_djm_option_groups) +- || value >= snd_pioneer_djm_option_groups[group].count) ++ if ((group >= device->ncontrols) || value >= device->controls[group].noptions) + return -EINVAL; + + err = snd_usb_lock_shutdown(mixer->chip); +@@ -2748,63 +2858,76 @@ static int snd_pioneer_djm_controls_update(struct usb_mixer_interface *mixer, u1 + mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), + USB_REQ_SET_FEATURE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- snd_pioneer_djm_option_groups[group].options[value].wValue, +- snd_pioneer_djm_option_groups[group].options[value].wIndex, ++ device->controls[group].options[value], ++ device->controls[group].wIndex, + NULL, 0); + + snd_usb_unlock_shutdown(mixer->chip); + return err; + } + +-static int snd_pioneer_djm_controls_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) ++static int snd_djm_controls_get(struct snd_kcontrol *kctl, ++ struct snd_ctl_elem_value *elem) + { +- elem->value.enumerated.item[0] = kctl->private_value & SND_PIONEER_DJM_VALUE_MASK; ++ elem->value.enumerated.item[0] = kctl->private_value & SND_DJM_VALUE_MASK; + return 0; + } + +-static int snd_pioneer_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) ++static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) + { + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); + struct usb_mixer_interface *mixer = list->mixer; + unsigned long private_value = kctl->private_value; +- u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK) >> SND_PIONEER_DJM_GROUP_SHIFT; ++ ++ u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; ++ u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; + u16 value = elem->value.enumerated.item[0]; + +- kctl->private_value = (group << SND_PIONEER_DJM_GROUP_SHIFT) | value; ++ kctl->private_value = ((device << SND_DJM_DEVICE_SHIFT) | ++ (group << SND_DJM_GROUP_SHIFT) | ++ value); + +- return snd_pioneer_djm_controls_update(mixer, group, value); ++ return snd_djm_controls_update(mixer, device, group, value); + } + +-static int snd_pioneer_djm_controls_resume(struct usb_mixer_elem_list *list) ++static int snd_djm_controls_resume(struct usb_mixer_elem_list *list) + { + unsigned long private_value = list->kctl->private_value; +- u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK) >> SND_PIONEER_DJM_GROUP_SHIFT; +- u16 value = (private_value & SND_PIONEER_DJM_VALUE_MASK); ++ u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; ++ u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; ++ u16 value = (private_value & SND_DJM_VALUE_MASK); + +- return snd_pioneer_djm_controls_update(list->mixer, group, value); ++ return snd_djm_controls_update(list->mixer, device, group, value); + } + +-static int snd_pioneer_djm_controls_create(struct usb_mixer_interface *mixer) ++static int snd_djm_controls_create(struct usb_mixer_interface *mixer, ++ const u8 device_idx) + { + int err, i; +- const struct snd_pioneer_djm_option_group *group; ++ u16 value; ++ ++ const struct snd_djm_device *device = &snd_djm_devices[device_idx]; ++ + struct snd_kcontrol_new knew = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .index = 0, +- .info = snd_pioneer_djm_controls_info, +- .get = snd_pioneer_djm_controls_get, +- .put = snd_pioneer_djm_controls_put ++ .info = snd_djm_controls_info, ++ .get = snd_djm_controls_get, ++ .put = snd_djm_controls_put + }; + +- for (i = 0; i < ARRAY_SIZE(snd_pioneer_djm_option_groups); i++) { +- group = &snd_pioneer_djm_option_groups[i]; +- knew.name = group->name; +- knew.private_value = (i << SND_PIONEER_DJM_GROUP_SHIFT) | group->default_value; +- err = snd_pioneer_djm_controls_update(mixer, i, group->default_value); ++ for (i = 0; i < device->ncontrols; i++) { ++ value = device->controls[i].default_value; ++ knew.name = device->controls[i].name; ++ knew.private_value = ( ++ (device_idx << SND_DJM_DEVICE_SHIFT) | ++ (i << SND_DJM_GROUP_SHIFT) | ++ value); ++ err = snd_djm_controls_update(mixer, device_idx, i, value); + if (err) + return err; +- err = add_single_ctl_with_resume(mixer, 0, snd_pioneer_djm_controls_resume, ++ err = add_single_ctl_with_resume(mixer, 0, snd_djm_controls_resume, + &knew, NULL); + if (err) + return err; +@@ -2917,7 +3040,13 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) + err = snd_bbfpro_controls_create(mixer); + break; + case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */ +- err = snd_pioneer_djm_controls_create(mixer); ++ err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX); ++ break; ++ case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ ++ err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); ++ break; ++ case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */ ++ err = snd_djm_controls_create(mixer, SND_DJM_900NXS2_IDX); + break; + } + diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.23-24.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.23-24.patch new file mode 100644 index 0000000000..19f4b04b1d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.23-24.patch @@ -0,0 +1,11590 @@ +diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory +index 2da2b1fba2c1c..16a727a611b1e 100644 +--- a/Documentation/ABI/testing/sysfs-devices-memory ++++ b/Documentation/ABI/testing/sysfs-devices-memory +@@ -26,8 +26,9 @@ Date: September 2008 + Contact: Badari Pulavarty + Description: + The file /sys/devices/system/memory/memoryX/phys_device +- is read-only and is designed to show the name of physical +- memory device. Implementation is currently incomplete. ++ is read-only; it is a legacy interface only ever used on s390x ++ to expose the covered storage increment. ++Users: Legacy s390-tools lsmem/chmem + + What: /sys/devices/system/memory/memoryX/phys_index + Date: September 2008 +diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst +index 5c4432c96c4b6..245739f55ac7d 100644 +--- a/Documentation/admin-guide/mm/memory-hotplug.rst ++++ b/Documentation/admin-guide/mm/memory-hotplug.rst +@@ -160,8 +160,8 @@ Under each memory block, you can see 5 files: + + "online_movable", "online", "offline" command + which will be performed on all sections in the block. +-``phys_device`` read-only: designed to show the name of physical memory +- device. This is not well implemented now. ++``phys_device`` read-only: legacy interface only ever used on s390x to ++ expose the covered storage increment. + ``removable`` read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory +diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst +index 654649556306f..7272a4bd74dd0 100644 +--- a/Documentation/gpu/todo.rst ++++ b/Documentation/gpu/todo.rst +@@ -560,6 +560,27 @@ Some of these date from the very introduction of KMS in 2008 ... + + Level: Intermediate + ++Remove automatic page mapping from dma-buf importing ++---------------------------------------------------- ++ ++When importing dma-bufs, the dma-buf and PRIME frameworks automatically map ++imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and ++drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach() ++even if they never do actual device DMA, but only CPU access through ++dma_buf_vmap(). This is a problem for USB devices, which do not support DMA ++operations. ++ ++To fix the issue, automatic page mappings should be removed from the ++buffer-sharing code. Fixing this is a bit more involved, since the import/export ++cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over ++this problem for USB devices by fishing out the USB host controller device, as ++long as that supports DMA. Otherwise importing can still needlessly fail. ++ ++Contact: Thomas Zimmermann , Daniel Vetter ++ ++Level: Advanced ++ ++ + Better Testing + ============== + +diff --git a/Documentation/networking/netdev-FAQ.rst b/Documentation/networking/netdev-FAQ.rst +index 4b9ed5874d5ad..be88ab15e53ce 100644 +--- a/Documentation/networking/netdev-FAQ.rst ++++ b/Documentation/networking/netdev-FAQ.rst +@@ -144,77 +144,13 @@ Please send incremental versions on top of what has been merged in order to fix + the patches the way they would look like if your latest patch series was to be + merged. + +-Q: How can I tell what patches are queued up for backporting to the various stable releases? +--------------------------------------------------------------------------------------------- +-A: Normally Greg Kroah-Hartman collects stable commits himself, but for +-networking, Dave collects up patches he deems critical for the +-networking subsystem, and then hands them off to Greg. +- +-There is a patchworks queue that you can see here: +- +- https://patchwork.kernel.org/bundle/netdev/stable/?state=* +- +-It contains the patches which Dave has selected, but not yet handed off +-to Greg. If Greg already has the patch, then it will be here: +- +- https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git +- +-A quick way to find whether the patch is in this stable-queue is to +-simply clone the repo, and then git grep the mainline commit ID, e.g. +-:: +- +- stable-queue$ git grep -l 284041ef21fdf2e +- releases/3.0.84/ipv6-fix-possible-crashes-in-ip6_cork_release.patch +- releases/3.4.51/ipv6-fix-possible-crashes-in-ip6_cork_release.patch +- releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch +- stable/stable-queue$ +- +-Q: I see a network patch and I think it should be backported to stable. +------------------------------------------------------------------------ +-Q: Should I request it via stable@vger.kernel.org like the references in +-the kernel's Documentation/process/stable-kernel-rules.rst file say? +-A: No, not for networking. Check the stable queues as per above first +-to see if it is already queued. If not, then send a mail to netdev, +-listing the upstream commit ID and why you think it should be a stable +-candidate. +- +-Before you jump to go do the above, do note that the normal stable rules +-in :ref:`Documentation/process/stable-kernel-rules.rst ` +-still apply. So you need to explicitly indicate why it is a critical +-fix and exactly what users are impacted. In addition, you need to +-convince yourself that you *really* think it has been overlooked, +-vs. having been considered and rejected. +- +-Generally speaking, the longer it has had a chance to "soak" in +-mainline, the better the odds that it is an OK candidate for stable. So +-scrambling to request a commit be added the day after it appears should +-be avoided. +- +-Q: I have created a network patch and I think it should be backported to stable. +--------------------------------------------------------------------------------- +-Q: Should I add a Cc: stable@vger.kernel.org like the references in the +-kernel's Documentation/ directory say? +-A: No. See above answer. In short, if you think it really belongs in +-stable, then ensure you write a decent commit log that describes who +-gets impacted by the bug fix and how it manifests itself, and when the +-bug was introduced. If you do that properly, then the commit will get +-handled appropriately and most likely get put in the patchworks stable +-queue if it really warrants it. +- +-If you think there is some valid information relating to it being in +-stable that does *not* belong in the commit log, then use the three dash +-marker line as described in +-:ref:`Documentation/process/submitting-patches.rst ` +-to temporarily embed that information into the patch that you send. +- +-Q: Are all networking bug fixes backported to all stable releases? +------------------------------------------------------------------- +-A: Due to capacity, Dave could only take care of the backports for the +-last two stable releases. For earlier stable releases, each stable +-branch maintainer is supposed to take care of them. If you find any +-patch is missing from an earlier stable branch, please notify +-stable@vger.kernel.org with either a commit ID or a formal patch +-backported, and CC Dave and other relevant networking developers. ++Q: Are there special rules regarding stable submissions on netdev? ++--------------------------------------------------------------- ++While it used to be the case that netdev submissions were not supposed ++to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer ++the case today. Please follow the standard stable rules in ++:ref:`Documentation/process/stable-kernel-rules.rst `, ++and make sure you include appropriate Fixes tags! + + Q: Is the comment style convention different for the networking content? + ------------------------------------------------------------------------ +diff --git a/Documentation/process/stable-kernel-rules.rst b/Documentation/process/stable-kernel-rules.rst +index 3973556250e17..003c865e9c212 100644 +--- a/Documentation/process/stable-kernel-rules.rst ++++ b/Documentation/process/stable-kernel-rules.rst +@@ -35,12 +35,6 @@ Rules on what kind of patches are accepted, and which ones are not, into the + Procedure for submitting patches to the -stable tree + ---------------------------------------------------- + +- - If the patch covers files in net/ or drivers/net please follow netdev stable +- submission guidelines as described in +- :ref:`Documentation/networking/netdev-FAQ.rst ` +- after first checking the stable networking queue at +- https://patchwork.kernel.org/bundle/netdev/stable/?state=* +- to ensure the requested patch is not already queued up. + - Security patches should not be handled (solely) by the -stable review + process but should follow the procedures in + :ref:`Documentation/admin-guide/security-bugs.rst `. +diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst +index 83d9a82055a78..5a267f5d1a501 100644 +--- a/Documentation/process/submitting-patches.rst ++++ b/Documentation/process/submitting-patches.rst +@@ -250,11 +250,6 @@ should also read + :ref:`Documentation/process/stable-kernel-rules.rst ` + in addition to this file. + +-Note, however, that some subsystem maintainers want to come to their own +-conclusions on which patches should go to the stable trees. The networking +-maintainer, in particular, would rather not see individual developers +-adding lines like the above to their patches. +- + If changes affect userland-kernel interfaces, please send the MAN-PAGES + maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at + least a notification of the change, so that some information makes its way +diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst +index 4ba0df574eb25..a5d27553d59c9 100644 +--- a/Documentation/virt/kvm/api.rst ++++ b/Documentation/virt/kvm/api.rst +@@ -182,6 +182,9 @@ is dependent on the CPU capability and the kernel configuration. The limit can + be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION + ioctl() at run-time. + ++Creation of the VM will fail if the requested IPA size (whether it is ++implicit or explicit) is unsupported on the host. ++ + Please note that configuring the IPA size does not affect the capability + exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects + size of the address translated by the stage2 level (guest physical to +diff --git a/Makefile b/Makefile +index 7fdb78b48f556..3a435c928e750 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 23 ++SUBLEVEL = 24 + EXTRAVERSION = + NAME = Dare mighty things + +@@ -1247,9 +1247,15 @@ define filechk_utsrelease.h + endef + + define filechk_version.h +- echo \#define LINUX_VERSION_CODE $(shell \ +- expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \ +- echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' ++ if [ $(SUBLEVEL) -gt 255 ]; then \ ++ echo \#define LINUX_VERSION_CODE $(shell \ ++ expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 255); \ ++ else \ ++ echo \#define LINUX_VERSION_CODE $(shell \ ++ expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \ ++ fi; \ ++ echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + \ ++ ((c) > 255 ? 255 : (c)))' + endef + + $(version_h): FORCE +diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S +index a0de09f994d88..247ce90559901 100644 +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -1440,8 +1440,7 @@ ENTRY(efi_enter_kernel) + mov r4, r0 @ preserve image base + mov r8, r1 @ preserve DT pointer + +- ARM( adrl r0, call_cache_fn ) +- THUMB( adr r0, call_cache_fn ) ++ adr_l r0, call_cache_fn + adr r1, 0f @ clean the region of code we + bl cache_clean_flush @ may run with the MMU off + +diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h +index feac2c8b86f29..72627c5fb3b2c 100644 +--- a/arch/arm/include/asm/assembler.h ++++ b/arch/arm/include/asm/assembler.h +@@ -494,4 +494,88 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) + #define _ASM_NOKPROBE(entry) + #endif + ++ .macro __adldst_l, op, reg, sym, tmp, c ++ .if __LINUX_ARM_ARCH__ < 7 ++ ldr\c \tmp, .La\@ ++ .subsection 1 ++ .align 2 ++.La\@: .long \sym - .Lpc\@ ++ .previous ++ .else ++ .ifnb \c ++ THUMB( ittt \c ) ++ .endif ++ movw\c \tmp, #:lower16:\sym - .Lpc\@ ++ movt\c \tmp, #:upper16:\sym - .Lpc\@ ++ .endif ++ ++#ifndef CONFIG_THUMB2_KERNEL ++ .set .Lpc\@, . + 8 // PC bias ++ .ifc \op, add ++ add\c \reg, \tmp, pc ++ .else ++ \op\c \reg, [pc, \tmp] ++ .endif ++#else ++.Lb\@: add\c \tmp, \tmp, pc ++ /* ++ * In Thumb-2 builds, the PC bias depends on whether we are currently ++ * emitting into a .arm or a .thumb section. The size of the add opcode ++ * above will be 2 bytes when emitting in Thumb mode and 4 bytes when ++ * emitting in ARM mode, so let's use this to account for the bias. ++ */ ++ .set .Lpc\@, . + (. - .Lb\@) ++ ++ .ifnc \op, add ++ \op\c \reg, [\tmp] ++ .endif ++#endif ++ .endm ++ ++ /* ++ * mov_l - move a constant value or [relocated] address into a register ++ */ ++ .macro mov_l, dst:req, imm:req ++ .if __LINUX_ARM_ARCH__ < 7 ++ ldr \dst, =\imm ++ .else ++ movw \dst, #:lower16:\imm ++ movt \dst, #:upper16:\imm ++ .endif ++ .endm ++ ++ /* ++ * adr_l - adr pseudo-op with unlimited range ++ * ++ * @dst: destination register ++ * @sym: name of the symbol ++ * @cond: conditional opcode suffix ++ */ ++ .macro adr_l, dst:req, sym:req, cond ++ __adldst_l add, \dst, \sym, \dst, \cond ++ .endm ++ ++ /* ++ * ldr_l - ldr pseudo-op with unlimited range ++ * ++ * @dst: destination register ++ * @sym: name of the symbol ++ * @cond: conditional opcode suffix ++ */ ++ .macro ldr_l, dst:req, sym:req, cond ++ __adldst_l ldr, \dst, \sym, \dst, \cond ++ .endm ++ ++ /* ++ * str_l - str pseudo-op with unlimited range ++ * ++ * @src: source register ++ * @sym: name of the symbol ++ * @tmp: mandatory scratch register ++ * @cond: conditional opcode suffix ++ */ ++ .macro str_l, src:req, sym:req, tmp:req, cond ++ __adldst_l str, \src, \sym, \tmp, \cond ++ .endm ++ + #endif /* __ASM_ASSEMBLER_H__ */ +diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S +index 0dcae787b004d..d2b4ac06e4ed8 100644 +--- a/arch/arm/kernel/iwmmxt.S ++++ b/arch/arm/kernel/iwmmxt.S +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include "iwmmxt.h" + + #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) + #define PJ4(code...) code +@@ -113,33 +114,33 @@ concan_save: + + concan_dump: + +- wstrw wCSSF, [r1, #MMX_WCSSF] +- wstrw wCASF, [r1, #MMX_WCASF] +- wstrw wCGR0, [r1, #MMX_WCGR0] +- wstrw wCGR1, [r1, #MMX_WCGR1] +- wstrw wCGR2, [r1, #MMX_WCGR2] +- wstrw wCGR3, [r1, #MMX_WCGR3] ++ wstrw wCSSF, r1, MMX_WCSSF ++ wstrw wCASF, r1, MMX_WCASF ++ wstrw wCGR0, r1, MMX_WCGR0 ++ wstrw wCGR1, r1, MMX_WCGR1 ++ wstrw wCGR2, r1, MMX_WCGR2 ++ wstrw wCGR3, r1, MMX_WCGR3 + + 1: @ MUP? wRn + tst r2, #0x2 + beq 2f + +- wstrd wR0, [r1, #MMX_WR0] +- wstrd wR1, [r1, #MMX_WR1] +- wstrd wR2, [r1, #MMX_WR2] +- wstrd wR3, [r1, #MMX_WR3] +- wstrd wR4, [r1, #MMX_WR4] +- wstrd wR5, [r1, #MMX_WR5] +- wstrd wR6, [r1, #MMX_WR6] +- wstrd wR7, [r1, #MMX_WR7] +- wstrd wR8, [r1, #MMX_WR8] +- wstrd wR9, [r1, #MMX_WR9] +- wstrd wR10, [r1, #MMX_WR10] +- wstrd wR11, [r1, #MMX_WR11] +- wstrd wR12, [r1, #MMX_WR12] +- wstrd wR13, [r1, #MMX_WR13] +- wstrd wR14, [r1, #MMX_WR14] +- wstrd wR15, [r1, #MMX_WR15] ++ wstrd wR0, r1, MMX_WR0 ++ wstrd wR1, r1, MMX_WR1 ++ wstrd wR2, r1, MMX_WR2 ++ wstrd wR3, r1, MMX_WR3 ++ wstrd wR4, r1, MMX_WR4 ++ wstrd wR5, r1, MMX_WR5 ++ wstrd wR6, r1, MMX_WR6 ++ wstrd wR7, r1, MMX_WR7 ++ wstrd wR8, r1, MMX_WR8 ++ wstrd wR9, r1, MMX_WR9 ++ wstrd wR10, r1, MMX_WR10 ++ wstrd wR11, r1, MMX_WR11 ++ wstrd wR12, r1, MMX_WR12 ++ wstrd wR13, r1, MMX_WR13 ++ wstrd wR14, r1, MMX_WR14 ++ wstrd wR15, r1, MMX_WR15 + + 2: teq r0, #0 @ anything to load? + reteq lr @ if not, return +@@ -147,30 +148,30 @@ concan_dump: + concan_load: + + @ Load wRn +- wldrd wR0, [r0, #MMX_WR0] +- wldrd wR1, [r0, #MMX_WR1] +- wldrd wR2, [r0, #MMX_WR2] +- wldrd wR3, [r0, #MMX_WR3] +- wldrd wR4, [r0, #MMX_WR4] +- wldrd wR5, [r0, #MMX_WR5] +- wldrd wR6, [r0, #MMX_WR6] +- wldrd wR7, [r0, #MMX_WR7] +- wldrd wR8, [r0, #MMX_WR8] +- wldrd wR9, [r0, #MMX_WR9] +- wldrd wR10, [r0, #MMX_WR10] +- wldrd wR11, [r0, #MMX_WR11] +- wldrd wR12, [r0, #MMX_WR12] +- wldrd wR13, [r0, #MMX_WR13] +- wldrd wR14, [r0, #MMX_WR14] +- wldrd wR15, [r0, #MMX_WR15] ++ wldrd wR0, r0, MMX_WR0 ++ wldrd wR1, r0, MMX_WR1 ++ wldrd wR2, r0, MMX_WR2 ++ wldrd wR3, r0, MMX_WR3 ++ wldrd wR4, r0, MMX_WR4 ++ wldrd wR5, r0, MMX_WR5 ++ wldrd wR6, r0, MMX_WR6 ++ wldrd wR7, r0, MMX_WR7 ++ wldrd wR8, r0, MMX_WR8 ++ wldrd wR9, r0, MMX_WR9 ++ wldrd wR10, r0, MMX_WR10 ++ wldrd wR11, r0, MMX_WR11 ++ wldrd wR12, r0, MMX_WR12 ++ wldrd wR13, r0, MMX_WR13 ++ wldrd wR14, r0, MMX_WR14 ++ wldrd wR15, r0, MMX_WR15 + + @ Load wCx +- wldrw wCSSF, [r0, #MMX_WCSSF] +- wldrw wCASF, [r0, #MMX_WCASF] +- wldrw wCGR0, [r0, #MMX_WCGR0] +- wldrw wCGR1, [r0, #MMX_WCGR1] +- wldrw wCGR2, [r0, #MMX_WCGR2] +- wldrw wCGR3, [r0, #MMX_WCGR3] ++ wldrw wCSSF, r0, MMX_WCSSF ++ wldrw wCASF, r0, MMX_WCASF ++ wldrw wCGR0, r0, MMX_WCGR0 ++ wldrw wCGR1, r0, MMX_WCGR1 ++ wldrw wCGR2, r0, MMX_WCGR2 ++ wldrw wCGR3, r0, MMX_WCGR3 + + @ clear CUP/MUP (only if r1 != 0) + teq r1, #0 +diff --git a/arch/arm/kernel/iwmmxt.h b/arch/arm/kernel/iwmmxt.h +new file mode 100644 +index 0000000000000..fb627286f5bb9 +--- /dev/null ++++ b/arch/arm/kernel/iwmmxt.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef __IWMMXT_H__ ++#define __IWMMXT_H__ ++ ++.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ++.set .LwR\b, \b ++.set .Lr\b, \b ++.endr ++ ++.set .LwCSSF, 0x2 ++.set .LwCASF, 0x3 ++.set .LwCGR0, 0x8 ++.set .LwCGR1, 0x9 ++.set .LwCGR2, 0xa ++.set .LwCGR3, 0xb ++ ++.macro wldrd, reg:req, base:req, offset:req ++.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) ++.endm ++ ++.macro wldrw, reg:req, base:req, offset:req ++.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) ++.endm ++ ++.macro wstrd, reg:req, base:req, offset:req ++.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) ++.endm ++ ++.macro wstrw, reg:req, base:req, offset:req ++.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) ++.endm ++ ++#ifdef __clang__ ++ ++#define wCon c1 ++ ++.macro tmrc, dest:req, control:req ++mrc p1, 0, \dest, \control, c0, 0 ++.endm ++ ++.macro tmcr, control:req, src:req ++mcr p1, 0, \src, \control, c0, 0 ++.endm ++#endif ++ ++#endif +diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h +index 54387ccd1ab26..044bb9e2cd74f 100644 +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -49,7 +49,7 @@ + #define __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context 2 + #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa 3 + #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid 4 +-#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_local_vmid 5 ++#define __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context 5 + #define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 6 + #define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7 + #define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_ich_vtr_el2 8 +@@ -180,10 +180,10 @@ DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs); + #define __bp_harden_hyp_vecs CHOOSE_HYP_SYM(__bp_harden_hyp_vecs) + + extern void __kvm_flush_vm_context(void); ++extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu); + extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, + int level); + extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); +-extern void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu); + + extern void __kvm_timer_set_cntvoff(u64 cntvoff); + +diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h +index 6b664de5ec1f4..123e67cb85050 100644 +--- a/arch/arm64/include/asm/kvm_hyp.h ++++ b/arch/arm64/include/asm/kvm_hyp.h +@@ -82,6 +82,11 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt); + void __debug_switch_to_guest(struct kvm_vcpu *vcpu); + void __debug_switch_to_host(struct kvm_vcpu *vcpu); + ++#ifdef __KVM_NVHE_HYPERVISOR__ ++void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu); ++void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu); ++#endif ++ + void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); + void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); + +@@ -94,7 +99,8 @@ u64 __guest_enter(struct kvm_vcpu *vcpu); + + void __noreturn hyp_panic(void); + #ifdef __KVM_NVHE_HYPERVISOR__ +-void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); ++void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, ++ u64 elr, u64 par); + #endif + + #endif /* __ARM64_KVM_HYP_H__ */ +diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h +index 75c8e9a350cc7..505bdd75b5411 100644 +--- a/arch/arm64/include/asm/memory.h ++++ b/arch/arm64/include/asm/memory.h +@@ -306,6 +306,11 @@ static inline void *phys_to_virt(phys_addr_t x) + #define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET) + + #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL) ++#define page_to_virt(x) ({ \ ++ __typeof__(x) __page = x; \ ++ void *__addr = __va(page_to_phys(__page)); \ ++ (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ ++}) + #define virt_to_page(x) pfn_to_page(virt_to_pfn(x)) + #else + #define page_to_virt(x) ({ \ +diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h +index 0672236e1aeab..4e2ba94778450 100644 +--- a/arch/arm64/include/asm/mmu_context.h ++++ b/arch/arm64/include/asm/mmu_context.h +@@ -65,10 +65,7 @@ extern u64 idmap_ptrs_per_pgd; + + static inline bool __cpu_uses_extended_idmap(void) + { +- if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52)) +- return false; +- +- return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)); ++ return unlikely(idmap_t0sz != TCR_T0SZ(vabits_actual)); + } + + /* +diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h +index 046be789fbb47..9a65fb5281100 100644 +--- a/arch/arm64/include/asm/pgtable-prot.h ++++ b/arch/arm64/include/asm/pgtable-prot.h +@@ -66,7 +66,6 @@ extern bool arm64_use_ng_mappings; + #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) + + #define PAGE_KERNEL __pgprot(PROT_NORMAL) +-#define PAGE_KERNEL_TAGGED __pgprot(PROT_NORMAL_TAGGED) + #define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY) + #define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY) + #define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN) +diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h +index 5628289b9d5e6..717f13d52ecc5 100644 +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -484,6 +484,9 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) + #define pgprot_device(prot) \ + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) ++#define pgprot_tagged(prot) \ ++ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_TAGGED)) ++#define pgprot_mhp pgprot_tagged + /* + * DMA allocations for non-coherent devices use what the Arm architecture calls + * "Normal non-cacheable" memory, which permits speculation, unaligned accesses +diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S +index e7550a5289fef..78cdd6b24172c 100644 +--- a/arch/arm64/kernel/head.S ++++ b/arch/arm64/kernel/head.S +@@ -334,7 +334,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables) + */ + adrp x5, __idmap_text_end + clz x5, x5 +- cmp x5, TCR_T0SZ(VA_BITS) // default T0SZ small enough? ++ cmp x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough? + b.ge 1f // .. then skip VA range extension + + adr_l x6, idmap_t0sz +diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c +index 3605f77ad4df1..11852e05ee32a 100644 +--- a/arch/arm64/kernel/perf_event.c ++++ b/arch/arm64/kernel/perf_event.c +@@ -460,7 +460,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx) + return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); + } + +-static inline u32 armv8pmu_read_evcntr(int idx) ++static inline u64 armv8pmu_read_evcntr(int idx) + { + u32 counter = ARMV8_IDX_TO_COUNTER(idx); + +diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c +index c0ffb019ca8be..a1c2c955474e9 100644 +--- a/arch/arm64/kvm/arm.c ++++ b/arch/arm64/kvm/arm.c +@@ -352,11 +352,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + last_ran = this_cpu_ptr(mmu->last_vcpu_ran); + + /* ++ * We guarantee that both TLBs and I-cache are private to each ++ * vcpu. If detecting that a vcpu from the same VM has ++ * previously run on the same physical CPU, call into the ++ * hypervisor code to nuke the relevant contexts. ++ * + * We might get preempted before the vCPU actually runs, but + * over-invalidation doesn't affect correctness. + */ + if (*last_ran != vcpu->vcpu_id) { +- kvm_call_hyp(__kvm_tlb_flush_local_vmid, mmu); ++ kvm_call_hyp(__kvm_flush_cpu_context, mmu); + *last_ran = vcpu->vcpu_id; + } + +diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S +index b0afad7a99c6e..0c66a1d408fd7 100644 +--- a/arch/arm64/kvm/hyp/entry.S ++++ b/arch/arm64/kvm/hyp/entry.S +@@ -146,7 +146,7 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) + // Now restore the hyp regs + restore_callee_saved_regs x2 + +- set_loaded_vcpu xzr, x1, x2 ++ set_loaded_vcpu xzr, x2, x3 + + alternative_if ARM64_HAS_RAS_EXTN + // If we have the RAS extensions we can consume a pending error +diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c +index 91a711aa8382e..f401724f12ef7 100644 +--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c ++++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c +@@ -58,16 +58,24 @@ static void __debug_restore_spe(u64 pmscr_el1) + write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1); + } + +-void __debug_switch_to_guest(struct kvm_vcpu *vcpu) ++void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) + { + /* Disable and flush SPE data generation */ + __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); ++} ++ ++void __debug_switch_to_guest(struct kvm_vcpu *vcpu) ++{ + __debug_switch_to_guest_common(vcpu); + } + +-void __debug_switch_to_host(struct kvm_vcpu *vcpu) ++void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) + { + __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); ++} ++ ++void __debug_switch_to_host(struct kvm_vcpu *vcpu) ++{ + __debug_switch_to_host_common(vcpu); + } + +diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S +index ed27f06a31ba2..4ce934fc1f72a 100644 +--- a/arch/arm64/kvm/hyp/nvhe/host.S ++++ b/arch/arm64/kvm/hyp/nvhe/host.S +@@ -64,10 +64,15 @@ __host_enter_without_restoring: + SYM_FUNC_END(__host_exit) + + /* +- * void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); ++ * void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, ++ * u64 elr, u64 par); + */ + SYM_FUNC_START(__hyp_do_panic) +- /* Load the format arguments into x1-7 */ ++ mov x29, x0 ++ ++ /* Load the format string into x0 and arguments into x1-7 */ ++ ldr x0, =__hyp_panic_string ++ + mov x6, x3 + get_vcpu_ptr x7, x3 + +@@ -82,13 +87,8 @@ SYM_FUNC_START(__hyp_do_panic) + ldr lr, =panic + msr elr_el2, lr + +- /* +- * Set the panic format string and enter the host, conditionally +- * restoring the host context. +- */ +- cmp x0, xzr +- ldr x0, =__hyp_panic_string +- b.eq __host_enter_without_restoring ++ /* Enter the host, conditionally restoring the host context. */ ++ cbz x29, __host_enter_without_restoring + b __host_enter_for_panic + SYM_FUNC_END(__hyp_do_panic) + +@@ -144,7 +144,7 @@ SYM_FUNC_END(__hyp_do_panic) + + .macro invalid_host_el1_vect + .align 7 +- mov x0, xzr /* restore_host = false */ ++ mov x0, xzr /* host_ctxt = NULL */ + mrs x1, spsr_el2 + mrs x2, elr_el2 + mrs x3, par_el1 +diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c +index e2eafe2c93aff..3df30b459215b 100644 +--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c ++++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c +@@ -46,11 +46,11 @@ static void handle_host_hcall(unsigned long func_id, + __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); + break; + } +- case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_local_vmid): { ++ case KVM_HOST_SMCCC_FUNC(__kvm_flush_cpu_context): { + unsigned long r1 = host_ctxt->regs.regs[1]; + struct kvm_s2_mmu *mmu = (struct kvm_s2_mmu *)r1; + +- __kvm_tlb_flush_local_vmid(kern_hyp_va(mmu)); ++ __kvm_flush_cpu_context(kern_hyp_va(mmu)); + break; + } + case KVM_HOST_SMCCC_FUNC(__kvm_timer_set_cntvoff): { +diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c +index 8ae8160bc93ab..6624596846d3d 100644 +--- a/arch/arm64/kvm/hyp/nvhe/switch.c ++++ b/arch/arm64/kvm/hyp/nvhe/switch.c +@@ -188,6 +188,14 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) + pmu_switch_needed = __pmu_switch_to_guest(host_ctxt); + + __sysreg_save_state_nvhe(host_ctxt); ++ /* ++ * We must flush and disable the SPE buffer for nVHE, as ++ * the translation regime(EL1&0) is going to be loaded with ++ * that of the guest. And we must do this before we change the ++ * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and ++ * before we load guest Stage1. ++ */ ++ __debug_save_host_buffers_nvhe(vcpu); + + /* + * We must restore the 32-bit state before the sysregs, thanks +@@ -228,11 +236,12 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) + if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) + __fpsimd_save_fpexc32(vcpu); + ++ __debug_switch_to_host(vcpu); + /* + * This must come after restoring the host sysregs, since a non-VHE + * system may enable SPE here and make use of the TTBRs. + */ +- __debug_switch_to_host(vcpu); ++ __debug_restore_host_buffers_nvhe(vcpu); + + if (pmu_switch_needed) + __pmu_switch_to_host(host_ctxt); +@@ -251,7 +260,6 @@ void __noreturn hyp_panic(void) + u64 spsr = read_sysreg_el2(SYS_SPSR); + u64 elr = read_sysreg_el2(SYS_ELR); + u64 par = read_sysreg_par(); +- bool restore_host = true; + struct kvm_cpu_context *host_ctxt; + struct kvm_vcpu *vcpu; + +@@ -265,7 +273,7 @@ void __noreturn hyp_panic(void) + __sysreg_restore_state_nvhe(host_ctxt); + } + +- __hyp_do_panic(restore_host, spsr, elr, par); ++ __hyp_do_panic(host_ctxt, spsr, elr, par); + unreachable(); + } + +diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c +index fbde89a2c6e83..229b06748c208 100644 +--- a/arch/arm64/kvm/hyp/nvhe/tlb.c ++++ b/arch/arm64/kvm/hyp/nvhe/tlb.c +@@ -123,7 +123,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) + __tlb_switch_to_host(&cxt); + } + +-void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) ++void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu) + { + struct tlb_inv_context cxt; + +@@ -131,6 +131,7 @@ void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) + __tlb_switch_to_guest(mmu, &cxt); + + __tlbi(vmalle1); ++ asm volatile("ic iallu"); + dsb(nsh); + isb(); + +diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c +index bdf8e55ed308e..4d99d07c610c8 100644 +--- a/arch/arm64/kvm/hyp/pgtable.c ++++ b/arch/arm64/kvm/hyp/pgtable.c +@@ -225,6 +225,7 @@ static inline int __kvm_pgtable_visit(struct kvm_pgtable_walk_data *data, + goto out; + + if (!table) { ++ data->addr = ALIGN_DOWN(data->addr, kvm_granule_size(level)); + data->addr += kvm_granule_size(level); + goto out; + } +diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c +index fd7895945bbc6..66f17349f0c36 100644 +--- a/arch/arm64/kvm/hyp/vhe/tlb.c ++++ b/arch/arm64/kvm/hyp/vhe/tlb.c +@@ -127,7 +127,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) + __tlb_switch_to_host(&cxt); + } + +-void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) ++void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu) + { + struct tlb_inv_context cxt; + +@@ -135,6 +135,7 @@ void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu) + __tlb_switch_to_guest(mmu, &cxt); + + __tlbi(vmalle1); ++ asm volatile("ic iallu"); + dsb(nsh); + isb(); + +diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c +index 75814a02d1894..26068456ec0f3 100644 +--- a/arch/arm64/kvm/mmu.c ++++ b/arch/arm64/kvm/mmu.c +@@ -1309,8 +1309,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + * Prevent userspace from creating a memory region outside of the IPA + * space addressable by the KVM guest IPA space. + */ +- if (memslot->base_gfn + memslot->npages >= +- (kvm_phys_size(kvm) >> PAGE_SHIFT)) ++ if ((memslot->base_gfn + memslot->npages) > (kvm_phys_size(kvm) >> PAGE_SHIFT)) + return -EFAULT; + + mmap_read_lock(current->mm); +diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c +index f32490229a4c7..e911eea36eb0e 100644 +--- a/arch/arm64/kvm/reset.c ++++ b/arch/arm64/kvm/reset.c +@@ -373,10 +373,9 @@ int kvm_set_ipa_limit(void) + } + + kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange); +- WARN(kvm_ipa_limit < KVM_PHYS_SHIFT, +- "KVM IPA Size Limit (%d bits) is smaller than default size\n", +- kvm_ipa_limit); +- kvm_info("IPA Size Limit: %d bits\n", kvm_ipa_limit); ++ kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit, ++ ((kvm_ipa_limit < KVM_PHYS_SHIFT) ? ++ " (Reduced IPA size, limited VM/VMM compatibility)" : "")); + + return 0; + } +@@ -405,6 +404,11 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type) + return -EINVAL; + } else { + phys_shift = KVM_PHYS_SHIFT; ++ if (phys_shift > kvm_ipa_limit) { ++ pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n", ++ current->comm); ++ return -EINVAL; ++ } + } + + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); +diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c +index b913844ab7404..916e0547fdccf 100644 +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -218,6 +218,18 @@ int pfn_valid(unsigned long pfn) + + if (!valid_section(__pfn_to_section(pfn))) + return 0; ++ ++ /* ++ * ZONE_DEVICE memory does not have the memblock entries. ++ * memblock_is_map_memory() check for ZONE_DEVICE based ++ * addresses will always fail. Even the normal hotplugged ++ * memory will never have MEMBLOCK_NOMAP flag set in their ++ * memblock entries. Skip memblock search for all non early ++ * memory sections covering all of hotplug memory including ++ * both normal and ZONE_DEVICE based. ++ */ ++ if (!early_section(__pfn_to_section(pfn))) ++ return pfn_section_valid(__pfn_to_section(pfn), pfn); + #endif + return memblock_is_map_memory(addr); + } +diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c +index ca692a8157315..6aabf1eced31e 100644 +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -40,7 +40,7 @@ + #define NO_BLOCK_MAPPINGS BIT(0) + #define NO_CONT_MAPPINGS BIT(1) + +-u64 idmap_t0sz = TCR_T0SZ(VA_BITS); ++u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN); + u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; + + u64 __section(".mmuoff.data.write") vabits_actual; +@@ -502,7 +502,8 @@ static void __init map_mem(pgd_t *pgdp) + * if MTE is present. Otherwise, it has the same attributes as + * PAGE_KERNEL. + */ +- __map_memblock(pgdp, start, end, PAGE_KERNEL_TAGGED, flags); ++ __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL), ++ flags); + } + + /* +diff --git a/arch/mips/crypto/Makefile b/arch/mips/crypto/Makefile +index 8e1deaf00e0c0..5e4105cccf9fa 100644 +--- a/arch/mips/crypto/Makefile ++++ b/arch/mips/crypto/Makefile +@@ -12,8 +12,8 @@ AFLAGS_chacha-core.o += -O2 # needed to fill branch delay slots + obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o + poly1305-mips-y := poly1305-core.o poly1305-glue.o + +-perlasm-flavour-$(CONFIG_CPU_MIPS32) := o32 +-perlasm-flavour-$(CONFIG_CPU_MIPS64) := 64 ++perlasm-flavour-$(CONFIG_32BIT) := o32 ++perlasm-flavour-$(CONFIG_64BIT) := 64 + + quiet_cmd_perlasm = PERLASM $@ + cmd_perlasm = $(PERL) $(<) $(perlasm-flavour-y) $(@) +diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h +index eacc9102c2515..d5b3c3bb95b40 100644 +--- a/arch/powerpc/include/asm/code-patching.h ++++ b/arch/powerpc/include/asm/code-patching.h +@@ -73,7 +73,7 @@ void __patch_exception(int exc, unsigned long addr); + #endif + + #define OP_RT_RA_MASK 0xffff0000UL +-#define LIS_R2 0x3c020000UL ++#define LIS_R2 0x3c400000UL + #define ADDIS_R2_R12 0x3c4c0000UL + #define ADDI_R2_R2 0x38420000UL + +diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h +index 475687f24f4ad..d319160d790c0 100644 +--- a/arch/powerpc/include/asm/machdep.h ++++ b/arch/powerpc/include/asm/machdep.h +@@ -59,6 +59,9 @@ struct machdep_calls { + int (*pcibios_root_bridge_prepare)(struct pci_host_bridge + *bridge); + ++ /* finds all the pci_controllers present at boot */ ++ void (*discover_phbs)(void); ++ + /* To setup PHBs when using automatic OF platform driver for PCI */ + int (*pci_setup_phb)(struct pci_controller *host); + +diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h +index e2c778c176a3a..d6f262df4f346 100644 +--- a/arch/powerpc/include/asm/ptrace.h ++++ b/arch/powerpc/include/asm/ptrace.h +@@ -62,6 +62,9 @@ struct pt_regs + }; + #endif + ++ ++#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)) ++ + #ifdef __powerpc64__ + + /* +@@ -190,7 +193,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno, + #define TRAP_FLAGS_MASK 0x11 + #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) + #define FULL_REGS(regs) (((regs)->trap & 1) == 0) +-#define SET_FULL_REGS(regs) ((regs)->trap |= 1) ++#define SET_FULL_REGS(regs) ((regs)->trap &= ~1) + #endif + #define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs)) + #define NV_REG_POISON 0xdeadbeefdeadbeefUL +@@ -205,7 +208,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno, + #define TRAP_FLAGS_MASK 0x1F + #define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK) + #define FULL_REGS(regs) (((regs)->trap & 1) == 0) +-#define SET_FULL_REGS(regs) ((regs)->trap |= 1) ++#define SET_FULL_REGS(regs) ((regs)->trap &= ~1) + #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0) + #define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0) + #define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0) +diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h +index fdab934283721..9d1fbd8be1c74 100644 +--- a/arch/powerpc/include/asm/switch_to.h ++++ b/arch/powerpc/include/asm/switch_to.h +@@ -71,6 +71,16 @@ static inline void disable_kernel_vsx(void) + { + msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); + } ++#else ++static inline void enable_kernel_vsx(void) ++{ ++ BUILD_BUG(); ++} ++ ++static inline void disable_kernel_vsx(void) ++{ ++ BUILD_BUG(); ++} + #endif + + #ifdef CONFIG_SPE +diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c +index c2722ff36e982..5c125255571cd 100644 +--- a/arch/powerpc/kernel/asm-offsets.c ++++ b/arch/powerpc/kernel/asm-offsets.c +@@ -307,7 +307,7 @@ int main(void) + + /* Interrupt register frame */ + DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE); +- DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); ++ DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_WITH_PT_REGS); + STACK_PT_REGS_OFFSET(GPR0, gpr[0]); + STACK_PT_REGS_OFFSET(GPR1, gpr[1]); + STACK_PT_REGS_OFFSET(GPR2, gpr[2]); +diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S +index 3cde2fbd74fce..9d3b468bd2d7a 100644 +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -470,7 +470,7 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real) + + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + /* MSR[RI] is clear iff using SRR regs */ +- .if IHSRR == EXC_HV_OR_STD ++ .if IHSRR_IF_HVMODE + BEGIN_FTR_SECTION + xori r10,r10,MSR_RI + END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) +diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S +index 2729d8fa6e77c..96b45901da647 100644 +--- a/arch/powerpc/kernel/head_book3s_32.S ++++ b/arch/powerpc/kernel/head_book3s_32.S +@@ -461,10 +461,11 @@ InstructionTLBMiss: + cmplw 0,r1,r3 + #endif + mfspr r2, SPRN_SPRG_PGDIR +- li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC ++ li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER + #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) + bgt- 112f + lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ ++ li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC + addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ + #endif + 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ +@@ -523,9 +524,10 @@ DataLoadTLBMiss: + lis r1, TASK_SIZE@h /* check if kernel address */ + cmplw 0,r1,r3 + mfspr r2, SPRN_SPRG_PGDIR +- li r1, _PAGE_PRESENT | _PAGE_ACCESSED ++ li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER + bgt- 112f + lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ ++ li r1, _PAGE_PRESENT | _PAGE_ACCESSED + addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ + 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ + lwz r2,0(r2) /* get pmd entry */ +@@ -599,9 +601,10 @@ DataStoreTLBMiss: + lis r1, TASK_SIZE@h /* check if kernel address */ + cmplw 0,r1,r3 + mfspr r2, SPRN_SPRG_PGDIR +- li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED ++ li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER + bgt- 112f + lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ ++ li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED + addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ + 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ + lwz r2,0(r2) /* get pmd entry */ +diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c +index be108616a721f..7920559a1ca81 100644 +--- a/arch/powerpc/kernel/pci-common.c ++++ b/arch/powerpc/kernel/pci-common.c +@@ -1625,3 +1625,13 @@ static void fixup_hide_host_resource_fsl(struct pci_dev *dev) + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); ++ ++ ++static int __init discover_phbs(void) ++{ ++ if (ppc_md.discover_phbs) ++ ppc_md.discover_phbs(); ++ ++ return 0; ++} ++core_initcall(discover_phbs); +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index d421a2c7f8224..1a1d2657fe8dd 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -2170,7 +2170,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack, + * See if this is an exception frame. + * We look for the "regshere" marker in the current frame. + */ +- if (validate_sp(sp, tsk, STACK_INT_FRAME_SIZE) ++ if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS) + && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { + struct pt_regs *regs = (struct pt_regs *) + (sp + STACK_FRAME_OVERHEAD); +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index 5006dcbe1d9fd..77dffea3d5373 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -509,8 +509,11 @@ out: + die("Unrecoverable nested System Reset", regs, SIGABRT); + #endif + /* Must die if the interrupt is not recoverable */ +- if (!(regs->msr & MSR_RI)) ++ if (!(regs->msr & MSR_RI)) { ++ /* For the reason explained in die_mce, nmi_exit before die */ ++ nmi_exit(); + die("Unrecoverable System Reset", regs, SIGABRT); ++ } + + if (saved_hsrrs) { + mtspr(SPRN_HSRR0, hsrr0); +diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c +index 43599e671d383..ded4a3efd3f06 100644 +--- a/arch/powerpc/perf/core-book3s.c ++++ b/arch/powerpc/perf/core-book3s.c +@@ -211,7 +211,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs * + if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid) + *addrp = mfspr(SPRN_SDAR); + +- if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0) ++ if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel) + *addrp = 0; + } + +@@ -477,7 +477,7 @@ static void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events * + * addresses, hence include a check before filtering code + */ + if (!(ppmu->flags & PPMU_ARCH_31) && +- is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0) ++ is_kernel_addr(addr) && event->attr.exclude_kernel) + continue; + + /* Branches are read most recent first (ie. mfbhrb 0 is +@@ -2112,7 +2112,17 @@ static void record_and_restart(struct perf_event *event, unsigned long val, + left += period; + if (left <= 0) + left = period; +- record = siar_valid(regs); ++ ++ /* ++ * If address is not requested in the sample via ++ * PERF_SAMPLE_IP, just record that sample irrespective ++ * of SIAR valid check. ++ */ ++ if (event->attr.sample_type & PERF_SAMPLE_IP) ++ record = siar_valid(regs); ++ else ++ record = 1; ++ + event->hw.last_period = event->hw.sample_period; + } + if (left < 0x80000000LL) +@@ -2130,9 +2140,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val, + * MMCR2. Check attr.exclude_kernel and address to drop the sample in + * these cases. + */ +- if (event->attr.exclude_kernel && record) +- if (is_kernel_addr(mfspr(SPRN_SIAR))) +- record = 0; ++ if (event->attr.exclude_kernel && ++ (event->attr.sample_type & PERF_SAMPLE_IP) && ++ is_kernel_addr(mfspr(SPRN_SIAR))) ++ record = 0; + + /* + * Finally record data if requested. +diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c +index b3ac2455faadc..637300330507f 100644 +--- a/arch/powerpc/platforms/pseries/msi.c ++++ b/arch/powerpc/platforms/pseries/msi.c +@@ -4,6 +4,7 @@ + * Copyright 2006-2007 Michael Ellerman, IBM Corp. + */ + ++#include + #include + #include + #include +@@ -458,8 +459,28 @@ again: + return hwirq; + } + +- virq = irq_create_mapping_affinity(NULL, hwirq, +- entry->affinity); ++ /* ++ * Depending on the number of online CPUs in the original ++ * kernel, it is likely for CPU #0 to be offline in a kdump ++ * kernel. The associated IRQs in the affinity mappings ++ * provided by irq_create_affinity_masks() are thus not ++ * started by irq_startup(), as per-design for managed IRQs. ++ * This can be a problem with multi-queue block devices driven ++ * by blk-mq : such a non-started IRQ is very likely paired ++ * with the single queue enforced by blk-mq during kdump (see ++ * blk_mq_alloc_tag_set()). This causes the device to remain ++ * silent and likely hangs the guest at some point. ++ * ++ * We don't really care for fine-grained affinity when doing ++ * kdump actually : simply ignore the pre-computed affinity ++ * masks in this case and let the default mask with all CPUs ++ * be used when creating the IRQ mappings. ++ */ ++ if (is_kdump_kernel()) ++ virq = irq_create_mapping(NULL, hwirq); ++ else ++ virq = irq_create_mapping_affinity(NULL, hwirq, ++ entry->affinity); + + if (!virq) { + pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 3a0d545f0ce84..791bc373418bd 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -775,7 +775,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail, + static int __smp_rescan_cpus(struct sclp_core_info *info, bool early) + { + struct sclp_core_entry *core; +- cpumask_t avail; ++ static cpumask_t avail; + bool configured; + u16 core_id; + int nr, i; +diff --git a/arch/sparc/include/asm/mman.h b/arch/sparc/include/asm/mman.h +index f94532f25db14..274217e7ed702 100644 +--- a/arch/sparc/include/asm/mman.h ++++ b/arch/sparc/include/asm/mman.h +@@ -57,35 +57,39 @@ static inline int sparc_validate_prot(unsigned long prot, unsigned long addr) + { + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI)) + return 0; +- if (prot & PROT_ADI) { +- if (!adi_capable()) +- return 0; ++ return 1; ++} + +- if (addr) { +- struct vm_area_struct *vma; ++#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) ++/* arch_validate_flags() - Ensure combination of flags is valid for a ++ * VMA. ++ */ ++static inline bool arch_validate_flags(unsigned long vm_flags) ++{ ++ /* If ADI is being enabled on this VMA, check for ADI ++ * capability on the platform and ensure VMA is suitable ++ * for ADI ++ */ ++ if (vm_flags & VM_SPARC_ADI) { ++ if (!adi_capable()) ++ return false; + +- vma = find_vma(current->mm, addr); +- if (vma) { +- /* ADI can not be enabled on PFN +- * mapped pages +- */ +- if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) +- return 0; ++ /* ADI can not be enabled on PFN mapped pages */ ++ if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) ++ return false; + +- /* Mergeable pages can become unmergeable +- * if ADI is enabled on them even if they +- * have identical data on them. This can be +- * because ADI enabled pages with identical +- * data may still not have identical ADI +- * tags on them. Disallow ADI on mergeable +- * pages. +- */ +- if (vma->vm_flags & VM_MERGEABLE) +- return 0; +- } +- } ++ /* Mergeable pages can become unmergeable ++ * if ADI is enabled on them even if they ++ * have identical data on them. This can be ++ * because ADI enabled pages with identical ++ * data may still not have identical ADI ++ * tags on them. Disallow ADI on mergeable ++ * pages. ++ */ ++ if (vm_flags & VM_MERGEABLE) ++ return false; + } +- return 1; ++ return true; + } + #endif /* CONFIG_SPARC64 */ + +diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c +index eb2946b1df8a4..6139c5700ccc9 100644 +--- a/arch/sparc/mm/init_32.c ++++ b/arch/sparc/mm/init_32.c +@@ -197,6 +197,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) + size = memblock_phys_mem_size() - memblock_reserved_size(); + *pages_avail = (size >> PAGE_SHIFT) - high_pages; + ++ /* Only allow low memory to be allocated via memblock allocation */ ++ memblock_set_current_limit(max_low_pfn << PAGE_SHIFT); ++ + return max_pfn; + } + +diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c +index de5358671750d..2e4d91f3feea4 100644 +--- a/arch/x86/entry/common.c ++++ b/arch/x86/entry/common.c +@@ -128,7 +128,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) + regs->ax = -EFAULT; + + instrumentation_end(); +- syscall_exit_to_user_mode(regs); ++ local_irq_disable(); ++ irqentry_exit_to_user_mode(regs); + return false; + } + +@@ -213,40 +214,6 @@ SYSCALL_DEFINE0(ni_syscall) + return -ENOSYS; + } + +-noinstr bool idtentry_enter_nmi(struct pt_regs *regs) +-{ +- bool irq_state = lockdep_hardirqs_enabled(); +- +- __nmi_enter(); +- lockdep_hardirqs_off(CALLER_ADDR0); +- lockdep_hardirq_enter(); +- rcu_nmi_enter(); +- +- instrumentation_begin(); +- trace_hardirqs_off_finish(); +- ftrace_nmi_enter(); +- instrumentation_end(); +- +- return irq_state; +-} +- +-noinstr void idtentry_exit_nmi(struct pt_regs *regs, bool restore) +-{ +- instrumentation_begin(); +- ftrace_nmi_exit(); +- if (restore) { +- trace_hardirqs_on_prepare(); +- lockdep_hardirqs_on_prepare(CALLER_ADDR0); +- } +- instrumentation_end(); +- +- rcu_nmi_exit(); +- lockdep_hardirq_exit(); +- if (restore) +- lockdep_hardirqs_on(CALLER_ADDR0); +- __nmi_exit(); +-} +- + #ifdef CONFIG_XEN_PV + #ifndef CONFIG_PREEMPTION + /* +diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S +index 541fdaf640453..0051cf5c792d1 100644 +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -210,6 +210,8 @@ SYM_CODE_START(entry_SYSCALL_compat) + /* Switch to the kernel stack */ + movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp + ++SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL) ++ + /* Construct struct pt_regs on stack */ + pushq $__USER32_DS /* pt_regs->ss */ + pushq %r8 /* pt_regs->sp */ +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index aaa7bffdb20f5..4b05c876f9f69 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3565,8 +3565,10 @@ static int intel_pmu_hw_config(struct perf_event *event) + if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) { + event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; + if (!(event->attr.sample_type & +- ~intel_pmu_large_pebs_flags(event))) ++ ~intel_pmu_large_pebs_flags(event))) { + event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS; ++ event->attach_state |= PERF_ATTACH_SCHED_CB; ++ } + } + if (x86_pmu.pebs_aliases) + x86_pmu.pebs_aliases(event); +@@ -3579,6 +3581,7 @@ static int intel_pmu_hw_config(struct perf_event *event) + ret = intel_pmu_setup_lbr_filter(event); + if (ret) + return ret; ++ event->attach_state |= PERF_ATTACH_SCHED_CB; + + /* + * BTS is set up earlier in this path, so don't account twice +diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h +index eb01c2618a9df..f656aabd1545c 100644 +--- a/arch/x86/include/asm/idtentry.h ++++ b/arch/x86/include/asm/idtentry.h +@@ -11,9 +11,6 @@ + + #include + +-bool idtentry_enter_nmi(struct pt_regs *regs); +-void idtentry_exit_nmi(struct pt_regs *regs, bool irq_state); +- + /** + * DECLARE_IDTENTRY - Declare functions for simple IDT entry points + * No error code pushed by hardware +diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h +index a0f839aa144d9..98b4dae5e8bc8 100644 +--- a/arch/x86/include/asm/insn-eval.h ++++ b/arch/x86/include/asm/insn-eval.h +@@ -23,6 +23,8 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); + int insn_get_code_seg_params(struct pt_regs *regs); + int insn_fetch_from_user(struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE]); ++int insn_fetch_from_user_inatomic(struct pt_regs *regs, ++ unsigned char buf[MAX_INSN_SIZE]); + bool insn_decode(struct insn *insn, struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE], int buf_size); + +diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h +index 2c35f1c01a2df..b6a9d51d1d791 100644 +--- a/arch/x86/include/asm/proto.h ++++ b/arch/x86/include/asm/proto.h +@@ -25,6 +25,7 @@ void __end_SYSENTER_singlestep_region(void); + void entry_SYSENTER_compat(void); + void __end_entry_SYSENTER_compat(void); + void entry_SYSCALL_compat(void); ++void entry_SYSCALL_compat_safe_stack(void); + void entry_INT80_compat(void); + #ifdef CONFIG_XEN_PV + void xen_entry_INT80_compat(void); +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index d8324a2366961..409f661481e11 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -94,6 +94,8 @@ struct pt_regs { + #include + #endif + ++#include ++ + struct cpuinfo_x86; + struct task_struct; + +@@ -175,6 +177,19 @@ static inline bool any_64bit_mode(struct pt_regs *regs) + #ifdef CONFIG_X86_64 + #define current_user_stack_pointer() current_pt_regs()->sp + #define compat_user_stack_pointer() current_pt_regs()->sp ++ ++static inline bool ip_within_syscall_gap(struct pt_regs *regs) ++{ ++ bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 && ++ regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack); ++ ++#ifdef CONFIG_IA32_EMULATION ++ ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat && ++ regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack); ++#endif ++ ++ return ret; ++} + #endif + + static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c +index 311688202ea51..b7a27589dfa0b 100644 +--- a/arch/x86/kernel/cpu/mce/core.c ++++ b/arch/x86/kernel/cpu/mce/core.c +@@ -1986,7 +1986,7 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check; + + static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) + { +- bool irq_state; ++ irqentry_state_t irq_state; + + WARN_ON_ONCE(user_mode(regs)); + +@@ -1998,7 +1998,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) + mce_check_crashing_cpu()) + return; + +- irq_state = idtentry_enter_nmi(regs); ++ irq_state = irqentry_nmi_enter(regs); + /* + * The call targets are marked noinstr, but objtool can't figure + * that out because it's an indirect call. Annotate it. +@@ -2009,7 +2009,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) + if (regs->flags & X86_EFLAGS_IF) + trace_hardirqs_on_prepare(); + instrumentation_end(); +- idtentry_exit_nmi(regs, irq_state); ++ irqentry_nmi_exit(regs, irq_state); + } + + static __always_inline void exc_machine_check_user(struct pt_regs *regs) +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index 34b18f6eeb2ce..5ee705b44560b 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -269,21 +269,20 @@ static void __init kvmclock_init_mem(void) + + static int __init kvm_setup_vsyscall_timeinfo(void) + { +-#ifdef CONFIG_X86_64 +- u8 flags; ++ kvmclock_init_mem(); + +- if (!per_cpu(hv_clock_per_cpu, 0) || !kvmclock_vsyscall) +- return 0; ++#ifdef CONFIG_X86_64 ++ if (per_cpu(hv_clock_per_cpu, 0) && kvmclock_vsyscall) { ++ u8 flags; + +- flags = pvclock_read_flags(&hv_clock_boot[0].pvti); +- if (!(flags & PVCLOCK_TSC_STABLE_BIT)) +- return 0; ++ flags = pvclock_read_flags(&hv_clock_boot[0].pvti); ++ if (!(flags & PVCLOCK_TSC_STABLE_BIT)) ++ return 0; + +- kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK; ++ kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK; ++ } + #endif + +- kvmclock_init_mem(); +- + return 0; + } + early_initcall(kvm_setup_vsyscall_timeinfo); +diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c +index 4bc77aaf13039..bf250a339655f 100644 +--- a/arch/x86/kernel/nmi.c ++++ b/arch/x86/kernel/nmi.c +@@ -475,7 +475,7 @@ static DEFINE_PER_CPU(unsigned long, nmi_dr7); + + DEFINE_IDTENTRY_RAW(exc_nmi) + { +- bool irq_state; ++ irqentry_state_t irq_state; + + /* + * Re-enable NMIs right here when running as an SEV-ES guest. This might +@@ -502,14 +502,14 @@ nmi_restart: + + this_cpu_write(nmi_dr7, local_db_save()); + +- irq_state = idtentry_enter_nmi(regs); ++ irq_state = irqentry_nmi_enter(regs); + + inc_irq_stat(__nmi_count); + + if (!ignore_nmis) + default_do_nmi(regs); + +- idtentry_exit_nmi(regs, irq_state); ++ irqentry_nmi_exit(regs, irq_state); + + local_db_restore(this_cpu_read(nmi_dr7)); + +diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c +index 84c1821819afb..04a780abb512d 100644 +--- a/arch/x86/kernel/sev-es.c ++++ b/arch/x86/kernel/sev-es.c +@@ -121,8 +121,18 @@ static void __init setup_vc_stacks(int cpu) + cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); + } + +-static __always_inline bool on_vc_stack(unsigned long sp) ++static __always_inline bool on_vc_stack(struct pt_regs *regs) + { ++ unsigned long sp = regs->sp; ++ ++ /* User-mode RSP is not trusted */ ++ if (user_mode(regs)) ++ return false; ++ ++ /* SYSCALL gap still has user-mode RSP */ ++ if (ip_within_syscall_gap(regs)) ++ return false; ++ + return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC))); + } + +@@ -144,7 +154,7 @@ void noinstr __sev_es_ist_enter(struct pt_regs *regs) + old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); + + /* Make room on the IST stack */ +- if (on_vc_stack(regs->sp)) ++ if (on_vc_stack(regs)) + new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist); + else + new_ist = old_ist - sizeof(old_ist); +@@ -248,7 +258,7 @@ static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) + int res; + + if (user_mode(ctxt->regs)) { +- res = insn_fetch_from_user(ctxt->regs, buffer); ++ res = insn_fetch_from_user_inatomic(ctxt->regs, buffer); + if (!res) { + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; +@@ -1248,13 +1258,12 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs) + DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + { + struct sev_es_runtime_data *data = this_cpu_read(runtime_data); ++ irqentry_state_t irq_state; + struct ghcb_state state; + struct es_em_ctxt ctxt; + enum es_result result; + struct ghcb *ghcb; + +- lockdep_assert_irqs_disabled(); +- + /* + * Handle #DB before calling into !noinstr code to avoid recursive #DB. + */ +@@ -1263,6 +1272,8 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + return; + } + ++ irq_state = irqentry_nmi_enter(regs); ++ lockdep_assert_irqs_disabled(); + instrumentation_begin(); + + /* +@@ -1325,6 +1336,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + + out: + instrumentation_end(); ++ irqentry_nmi_exit(regs, irq_state); + + return; + +diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c +index 170c94ec00685..7692bf7908e6c 100644 +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -406,7 +406,7 @@ DEFINE_IDTENTRY_DF(exc_double_fault) + } + #endif + +- idtentry_enter_nmi(regs); ++ irqentry_nmi_enter(regs); + instrumentation_begin(); + notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); + +@@ -652,12 +652,13 @@ DEFINE_IDTENTRY_RAW(exc_int3) + instrumentation_end(); + irqentry_exit_to_user_mode(regs); + } else { +- bool irq_state = idtentry_enter_nmi(regs); ++ irqentry_state_t irq_state = irqentry_nmi_enter(regs); ++ + instrumentation_begin(); + if (!do_int3(regs)) + die("int3", regs, 0); + instrumentation_end(); +- idtentry_exit_nmi(regs, irq_state); ++ irqentry_nmi_exit(regs, irq_state); + } + } + +@@ -686,8 +687,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r + * In the SYSCALL entry path the RSP value comes from user-space - don't + * trust it and switch to the current kernel stack + */ +- if (regs->ip >= (unsigned long)entry_SYSCALL_64 && +- regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack) { ++ if (ip_within_syscall_gap(regs)) { + sp = this_cpu_read(cpu_current_top_of_stack); + goto sync; + } +@@ -852,7 +852,7 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, + * includes the entry stack is excluded for everything. + */ + unsigned long dr7 = local_db_save(); +- bool irq_state = idtentry_enter_nmi(regs); ++ irqentry_state_t irq_state = irqentry_nmi_enter(regs); + instrumentation_begin(); + + /* +@@ -909,7 +909,7 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, + regs->flags &= ~X86_EFLAGS_TF; + out: + instrumentation_end(); +- idtentry_exit_nmi(regs, irq_state); ++ irqentry_nmi_exit(regs, irq_state); + + local_db_restore(dr7); + } +@@ -927,7 +927,7 @@ static __always_inline void exc_debug_user(struct pt_regs *regs, + + /* + * NB: We can't easily clear DR7 here because +- * idtentry_exit_to_usermode() can invoke ptrace, schedule, access ++ * irqentry_exit_to_usermode() can invoke ptrace, schedule, access + * user memory, etc. This means that a recursive #DB is possible. If + * this happens, that #DB will hit exc_debug_kernel() and clear DR7. + * Since we're not on the IST stack right now, everything will be +diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c +index 73f8001000669..c451d5f6422f6 100644 +--- a/arch/x86/kernel/unwind_orc.c ++++ b/arch/x86/kernel/unwind_orc.c +@@ -367,8 +367,8 @@ static bool deref_stack_regs(struct unwind_state *state, unsigned long addr, + if (!stack_access_ok(state, addr, sizeof(struct pt_regs))) + return false; + +- *ip = regs->ip; +- *sp = regs->sp; ++ *ip = READ_ONCE_NOCHECK(regs->ip); ++ *sp = READ_ONCE_NOCHECK(regs->sp); + return true; + } + +@@ -380,8 +380,8 @@ static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr + if (!stack_access_ok(state, addr, IRET_FRAME_SIZE)) + return false; + +- *ip = regs->ip; +- *sp = regs->sp; ++ *ip = READ_ONCE_NOCHECK(regs->ip); ++ *sp = READ_ONCE_NOCHECK(regs->sp); + return true; + } + +@@ -402,12 +402,12 @@ static bool get_reg(struct unwind_state *state, unsigned int reg_off, + return false; + + if (state->full_regs) { +- *val = ((unsigned long *)state->regs)[reg]; ++ *val = READ_ONCE_NOCHECK(((unsigned long *)state->regs)[reg]); + return true; + } + + if (state->prev_regs) { +- *val = ((unsigned long *)state->prev_regs)[reg]; ++ *val = READ_ONCE_NOCHECK(((unsigned long *)state->prev_regs)[reg]); + return true; + } + +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 86c33d53c90a0..4ca81ae9bc8ad 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1641,7 +1641,16 @@ static void apic_timer_expired(struct kvm_lapic *apic, bool from_timer_fn) + } + + if (kvm_use_posted_timer_interrupt(apic->vcpu)) { +- kvm_wait_lapic_expire(vcpu); ++ /* ++ * Ensure the guest's timer has truly expired before posting an ++ * interrupt. Open code the relevant checks to avoid querying ++ * lapic_timer_int_injected(), which will be false since the ++ * interrupt isn't yet injected. Waiting until after injecting ++ * is not an option since that won't help a posted interrupt. ++ */ ++ if (vcpu->arch.apic->lapic_timer.expired_tscdeadline && ++ vcpu->arch.apic->lapic_timer.timer_advance_ns) ++ __kvm_wait_lapic_expire(vcpu); + kvm_apic_inject_pending_timer_irqs(apic); + return; + } +diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c +index 4229950a5d78c..bb0b3fe1e0a02 100644 +--- a/arch/x86/lib/insn-eval.c ++++ b/arch/x86/lib/insn-eval.c +@@ -1415,6 +1415,25 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) + } + } + ++static unsigned long insn_get_effective_ip(struct pt_regs *regs) ++{ ++ unsigned long seg_base = 0; ++ ++ /* ++ * If not in user-space long mode, a custom code segment could be in ++ * use. This is true in protected mode (if the process defined a local ++ * descriptor table), or virtual-8086 mode. In most of the cases ++ * seg_base will be zero as in USER_CS. ++ */ ++ if (!user_64bit_mode(regs)) { ++ seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); ++ if (seg_base == -1L) ++ return 0; ++ } ++ ++ return seg_base + regs->ip; ++} ++ + /** + * insn_fetch_from_user() - Copy instruction bytes from user-space memory + * @regs: Structure with register values as seen when entering kernel mode +@@ -1431,24 +1450,43 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) + */ + int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) + { +- unsigned long seg_base = 0; ++ unsigned long ip; + int not_copied; + +- /* +- * If not in user-space long mode, a custom code segment could be in +- * use. This is true in protected mode (if the process defined a local +- * descriptor table), or virtual-8086 mode. In most of the cases +- * seg_base will be zero as in USER_CS. +- */ +- if (!user_64bit_mode(regs)) { +- seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); +- if (seg_base == -1L) +- return 0; +- } ++ ip = insn_get_effective_ip(regs); ++ if (!ip) ++ return 0; ++ ++ not_copied = copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE); + ++ return MAX_INSN_SIZE - not_copied; ++} ++ ++/** ++ * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-space memory ++ * while in atomic code ++ * @regs: Structure with register values as seen when entering kernel mode ++ * @buf: Array to store the fetched instruction ++ * ++ * Gets the linear address of the instruction and copies the instruction bytes ++ * to the buf. This function must be used in atomic context. ++ * ++ * Returns: ++ * ++ * Number of instruction bytes copied. ++ * ++ * 0 if nothing was copied. ++ */ ++int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) ++{ ++ unsigned long ip; ++ int not_copied; ++ ++ ip = insn_get_effective_ip(regs); ++ if (!ip) ++ return 0; + +- not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip), +- MAX_INSN_SIZE); ++ not_copied = __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN_SIZE); + + return MAX_INSN_SIZE - not_copied; + } +diff --git a/block/blk-zoned.c b/block/blk-zoned.c +index 6817a673e5cec..4676c6f00489c 100644 +--- a/block/blk-zoned.c ++++ b/block/blk-zoned.c +@@ -318,6 +318,22 @@ int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, + return 0; + } + ++static int blkdev_truncate_zone_range(struct block_device *bdev, fmode_t mode, ++ const struct blk_zone_range *zrange) ++{ ++ loff_t start, end; ++ ++ if (zrange->sector + zrange->nr_sectors <= zrange->sector || ++ zrange->sector + zrange->nr_sectors > get_capacity(bdev->bd_disk)) ++ /* Out of range */ ++ return -EINVAL; ++ ++ start = zrange->sector << SECTOR_SHIFT; ++ end = ((zrange->sector + zrange->nr_sectors) << SECTOR_SHIFT) - 1; ++ ++ return truncate_bdev_range(bdev, mode, start, end); ++} ++ + /* + * BLKRESETZONE, BLKOPENZONE, BLKCLOSEZONE and BLKFINISHZONE ioctl processing. + * Called from blkdev_ioctl. +@@ -329,6 +345,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, + struct request_queue *q; + struct blk_zone_range zrange; + enum req_opf op; ++ int ret; + + if (!argp) + return -EINVAL; +@@ -352,6 +369,11 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, + switch (cmd) { + case BLKRESETZONE: + op = REQ_OP_ZONE_RESET; ++ ++ /* Invalidate the page cache, including dirty pages. */ ++ ret = blkdev_truncate_zone_range(bdev, mode, &zrange); ++ if (ret) ++ return ret; + break; + case BLKOPENZONE: + op = REQ_OP_ZONE_OPEN; +@@ -366,8 +388,20 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, + return -ENOTTY; + } + +- return blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, +- GFP_KERNEL); ++ ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, ++ GFP_KERNEL); ++ ++ /* ++ * Invalidate the page cache again for zone reset: writes can only be ++ * direct for zoned devices so concurrent writes would not add any page ++ * to the page cache after/during reset. The page cache may be filled ++ * again due to concurrent reads though and dropping the pages for ++ * these is fine. ++ */ ++ if (!ret && cmd == BLKRESETZONE) ++ ret = blkdev_truncate_zone_range(bdev, mode, &zrange); ++ ++ return ret; + } + + static inline unsigned long *blk_alloc_zone_bitmap(int node, +diff --git a/crypto/Kconfig b/crypto/Kconfig +index 37de7d006858d..774adc9846fa8 100644 +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -772,7 +772,7 @@ config CRYPTO_POLY1305_X86_64 + + config CRYPTO_POLY1305_MIPS + tristate "Poly1305 authenticator algorithm (MIPS optimized)" +- depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT) ++ depends on MIPS + select CRYPTO_ARCH_HAVE_LIB_POLY1305 + + config CRYPTO_MD4 +diff --git a/drivers/base/memory.c b/drivers/base/memory.c +index eef4ffb6122c9..de058d15b33ea 100644 +--- a/drivers/base/memory.c ++++ b/drivers/base/memory.c +@@ -290,20 +290,20 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, + } + + /* +- * phys_device is a bad name for this. What I really want +- * is a way to differentiate between memory ranges that +- * are part of physical devices that constitute +- * a complete removable unit or fru. +- * i.e. do these ranges belong to the same physical device, +- * s.t. if I offline all of these sections I can then +- * remove the physical device? ++ * Legacy interface that we cannot remove: s390x exposes the storage increment ++ * covered by a memory block, allowing for identifying which memory blocks ++ * comprise a storage increment. Since a memory block spans complete ++ * storage increments nowadays, this interface is basically unused. Other ++ * archs never exposed != 0. + */ + static ssize_t phys_device_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct memory_block *mem = to_memory_block(dev); ++ unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); + +- return sysfs_emit(buf, "%d\n", mem->phys_device); ++ return sysfs_emit(buf, "%d\n", ++ arch_get_memory_phys_device(start_pfn)); + } + + #ifdef CONFIG_MEMORY_HOTREMOVE +@@ -488,11 +488,7 @@ static DEVICE_ATTR_WO(soft_offline_page); + static DEVICE_ATTR_WO(hard_offline_page); + #endif + +-/* +- * Note that phys_device is optional. It is here to allow for +- * differentiation between which *physical* devices each +- * section belongs to... +- */ ++/* See phys_device_show(). */ + int __weak arch_get_memory_phys_device(unsigned long start_pfn) + { + return 0; +@@ -574,7 +570,6 @@ int register_memory(struct memory_block *memory) + static int init_memory_block(unsigned long block_id, unsigned long state) + { + struct memory_block *mem; +- unsigned long start_pfn; + int ret = 0; + + mem = find_memory_block_by_id(block_id); +@@ -588,8 +583,6 @@ static int init_memory_block(unsigned long block_id, unsigned long state) + + mem->start_section_nr = block_id * sections_per_block; + mem->state = state; +- start_pfn = section_nr_to_pfn(mem->start_section_nr); +- mem->phys_device = arch_get_memory_phys_device(start_pfn); + mem->nid = NUMA_NO_NODE; + + ret = register_memory(mem); +diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c +index 615a0c93e1166..206bd4d7d7e23 100644 +--- a/drivers/base/swnode.c ++++ b/drivers/base/swnode.c +@@ -786,6 +786,9 @@ int software_node_register(const struct software_node *node) + if (software_node_to_swnode(node)) + return -EEXIST; + ++ if (node->parent && !parent) ++ return -EINVAL; ++ + return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); + } + EXPORT_SYMBOL_GPL(software_node_register); +diff --git a/drivers/base/test/Makefile b/drivers/base/test/Makefile +index 3ca56367c84b7..2f15fae8625f1 100644 +--- a/drivers/base/test/Makefile ++++ b/drivers/base/test/Makefile +@@ -2,3 +2,4 @@ + obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o + + obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o ++CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all +diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c +index 5ac1881396afb..227e1be4c6f99 100644 +--- a/drivers/block/rsxx/core.c ++++ b/drivers/block/rsxx/core.c +@@ -871,6 +871,7 @@ static int rsxx_pci_probe(struct pci_dev *dev, + card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event"); + if (!card->event_wq) { + dev_err(CARD_TO_DEV(card), "Failed card event setup.\n"); ++ st = -ENOMEM; + goto failed_event_handler; + } + +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 711168451e9e5..7dce17fd59baa 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -633,7 +633,7 @@ static ssize_t writeback_store(struct device *dev, + struct bio_vec bio_vec; + struct page *page; + ssize_t ret = len; +- int mode; ++ int mode, err; + unsigned long blk_idx = 0; + + if (sysfs_streq(buf, "idle")) +@@ -725,12 +725,17 @@ static ssize_t writeback_store(struct device *dev, + * XXX: A single page IO would be inefficient for write + * but it would be not bad as starter. + */ +- ret = submit_bio_wait(&bio); +- if (ret) { ++ err = submit_bio_wait(&bio); ++ if (err) { + zram_slot_lock(zram, index); + zram_clear_flag(zram, index, ZRAM_UNDER_WB); + zram_clear_flag(zram, index, ZRAM_IDLE); + zram_slot_unlock(zram, index); ++ /* ++ * Return last IO error unless every IO were ++ * not suceeded. ++ */ ++ ret = err; + continue; + } + +diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c +index af26e0695b866..51ed640e527b4 100644 +--- a/drivers/clk/qcom/gdsc.c ++++ b/drivers/clk/qcom/gdsc.c +@@ -183,7 +183,10 @@ static inline int gdsc_assert_reset(struct gdsc *sc) + static inline void gdsc_force_mem_on(struct gdsc *sc) + { + int i; +- u32 mask = RETAIN_MEM | RETAIN_PERIPH; ++ u32 mask = RETAIN_MEM; ++ ++ if (!(sc->flags & NO_RET_PERIPH)) ++ mask |= RETAIN_PERIPH; + + for (i = 0; i < sc->cxc_count; i++) + regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask); +@@ -192,7 +195,10 @@ static inline void gdsc_force_mem_on(struct gdsc *sc) + static inline void gdsc_clear_mem_on(struct gdsc *sc) + { + int i; +- u32 mask = RETAIN_MEM | RETAIN_PERIPH; ++ u32 mask = RETAIN_MEM; ++ ++ if (!(sc->flags & NO_RET_PERIPH)) ++ mask |= RETAIN_PERIPH; + + for (i = 0; i < sc->cxc_count; i++) + regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0); +diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h +index bd537438c7932..5bb396b344d16 100644 +--- a/drivers/clk/qcom/gdsc.h ++++ b/drivers/clk/qcom/gdsc.h +@@ -42,7 +42,7 @@ struct gdsc { + #define PWRSTS_ON BIT(2) + #define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) + #define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) +- const u8 flags; ++ const u16 flags; + #define VOTABLE BIT(0) + #define CLAMP_IO BIT(1) + #define HW_CTRL BIT(2) +@@ -51,6 +51,7 @@ struct gdsc { + #define POLL_CFG_GDSCR BIT(5) + #define ALWAYS_ON BIT(6) + #define RETAIN_FF_ENABLE BIT(7) ++#define NO_RET_PERIPH BIT(8) + struct reset_controller_dev *rcdev; + unsigned int *resets; + unsigned int reset_count; +diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c +index 9b3923af02a14..1a518c4915b4b 100644 +--- a/drivers/clk/qcom/gpucc-msm8998.c ++++ b/drivers/clk/qcom/gpucc-msm8998.c +@@ -253,12 +253,16 @@ static struct gdsc gpu_cx_gdsc = { + static struct gdsc gpu_gx_gdsc = { + .gdscr = 0x1094, + .clamp_io_ctrl = 0x130, ++ .resets = (unsigned int []){ GPU_GX_BCR }, ++ .reset_count = 1, ++ .cxcs = (unsigned int []){ 0x1098 }, ++ .cxc_count = 1, + .pd = { + .name = "gpu_gx", + }, + .parent = &gpu_cx_gdsc.pd, +- .pwrsts = PWRSTS_OFF_ON, +- .flags = CLAMP_IO | AON_RESET, ++ .pwrsts = PWRSTS_OFF_ON | PWRSTS_RET, ++ .flags = CLAMP_IO | SW_RESET | AON_RESET | NO_RET_PERIPH, + }; + + static struct clk_regmap *gpucc_msm8998_clocks[] = { +diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c +index 2726e77c9e5a9..6de07556665b1 100644 +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -317,9 +317,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) + } + + base = ioremap(res->start, resource_size(res)); +- if (IS_ERR(base)) { ++ if (!base) { + dev_err(dev, "failed to map resource %pR\n", res); +- ret = PTR_ERR(base); ++ ret = -ENOMEM; + goto release_region; + } + +@@ -368,7 +368,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) + error: + kfree(data); + unmap_base: +- iounmap(data->base); ++ iounmap(base); + release_region: + release_mem_region(res->start, resource_size(res)); + return ret; +diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c +index 914a343c7785c..0ab439c53eee3 100644 +--- a/drivers/firmware/efi/libstub/efi-stub.c ++++ b/drivers/firmware/efi/libstub/efi-stub.c +@@ -96,6 +96,18 @@ static void install_memreserve_table(void) + efi_err("Failed to install memreserve config table!\n"); + } + ++static u32 get_supported_rt_services(void) ++{ ++ const efi_rt_properties_table_t *rt_prop_table; ++ u32 supported = EFI_RT_SUPPORTED_ALL; ++ ++ rt_prop_table = get_efi_config_table(EFI_RT_PROPERTIES_TABLE_GUID); ++ if (rt_prop_table) ++ supported &= rt_prop_table->runtime_services_supported; ++ ++ return supported; ++} ++ + /* + * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint + * that is described in the PE/COFF header. Most of the code is the same +@@ -250,6 +262,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, + (prop_tbl->memory_protection_attribute & + EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + ++ /* force efi_novamap if SetVirtualAddressMap() is unsupported */ ++ efi_novamap |= !(get_supported_rt_services() & ++ EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP); ++ + /* hibernation expects the runtime regions to stay in the same place */ + if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) { + /* +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index 825b362eb4b7d..6898c27f71f85 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -112,8 +112,29 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id); + #ifdef CONFIG_GPIO_PCA953X_IRQ + + #include +-#include +-#include ++ ++static const struct acpi_gpio_params pca953x_irq_gpios = { 0, 0, true }; ++ ++static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] = { ++ { "irq-gpios", &pca953x_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER }, ++ { } ++}; ++ ++static int pca953x_acpi_get_irq(struct device *dev) ++{ ++ int ret; ++ ++ ret = devm_acpi_dev_add_driver_gpios(dev, pca953x_acpi_irq_gpios); ++ if (ret) ++ dev_warn(dev, "can't add GPIO ACPI mapping\n"); ++ ++ ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0); ++ if (ret < 0) ++ return ret; ++ ++ dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret); ++ return ret; ++} + + static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { + { +@@ -132,59 +153,6 @@ static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { + }, + {} + }; +- +-#ifdef CONFIG_ACPI +-static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data) +-{ +- struct acpi_resource_gpio *agpio; +- int *pin = data; +- +- if (acpi_gpio_get_irq_resource(ares, &agpio)) +- *pin = agpio->pin_table[0]; +- return 1; +-} +- +-static int pca953x_acpi_find_pin(struct device *dev) +-{ +- struct acpi_device *adev = ACPI_COMPANION(dev); +- int pin = -ENOENT, ret; +- LIST_HEAD(r); +- +- ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin); +- acpi_dev_free_resource_list(&r); +- if (ret < 0) +- return ret; +- +- return pin; +-} +-#else +-static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; } +-#endif +- +-static int pca953x_acpi_get_irq(struct device *dev) +-{ +- int pin, ret; +- +- pin = pca953x_acpi_find_pin(dev); +- if (pin < 0) +- return pin; +- +- dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin); +- +- if (!gpio_is_valid(pin)) +- return -EINVAL; +- +- ret = gpio_request(pin, "pca953x interrupt"); +- if (ret) +- return ret; +- +- ret = gpio_to_irq(pin); +- +- /* When pin is used as an IRQ, no need to keep it requested */ +- gpio_free(pin); +- +- return ret; +-} + #endif + + static const struct acpi_device_id pca953x_acpi_ids[] = { +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index 834a12f3219e5..49a1f8ce4baa6 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -649,6 +649,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) + if (!lookup->desc) { + const struct acpi_resource_gpio *agpio = &ares->data.gpio; + bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT; ++ struct gpio_desc *desc; + int pin_index; + + if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint) +@@ -661,8 +662,12 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) + if (pin_index >= agpio->pin_table_length) + return 1; + +- lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr, ++ if (lookup->info.quirks & ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER) ++ desc = gpio_to_desc(agpio->pin_table[pin_index]); ++ else ++ desc = acpi_get_gpiod(agpio->resource_source.string_ptr, + agpio->pin_table[pin_index]); ++ lookup->desc = desc; + lookup->info.pin_config = agpio->pin_config; + lookup->info.gpioint = gpioint; + +@@ -911,8 +916,9 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, + } + + /** +- * acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number ++ * acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number + * @adev: pointer to a ACPI device to get IRQ from ++ * @name: optional name of GpioInt resource + * @index: index of GpioInt resource (starting from %0) + * + * If the device has one or more GpioInt resources, this function can be +@@ -922,9 +928,12 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, + * The function is idempotent, though each time it runs it will configure GPIO + * pin direction according to the flags in GpioInt resource. + * ++ * The function takes optional @name parameter. If the resource has a property ++ * name, then only those will be taken into account. ++ * + * Return: Linux IRQ number (> %0) on success, negative errno on failure. + */ +-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) ++int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index) + { + int idx, i; + unsigned int irq_flags; +@@ -934,7 +943,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) + struct acpi_gpio_info info; + struct gpio_desc *desc; + +- desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); ++ desc = acpi_get_gpiod_by_index(adev, name, i, &info); + + /* Ignore -EPROBE_DEFER, it only matters if idx matches */ + if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) +@@ -971,7 +980,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) + } + return -ENOENT; + } +-EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); ++EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by); + + static acpi_status + acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 7e17d4edccb12..7f557ea905424 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -472,8 +472,12 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); + static void gpiodevice_release(struct device *dev) + { + struct gpio_device *gdev = dev_get_drvdata(dev); ++ unsigned long flags; + ++ spin_lock_irqsave(&gpio_lock, flags); + list_del(&gdev->list); ++ spin_unlock_irqrestore(&gpio_lock, flags); ++ + ida_free(&gpio_ida, gdev->id); + kfree_const(gdev->label); + kfree(gdev->descs); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 87f095dc385c7..76c31aa7b84df 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -178,6 +178,7 @@ extern uint amdgpu_smu_memory_pool_size; + extern uint amdgpu_dc_feature_mask; + extern uint amdgpu_dc_debug_mask; + extern uint amdgpu_dm_abm_level; ++extern int amdgpu_backlight; + extern struct amdgpu_mgpu_info mgpu_info; + extern int amdgpu_ras_enable; + extern uint amdgpu_ras_mask; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 0b786d8dd8bc7..1a880cb48d19e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -768,6 +768,10 @@ uint amdgpu_dm_abm_level = 0; + MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); + module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); + ++int amdgpu_backlight = -1; ++MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); ++module_param_named(backlight, amdgpu_backlight, bint, 0444); ++ + /** + * DOC: tmz (int) + * Trusted Memory Zone (TMZ) is a method to protect data being written +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index bffaefaf5a292..ea1ea147f6073 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2140,6 +2140,11 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) + caps->ext_caps->bits.hdr_aux_backlight_control == 1) + caps->aux_support = true; + ++ if (amdgpu_backlight == 0) ++ caps->aux_support = false; ++ else if (amdgpu_backlight == 1) ++ caps->aux_support = true; ++ + /* From the specification (CTA-861-G), for calculating the maximum + * luminance we need to use: + * Luminance = 50*2**(CV/32) +@@ -3038,19 +3043,6 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm) + #endif + } + +-static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness) +-{ +- bool rc; +- +- if (!link) +- return 1; +- +- rc = dc_link_set_backlight_level_nits(link, true, brightness, +- AUX_BL_DEFAULT_TRANSITION_TIME_MS); +- +- return rc ? 0 : 1; +-} +- + static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, + unsigned *min, unsigned *max) + { +@@ -3113,9 +3105,10 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) + brightness = convert_brightness_from_user(&caps, bd->props.brightness); + // Change brightness based on AUX property + if (caps.aux_support) +- return set_backlight_via_aux(link, brightness); +- +- rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); ++ rc = dc_link_set_backlight_level_nits(link, true, brightness, ++ AUX_BL_DEFAULT_TRANSITION_TIME_MS); ++ else ++ rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); + + return rc ? 0 : 1; + } +@@ -3123,11 +3116,27 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) + static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) + { + struct amdgpu_display_manager *dm = bl_get_data(bd); +- int ret = dc_link_get_backlight_level(dm->backlight_link); ++ struct amdgpu_dm_backlight_caps caps; ++ ++ amdgpu_dm_update_backlight_caps(dm); ++ caps = dm->backlight_caps; ++ ++ if (caps.aux_support) { ++ struct dc_link *link = (struct dc_link *)dm->backlight_link; ++ u32 avg, peak; ++ bool rc; + +- if (ret == DC_ERROR_UNEXPECTED) +- return bd->props.brightness; +- return convert_brightness_to_user(&dm->backlight_caps, ret); ++ rc = dc_link_get_backlight_level_nits(link, &avg, &peak); ++ if (!rc) ++ return bd->props.brightness; ++ return convert_brightness_to_user(&caps, avg); ++ } else { ++ int ret = dc_link_get_backlight_level(dm->backlight_link); ++ ++ if (ret == DC_ERROR_UNEXPECTED) ++ return bd->props.brightness; ++ return convert_brightness_to_user(&caps, ret); ++ } + } + + static const struct backlight_ops amdgpu_dm_backlight_ops = { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +index 21c7b642a8b4e..f0039599e02f7 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -2555,7 +2555,6 @@ bool dc_link_set_backlight_level(const struct dc_link *link, + if (pipe_ctx->plane_state == NULL) + frame_ramp = 0; + } else { +- ASSERT(false); + return false; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 4e2dcf259428f..b5fe2a008bd47 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -1058,8 +1058,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s + { + int i; + +- DC_FP_START(); +- + if (dc->bb_overrides.sr_exit_time_ns) { + for (i = 0; i < WM_SET_COUNT; i++) { + dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = +@@ -1084,8 +1082,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s + dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; + } + } +- +- DC_FP_END(); + } + + void dcn21_calculate_wm( +@@ -1183,7 +1179,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc, + int vlevel = 0; + int pipe_split_from[MAX_PIPES]; + int pipe_cnt = 0; +- display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); ++ display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); + DC_LOGGER_INIT(dc->ctx->logger); + + BW_VAL_TRACE_COUNT(); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index 7eada3098ffcc..18e4eb8884c26 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -1506,6 +1506,48 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr, + return 0; + } + ++static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ struct vega10_hwmgr *data = ++ (struct vega10_hwmgr *)(hwmgr->backend); ++ uint32_t pcie_gen = 0, pcie_width = 0; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; ++ ++ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) ++ pcie_gen = 3; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ pcie_gen = 2; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) ++ pcie_gen = 1; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) ++ pcie_gen = 0; ++ ++ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) ++ pcie_width = 6; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) ++ pcie_width = 5; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) ++ pcie_width = 4; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) ++ pcie_width = 3; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) ++ pcie_width = 2; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) ++ pcie_width = 1; ++ ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ if (pp_table->PcieGenSpeed[i] > pcie_gen) ++ pp_table->PcieGenSpeed[i] = pcie_gen; ++ ++ if (pp_table->PcieLaneCount[i] > pcie_width) ++ pp_table->PcieLaneCount[i] = pcie_width; ++ } ++ ++ return 0; ++} ++ + static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) + { + int result = -1; +@@ -2557,6 +2599,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) + "Failed to initialize Link Level!", + return result); + ++ result = vega10_override_pcie_parameters(hwmgr); ++ PP_ASSERT_WITH_CODE(!result, ++ "Failed to override pcie parameters!", ++ return result); ++ + result = vega10_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Graphics Level!", +@@ -2923,6 +2970,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap) + return 0; + } + ++ + static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) + { + struct vega10_hwmgr *data = hwmgr->backend; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +index dc206fa88c5e5..62076035029ac 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +@@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) + dpm_state->hard_max_level = 0xffff; + } + ++static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ struct vega12_hwmgr *data = ++ (struct vega12_hwmgr *)(hwmgr->backend); ++ uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; ++ int ret; ++ ++ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) ++ pcie_gen = 3; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ pcie_gen = 2; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) ++ pcie_gen = 1; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) ++ pcie_gen = 0; ++ ++ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) ++ pcie_width = 6; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) ++ pcie_width = 5; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) ++ pcie_width = 4; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) ++ pcie_width = 3; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) ++ pcie_width = 2; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) ++ pcie_width = 1; ++ ++ /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 ++ * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 ++ * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 ++ */ ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : ++ pp_table->PcieGenSpeed[i]; ++ pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : ++ pp_table->PcieLaneCount[i]; ++ ++ if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != ++ pp_table->PcieLaneCount[i]) { ++ smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ } ++ ++ /* update the pptable */ ++ pp_table->PcieGenSpeed[i] = pcie_gen_arg; ++ pp_table->PcieLaneCount[i] = pcie_width_arg; ++ } ++ ++ return 0; ++} ++ + static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, + PPCLK_e clk_id, uint32_t *num_of_levels) + { +@@ -969,6 +1030,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) + "Failed to enable all smu features!", + return result); + ++ result = vega12_override_pcie_parameters(hwmgr); ++ PP_ASSERT_WITH_CODE(!result, ++ "[EnableDPMTasks] Failed to override pcie parameters!", ++ return result); ++ + tmp_result = vega12_power_control_set_level(hwmgr); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to power control set level!", +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +index da84012b7fd51..251979c059c8b 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -832,7 +832,9 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); +- uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; ++ uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; + int ret; + + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) +@@ -861,17 +863,27 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 + */ +- smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; +- ret = smum_send_msg_to_smc_with_parameter(hwmgr, +- PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, +- NULL); +- PP_ASSERT_WITH_CODE(!ret, +- "[OverridePcieParameters] Attempt to override pcie params failed!", +- return ret); ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : ++ pp_table->PcieGenSpeed[i]; ++ pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : ++ pp_table->PcieLaneCount[i]; ++ ++ if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != ++ pp_table->PcieLaneCount[i]) { ++ smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ } + +- data->pcie_parameters_override = true; +- data->pcie_gen_level1 = pcie_gen; +- data->pcie_width_level1 = pcie_width; ++ /* update the pptable */ ++ pp_table->PcieGenSpeed[i] = pcie_gen_arg; ++ pp_table->PcieLaneCount[i] = pcie_width_arg; ++ } + + return 0; + } +@@ -3320,9 +3332,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, + data->od8_settings.od8_settings_array; + OverDriveTable_t *od_table = + &(data->smc_state_table.overdrive_table); +- struct phm_ppt_v3_information *pptable_information = +- (struct phm_ppt_v3_information *)hwmgr->pptable; +- PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; ++ PPTable_t *pptable = &(data->smc_state_table.pp_table); + struct pp_clock_levels_with_latency clocks; + struct vega20_single_dpm_table *fclk_dpm_table = + &(data->dpm_table.fclk_table); +@@ -3421,13 +3431,9 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, + current_lane_width = + vega20_get_current_pcie_link_width_level(hwmgr); + for (i = 0; i < NUM_LINK_LEVELS; i++) { +- if (i == 1 && data->pcie_parameters_override) { +- gen_speed = data->pcie_gen_level1; +- lane_width = data->pcie_width_level1; +- } else { +- gen_speed = pptable->PcieGenSpeed[i]; +- lane_width = pptable->PcieLaneCount[i]; +- } ++ gen_speed = pptable->PcieGenSpeed[i]; ++ lane_width = pptable->PcieLaneCount[i]; ++ + size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, + (gen_speed == 0) ? "2.5GT/s," : + (gen_speed == 1) ? "5.0GT/s," : +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index e00616d94f26e..cfacce0418a49 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -340,13 +340,14 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem) + if (--shmem->vmap_use_count > 0) + return; + +- if (obj->import_attach) ++ if (obj->import_attach) { + dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr); +- else ++ } else { + vunmap(shmem->vaddr); ++ drm_gem_shmem_put_pages(shmem); ++ } + + shmem->vaddr = NULL; +- drm_gem_shmem_put_pages(shmem); + } + + /* +@@ -534,14 +535,28 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) + struct drm_gem_object *obj = vma->vm_private_data; + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + loff_t num_pages = obj->size >> PAGE_SHIFT; ++ vm_fault_t ret; + struct page *page; ++ pgoff_t page_offset; + +- if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages)) +- return VM_FAULT_SIGBUS; ++ /* We don't use vmf->pgoff since that has the fake offset */ ++ page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; + +- page = shmem->pages[vmf->pgoff]; ++ mutex_lock(&shmem->pages_lock); + +- return vmf_insert_page(vma, vmf->address, page); ++ if (page_offset >= num_pages || ++ WARN_ON_ONCE(!shmem->pages) || ++ shmem->madv < 0) { ++ ret = VM_FAULT_SIGBUS; ++ } else { ++ page = shmem->pages[page_offset]; ++ ++ ret = vmf_insert_page(vma, vmf->address, page); ++ } ++ ++ mutex_unlock(&shmem->pages_lock); ++ ++ return ret; + } + + static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) +@@ -590,9 +605,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) + struct drm_gem_shmem_object *shmem; + int ret; + +- /* Remove the fake offset */ +- vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); +- + if (obj->import_attach) { + /* Drop the reference drm_gem_mmap_obj() acquired.*/ + drm_gem_object_put(obj); +diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c +index f86448ab1fe04..dc734d4828a17 100644 +--- a/drivers/gpu/drm/drm_ioc32.c ++++ b/drivers/gpu/drm/drm_ioc32.c +@@ -99,6 +99,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd, + if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) + return -EFAULT; + ++ memset(&v, 0, sizeof(v)); ++ + v = (struct drm_version) { + .name_len = v32.name_len, + .name = compat_ptr(v32.name), +@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, + + if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) + return -EFAULT; ++ ++ memset(&uq, 0, sizeof(uq)); ++ + uq = (struct drm_unique){ + .unique_len = uq32.unique_len, + .unique = compat_ptr(uq32.unique), +@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, + if (copy_from_user(&c32, argp, sizeof(c32))) + return -EFAULT; + ++ memset(&client, 0, sizeof(client)); ++ + client.idx = c32.idx; + + err = drm_ioctl_kernel(file, drm_getclient, &client, 0); +@@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, + if (copy_from_user(&req32, argp, sizeof(req32))) + return -EFAULT; + ++ memset(&req, 0, sizeof(req)); ++ + req.request.type = req32.request.type; + req.request.sequence = req32.request.sequence; + req.request.signal = req32.request.signal; +@@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd, + struct drm_mode_fb_cmd2 req64; + int err; + ++ memset(&req64, 0, sizeof(req64)); ++ + if (copy_from_user(&req64, argp, + offsetof(drm_mode_fb_cmd232_t, modifier))) + return -EFAULT; +diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +index efdeb7b7b2a0a..a19537706ed1f 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c ++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +@@ -708,9 +708,12 @@ static int engine_setup_common(struct intel_engine_cs *engine) + goto err_status; + } + ++ err = intel_engine_init_cmd_parser(engine); ++ if (err) ++ goto err_cmd_parser; ++ + intel_engine_init_active(engine, ENGINE_PHYSICAL); + intel_engine_init_execlists(engine); +- intel_engine_init_cmd_parser(engine); + intel_engine_init__pm(engine); + intel_engine_init_retire(engine); + +@@ -724,6 +727,8 @@ static int engine_setup_common(struct intel_engine_cs *engine) + + return 0; + ++err_cmd_parser: ++ intel_breadcrumbs_free(engine->breadcrumbs); + err_status: + cleanup_status_page(engine); + return err; +diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c +index e7362ec22aded..9ce174950340b 100644 +--- a/drivers/gpu/drm/i915/i915_cmd_parser.c ++++ b/drivers/gpu/drm/i915/i915_cmd_parser.c +@@ -939,7 +939,7 @@ static void fini_hash_table(struct intel_engine_cs *engine) + * struct intel_engine_cs based on whether the platform requires software + * command parsing. + */ +-void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) ++int intel_engine_init_cmd_parser(struct intel_engine_cs *engine) + { + const struct drm_i915_cmd_table *cmd_tables; + int cmd_table_count; +@@ -947,7 +947,7 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) + + if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) && + engine->class == COPY_ENGINE_CLASS)) +- return; ++ return 0; + + switch (engine->class) { + case RENDER_CLASS: +@@ -1012,19 +1012,19 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) + break; + default: + MISSING_CASE(engine->class); +- return; ++ goto out; + } + + if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) { + drm_err(&engine->i915->drm, + "%s: command descriptions are not sorted\n", + engine->name); +- return; ++ goto out; + } + if (!validate_regs_sorted(engine)) { + drm_err(&engine->i915->drm, + "%s: registers are not sorted\n", engine->name); +- return; ++ goto out; + } + + ret = init_hash_table(engine, cmd_tables, cmd_table_count); +@@ -1032,10 +1032,17 @@ void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) + drm_err(&engine->i915->drm, + "%s: initialised failed!\n", engine->name); + fini_hash_table(engine); +- return; ++ goto out; + } + + engine->flags |= I915_ENGINE_USING_CMD_PARSER; ++ ++out: ++ if (intel_engine_requires_cmd_parser(engine) && ++ !intel_engine_using_cmd_parser(engine)) ++ return -EINVAL; ++ ++ return 0; + } + + /** +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fa830e77bb648..6909901b35513 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1946,7 +1946,7 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type); + + /* i915_cmd_parser.c */ + int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); +-void intel_engine_init_cmd_parser(struct intel_engine_cs *engine); ++int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); + void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); + int intel_engine_cmd_parser(struct intel_engine_cs *engine, + struct i915_vma *batch, +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index 3d1de9cbb1c8d..db56732bdd260 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -482,6 +482,16 @@ static int meson_probe_remote(struct platform_device *pdev, + return count; + } + ++static void meson_drv_shutdown(struct platform_device *pdev) ++{ ++ struct meson_drm *priv = dev_get_drvdata(&pdev->dev); ++ struct drm_device *drm = priv->drm; ++ ++ DRM_DEBUG_DRIVER("\n"); ++ drm_kms_helper_poll_fini(drm); ++ drm_atomic_helper_shutdown(drm); ++} ++ + static int meson_drv_probe(struct platform_device *pdev) + { + struct component_match *match = NULL; +@@ -553,6 +563,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = { + + static struct platform_driver meson_drm_platform_driver = { + .probe = meson_drv_probe, ++ .shutdown = meson_drv_shutdown, + .driver = { + .name = "meson-drm", + .of_match_table = dt_match, +diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c +index 6063f3a153290..862ef59d4d033 100644 +--- a/drivers/gpu/drm/qxl/qxl_display.c ++++ b/drivers/gpu/drm/qxl/qxl_display.c +@@ -327,6 +327,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc, + + head.id = i; + head.flags = 0; ++ head.surface_id = 0; + oldcount = qdev->monitors_config->count; + if (crtc->state->active) { + struct drm_display_mode *mode = &crtc->mode; +diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c +index cc397671f6898..0f5d1e598d75f 100644 +--- a/drivers/gpu/drm/tiny/gm12u320.c ++++ b/drivers/gpu/drm/tiny/gm12u320.c +@@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); + + struct gm12u320_device { + struct drm_device dev; ++ struct device *dmadev; + struct drm_simple_display_pipe pipe; + struct drm_connector conn; + struct usb_device *udev; +@@ -598,6 +599,22 @@ static const uint64_t gm12u320_pipe_modifiers[] = { + DRM_FORMAT_MOD_INVALID + }; + ++/* ++ * FIXME: Dma-buf sharing requires DMA support by the importing device. ++ * This function is a workaround to make USB devices work as well. ++ * See todo.rst for how to fix the issue in the dma-buf framework. ++ */ ++static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev, ++ struct dma_buf *dma_buf) ++{ ++ struct gm12u320_device *gm12u320 = to_gm12u320(dev); ++ ++ if (!gm12u320->dmadev) ++ return ERR_PTR(-ENODEV); ++ ++ return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev); ++} ++ + DEFINE_DRM_GEM_FOPS(gm12u320_fops); + + static struct drm_driver gm12u320_drm_driver = { +@@ -611,6 +628,7 @@ static struct drm_driver gm12u320_drm_driver = { + + .fops = &gm12u320_fops, + DRM_GEM_SHMEM_DRIVER_OPS, ++ .gem_prime_import = gm12u320_gem_prime_import, + }; + + static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { +@@ -637,16 +655,19 @@ static int gm12u320_usb_probe(struct usb_interface *interface, + struct gm12u320_device, dev); + if (IS_ERR(gm12u320)) + return PTR_ERR(gm12u320); ++ dev = &gm12u320->dev; ++ ++ gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); ++ if (!gm12u320->dmadev) ++ drm_warn(dev, "buffer sharing not supported"); /* not an error */ + + gm12u320->udev = interface_to_usbdev(interface); + INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); + mutex_init(&gm12u320->fb_update.lock); + +- dev = &gm12u320->dev; +- + ret = drmm_mode_config_init(dev); + if (ret) +- return ret; ++ goto err_put_device; + + dev->mode_config.min_width = GM12U320_USER_WIDTH; + dev->mode_config.max_width = GM12U320_USER_WIDTH; +@@ -656,15 +677,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface, + + ret = gm12u320_usb_alloc(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = gm12u320_set_ecomode(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = gm12u320_conn_init(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = drm_simple_display_pipe_init(&gm12u320->dev, + &gm12u320->pipe, +@@ -674,24 +695,31 @@ static int gm12u320_usb_probe(struct usb_interface *interface, + gm12u320_pipe_modifiers, + &gm12u320->conn); + if (ret) +- return ret; ++ goto err_put_device; + + drm_mode_config_reset(dev); + + usb_set_intfdata(interface, dev); + ret = drm_dev_register(dev, 0); + if (ret) +- return ret; ++ goto err_put_device; + + drm_fbdev_generic_setup(dev, 0); + + return 0; ++ ++err_put_device: ++ put_device(gm12u320->dmadev); ++ return ret; + } + + static void gm12u320_usb_disconnect(struct usb_interface *interface) + { + struct drm_device *dev = usb_get_intfdata(interface); ++ struct gm12u320_device *gm12u320 = to_gm12u320(dev); + ++ put_device(gm12u320->dmadev); ++ gm12u320->dmadev = NULL; + drm_dev_unplug(dev); + drm_atomic_helper_shutdown(dev); + } +diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c +index 96d4317a2c1bd..bcf32d188c1b1 100644 +--- a/drivers/gpu/drm/udl/udl_drv.c ++++ b/drivers/gpu/drm/udl/udl_drv.c +@@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_interface *interface) + return drm_mode_config_helper_resume(dev); + } + ++/* ++ * FIXME: Dma-buf sharing requires DMA support by the importing device. ++ * This function is a workaround to make USB devices work as well. ++ * See todo.rst for how to fix the issue in the dma-buf framework. ++ */ ++static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev, ++ struct dma_buf *dma_buf) ++{ ++ struct udl_device *udl = to_udl(dev); ++ ++ if (!udl->dmadev) ++ return ERR_PTR(-ENODEV); ++ ++ return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev); ++} ++ + DEFINE_DRM_GEM_FOPS(udl_driver_fops); + + static struct drm_driver driver = { +@@ -42,6 +58,7 @@ static struct drm_driver driver = { + + .fops = &udl_driver_fops, + DRM_GEM_SHMEM_DRIVER_OPS, ++ .gem_prime_import = udl_driver_gem_prime_import, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h +index b1461f30780bc..8aab14871e1b7 100644 +--- a/drivers/gpu/drm/udl/udl_drv.h ++++ b/drivers/gpu/drm/udl/udl_drv.h +@@ -50,6 +50,7 @@ struct urb_list { + struct udl_device { + struct drm_device drm; + struct device *dev; ++ struct device *dmadev; + struct usb_device *udev; + + struct drm_simple_display_pipe display_pipe; +diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c +index f5d27f2a56543..5f1d3891ed549 100644 +--- a/drivers/gpu/drm/udl/udl_main.c ++++ b/drivers/gpu/drm/udl/udl_main.c +@@ -314,6 +314,10 @@ int udl_init(struct udl_device *udl) + + DRM_DEBUG("\n"); + ++ udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); ++ if (!udl->dmadev) ++ drm_warn(dev, "buffer sharing not supported"); /* not an error */ ++ + mutex_init(&udl->gem_lock); + + if (!udl_parse_vendor_descriptor(dev, udl->udev)) { +@@ -342,12 +346,18 @@ int udl_init(struct udl_device *udl) + err: + if (udl->urbs.count) + udl_free_urb_list(dev); ++ put_device(udl->dmadev); + DRM_ERROR("%d\n", ret); + return ret; + } + + int udl_drop_usb(struct drm_device *dev) + { ++ struct udl_device *udl = to_udl(dev); ++ + udl_free_urb_list(dev); ++ put_device(udl->dmadev); ++ udl->dmadev = NULL; ++ + return 0; + } +diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c +index fcdc922bc9733..271bd8d243395 100644 +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -995,7 +995,12 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev, + workitem.reports_supported |= STD_KEYBOARD; + break; + case 0x0d: +- device_type = "eQUAD Lightspeed 1_1"; ++ device_type = "eQUAD Lightspeed 1.1"; ++ logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); ++ workitem.reports_supported |= STD_KEYBOARD; ++ break; ++ case 0x0f: ++ device_type = "eQUAD Lightspeed 1.2"; + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; + break; +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 217def2d7cb44..ad6630e3cc779 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -91,7 +91,6 @@ + + #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) + #define RCAR_BUS_PHASE_DATA (MDBS | MIE) +-#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) + #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) + + #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) +@@ -120,6 +119,7 @@ enum rcar_i2c_type { + }; + + struct rcar_i2c_priv { ++ u32 flags; + void __iomem *io; + struct i2c_adapter adap; + struct i2c_msg *msg; +@@ -130,7 +130,6 @@ struct rcar_i2c_priv { + + int pos; + u32 icccr; +- u32 flags; + u8 recovery_icmcr; /* protected by adapter lock */ + enum rcar_i2c_type devtype; + struct i2c_client *slave; +@@ -621,7 +620,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + /* + * This driver has a lock-free design because there are IP cores (at least + * R-Car Gen2) which have an inherent race condition in their hardware design. +- * There, we need to clear RCAR_BUS_MASK_DATA bits as soon as possible after ++ * There, we need to switch to RCAR_BUS_PHASE_DATA as soon as possible after + * the interrupt was generated, otherwise an unwanted repeated message gets + * generated. It turned out that taking a spinlock at the beginning of the ISR + * was already causing repeated messages. Thus, this driver was converted to +@@ -630,13 +629,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + { + struct rcar_i2c_priv *priv = ptr; +- u32 msr, val; ++ u32 msr; + + /* Clear START or STOP immediately, except for REPSTART after read */ +- if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) { +- val = rcar_i2c_read(priv, ICMCR); +- rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); +- } ++ if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) ++ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + + msr = rcar_i2c_read(priv, ICMSR); + +diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c +index 5157ae29a4460..076526710fe30 100644 +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -220,10 +220,10 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, + + cur_base += ret * PAGE_SIZE; + npages -= ret; +- sg = __sg_alloc_table_from_pages( +- &umem->sg_head, page_list, ret, 0, ret << PAGE_SHIFT, +- dma_get_max_seg_size(device->dma_device), sg, npages, +- GFP_KERNEL); ++ sg = __sg_alloc_table_from_pages(&umem->sg_head, page_list, ret, ++ 0, ret << PAGE_SHIFT, ++ ib_dma_max_seg_size(device), sg, npages, ++ GFP_KERNEL); + umem->sg_nents = umem->sg_head.nents; + if (IS_ERR(sg)) { + unpin_user_pages_dirty_lock(page_list, ret, 0); +diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c +index 14362ebab9a9d..0b46bc014cde7 100644 +--- a/drivers/input/keyboard/applespi.c ++++ b/drivers/input/keyboard/applespi.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -400,7 +401,7 @@ struct applespi_data { + unsigned int cmd_msg_cntr; + /* lock to protect the above parameters and flags below */ + spinlock_t cmd_msg_lock; +- bool cmd_msg_queued; ++ ktime_t cmd_msg_queued; + enum applespi_evt_type cmd_evt_type; + + struct led_classdev backlight_info; +@@ -716,7 +717,7 @@ static void applespi_msg_complete(struct applespi_data *applespi, + wake_up_all(&applespi->drain_complete); + + if (is_write_msg) { +- applespi->cmd_msg_queued = false; ++ applespi->cmd_msg_queued = 0; + applespi_send_cmd_msg(applespi); + } + +@@ -758,8 +759,16 @@ static int applespi_send_cmd_msg(struct applespi_data *applespi) + return 0; + + /* check whether send is in progress */ +- if (applespi->cmd_msg_queued) +- return 0; ++ if (applespi->cmd_msg_queued) { ++ if (ktime_ms_delta(ktime_get(), applespi->cmd_msg_queued) < 1000) ++ return 0; ++ ++ dev_warn(&applespi->spi->dev, "Command %d timed out\n", ++ applespi->cmd_evt_type); ++ ++ applespi->cmd_msg_queued = 0; ++ applespi->write_active = false; ++ } + + /* set up packet */ + memset(packet, 0, APPLESPI_PACKET_SIZE); +@@ -856,7 +865,7 @@ static int applespi_send_cmd_msg(struct applespi_data *applespi) + return sts; + } + +- applespi->cmd_msg_queued = true; ++ applespi->cmd_msg_queued = ktime_get_coarse(); + applespi->write_active = true; + + return 0; +@@ -1908,7 +1917,7 @@ static int __maybe_unused applespi_resume(struct device *dev) + applespi->drain = false; + applespi->have_cl_led_on = false; + applespi->have_bl_level = 0; +- applespi->cmd_msg_queued = false; ++ applespi->cmd_msg_queued = 0; + applespi->read_active = false; + applespi->write_active = false; + +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index c842545368fdd..3c215f0a6052b 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -254,6 +255,8 @@ static enum iommu_init_state init_state = IOMMU_START_STATE; + static int amd_iommu_enable_interrupts(void); + static int __init iommu_go_to_state(enum iommu_init_state state); + static void init_device_table_dma(void); ++static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, ++ u8 fxn, u64 *value, bool is_write); + + static bool amd_iommu_pre_enabled = true; + +@@ -1717,13 +1720,11 @@ static int __init init_iommu_all(struct acpi_table_header *table) + return 0; + } + +-static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, +- u8 fxn, u64 *value, bool is_write); +- +-static void init_iommu_perf_ctr(struct amd_iommu *iommu) ++static void __init init_iommu_perf_ctr(struct amd_iommu *iommu) + { ++ int retry; + struct pci_dev *pdev = iommu->dev; +- u64 val = 0xabcd, val2 = 0, save_reg = 0; ++ u64 val = 0xabcd, val2 = 0, save_reg, save_src; + + if (!iommu_feature(iommu, FEATURE_PC)) + return; +@@ -1731,17 +1732,39 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu) + amd_iommu_pc_present = true; + + /* save the value to restore, if writable */ +- if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false)) ++ if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false) || ++ iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, false)) + goto pc_false; + +- /* Check if the performance counters can be written to */ +- if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) || +- (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) || +- (val != val2)) ++ /* ++ * Disable power gating by programing the performance counter ++ * source to 20 (i.e. counts the reads and writes from/to IOMMU ++ * Reserved Register [MMIO Offset 1FF8h] that are ignored.), ++ * which never get incremented during this init phase. ++ * (Note: The event is also deprecated.) ++ */ ++ val = 20; ++ if (iommu_pc_get_set_reg(iommu, 0, 0, 8, &val, true)) + goto pc_false; + ++ /* Check if the performance counters can be written to */ ++ val = 0xabcd; ++ for (retry = 5; retry; retry--) { ++ if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true) || ++ iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false) || ++ val2) ++ break; ++ ++ /* Wait about 20 msec for power gating to disable and retry. */ ++ msleep(20); ++ } ++ + /* restore */ +- if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true)) ++ if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true) || ++ iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, true)) ++ goto pc_false; ++ ++ if (val != val2) + goto pc_false; + + pci_info(pdev, "IOMMU performance counters supported\n"); +diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c +index 43f392d27d318..b200a3acc6ed9 100644 +--- a/drivers/iommu/intel/svm.c ++++ b/drivers/iommu/intel/svm.c +@@ -1079,8 +1079,17 @@ prq_advance: + * Clear the page request overflow bit and wake up all threads that + * are waiting for the completion of this handling. + */ +- if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) +- writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG); ++ if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) { ++ pr_info_ratelimited("IOMMU: %s: PRQ overflow detected\n", ++ iommu->name); ++ head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK; ++ tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK; ++ if (head == tail) { ++ writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG); ++ pr_info_ratelimited("IOMMU: %s: PRQ overflow cleared", ++ iommu->name); ++ } ++ } + + if (!completion_done(&iommu->prq_complete)) + complete(&iommu->prq_complete); +diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c +index 86d5e3f4b1ffc..06f74d410973e 100644 +--- a/drivers/media/platform/vsp1/vsp1_drm.c ++++ b/drivers/media/platform/vsp1/vsp1_drm.c +@@ -245,7 +245,7 @@ static int vsp1_du_pipeline_setup_brx(struct vsp1_device *vsp1, + brx = &vsp1->bru->entity; + else if (pipe->brx && !drm_pipe->force_brx_release) + brx = pipe->brx; +- else if (!vsp1->bru->entity.pipe) ++ else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe) + brx = &vsp1->bru->entity; + else + brx = &vsp1->brs->entity; +@@ -462,9 +462,9 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1, + * make sure it is present in the pipeline's list of entities if it + * wasn't already. + */ +- if (!use_uif) { ++ if (drm_pipe->uif && !use_uif) { + drm_pipe->uif->pipe = NULL; +- } else if (!drm_pipe->uif->pipe) { ++ } else if (drm_pipe->uif && !drm_pipe->uif->pipe) { + drm_pipe->uif->pipe = pipe; + list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities); + } +diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile +index 5bb2932ab1195..ff6a8fc4c38e5 100644 +--- a/drivers/media/rc/Makefile ++++ b/drivers/media/rc/Makefile +@@ -5,6 +5,7 @@ obj-y += keymaps/ + obj-$(CONFIG_RC_CORE) += rc-core.o + rc-core-y := rc-main.o rc-ir-raw.o + rc-core-$(CONFIG_LIRC) += lirc_dev.o ++rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o + rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o + obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o + obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index aaa1bf81d00d4..3581761e9797d 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -21,7 +21,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-behold.o \ + rc-behold-columbus.o \ + rc-budget-ci-old.o \ +- rc-cec.o \ + rc-cinergy-1400.o \ + rc-cinergy.o \ + rc-d680-dmb.o \ +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +index 3e3bd11092b45..068e22aeac8c3 100644 +--- a/drivers/media/rc/keymaps/rc-cec.c ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -1,5 +1,15 @@ + // SPDX-License-Identifier: GPL-2.0-or-later + /* Keytable for the CEC remote control ++ * ++ * This keymap is unusual in that it can't be built as a module, ++ * instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC ++ * is set. This is because it can be called from drm_dp_cec_set_edid() via ++ * cec_register_adapter() in an asynchronous context, and it is not ++ * allowed to use request_module() to load rc-cec.ko in that case. ++ * ++ * Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we ++ * just compile this keymap into the rc-core module and never as a ++ * separate module. + * + * Copyright (c) 2015 by Kamil Debski + */ +@@ -152,7 +162,7 @@ static struct rc_map_table cec[] = { + /* 0x77-0xff: Reserved */ + }; + +-static struct rc_map_list cec_map = { ++struct rc_map_list cec_map = { + .map = { + .scan = cec, + .size = ARRAY_SIZE(cec), +@@ -160,19 +170,3 @@ static struct rc_map_list cec_map = { + .name = RC_MAP_CEC, + } + }; +- +-static int __init init_rc_map_cec(void) +-{ +- return rc_map_register(&cec_map); +-} +- +-static void __exit exit_rc_map_cec(void) +-{ +- rc_map_unregister(&cec_map); +-} +- +-module_init(init_rc_map_cec); +-module_exit(exit_rc_map_cec); +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Kamil Debski"); +diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c +index 1fd62c1dac768..8e88dc8ea6c5e 100644 +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -2069,6 +2069,9 @@ static int __init rc_core_init(void) + + led_trigger_register_simple("rc-feedback", &led_feedback); + rc_map_register(&empty_map); ++#ifdef CONFIG_MEDIA_CEC_RC ++ rc_map_register(&cec_map); ++#endif + + return 0; + } +@@ -2078,6 +2081,9 @@ static void __exit rc_core_exit(void) + lirc_dev_exit(); + class_unregister(&rc_class); + led_trigger_unregister_simple(led_feedback); ++#ifdef CONFIG_MEDIA_CEC_RC ++ rc_map_unregister(&cec_map); ++#endif + rc_map_unregister(&empty_map); + } + +diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c +index b57e94fb19770..333bd305a4f9f 100644 +--- a/drivers/media/usb/usbtv/usbtv-audio.c ++++ b/drivers/media/usb/usbtv/usbtv-audio.c +@@ -371,7 +371,7 @@ void usbtv_audio_free(struct usbtv *usbtv) + cancel_work_sync(&usbtv->snd_trigger); + + if (usbtv->snd && usbtv->udev) { +- snd_card_free(usbtv->snd); ++ snd_card_free_when_closed(usbtv->snd); + usbtv->snd = NULL; + } + } +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index 815d01f785dff..273d9c1591793 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -948,6 +948,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, + if (!fl->cctx->rpdev) + return -EPIPE; + ++ if (handle == FASTRPC_INIT_HANDLE && !kernel) { ++ dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle); ++ return -EPERM; ++ } ++ + ctx = fastrpc_context_alloc(fl, kernel, sc, args); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); +diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c +index e16a5e51006e5..d9140e75602d7 100644 +--- a/drivers/misc/pvpanic.c ++++ b/drivers/misc/pvpanic.c +@@ -166,6 +166,7 @@ static const struct of_device_id pvpanic_mmio_match[] = { + { .compatible = "qemu,pvpanic-mmio", }, + {} + }; ++MODULE_DEVICE_TABLE(of, pvpanic_mmio_match); + + static struct platform_driver pvpanic_mmio_driver = { + .driver = { +diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c +index c2e70b757dd12..4383c262b3f5a 100644 +--- a/drivers/mmc/core/bus.c ++++ b/drivers/mmc/core/bus.c +@@ -399,11 +399,6 @@ void mmc_remove_card(struct mmc_card *card) + mmc_remove_card_debugfs(card); + #endif + +- if (host->cqe_enabled) { +- host->cqe_ops->cqe_disable(host); +- host->cqe_enabled = false; +- } +- + if (mmc_card_present(card)) { + if (mmc_host_is_spi(card->host)) { + pr_info("%s: SPI card removed\n", +@@ -416,6 +411,10 @@ void mmc_remove_card(struct mmc_card *card) + of_node_put(card->dev.of_node); + } + ++ if (host->cqe_enabled) { ++ host->cqe_ops->cqe_disable(host); ++ host->cqe_enabled = false; ++ } ++ + put_device(&card->dev); + } +- +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index ff3063ce2acda..9ce34e8800335 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -423,10 +423,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) + + /* EXT_CSD value is in units of 10ms, but we store in ms */ + card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; +- /* Some eMMC set the value too low so set a minimum */ +- if (card->ext_csd.part_time && +- card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) +- card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; + + /* Sleep / awake timeout in 100ns units */ + if (sa_shift > 0 && sa_shift <= 0x17) +@@ -616,6 +612,17 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) + card->ext_csd.data_sector_size = 512; + } + ++ /* ++ * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined ++ * when accessing a specific field", so use it here if there is no ++ * PARTITION_SWITCH_TIME. ++ */ ++ if (!card->ext_csd.part_time) ++ card->ext_csd.part_time = card->ext_csd.generic_cmd6_time; ++ /* Some eMMC set the value too low so set a minimum */ ++ if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) ++ card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; ++ + /* eMMC v5 or later */ + if (card->ext_csd.rev >= 7) { + memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], +diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c +index b5a41a7ce1658..9bde0def114b5 100644 +--- a/drivers/mmc/host/mmci.c ++++ b/drivers/mmc/host/mmci.c +@@ -1241,7 +1241,11 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) + if (!cmd->busy_timeout) + cmd->busy_timeout = 10 * MSEC_PER_SEC; + +- clks = (unsigned long long)cmd->busy_timeout * host->cclk; ++ if (cmd->busy_timeout > host->mmc->max_busy_timeout) ++ clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk; ++ else ++ clks = (unsigned long long)cmd->busy_timeout * host->cclk; ++ + do_div(clks, MSEC_PER_SEC); + writel_relaxed(clks, host->base + MMCIDATATIMER); + } +@@ -2091,6 +2095,10 @@ static int mmci_probe(struct amba_device *dev, + mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; + } + ++ /* Variants with mandatory busy timeout in HW needs R1B responses. */ ++ if (variant->busy_timeout) ++ mmc->caps |= MMC_CAP_NEED_RSP_BUSY; ++ + /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ + host->stop_abort.opcode = MMC_STOP_TRANSMISSION; + host->stop_abort.arg = 0; +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 004fbfc236721..dc84e2dff4085 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -1101,13 +1101,13 @@ static void msdc_track_cmd_data(struct msdc_host *host, + static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) + { + unsigned long flags; +- bool ret; + +- ret = cancel_delayed_work(&host->req_timeout); +- if (!ret) { +- /* delay work already running */ +- return; +- } ++ /* ++ * No need check the return value of cancel_delayed_work, as only ONE ++ * path will go here! ++ */ ++ cancel_delayed_work(&host->req_timeout); ++ + spin_lock_irqsave(&host->lock, flags); + host->mrq = NULL; + spin_unlock_irqrestore(&host->lock, flags); +@@ -1129,7 +1129,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, + bool done = false; + bool sbc_error; + unsigned long flags; +- u32 *rsp = cmd->resp; ++ u32 *rsp; + + if (mrq->sbc && cmd == mrq->cmd && + (events & (MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR +@@ -1150,6 +1150,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, + + if (done) + return true; ++ rsp = cmd->resp; + + sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask); + +@@ -1337,7 +1338,7 @@ static void msdc_data_xfer_next(struct msdc_host *host, + static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, + struct mmc_request *mrq, struct mmc_data *data) + { +- struct mmc_command *stop = data->stop; ++ struct mmc_command *stop; + unsigned long flags; + bool done; + unsigned int check_data = events & +@@ -1353,6 +1354,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, + + if (done) + return true; ++ stop = data->stop; + + if (check_data || (stop && stop->error)) { + dev_dbg(host->dev, "DMA status: 0x%8X\n", +diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c +index 75007f61df972..4fbbff03137c3 100644 +--- a/drivers/mmc/host/mxs-mmc.c ++++ b/drivers/mmc/host/mxs-mmc.c +@@ -643,7 +643,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) + + ret = mmc_of_parse(mmc); + if (ret) +- goto out_clk_disable; ++ goto out_free_dma; + + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + +diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c +index c9434b461aabc..ddeaf8e1f72f9 100644 +--- a/drivers/mmc/host/sdhci-iproc.c ++++ b/drivers/mmc/host/sdhci-iproc.c +@@ -296,9 +296,27 @@ static const struct of_device_id sdhci_iproc_of_match[] = { + MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match); + + #ifdef CONFIG_ACPI ++/* ++ * This is a duplicate of bcm2835_(pltfrm_)data without caps quirks ++ * which are provided by the ACPI table. ++ */ ++static const struct sdhci_pltfm_data sdhci_bcm_arasan_data = { ++ .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | ++ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_NO_HISPD_BIT, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, ++ .ops = &sdhci_iproc_32only_ops, ++}; ++ ++static const struct sdhci_iproc_data bcm_arasan_data = { ++ .pdata = &sdhci_bcm_arasan_data, ++}; ++ + static const struct acpi_device_id sdhci_iproc_acpi_ids[] = { + { .id = "BRCM5871", .driver_data = (kernel_ulong_t)&iproc_cygnus_data }, + { .id = "BRCM5872", .driver_data = (kernel_ulong_t)&iproc_data }, ++ { .id = "BCM2847", .driver_data = (kernel_ulong_t)&bcm_arasan_data }, ++ { .id = "BRCME88C", .driver_data = (kernel_ulong_t)&bcm2711_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(acpi, sdhci_iproc_acpi_ids); +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index 3561ae8a481a0..6edf9fffd934a 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -3994,10 +3994,10 @@ void __sdhci_read_caps(struct sdhci_host *host, const u16 *ver, + if (host->v4_mode) + sdhci_do_enable_v4_mode(host); + +- of_property_read_u64(mmc_dev(host->mmc)->of_node, +- "sdhci-caps-mask", &dt_caps_mask); +- of_property_read_u64(mmc_dev(host->mmc)->of_node, +- "sdhci-caps", &dt_caps); ++ device_property_read_u64_array(mmc_dev(host->mmc), ++ "sdhci-caps-mask", &dt_caps_mask, 1); ++ device_property_read_u64_array(mmc_dev(host->mmc), ++ "sdhci-caps", &dt_caps, 1); + + v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION); + host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index 13e0a8caf3b6f..600b9d09ec087 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -92,7 +92,7 @@ config WIREGUARD + select CRYPTO_POLY1305_ARM if ARM + select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON + select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2 +- select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT) ++ select CRYPTO_POLY1305_MIPS if MIPS + help + WireGuard is a secure, fast, and easy to use replacement for IPSec + that uses modern cryptography and clever networking tricks. It's +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index 99e5f272205d3..d712c6fdbc87d 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -662,7 +662,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv) + u32 reg; + + reg = priv->read(®s->mcr); +- reg |= FLEXCAN_MCR_HALT; ++ reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; + priv->write(reg, ®s->mcr); + + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) +@@ -1375,10 +1375,13 @@ static int flexcan_chip_start(struct net_device *dev) + + flexcan_set_bittiming(dev); + ++ /* set freeze, halt */ ++ err = flexcan_chip_freeze(priv); ++ if (err) ++ goto out_chip_disable; ++ + /* MCR + * +- * enable freeze +- * halt now + * only supervisor access + * enable warning int + * enable individual RX masking +@@ -1387,9 +1390,8 @@ static int flexcan_chip_start(struct net_device *dev) + */ + reg_mcr = priv->read(®s->mcr); + reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); +- reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | +- FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C | +- FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); ++ reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | ++ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); + + /* MCR + * +@@ -1800,10 +1802,14 @@ static int register_flexcandev(struct net_device *dev) + if (err) + goto out_chip_disable; + +- /* set freeze, halt and activate FIFO, restrict register access */ ++ /* set freeze, halt */ ++ err = flexcan_chip_freeze(priv); ++ if (err) ++ goto out_chip_disable; ++ ++ /* activate FIFO, restrict register access */ + reg = priv->read(®s->mcr); +- reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | +- FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; ++ reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; + priv->write(reg, ®s->mcr); + + /* Currently we only support newer versions of this core +diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c +index f726c5112294f..01f5b6e03a2dd 100644 +--- a/drivers/net/can/m_can/tcan4x5x.c ++++ b/drivers/net/can/m_can/tcan4x5x.c +@@ -328,14 +328,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev) + if (ret) + return ret; + ++ /* Zero out the MCAN buffers */ ++ m_can_init_ram(cdev); ++ + ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, + TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); + if (ret) + return ret; + +- /* Zero out the MCAN buffers */ +- m_can_init_ram(cdev); +- + return ret; + } + +diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c +index 4ca0296509936..1a855816cbc9d 100644 +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -1834,7 +1834,7 @@ out_unlock_ptp: + speed = SPEED_1000; + else if (bmcr & BMCR_SPEED100) + speed = SPEED_100; +- else if (bmcr & BMCR_SPEED10) ++ else + speed = SPEED_10; + + sja1105_sgmii_pcs_force_speed(priv, speed); +diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c +index 9b7f1af5f5747..9e02f88645931 100644 +--- a/drivers/net/ethernet/atheros/alx/main.c ++++ b/drivers/net/ethernet/atheros/alx/main.c +@@ -1894,13 +1894,16 @@ static int alx_resume(struct device *dev) + + if (!netif_running(alx->dev)) + return 0; +- netif_device_attach(alx->dev); + + rtnl_lock(); + err = __alx_open(alx, true); + rtnl_unlock(); ++ if (err) ++ return err; + +- return err; ++ netif_device_attach(alx->dev); ++ ++ return 0; + } + + static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index c7c5c01a783a0..a59c1f1fb31ed 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -8430,10 +8430,18 @@ static void bnxt_setup_inta(struct bnxt *bp) + bp->irq_tbl[0].handler = bnxt_inta; + } + ++static int bnxt_init_int_mode(struct bnxt *bp); ++ + static int bnxt_setup_int_mode(struct bnxt *bp) + { + int rc; + ++ if (!bp->irq_tbl) { ++ rc = bnxt_init_int_mode(bp); ++ if (rc || !bp->irq_tbl) ++ return rc ?: -ENODEV; ++ } ++ + if (bp->flags & BNXT_FLAG_USING_MSIX) + bnxt_setup_msix(bp); + else +@@ -8618,7 +8626,7 @@ static int bnxt_init_inta(struct bnxt *bp) + + static int bnxt_init_int_mode(struct bnxt *bp) + { +- int rc = 0; ++ int rc = -ENODEV; + + if (bp->flags & BNXT_FLAG_MSIX_CAP) + rc = bnxt_init_msix(bp); +@@ -9339,7 +9347,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) + { + struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_drv_if_change_input req = {0}; +- bool resc_reinit = false, fw_reset = false; ++ bool fw_reset = !bp->irq_tbl; ++ bool resc_reinit = false; + u32 flags = 0; + int rc; + +@@ -9367,6 +9376,7 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) + + if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) { + netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n"); ++ set_bit(BNXT_STATE_ABORT_ERR, &bp->state); + return -ENODEV; + } + if (resc_reinit || fw_reset) { +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index 5c6c8c5ec7471..ba7f857d1710d 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -133,6 +133,8 @@ struct board_info { + u32 wake_state; + + int ip_summed; ++ ++ struct regulator *power_supply; + }; + + /* debug code */ +@@ -1452,7 +1454,7 @@ dm9000_probe(struct platform_device *pdev) + if (ret) { + dev_err(dev, "failed to request reset gpio %d: %d\n", + reset_gpios, ret); +- return -ENODEV; ++ goto out_regulator_disable; + } + + /* According to manual PWRST# Low Period Min 1ms */ +@@ -1464,8 +1466,10 @@ dm9000_probe(struct platform_device *pdev) + + if (!pdata) { + pdata = dm9000_parse_dt(&pdev->dev); +- if (IS_ERR(pdata)) +- return PTR_ERR(pdata); ++ if (IS_ERR(pdata)) { ++ ret = PTR_ERR(pdata); ++ goto out_regulator_disable; ++ } + } + + /* Init network device */ +@@ -1482,6 +1486,8 @@ dm9000_probe(struct platform_device *pdev) + + db->dev = &pdev->dev; + db->ndev = ndev; ++ if (!IS_ERR(power)) ++ db->power_supply = power; + + spin_lock_init(&db->lock); + mutex_init(&db->addr_lock); +@@ -1706,6 +1712,10 @@ out: + dm9000_release_board(pdev, db); + free_netdev(ndev); + ++out_regulator_disable: ++ if (!IS_ERR(power)) ++ regulator_disable(power); ++ + return ret; + } + +@@ -1763,10 +1773,13 @@ static int + dm9000_drv_remove(struct platform_device *pdev) + { + struct net_device *ndev = platform_get_drvdata(pdev); ++ struct board_info *dm = to_dm9000_board(ndev); + + unregister_netdev(ndev); +- dm9000_release_board(pdev, netdev_priv(ndev)); ++ dm9000_release_board(pdev, dm); + free_netdev(ndev); /* free device structure */ ++ if (dm->power_supply) ++ regulator_disable(dm->power_supply); + + dev_dbg(&pdev->dev, "released and freed device\n"); + return 0; +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index fc2075ea57fea..df4a858c80015 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -321,6 +321,8 @@ static int enetc_poll(struct napi_struct *napi, int budget) + int work_done; + int i; + ++ enetc_lock_mdio(); ++ + for (i = 0; i < v->count_tx_rings; i++) + if (!enetc_clean_tx_ring(&v->tx_ring[i], budget)) + complete = false; +@@ -331,8 +333,10 @@ static int enetc_poll(struct napi_struct *napi, int budget) + if (work_done) + v->rx_napi_work = true; + +- if (!complete) ++ if (!complete) { ++ enetc_unlock_mdio(); + return budget; ++ } + + napi_complete_done(napi, work_done); + +@@ -341,8 +345,6 @@ static int enetc_poll(struct napi_struct *napi, int budget) + + v->rx_napi_work = false; + +- enetc_lock_mdio(); +- + /* enable interrupts */ + enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE); + +@@ -367,8 +369,8 @@ static void enetc_get_tx_tstamp(struct enetc_hw *hw, union enetc_tx_bd *txbd, + { + u32 lo, hi, tstamp_lo; + +- lo = enetc_rd(hw, ENETC_SICTR0); +- hi = enetc_rd(hw, ENETC_SICTR1); ++ lo = enetc_rd_hot(hw, ENETC_SICTR0); ++ hi = enetc_rd_hot(hw, ENETC_SICTR1); + tstamp_lo = le32_to_cpu(txbd->wb.tstamp); + if (lo <= tstamp_lo) + hi -= 1; +@@ -382,6 +384,12 @@ static void enetc_tstamp_tx(struct sk_buff *skb, u64 tstamp) + if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) { + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(tstamp); ++ /* Ensure skb_mstamp_ns, which might have been populated with ++ * the txtime, is not mistaken for a software timestamp, ++ * because this will prevent the dispatch of our hardware ++ * timestamp to the socket. ++ */ ++ skb->tstamp = ktime_set(0, 0); + skb_tstamp_tx(skb, &shhwtstamps); + } + } +@@ -398,9 +406,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) + i = tx_ring->next_to_clean; + tx_swbd = &tx_ring->tx_swbd[i]; + +- enetc_lock_mdio(); + bds_to_clean = enetc_bd_ready_count(tx_ring, i); +- enetc_unlock_mdio(); + + do_tstamp = false; + +@@ -443,8 +449,6 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) + tx_swbd = tx_ring->tx_swbd; + } + +- enetc_lock_mdio(); +- + /* BD iteration loop end */ + if (is_eof) { + tx_frm_cnt++; +@@ -455,8 +459,6 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) + + if (unlikely(!bds_to_clean)) + bds_to_clean = enetc_bd_ready_count(tx_ring, i); +- +- enetc_unlock_mdio(); + } + + tx_ring->next_to_clean = i; +@@ -567,9 +569,8 @@ static void enetc_get_rx_tstamp(struct net_device *ndev, + static void enetc_get_offloads(struct enetc_bdr *rx_ring, + union enetc_rx_bd *rxbd, struct sk_buff *skb) + { +-#ifdef CONFIG_FSL_ENETC_PTP_CLOCK + struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev); +-#endif ++ + /* TODO: hashing */ + if (rx_ring->ndev->features & NETIF_F_RXCSUM) { + u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum); +@@ -578,12 +579,31 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring, + skb->ip_summed = CHECKSUM_COMPLETE; + } + +- /* copy VLAN to skb, if one is extracted, for now we assume it's a +- * standard TPID, but HW also supports custom values +- */ +- if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) +- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), +- le16_to_cpu(rxbd->r.vlan_opt)); ++ if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) { ++ __be16 tpid = 0; ++ ++ switch (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TPID) { ++ case 0: ++ tpid = htons(ETH_P_8021Q); ++ break; ++ case 1: ++ tpid = htons(ETH_P_8021AD); ++ break; ++ case 2: ++ tpid = htons(enetc_port_rd(&priv->si->hw, ++ ENETC_PCVLANR1)); ++ break; ++ case 3: ++ tpid = htons(enetc_port_rd(&priv->si->hw, ++ ENETC_PCVLANR2)); ++ break; ++ default: ++ break; ++ } ++ ++ __vlan_hwaccel_put_tag(skb, tpid, le16_to_cpu(rxbd->r.vlan_opt)); ++ } ++ + #ifdef CONFIG_FSL_ENETC_PTP_CLOCK + if (priv->active_offloads & ENETC_F_RX_TSTAMP) + enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb); +@@ -700,8 +720,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, + u32 bd_status; + u16 size; + +- enetc_lock_mdio(); +- + if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { + int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt); + +@@ -712,19 +730,15 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, + + rxbd = enetc_rxbd(rx_ring, i); + bd_status = le32_to_cpu(rxbd->r.lstatus); +- if (!bd_status) { +- enetc_unlock_mdio(); ++ if (!bd_status) + break; +- } + + enetc_wr_reg_hot(rx_ring->idr, BIT(rx_ring->index)); + dma_rmb(); /* for reading other rxbd fields */ + size = le16_to_cpu(rxbd->r.buf_len); + skb = enetc_map_rx_buff_to_skb(rx_ring, i, size); +- if (!skb) { +- enetc_unlock_mdio(); ++ if (!skb) + break; +- } + + enetc_get_offloads(rx_ring, rxbd, skb); + +@@ -736,7 +750,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, + + if (unlikely(bd_status & + ENETC_RXBD_LSTATUS(ENETC_RXBD_ERR_MASK))) { +- enetc_unlock_mdio(); + dev_kfree_skb(skb); + while (!(bd_status & ENETC_RXBD_LSTATUS_F)) { + dma_rmb(); +@@ -776,8 +789,6 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, + + enetc_process_skb(rx_ring, skb); + +- enetc_unlock_mdio(); +- + napi_gro_receive(napi, skb); + + rx_frm_cnt++; +@@ -1024,7 +1035,7 @@ static void enetc_free_rxtx_rings(struct enetc_ndev_priv *priv) + enetc_free_tx_ring(priv->tx_ring[i]); + } + +-static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) ++int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) + { + int size = cbdr->bd_count * sizeof(struct enetc_cbd); + +@@ -1045,7 +1056,7 @@ static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) + return 0; + } + +-static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) ++void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) + { + int size = cbdr->bd_count * sizeof(struct enetc_cbd); + +@@ -1053,7 +1064,7 @@ static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) + cbdr->bd_base = NULL; + } + +-static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) ++void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) + { + /* set CBDR cache attributes */ + enetc_wr(hw, ENETC_SICAR2, +@@ -1073,7 +1084,7 @@ static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) + cbdr->cir = hw->reg + ENETC_SICBDRCIR; + } + +-static void enetc_clear_cbdr(struct enetc_hw *hw) ++void enetc_clear_cbdr(struct enetc_hw *hw) + { + enetc_wr(hw, ENETC_SICBDRMR, 0); + } +@@ -1098,13 +1109,12 @@ static int enetc_setup_default_rss_table(struct enetc_si *si, int num_groups) + return 0; + } + +-static int enetc_configure_si(struct enetc_ndev_priv *priv) ++int enetc_configure_si(struct enetc_ndev_priv *priv) + { + struct enetc_si *si = priv->si; + struct enetc_hw *hw = &si->hw; + int err; + +- enetc_setup_cbdr(hw, &si->cbd_ring); + /* set SI cache attributes */ + enetc_wr(hw, ENETC_SICAR0, + ENETC_SICAR_RD_COHERENT | ENETC_SICAR_WR_COHERENT); +@@ -1152,6 +1162,8 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv) + if (err) + return err; + ++ enetc_setup_cbdr(&si->hw, &si->cbd_ring); ++ + priv->cls_rules = kcalloc(si->num_fs_entries, sizeof(*priv->cls_rules), + GFP_KERNEL); + if (!priv->cls_rules) { +@@ -1159,14 +1171,8 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv) + goto err_alloc_cls; + } + +- err = enetc_configure_si(priv); +- if (err) +- goto err_config_si; +- + return 0; + +-err_config_si: +- kfree(priv->cls_rules); + err_alloc_cls: + enetc_clear_cbdr(&si->hw); + enetc_free_cbdr(priv->dev, &si->cbd_ring); +@@ -1252,7 +1258,8 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) + rx_ring->idr = hw->reg + ENETC_SIRXIDR; + + enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); +- enetc_wr(hw, ENETC_SIRXIDR, rx_ring->next_to_use); ++ /* update ENETC's consumer index */ ++ enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use); + + /* enable ring */ + enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h +index dd0fb0c066d75..15d19cbd5a954 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.h ++++ b/drivers/net/ethernet/freescale/enetc/enetc.h +@@ -293,6 +293,7 @@ void enetc_get_si_caps(struct enetc_si *si); + void enetc_init_si_rings_params(struct enetc_ndev_priv *priv); + int enetc_alloc_si_resources(struct enetc_ndev_priv *priv); + void enetc_free_si_resources(struct enetc_ndev_priv *priv); ++int enetc_configure_si(struct enetc_ndev_priv *priv); + + int enetc_open(struct net_device *ndev); + int enetc_close(struct net_device *ndev); +@@ -310,6 +311,10 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, + void enetc_set_ethtool_ops(struct net_device *ndev); + + /* control buffer descriptor ring (CBDR) */ ++int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr); ++void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr); ++void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr); ++void enetc_clear_cbdr(struct enetc_hw *hw); + int enetc_set_mac_flt_entry(struct enetc_si *si, int index, + char *mac_addr, int si_map); + int enetc_clear_mac_flt_entry(struct enetc_si *si, int index); +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +index 014ca6ae121f8..21a6ce415cb22 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h ++++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +@@ -172,6 +172,8 @@ enum enetc_bdr_type {TX, RX}; + #define ENETC_PSIPMAR0(n) (0x0100 + (n) * 0x8) /* n = SI index */ + #define ENETC_PSIPMAR1(n) (0x0104 + (n) * 0x8) + #define ENETC_PVCLCTR 0x0208 ++#define ENETC_PCVLANR1 0x0210 ++#define ENETC_PCVLANR2 0x0214 + #define ENETC_VLAN_TYPE_C BIT(0) + #define ENETC_VLAN_TYPE_S BIT(1) + #define ENETC_PVCLCTR_OVTPIDL(bmp) ((bmp) & 0xff) /* VLAN_TYPE */ +@@ -236,10 +238,17 @@ enum enetc_bdr_type {TX, RX}; + #define ENETC_PM_IMDIO_BASE 0x8030 + + #define ENETC_PM0_IF_MODE 0x8300 +-#define ENETC_PMO_IFM_RG BIT(2) ++#define ENETC_PM0_IFM_RG BIT(2) + #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11)) +-#define ENETC_PM0_IFM_RGAUTO (BIT(15) | ENETC_PMO_IFM_RG | BIT(1)) +-#define ENETC_PM0_IFM_XGMII BIT(12) ++#define ENETC_PM0_IFM_EN_AUTO BIT(15) ++#define ENETC_PM0_IFM_SSP_MASK GENMASK(14, 13) ++#define ENETC_PM0_IFM_SSP_1000 (2 << 13) ++#define ENETC_PM0_IFM_SSP_100 (0 << 13) ++#define ENETC_PM0_IFM_SSP_10 (1 << 13) ++#define ENETC_PM0_IFM_FULL_DPX BIT(12) ++#define ENETC_PM0_IFM_IFMODE_MASK GENMASK(1, 0) ++#define ENETC_PM0_IFM_IFMODE_XGMII 0 ++#define ENETC_PM0_IFM_IFMODE_GMII 2 + #define ENETC_PSIDCAPR 0x1b08 + #define ENETC_PSIDCAPR_MSK GENMASK(15, 0) + #define ENETC_PSFCAPR 0x1b18 +@@ -453,6 +462,8 @@ static inline u64 _enetc_rd_reg64_wa(void __iomem *reg) + #define enetc_wr_reg(reg, val) _enetc_wr_reg_wa((reg), (val)) + #define enetc_rd(hw, off) enetc_rd_reg((hw)->reg + (off)) + #define enetc_wr(hw, off, val) enetc_wr_reg((hw)->reg + (off), val) ++#define enetc_rd_hot(hw, off) enetc_rd_reg_hot((hw)->reg + (off)) ++#define enetc_wr_hot(hw, off, val) enetc_wr_reg_hot((hw)->reg + (off), val) + #define enetc_rd64(hw, off) _enetc_rd_reg64_wa((hw)->reg + (off)) + /* port register accessors - PF only */ + #define enetc_port_rd(hw, off) enetc_rd_reg((hw)->port + (off)) +@@ -573,6 +584,7 @@ union enetc_rx_bd { + #define ENETC_RXBD_LSTATUS(flags) ((flags) << 16) + #define ENETC_RXBD_FLAG_VLAN BIT(9) + #define ENETC_RXBD_FLAG_TSTMP BIT(10) ++#define ENETC_RXBD_FLAG_TPID GENMASK(1, 0) + + #define ENETC_MAC_ADDR_FILT_CNT 8 /* # of supported entries per port */ + #define EMETC_MAC_ADDR_FILT_RES 3 /* # of reserved entries at the beginning */ +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +index 796e3d6f23f09..83187cd59fddd 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +@@ -190,7 +190,6 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev) + { + struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_pf *pf = enetc_si_priv(priv->si); +- char vlan_promisc_simap = pf->vlan_promisc_simap; + struct enetc_hw *hw = &priv->si->hw; + bool uprom = false, mprom = false; + struct enetc_mac_filter *filter; +@@ -203,16 +202,12 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev) + psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0); + uprom = true; + mprom = true; +- /* Enable VLAN promiscuous mode for SI0 (PF) */ +- vlan_promisc_simap |= BIT(0); + } else if (ndev->flags & IFF_ALLMULTI) { + /* enable multi cast promisc mode for SI0 (PF) */ + psipmr = ENETC_PSIPMR_SET_MP(0); + mprom = true; + } + +- enetc_set_vlan_promisc(&pf->si->hw, vlan_promisc_simap); +- + /* first 2 filter entries belong to PF */ + if (!uprom) { + /* Update unicast filters */ +@@ -320,7 +315,7 @@ static void enetc_set_loopback(struct net_device *ndev, bool en) + u32 reg; + + reg = enetc_port_rd(hw, ENETC_PM0_IF_MODE); +- if (reg & ENETC_PMO_IFM_RG) { ++ if (reg & ENETC_PM0_IFM_RG) { + /* RGMII mode */ + reg = (reg & ~ENETC_PM0_IFM_RLP) | + (en ? ENETC_PM0_IFM_RLP : 0); +@@ -499,13 +494,20 @@ static void enetc_configure_port_mac(struct enetc_hw *hw) + + static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) + { +- /* set auto-speed for RGMII */ +- if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || +- phy_interface_mode_is_rgmii(phy_mode)) +- enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); ++ u32 val; + +- if (phy_mode == PHY_INTERFACE_MODE_USXGMII) +- enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); ++ if (phy_interface_mode_is_rgmii(phy_mode)) { ++ val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); ++ val &= ~ENETC_PM0_IFM_EN_AUTO; ++ val &= ENETC_PM0_IFM_IFMODE_MASK; ++ val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG; ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++ } ++ ++ if (phy_mode == PHY_INTERFACE_MODE_USXGMII) { ++ val = ENETC_PM0_IFM_FULL_DPX | ENETC_PM0_IFM_IFMODE_XGMII; ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++ } + } + + static void enetc_mac_enable(struct enetc_hw *hw, bool en) +@@ -857,13 +859,12 @@ static bool enetc_port_has_pcs(struct enetc_pf *pf) + pf->if_mode == PHY_INTERFACE_MODE_USXGMII); + } + +-static int enetc_mdiobus_create(struct enetc_pf *pf) ++static int enetc_mdiobus_create(struct enetc_pf *pf, struct device_node *node) + { +- struct device *dev = &pf->si->pdev->dev; + struct device_node *mdio_np; + int err; + +- mdio_np = of_get_child_by_name(dev->of_node, "mdio"); ++ mdio_np = of_get_child_by_name(node, "mdio"); + if (mdio_np) { + err = enetc_mdio_probe(pf, mdio_np); + +@@ -944,6 +945,34 @@ static void enetc_pl_mac_config(struct phylink_config *config, + phylink_set_pcs(priv->phylink, &pf->pcs->pcs); + } + ++static void enetc_force_rgmii_mac(struct enetc_hw *hw, int speed, int duplex) ++{ ++ u32 old_val, val; ++ ++ old_val = val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); ++ ++ if (speed == SPEED_1000) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_1000; ++ } else if (speed == SPEED_100) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_100; ++ } else if (speed == SPEED_10) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_10; ++ } ++ ++ if (duplex == DUPLEX_FULL) ++ val |= ENETC_PM0_IFM_FULL_DPX; ++ else ++ val &= ~ENETC_PM0_IFM_FULL_DPX; ++ ++ if (val == old_val) ++ return; ++ ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++} ++ + static void enetc_pl_mac_link_up(struct phylink_config *config, + struct phy_device *phy, unsigned int mode, + phy_interface_t interface, int speed, +@@ -956,6 +985,10 @@ static void enetc_pl_mac_link_up(struct phylink_config *config, + if (priv->active_offloads & ENETC_F_QBV) + enetc_sched_speed_set(priv, speed); + ++ if (!phylink_autoneg_inband(mode) && ++ phy_interface_mode_is_rgmii(interface)) ++ enetc_force_rgmii_mac(&pf->si->hw, speed, duplex); ++ + enetc_mac_enable(&pf->si->hw, true); + } + +@@ -975,18 +1008,17 @@ static const struct phylink_mac_ops enetc_mac_phylink_ops = { + .mac_link_down = enetc_pl_mac_link_down, + }; + +-static int enetc_phylink_create(struct enetc_ndev_priv *priv) ++static int enetc_phylink_create(struct enetc_ndev_priv *priv, ++ struct device_node *node) + { + struct enetc_pf *pf = enetc_si_priv(priv->si); +- struct device *dev = &pf->si->pdev->dev; + struct phylink *phylink; + int err; + + pf->phylink_config.dev = &priv->ndev->dev; + pf->phylink_config.type = PHYLINK_NETDEV; + +- phylink = phylink_create(&pf->phylink_config, +- of_fwnode_handle(dev->of_node), ++ phylink = phylink_create(&pf->phylink_config, of_fwnode_handle(node), + pf->if_mode, &enetc_mac_phylink_ops); + if (IS_ERR(phylink)) { + err = PTR_ERR(phylink); +@@ -1049,20 +1081,36 @@ static int enetc_init_port_rss_memory(struct enetc_si *si) + return err; + } + ++static void enetc_init_unused_port(struct enetc_si *si) ++{ ++ struct device *dev = &si->pdev->dev; ++ struct enetc_hw *hw = &si->hw; ++ int err; ++ ++ si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE; ++ err = enetc_alloc_cbdr(dev, &si->cbd_ring); ++ if (err) ++ return; ++ ++ enetc_setup_cbdr(hw, &si->cbd_ring); ++ ++ enetc_init_port_rfs_memory(si); ++ enetc_init_port_rss_memory(si); ++ ++ enetc_clear_cbdr(hw); ++ enetc_free_cbdr(dev, &si->cbd_ring); ++} ++ + static int enetc_pf_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { ++ struct device_node *node = pdev->dev.of_node; + struct enetc_ndev_priv *priv; + struct net_device *ndev; + struct enetc_si *si; + struct enetc_pf *pf; + int err; + +- if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { +- dev_info(&pdev->dev, "device is disabled, skipping\n"); +- return -ENODEV; +- } +- + err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf)); + if (err) { + dev_err(&pdev->dev, "PCI probing failed\n"); +@@ -1076,6 +1124,13 @@ static int enetc_pf_probe(struct pci_dev *pdev, + goto err_map_pf_space; + } + ++ if (node && !of_device_is_available(node)) { ++ enetc_init_unused_port(si); ++ dev_info(&pdev->dev, "device is disabled, skipping\n"); ++ err = -ENODEV; ++ goto err_device_disabled; ++ } ++ + pf = enetc_si_priv(si); + pf->si = si; + pf->total_vfs = pci_sriov_get_totalvfs(pdev); +@@ -1115,18 +1170,24 @@ static int enetc_pf_probe(struct pci_dev *pdev, + goto err_init_port_rss; + } + ++ err = enetc_configure_si(priv); ++ if (err) { ++ dev_err(&pdev->dev, "Failed to configure SI\n"); ++ goto err_config_si; ++ } ++ + err = enetc_alloc_msix(priv); + if (err) { + dev_err(&pdev->dev, "MSIX alloc failed\n"); + goto err_alloc_msix; + } + +- if (!of_get_phy_mode(pdev->dev.of_node, &pf->if_mode)) { +- err = enetc_mdiobus_create(pf); ++ if (!of_get_phy_mode(node, &pf->if_mode)) { ++ err = enetc_mdiobus_create(pf, node); + if (err) + goto err_mdiobus_create; + +- err = enetc_phylink_create(priv); ++ err = enetc_phylink_create(priv, node); + if (err) + goto err_phylink_create; + } +@@ -1143,6 +1204,7 @@ err_phylink_create: + enetc_mdiobus_destroy(pf); + err_mdiobus_create: + enetc_free_msix(priv); ++err_config_si: + err_init_port_rss: + err_init_port_rfs: + err_alloc_msix: +@@ -1151,6 +1213,7 @@ err_alloc_si_res: + si->ndev = NULL; + free_netdev(ndev); + err_alloc_netdev: ++err_device_disabled: + err_map_pf_space: + enetc_pci_remove(pdev); + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c +index 7b5c82c7e4e5a..33c125735db7e 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c +@@ -177,6 +177,12 @@ static int enetc_vf_probe(struct pci_dev *pdev, + goto err_alloc_si_res; + } + ++ err = enetc_configure_si(priv); ++ if (err) { ++ dev_err(&pdev->dev, "Failed to configure SI\n"); ++ goto err_config_si; ++ } ++ + err = enetc_alloc_msix(priv); + if (err) { + dev_err(&pdev->dev, "MSIX alloc failed\n"); +@@ -193,6 +199,7 @@ static int enetc_vf_probe(struct pci_dev *pdev, + + err_reg_netdev: + enetc_free_msix(priv); ++err_config_si: + err_alloc_msix: + enetc_free_si_resources(priv); + err_alloc_si_res: +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +index 096e26a2e16b4..36690fc5c1aff 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +@@ -1031,16 +1031,16 @@ struct hclge_fd_tcam_config_3_cmd { + #define HCLGE_FD_AD_DROP_B 0 + #define HCLGE_FD_AD_DIRECT_QID_B 1 + #define HCLGE_FD_AD_QID_S 2 +-#define HCLGE_FD_AD_QID_M GENMASK(12, 2) ++#define HCLGE_FD_AD_QID_M GENMASK(11, 2) + #define HCLGE_FD_AD_USE_COUNTER_B 12 + #define HCLGE_FD_AD_COUNTER_NUM_S 13 + #define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(20, 13) + #define HCLGE_FD_AD_NXT_STEP_B 20 + #define HCLGE_FD_AD_NXT_KEY_S 21 +-#define HCLGE_FD_AD_NXT_KEY_M GENMASK(26, 21) ++#define HCLGE_FD_AD_NXT_KEY_M GENMASK(25, 21) + #define HCLGE_FD_AD_WR_RULE_ID_B 0 + #define HCLGE_FD_AD_RULE_ID_S 1 +-#define HCLGE_FD_AD_RULE_ID_M GENMASK(13, 1) ++#define HCLGE_FD_AD_RULE_ID_M GENMASK(12, 1) + + struct hclge_fd_ad_config_cmd { + u8 stage; +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index c40820baf48a6..b856dbe4db73b 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -5115,9 +5115,9 @@ static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y, + case BIT(INNER_SRC_MAC): + for (i = 0; i < ETH_ALEN; i++) { + calc_x(key_x[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], +- rule->tuples.src_mac[i]); ++ rule->tuples_mask.src_mac[i]); + calc_y(key_y[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], +- rule->tuples.src_mac[i]); ++ rule->tuples_mask.src_mac[i]); + } + + return true; +@@ -6183,8 +6183,7 @@ static void hclge_fd_get_ext_info(struct ethtool_rx_flow_spec *fs, + fs->h_ext.vlan_tci = cpu_to_be16(rule->tuples.vlan_tag1); + fs->m_ext.vlan_tci = + rule->unused_tuple & BIT(INNER_VLAN_TAG_FST) ? +- cpu_to_be16(VLAN_VID_MASK) : +- cpu_to_be16(rule->tuples_mask.vlan_tag1); ++ 0 : cpu_to_be16(rule->tuples_mask.vlan_tag1); + } + + if (fs->flow_type & FLOW_MAC_EXT) { +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 5e1f4e71af7bc..f184f4a79cc39 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -1832,10 +1832,9 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p) + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + +- if (adapter->state != VNIC_PROBED) { +- ether_addr_copy(adapter->mac_addr, addr->sa_data); ++ ether_addr_copy(adapter->mac_addr, addr->sa_data); ++ if (adapter->state != VNIC_PROBED) + rc = __ibmvnic_set_mac(netdev, addr->sa_data); +- } + + return rc; + } +@@ -5176,16 +5175,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset) + { + struct device *dev = &adapter->vdev->dev; + unsigned long timeout = msecs_to_jiffies(20000); +- u64 old_num_rx_queues, old_num_tx_queues; ++ u64 old_num_rx_queues = adapter->req_rx_queues; ++ u64 old_num_tx_queues = adapter->req_tx_queues; + int rc; + + adapter->from_passive_init = false; + +- if (reset) { +- old_num_rx_queues = adapter->req_rx_queues; +- old_num_tx_queues = adapter->req_tx_queues; ++ if (reset) + reinit_completion(&adapter->init_done); +- } + + adapter->init_done_rc = 0; + rc = ibmvnic_send_crq_init(adapter); +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 59971f62e6268..3e4a4d6f0419c 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -15100,6 +15100,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + if (err) { + dev_info(&pdev->dev, + "setup of misc vector failed: %d\n", err); ++ i40e_cloud_filter_exit(pf); ++ i40e_fdir_teardown(pf); + goto err_vsis; + } + } +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +index eca73526ac86b..54d47265a7ac1 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +@@ -575,6 +575,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs) + return -EINVAL; + } + ++ if (xs->props.mode != XFRM_MODE_TRANSPORT) { ++ netdev_err(dev, "Unsupported mode for ipsec offload\n"); ++ return -EINVAL; ++ } ++ + if (ixgbe_ipsec_check_mgmt_ip(xs)) { + netdev_err(dev, "IPsec IP addr clash with mgmt filters\n"); + return -EINVAL; +diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c +index 5170dd9d8705b..caaea2c920a6e 100644 +--- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c +@@ -272,6 +272,11 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs) + return -EINVAL; + } + ++ if (xs->props.mode != XFRM_MODE_TRANSPORT) { ++ netdev_err(dev, "Unsupported mode for ipsec offload\n"); ++ return -EINVAL; ++ } ++ + if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { + struct rx_sa rsa; + +diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c +index a8641a407c06a..96d2891f1675a 100644 +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1225,8 +1225,6 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv) + goto push_new_skb; + } + +- desc_data.dma_addr = new_dma_addr; +- + /* We can't fail anymore at this point: it's safe to unmap the skb. */ + mtk_star_dma_unmap_rx(priv, &desc_data); + +@@ -1236,6 +1234,9 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv) + desc_data.skb->dev = ndev; + netif_receive_skb(desc_data.skb); + ++ /* update dma_addr for new skb */ ++ desc_data.dma_addr = new_dma_addr; ++ + push_new_skb: + desc_data.len = skb_tailroom(new_skb); + desc_data.skb = new_skb; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index 23849f2b9c252..1434df66fcf2e 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -47,7 +47,7 @@ + #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) + #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) + +-static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv) + { + int i, t; + int err = 0; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index 6f290319b6178..d8a20e83d9040 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -3559,6 +3559,8 @@ int mlx4_en_reset_config(struct net_device *dev, + en_err(priv, "Failed starting port\n"); + } + ++ if (!err) ++ err = mlx4_en_moderation_update(priv); + out: + mutex_unlock(&mdev->state_lock); + kfree(tmp); +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +index 30378e4c90b5b..0aa4a23ad3def 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -795,6 +795,7 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); + #define DEV_FEATURE_CHANGED(dev, new_features, feature) \ + ((dev->features & feature) ^ (new_features & feature)) + ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv); + int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t new_features); +diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h +index 39eff6a57ba22..3c3069afc0a31 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h ++++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h +@@ -4208,6 +4208,7 @@ MLXSW_ITEM32(reg, ptys, ext_eth_proto_cap, 0x08, 0, 32); + #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 BIT(20) + #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 BIT(21) + #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 BIT(22) ++#define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4 BIT(23) + #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR BIT(27) + #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR BIT(28) + #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR BIT(29) +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +index 540616469e284..68333ecf6151e 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +@@ -1171,6 +1171,11 @@ static const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = { + .mask_ethtool = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + .speed = SPEED_100000, + }, ++ { ++ .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4, ++ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, ++ .speed = SPEED_100000, ++ }, + }; + + #define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode) +diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c +index 5023d91269f45..28bfe1ea9d947 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c +@@ -612,7 +612,8 @@ static const struct mlxsw_sx_port_link_mode mlxsw_sx_port_link_mode[] = { + { + .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 | + MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 | +- MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4, ++ MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 | ++ MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4, + .speed = 100000, + }, + }; +diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c +index 729495a1a77ee..3655503352928 100644 +--- a/drivers/net/ethernet/mscc/ocelot_flower.c ++++ b/drivers/net/ethernet/mscc/ocelot_flower.c +@@ -540,13 +540,14 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress, + return -EOPNOTSUPP; + } + ++ flow_rule_match_ipv4_addrs(rule, &match); ++ + if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) { + NL_SET_ERR_MSG_MOD(extack, + "Key type S1_NORMAL cannot match on destination IP"); + return -EOPNOTSUPP; + } + +- flow_rule_match_ipv4_addrs(rule, &match); + tmp = &filter->key.ipv4.sip.value.addr[0]; + memcpy(tmp, &match.key->src, 4); + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index b7d5eaa70a67b..1591715c97177 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -1042,7 +1042,7 @@ static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int typ + { + /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ + if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) +- *cmd |= 0x7f0 << 18; ++ *cmd |= 0xf70 << 18; + } + + DECLARE_RTL_COND(rtl_eriar_cond) +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index d5d236d687e9e..6d84266c03caf 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -560,6 +560,8 @@ static struct sh_eth_cpu_data r7s72100_data = { + EESR_TDE, + .fdr_value = 0x0000070f, + ++ .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5, ++ + .no_psr = 1, + .apr = 1, + .mpr = 1, +@@ -780,6 +782,8 @@ static struct sh_eth_cpu_data r7s9210_data = { + + .fdr_value = 0x0000070f, + ++ .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5, ++ + .apr = 1, + .mpr = 1, + .tpauser = 1, +@@ -1089,6 +1093,9 @@ static struct sh_eth_cpu_data sh771x_data = { + EESIPR_CEEFIP | EESIPR_CELFIP | + EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP | + EESIPR_PREIP | EESIPR_CERFIP, ++ ++ .trscer_err_mask = DESC_I_RINT8, ++ + .tsu = 1, + .dual_port = 1, + }; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +index 103d2448e9e0d..a9087dae767de 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +@@ -233,6 +233,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat) + static int intel_mgbe_common_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) + { ++ char clk_name[20]; + int ret; + int i; + +@@ -300,8 +301,10 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, + plat->eee_usecs_rate = plat->clk_ptp_rate; + + /* Set system clock */ ++ sprintf(clk_name, "%s-%s", "stmmac", pci_name(pdev)); ++ + plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev, +- "stmmac-clk", NULL, 0, ++ clk_name, NULL, 0, + plat->clk_ptp_rate); + + if (IS_ERR(plat->stmmac_clk)) { +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index c6540b003b430..2ecd3a8a690c2 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -499,10 +499,15 @@ static void dwmac4_get_rx_header_len(struct dma_desc *p, unsigned int *len) + *len = le32_to_cpu(p->des2) & RDES2_HL; + } + +-static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr) ++static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool buf2_valid) + { + p->des2 = cpu_to_le32(lower_32_bits(addr)); +- p->des3 = cpu_to_le32(upper_32_bits(addr) | RDES3_BUFFER2_VALID_ADDR); ++ p->des3 = cpu_to_le32(upper_32_bits(addr)); ++ ++ if (buf2_valid) ++ p->des3 |= cpu_to_le32(RDES3_BUFFER2_VALID_ADDR); ++ else ++ p->des3 &= cpu_to_le32(~RDES3_BUFFER2_VALID_ADDR); + } + + static void dwmac4_set_tbs(struct dma_edesc *p, u32 sec, u32 nsec) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +index bb29bfcd62c34..62aa0e95beb70 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +@@ -124,6 +124,23 @@ static void dwmac4_dma_init_channel(void __iomem *ioaddr, + ioaddr + DMA_CHAN_INTR_ENA(chan)); + } + ++static void dwmac410_dma_init_channel(void __iomem *ioaddr, ++ struct stmmac_dma_cfg *dma_cfg, u32 chan) ++{ ++ u32 value; ++ ++ /* common channel control register config */ ++ value = readl(ioaddr + DMA_CHAN_CONTROL(chan)); ++ if (dma_cfg->pblx8) ++ value = value | DMA_BUS_MODE_PBL; ++ ++ writel(value, ioaddr + DMA_CHAN_CONTROL(chan)); ++ ++ /* Mask interrupts by writing to CSR7 */ ++ writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10, ++ ioaddr + DMA_CHAN_INTR_ENA(chan)); ++} ++ + static void dwmac4_dma_init(void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, int atds) + { +@@ -523,7 +540,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = { + const struct stmmac_dma_ops dwmac410_dma_ops = { + .reset = dwmac4_dma_reset, + .init = dwmac4_dma_init, +- .init_chan = dwmac4_dma_init_channel, ++ .init_chan = dwmac410_dma_init_channel, + .init_rx_chan = dwmac4_dma_init_rx_chan, + .init_tx_chan = dwmac4_dma_init_tx_chan, + .axi = dwmac4_dma_axi, +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +index 0b4ee2dbb691d..71e50751ef2dc 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +@@ -53,10 +53,6 @@ void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan) + + value &= ~DMA_CONTROL_ST; + writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan)); +- +- value = readl(ioaddr + GMAC_CONFIG); +- value &= ~GMAC_CONFIG_TE; +- writel(value, ioaddr + GMAC_CONFIG); + } + + void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +index 0aaf19ab56729..ccfb0102dde49 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +@@ -292,7 +292,7 @@ static void dwxgmac2_get_rx_header_len(struct dma_desc *p, unsigned int *len) + *len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL; + } + +-static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr) ++static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool is_valid) + { + p->des2 = cpu_to_le32(lower_32_bits(addr)); + p->des3 = cpu_to_le32(upper_32_bits(addr)); +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h +index e2dca9b6e9926..afe7ec496545a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -91,7 +91,7 @@ struct stmmac_desc_ops { + int (*get_rx_hash)(struct dma_desc *p, u32 *hash, + enum pkt_hash_types *type); + void (*get_rx_header_len)(struct dma_desc *p, unsigned int *len); +- void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr); ++ void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr, bool buf2_valid); + void (*set_sarc)(struct dma_desc *p, u32 sarc_type); + void (*set_vlan_tag)(struct dma_desc *p, u16 tag, u16 inner_tag, + u32 inner_type); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index b3d6d8e3f4de9..7d01c5cf60c96 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1279,9 +1279,10 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, + return -ENOMEM; + + buf->sec_addr = page_pool_get_dma_addr(buf->sec_page); +- stmmac_set_desc_sec_addr(priv, p, buf->sec_addr); ++ stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true); + } else { + buf->sec_page = NULL; ++ stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false); + } + + buf->addr = page_pool_get_dma_addr(buf->page); +@@ -3618,7 +3619,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) + DMA_FROM_DEVICE); + + stmmac_set_desc_addr(priv, p, buf->addr); +- stmmac_set_desc_sec_addr(priv, p, buf->sec_addr); ++ if (priv->sph) ++ stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true); ++ else ++ stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false); + stmmac_refill_desc3(priv, rx_q, p); + + rx_q->rx_count_frames++; +@@ -5114,13 +5118,16 @@ int stmmac_dvr_remove(struct device *dev) + netdev_info(priv->dev, "%s: removing driver", __func__); + + stmmac_stop_all_dma(priv); ++ stmmac_mac_set(priv, priv->ioaddr, false); ++ netif_carrier_off(ndev); ++ unregister_netdev(ndev); + ++ /* Serdes power down needs to happen after VLAN filter ++ * is deleted that is triggered by unregister_netdev(). ++ */ + if (priv->plat->serdes_powerdown) + priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv); + +- stmmac_mac_set(priv, priv->ioaddr, false); +- netif_carrier_off(ndev); +- unregister_netdev(ndev); + #ifdef CONFIG_DEBUG_FS + stmmac_exit_fs(ndev); + #endif +@@ -5227,6 +5234,8 @@ static void stmmac_reset_queues_param(struct stmmac_priv *priv) + tx_q->cur_tx = 0; + tx_q->dirty_tx = 0; + tx_q->mss = 0; ++ ++ netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); + } + } + +diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c +index 7178468302c8f..ad6dbf0110526 100644 +--- a/drivers/net/netdevsim/netdev.c ++++ b/drivers/net/netdevsim/netdev.c +@@ -296,6 +296,7 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port) + dev_net_set(dev, nsim_dev_net(nsim_dev)); + ns = netdev_priv(dev); + ns->netdev = dev; ++ u64_stats_init(&ns->syncp); + ns->nsim_dev = nsim_dev; + ns->nsim_dev_port = nsim_dev_port; + ns->nsim_bus_dev = nsim_dev->nsim_bus_dev; +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 35525a671400d..49e96ca585fff 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -293,14 +293,16 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev, + + phydev->autoneg = autoneg; + +- phydev->speed = speed; ++ if (autoneg == AUTONEG_DISABLE) { ++ phydev->speed = speed; ++ phydev->duplex = duplex; ++ } + + linkmode_copy(phydev->advertising, advertising); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, + phydev->advertising, autoneg == AUTONEG_ENABLE); + +- phydev->duplex = duplex; + phydev->master_slave_set = cmd->base.master_slave_cfg; + phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl; + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index dd1f711140c3d..2d4eed2d61ce9 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -230,7 +230,6 @@ static struct phy_driver genphy_driver; + static LIST_HEAD(phy_fixup_list); + static DEFINE_MUTEX(phy_fixup_lock); + +-#ifdef CONFIG_PM + static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) + { + struct device_driver *drv = phydev->mdio.dev.driver; +@@ -270,7 +269,7 @@ out: + return !phydev->suspended; + } + +-static int mdio_bus_phy_suspend(struct device *dev) ++static __maybe_unused int mdio_bus_phy_suspend(struct device *dev) + { + struct phy_device *phydev = to_phy_device(dev); + +@@ -290,7 +289,7 @@ static int mdio_bus_phy_suspend(struct device *dev) + return phy_suspend(phydev); + } + +-static int mdio_bus_phy_resume(struct device *dev) ++static __maybe_unused int mdio_bus_phy_resume(struct device *dev) + { + struct phy_device *phydev = to_phy_device(dev); + int ret; +@@ -316,7 +315,6 @@ no_resume: + + static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend, + mdio_bus_phy_resume); +-#endif /* CONFIG_PM */ + + /** + * phy_register_fixup - creates a new phy_fixup and adds it to the list +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index c7320861943b4..6e033ba717030 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -419,13 +419,6 @@ static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, c + goto err; + } + +- /* we don't want to modify a running netdev */ +- if (netif_running(dev->net)) { +- netdev_err(dev->net, "Cannot change a running device\n"); +- ret = -EBUSY; +- goto err; +- } +- + ret = qmimux_register_device(dev->net, mux_id); + if (!ret) { + info->flags |= QMI_WWAN_FLAG_MUX; +@@ -455,13 +448,6 @@ static ssize_t del_mux_store(struct device *d, struct device_attribute *attr, c + if (!rtnl_trylock()) + return restart_syscall(); + +- /* we don't want to modify a running netdev */ +- if (netif_running(dev->net)) { +- netdev_err(dev->net, "Cannot change a running device\n"); +- ret = -EBUSY; +- goto err; +- } +- + del_dev = qmimux_find_dev(dev, mux_id); + if (!del_dev) { + netdev_err(dev->net, "mux_id not present\n"); +diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c +index b6be2454b8bdd..605c01fb73f15 100644 +--- a/drivers/net/wan/lapbether.c ++++ b/drivers/net/wan/lapbether.c +@@ -283,7 +283,6 @@ static int lapbeth_open(struct net_device *dev) + return -ENODEV; + } + +- netif_start_queue(dev); + return 0; + } + +@@ -291,8 +290,6 @@ static int lapbeth_close(struct net_device *dev) + { + int err; + +- netif_stop_queue(dev); +- + if ((err = lapb_unregister(dev)) != LAPB_OK) + pr_err("lapb_unregister error: %d\n", err); + +diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c +index ebd6886a8c184..a68fe3a45a744 100644 +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -774,6 +774,7 @@ static void ath11k_core_restart(struct work_struct *work) + complete(&ar->scan.started); + complete(&ar->scan.completed); + complete(&ar->peer_assoc_done); ++ complete(&ar->peer_delete_done); + complete(&ar->install_key_done); + complete(&ar->vdev_setup_done); + complete(&ar->bss_survey_done); +diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h +index 5a7915f75e1e2..c8e36251068c9 100644 +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -502,6 +502,7 @@ struct ath11k { + u8 lmac_id; + + struct completion peer_assoc_done; ++ struct completion peer_delete_done; + + int install_key_status; + struct completion install_key_done; +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index b5bd9b06da89e..ee0edd9185604 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2986,6 +2986,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, + } + + if (ab->hw_params.vdev_start_delay && ++ !arvif->is_started && + arvif->vdev_type != WMI_VDEV_TYPE_AP) { + ret = ath11k_start_vdev_delay(ar->hw, vif); + if (ret) { +@@ -4589,8 +4590,22 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, + + err_peer_del: + if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ++ reinit_completion(&ar->peer_delete_done); ++ ++ ret = ath11k_wmi_send_peer_delete_cmd(ar, vif->addr, ++ arvif->vdev_id); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", ++ arvif->vdev_id, vif->addr); ++ return ret; ++ } ++ ++ ret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id, ++ vif->addr); ++ if (ret) ++ return ret; ++ + ar->num_peers--; +- ath11k_wmi_send_peer_delete_cmd(ar, vif->addr, arvif->vdev_id); + } + + err_vdev_del: +@@ -5234,7 +5249,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + /* for QCA6390 bss peer must be created before vdev_start */ + if (ab->hw_params.vdev_start_delay && + arvif->vdev_type != WMI_VDEV_TYPE_AP && +- arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { ++ arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && ++ !ath11k_peer_find_by_vdev_id(ab, arvif->vdev_id)) { + memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); + ret = 0; + goto out; +@@ -5245,7 +5261,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + goto out; + } + +- if (ab->hw_params.vdev_start_delay) { ++ if (ab->hw_params.vdev_start_delay && ++ arvif->vdev_type != WMI_VDEV_TYPE_AP && ++ arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { + param.vdev_id = arvif->vdev_id; + param.peer_type = WMI_PEER_TYPE_DEFAULT; + param.peer_addr = ar->mac_addr; +@@ -6413,6 +6431,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab) + mutex_init(&ar->conf_mutex); + init_completion(&ar->vdev_setup_done); + init_completion(&ar->peer_assoc_done); ++ init_completion(&ar->peer_delete_done); + init_completion(&ar->install_key_done); + init_completion(&ar->bss_survey_done); + init_completion(&ar->scan.started); +diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c +index 61ad9300eafb1..b69e7ebfa9303 100644 +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -76,6 +76,23 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, + return NULL; + } + ++struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, ++ int vdev_id) ++{ ++ struct ath11k_peer *peer; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) { ++ if (vdev_id == peer->vdev_id) { ++ spin_unlock_bh(&ab->base_lock); ++ return peer; ++ } ++ } ++ spin_unlock_bh(&ab->base_lock); ++ return NULL; ++} ++ + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) + { + struct ath11k_peer *peer; +@@ -177,12 +194,36 @@ static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 + return ath11k_wait_for_peer_common(ar->ab, vdev_id, addr, false); + } + ++int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, ++ const u8 *addr) ++{ ++ int ret; ++ unsigned long time_left; ++ ++ ret = ath11k_wait_for_peer_deleted(ar, vdev_id, addr); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed wait for peer deleted"); ++ return ret; ++ } ++ ++ time_left = wait_for_completion_timeout(&ar->peer_delete_done, ++ 3 * HZ); ++ if (time_left == 0) { ++ ath11k_warn(ar->ab, "Timeout in receiving peer delete response\n"); ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) + { + int ret; + + lockdep_assert_held(&ar->conf_mutex); + ++ reinit_completion(&ar->peer_delete_done); ++ + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); + if (ret) { + ath11k_warn(ar->ab, +@@ -191,7 +232,7 @@ int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) + return ret; + } + +- ret = ath11k_wait_for_peer_deleted(ar, vdev_id, addr); ++ ret = ath11k_wait_for_peer_delete_done(ar, vdev_id, addr); + if (ret) + return ret; + +@@ -247,8 +288,22 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, + spin_unlock_bh(&ar->ab->base_lock); + ath11k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", + param->peer_addr, param->vdev_id); +- ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, +- param->vdev_id); ++ ++ reinit_completion(&ar->peer_delete_done); ++ ++ ret = ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, ++ param->vdev_id); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", ++ param->vdev_id, param->peer_addr); ++ return ret; ++ } ++ ++ ret = ath11k_wait_for_peer_delete_done(ar, param->vdev_id, ++ param->peer_addr); ++ if (ret) ++ return ret; ++ + return -ENOENT; + } + +diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h +index 5d125ce8984e3..8553ed061aeaa 100644 +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -41,5 +41,9 @@ void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); + int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, + struct ieee80211_sta *sta, struct peer_create_params *param); ++int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, ++ const u8 *addr); ++struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, ++ int vdev_id); + + #endif /* _PEER_H_ */ +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 04b8b002edfe0..173ab6ceed1f6 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -5532,15 +5532,26 @@ static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb) + static void ath11k_peer_delete_resp_event(struct ath11k_base *ab, struct sk_buff *skb) + { + struct wmi_peer_delete_resp_event peer_del_resp; ++ struct ath11k *ar; + + if (ath11k_pull_peer_del_resp_ev(ab, skb, &peer_del_resp) != 0) { + ath11k_warn(ab, "failed to extract peer delete resp"); + return; + } + +- /* TODO: Do we need to validate whether ath11k_peer_find() return NULL +- * Why this is needed when there is HTT event for peer delete +- */ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_del_resp.vdev_id); ++ if (!ar) { ++ ath11k_warn(ab, "invalid vdev id in peer delete resp ev %d", ++ peer_del_resp.vdev_id); ++ rcu_read_unlock(); ++ return; ++ } ++ ++ complete(&ar->peer_delete_done); ++ rcu_read_unlock(); ++ ath11k_dbg(ab, ATH11K_DBG_WMI, "peer delete resp for vdev id %d addr %pM\n", ++ peer_del_resp.vdev_id, peer_del_resp.peer_macaddr.addr); + } + + static inline const char *ath11k_wmi_vdev_resp_print(u32 vdev_resp_status) +diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h +index e06b74a54a697..01d85f2509362 100644 +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -177,7 +177,8 @@ struct ath_frame_info { + s8 txq; + u8 keyix; + u8 rtscts_rate; +- u8 retries : 7; ++ u8 retries : 6; ++ u8 dyn_smps : 1; + u8 baw_tracked : 1; + u8 tx_power; + enum ath9k_key_type keytype:2; +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index e60d4737fc6e4..5691bd6eb82c2 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1271,6 +1271,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, + is_40, is_sgi, is_sp); + if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) + info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; ++ if (rix >= 8 && fi->dyn_smps) { ++ info->rates[i].RateFlags |= ++ ATH9K_RATESERIES_RTS_CTS; ++ info->flags |= ATH9K_TXDESC_CTSENA; ++ } + + info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, + is_40, false); +@@ -2114,6 +2119,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, + fi->keyix = an->ps_key; + else + fi->keyix = ATH9K_TXKEYIX_INVALID; ++ fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC; + fi->keytype = keytype; + fi->framelen = framelen; + fi->tx_power = txpower; +diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c +index 917617aad8d3c..262c40dc14a63 100644 +--- a/drivers/net/wireless/mediatek/mt76/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/dma.c +@@ -521,13 +521,13 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, + { + struct sk_buff *skb = q->rx_head; + struct skb_shared_info *shinfo = skb_shinfo(skb); ++ int nr_frags = shinfo->nr_frags; + +- if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { ++ if (nr_frags < ARRAY_SIZE(shinfo->frags)) { + struct page *page = virt_to_head_page(data); + int offset = data - page_address(page) + q->buf_offset; + +- skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, +- q->buf_size); ++ skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size); + } else { + skb_free_frag(data); + } +@@ -536,7 +536,10 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, + return; + + q->rx_head = NULL; +- dev->drv->rx_skb(dev, q - dev->q_rx, skb); ++ if (nr_frags < ARRAY_SIZE(shinfo->frags)) ++ dev->drv->rx_skb(dev, q - dev->q_rx, skb); ++ else ++ dev_kfree_skb(skb); + } + + static int +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index 5ead217ac2bc8..fab068c8ba026 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2055,7 +2055,7 @@ done: + nvme_fc_complete_rq(rq); + + check_error: +- if (terminate_assoc) ++ if (terminate_assoc && ctrl->ctrl.state != NVME_CTRL_RESETTING) + queue_work(nvme_reset_wq, &ctrl->ioerr_work); + } + +diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c +index 2470782cb01af..1c34c897a7e2a 100644 +--- a/drivers/pci/controller/pci-xgene-msi.c ++++ b/drivers/pci/controller/pci-xgene-msi.c +@@ -384,13 +384,9 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu) + if (!msi_group->gic_irq) + continue; + +- irq_set_chained_handler(msi_group->gic_irq, +- xgene_msi_isr); +- err = irq_set_handler_data(msi_group->gic_irq, msi_group); +- if (err) { +- pr_err("failed to register GIC IRQ handler\n"); +- return -EINVAL; +- } ++ irq_set_chained_handler_and_data(msi_group->gic_irq, ++ xgene_msi_isr, msi_group); ++ + /* + * Statically allocate MSI GIC IRQs to each CPU core. + * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated +diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c +index cf4c18f0c25ab..23548b517e4b6 100644 +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -1035,14 +1035,14 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) + err = of_pci_get_devfn(child); + if (err < 0) { + dev_err(dev, "failed to parse devfn: %d\n", err); +- return err; ++ goto error_put_node; + } + + slot = PCI_SLOT(err); + + err = mtk_pcie_parse_port(pcie, child, slot); + if (err) +- return err; ++ goto error_put_node; + } + + err = mtk_pcie_subsys_powerup(pcie); +@@ -1058,6 +1058,9 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) + mtk_pcie_subsys_powerdown(pcie); + + return 0; ++error_put_node: ++ of_node_put(child); ++ return err; + } + + static int mtk_pcie_probe(struct platform_device *pdev) +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 5c93450725108..9e971fffeb6a3 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -4010,6 +4010,10 @@ int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr, + ret = logic_pio_register_range(range); + if (ret) + kfree(range); ++ ++ /* Ignore duplicates due to deferred probing */ ++ if (ret == -EEXIST) ++ ret = 0; + #endif + + return ret; +diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig +index 3946555a60422..45a2ef702b45b 100644 +--- a/drivers/pci/pcie/Kconfig ++++ b/drivers/pci/pcie/Kconfig +@@ -133,14 +133,6 @@ config PCIE_PTM + This is only useful if you have devices that support PTM, but it + is safe to enable even if you don't. + +-config PCIE_BW +- bool "PCI Express Bandwidth Change Notification" +- depends on PCIEPORTBUS +- help +- This enables PCI Express Bandwidth Change Notification. If +- you know link width or rate changes occur only to correct +- unreliable links, you may answer Y. +- + config PCIE_EDR + bool "PCI Express Error Disconnect Recover support" + depends on PCIE_DPC && ACPI +diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile +index 68da9280ff117..9a7085668466f 100644 +--- a/drivers/pci/pcie/Makefile ++++ b/drivers/pci/pcie/Makefile +@@ -12,5 +12,4 @@ obj-$(CONFIG_PCIEAER_INJECT) += aer_inject.o + obj-$(CONFIG_PCIE_PME) += pme.o + obj-$(CONFIG_PCIE_DPC) += dpc.o + obj-$(CONFIG_PCIE_PTM) += ptm.o +-obj-$(CONFIG_PCIE_BW) += bw_notification.o + obj-$(CONFIG_PCIE_EDR) += edr.o +diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c +deleted file mode 100644 +index 565d23cccb8b5..0000000000000 +--- a/drivers/pci/pcie/bw_notification.c ++++ /dev/null +@@ -1,138 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * PCI Express Link Bandwidth Notification services driver +- * Author: Alexandru Gagniuc +- * +- * Copyright (C) 2019, Dell Inc +- * +- * The PCIe Link Bandwidth Notification provides a way to notify the +- * operating system when the link width or data rate changes. This +- * capability is required for all root ports and downstream ports +- * supporting links wider than x1 and/or multiple link speeds. +- * +- * This service port driver hooks into the bandwidth notification interrupt +- * and warns when links become degraded in operation. +- */ +- +-#define dev_fmt(fmt) "bw_notification: " fmt +- +-#include "../pci.h" +-#include "portdrv.h" +- +-static bool pcie_link_bandwidth_notification_supported(struct pci_dev *dev) +-{ +- int ret; +- u32 lnk_cap; +- +- ret = pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnk_cap); +- return (ret == PCIBIOS_SUCCESSFUL) && (lnk_cap & PCI_EXP_LNKCAP_LBNC); +-} +- +-static void pcie_enable_link_bandwidth_notification(struct pci_dev *dev) +-{ +- u16 lnk_ctl; +- +- pcie_capability_write_word(dev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS); +- +- pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl); +- lnk_ctl |= PCI_EXP_LNKCTL_LBMIE; +- pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl); +-} +- +-static void pcie_disable_link_bandwidth_notification(struct pci_dev *dev) +-{ +- u16 lnk_ctl; +- +- pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl); +- lnk_ctl &= ~PCI_EXP_LNKCTL_LBMIE; +- pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl); +-} +- +-static irqreturn_t pcie_bw_notification_irq(int irq, void *context) +-{ +- struct pcie_device *srv = context; +- struct pci_dev *port = srv->port; +- u16 link_status, events; +- int ret; +- +- ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); +- events = link_status & PCI_EXP_LNKSTA_LBMS; +- +- if (ret != PCIBIOS_SUCCESSFUL || !events) +- return IRQ_NONE; +- +- pcie_capability_write_word(port, PCI_EXP_LNKSTA, events); +- pcie_update_link_speed(port->subordinate, link_status); +- return IRQ_WAKE_THREAD; +-} +- +-static irqreturn_t pcie_bw_notification_handler(int irq, void *context) +-{ +- struct pcie_device *srv = context; +- struct pci_dev *port = srv->port; +- struct pci_dev *dev; +- +- /* +- * Print status from downstream devices, not this root port or +- * downstream switch port. +- */ +- down_read(&pci_bus_sem); +- list_for_each_entry(dev, &port->subordinate->devices, bus_list) +- pcie_report_downtraining(dev); +- up_read(&pci_bus_sem); +- +- return IRQ_HANDLED; +-} +- +-static int pcie_bandwidth_notification_probe(struct pcie_device *srv) +-{ +- int ret; +- +- /* Single-width or single-speed ports do not have to support this. */ +- if (!pcie_link_bandwidth_notification_supported(srv->port)) +- return -ENODEV; +- +- ret = request_threaded_irq(srv->irq, pcie_bw_notification_irq, +- pcie_bw_notification_handler, +- IRQF_SHARED, "PCIe BW notif", srv); +- if (ret) +- return ret; +- +- pcie_enable_link_bandwidth_notification(srv->port); +- pci_info(srv->port, "enabled with IRQ %d\n", srv->irq); +- +- return 0; +-} +- +-static void pcie_bandwidth_notification_remove(struct pcie_device *srv) +-{ +- pcie_disable_link_bandwidth_notification(srv->port); +- free_irq(srv->irq, srv); +-} +- +-static int pcie_bandwidth_notification_suspend(struct pcie_device *srv) +-{ +- pcie_disable_link_bandwidth_notification(srv->port); +- return 0; +-} +- +-static int pcie_bandwidth_notification_resume(struct pcie_device *srv) +-{ +- pcie_enable_link_bandwidth_notification(srv->port); +- return 0; +-} +- +-static struct pcie_port_service_driver pcie_bandwidth_notification_driver = { +- .name = "pcie_bw_notification", +- .port_type = PCIE_ANY_PORT, +- .service = PCIE_PORT_SERVICE_BWNOTIF, +- .probe = pcie_bandwidth_notification_probe, +- .suspend = pcie_bandwidth_notification_suspend, +- .resume = pcie_bandwidth_notification_resume, +- .remove = pcie_bandwidth_notification_remove, +-}; +- +-int __init pcie_bandwidth_notification_init(void) +-{ +- return pcie_port_service_register(&pcie_bandwidth_notification_driver); +-} +diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h +index af7cf237432ac..2ff5724b8f13f 100644 +--- a/drivers/pci/pcie/portdrv.h ++++ b/drivers/pci/pcie/portdrv.h +@@ -53,12 +53,6 @@ int pcie_dpc_init(void); + static inline int pcie_dpc_init(void) { return 0; } + #endif + +-#ifdef CONFIG_PCIE_BW +-int pcie_bandwidth_notification_init(void); +-#else +-static inline int pcie_bandwidth_notification_init(void) { return 0; } +-#endif +- + /* Port Type */ + #define PCIE_ANY_PORT (~0) + +diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c +index 3a3ce40ae1abd..d4559cf88f79d 100644 +--- a/drivers/pci/pcie/portdrv_pci.c ++++ b/drivers/pci/pcie/portdrv_pci.c +@@ -248,7 +248,6 @@ static void __init pcie_init_services(void) + pcie_pme_init(); + pcie_dpc_init(); + pcie_hp_init(); +- pcie_bandwidth_notification_init(); + } + + static int __init pcie_portdrv_init(void) +diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c +index f64b82824db28..2db7113383fdc 100644 +--- a/drivers/platform/olpc/olpc-ec.c ++++ b/drivers/platform/olpc/olpc-ec.c +@@ -426,11 +426,8 @@ static int olpc_ec_probe(struct platform_device *pdev) + + /* get the EC revision */ + err = olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, &ec->version, 1); +- if (err) { +- ec_priv = NULL; +- kfree(ec); +- return err; +- } ++ if (err) ++ goto error; + + config.dev = pdev->dev.parent; + config.driver_data = ec; +@@ -440,12 +437,16 @@ static int olpc_ec_probe(struct platform_device *pdev) + if (IS_ERR(ec->dcon_rdev)) { + dev_err(&pdev->dev, "failed to register DCON regulator\n"); + err = PTR_ERR(ec->dcon_rdev); +- kfree(ec); +- return err; ++ goto error; + } + + ec->dbgfs_dir = olpc_ec_setup_debugfs(); + ++ return 0; ++ ++error: ++ ec_priv = NULL; ++ kfree(ec); + return err; + } + +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index 217a7b84abdfa..2adfab552e22a 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -3087,7 +3087,8 @@ static blk_status_t do_dasd_request(struct blk_mq_hw_ctx *hctx, + + basedev = block->base; + spin_lock_irq(&dq->lock); +- if (basedev->state < DASD_STATE_READY) { ++ if (basedev->state < DASD_STATE_READY || ++ test_bit(DASD_FLAG_OFFLINE, &basedev->flags)) { + DBF_DEV_EVENT(DBF_ERR, basedev, + "device not ready for request %p", req); + rc = BLK_STS_IOERR; +@@ -3522,8 +3523,6 @@ void dasd_generic_remove(struct ccw_device *cdev) + struct dasd_device *device; + struct dasd_block *block; + +- cdev->handler = NULL; +- + device = dasd_device_from_cdev(cdev); + if (IS_ERR(device)) { + dasd_remove_sysfs_files(cdev); +@@ -3542,6 +3541,7 @@ void dasd_generic_remove(struct ccw_device *cdev) + * no quite down yet. + */ + dasd_set_target_state(device, DASD_STATE_NEW); ++ cdev->handler = NULL; + /* dasd_delete_device destroys the device reference. */ + block = device->block; + dasd_delete_device(device); +diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c +index 8b3ed5b45277a..1ad5f7018ec2d 100644 +--- a/drivers/s390/cio/vfio_ccw_ops.c ++++ b/drivers/s390/cio/vfio_ccw_ops.c +@@ -539,7 +539,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, + if (ret) + return ret; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; + } + case VFIO_DEVICE_GET_REGION_INFO: + { +@@ -557,7 +557,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, + if (ret) + return ret; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; + } + case VFIO_DEVICE_GET_IRQ_INFO: + { +@@ -578,7 +578,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, + if (info.count == -1) + return -EINVAL; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; + } + case VFIO_DEVICE_SET_IRQS: + { +diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c +index 7ceb6c433b3ba..72eb8f984534f 100644 +--- a/drivers/s390/crypto/vfio_ap_ops.c ++++ b/drivers/s390/crypto/vfio_ap_ops.c +@@ -1279,7 +1279,7 @@ static int vfio_ap_mdev_get_device_info(unsigned long arg) + info.num_regions = 0; + info.num_irqs = 0; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; + } + + static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev, +diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h +index 2f7e06ec9a30e..bf8404b0e74ff 100644 +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -424,8 +424,6 @@ enum qeth_qdio_out_buffer_state { + /* Received QAOB notification on CQ: */ + QETH_QDIO_BUF_QAOB_OK, + QETH_QDIO_BUF_QAOB_ERROR, +- /* Handled via transfer pending / completion queue. */ +- QETH_QDIO_BUF_HANDLED_DELAYED, + }; + + struct qeth_qdio_out_buffer { +@@ -438,7 +436,7 @@ struct qeth_qdio_out_buffer { + int is_header[QDIO_MAX_ELEMENTS_PER_BUFFER]; + + struct qeth_qdio_out_q *q; +- struct qeth_qdio_out_buffer *next_pending; ++ struct list_head list_entry; + }; + + struct qeth_card; +@@ -502,6 +500,7 @@ struct qeth_qdio_out_q { + struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; + struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q]; + struct qdio_outbuf_state *bufstates; /* convenience pointer */ ++ struct list_head pending_bufs; + struct qeth_out_q_stats stats; + spinlock_t lock; + unsigned int priority; +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index f108232498baf..03f96177e58ee 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -73,9 +73,6 @@ static void qeth_free_qdio_queues(struct qeth_card *card); + static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf, + enum iucv_tx_notify notification); +-static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, +- int budget); +-static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); + + static void qeth_close_dev_handler(struct work_struct *work) + { +@@ -466,42 +463,6 @@ static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15, + return n; + } + +-static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx, +- int forced_cleanup) +-{ +- if (q->card->options.cq != QETH_CQ_ENABLED) +- return; +- +- if (q->bufs[bidx]->next_pending != NULL) { +- struct qeth_qdio_out_buffer *head = q->bufs[bidx]; +- struct qeth_qdio_out_buffer *c = q->bufs[bidx]->next_pending; +- +- while (c) { +- if (forced_cleanup || +- atomic_read(&c->state) == +- QETH_QDIO_BUF_HANDLED_DELAYED) { +- struct qeth_qdio_out_buffer *f = c; +- +- QETH_CARD_TEXT(f->q->card, 5, "fp"); +- QETH_CARD_TEXT_(f->q->card, 5, "%lx", (long) f); +- /* release here to avoid interleaving between +- outbound tasklet and inbound tasklet +- regarding notifications and lifecycle */ +- qeth_tx_complete_buf(c, forced_cleanup, 0); +- +- c = f->next_pending; +- WARN_ON_ONCE(head->next_pending != f); +- head->next_pending = c; +- kmem_cache_free(qeth_qdio_outbuf_cache, f); +- } else { +- head = c; +- c = c->next_pending; +- } +- +- } +- } +-} +- + static void qeth_qdio_handle_aob(struct qeth_card *card, + unsigned long phys_aob_addr) + { +@@ -517,18 +478,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, + buffer = (struct qeth_qdio_out_buffer *) aob->user1; + QETH_CARD_TEXT_(card, 5, "%lx", aob->user1); + +- /* Free dangling allocations. The attached skbs are handled by +- * qeth_cleanup_handled_pending(). +- */ +- for (i = 0; +- i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); +- i++) { +- void *data = phys_to_virt(aob->sba[i]); +- +- if (data && buffer->is_header[i]) +- kmem_cache_free(qeth_core_header_cache, data); +- } +- + if (aob->aorc) { + QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); + new_state = QETH_QDIO_BUF_QAOB_ERROR; +@@ -536,10 +485,9 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, + + switch (atomic_xchg(&buffer->state, new_state)) { + case QETH_QDIO_BUF_PRIMED: +- /* Faster than TX completion code. */ +- notification = qeth_compute_cq_notification(aob->aorc, 0); +- qeth_notify_skbs(buffer->q, buffer, notification); +- atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); ++ /* Faster than TX completion code, let it handle the async ++ * completion for us. ++ */ + break; + case QETH_QDIO_BUF_PENDING: + /* TX completion code is active and will handle the async +@@ -550,7 +498,20 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, + /* TX completion code is already finished. */ + notification = qeth_compute_cq_notification(aob->aorc, 1); + qeth_notify_skbs(buffer->q, buffer, notification); +- atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); ++ ++ /* Free dangling allocations. The attached skbs are handled by ++ * qeth_tx_complete_pending_bufs(). ++ */ ++ for (i = 0; ++ i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); ++ i++) { ++ void *data = phys_to_virt(aob->sba[i]); ++ ++ if (data && buffer->is_header[i]) ++ kmem_cache_free(qeth_core_header_cache, data); ++ } ++ ++ atomic_set(&buffer->state, QETH_QDIO_BUF_EMPTY); + break; + default: + WARN_ON_ONCE(1); +@@ -1422,9 +1383,6 @@ static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, + struct qeth_qdio_out_q *queue = buf->q; + struct sk_buff *skb; + +- if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING) +- qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR); +- + /* Empty buffer? */ + if (buf->next_element_to_fill == 0) + return; +@@ -1486,14 +1444,38 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); + } + ++static void qeth_tx_complete_pending_bufs(struct qeth_card *card, ++ struct qeth_qdio_out_q *queue, ++ bool drain) ++{ ++ struct qeth_qdio_out_buffer *buf, *tmp; ++ ++ list_for_each_entry_safe(buf, tmp, &queue->pending_bufs, list_entry) { ++ if (drain || atomic_read(&buf->state) == QETH_QDIO_BUF_EMPTY) { ++ QETH_CARD_TEXT(card, 5, "fp"); ++ QETH_CARD_TEXT_(card, 5, "%lx", (long) buf); ++ ++ if (drain) ++ qeth_notify_skbs(queue, buf, ++ TX_NOTIFY_GENERALERROR); ++ qeth_tx_complete_buf(buf, drain, 0); ++ ++ list_del(&buf->list_entry); ++ kmem_cache_free(qeth_qdio_outbuf_cache, buf); ++ } ++ } ++} ++ + static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free) + { + int j; + ++ qeth_tx_complete_pending_bufs(q->card, q, true); ++ + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { + if (!q->bufs[j]) + continue; +- qeth_cleanup_handled_pending(q, j, 1); ++ + qeth_clear_output_buffer(q, q->bufs[j], true, 0); + if (free) { + kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]); +@@ -2613,7 +2595,6 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) + skb_queue_head_init(&newbuf->skb_list); + lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key); + newbuf->q = q; +- newbuf->next_pending = q->bufs[bidx]; + atomic_set(&newbuf->state, QETH_QDIO_BUF_EMPTY); + q->bufs[bidx] = newbuf; + return 0; +@@ -2632,15 +2613,28 @@ static void qeth_free_output_queue(struct qeth_qdio_out_q *q) + static struct qeth_qdio_out_q *qeth_alloc_output_queue(void) + { + struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL); ++ unsigned int i; + + if (!q) + return NULL; + +- if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { +- kfree(q); +- return NULL; ++ if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) ++ goto err_qdio_bufs; ++ ++ for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) { ++ if (qeth_init_qdio_out_buf(q, i)) ++ goto err_out_bufs; + } ++ + return q; ++ ++err_out_bufs: ++ while (i > 0) ++ kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[--i]); ++ qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); ++err_qdio_bufs: ++ kfree(q); ++ return NULL; + } + + static void qeth_tx_completion_timer(struct timer_list *timer) +@@ -2653,7 +2647,7 @@ static void qeth_tx_completion_timer(struct timer_list *timer) + + static int qeth_alloc_qdio_queues(struct qeth_card *card) + { +- int i, j; ++ unsigned int i; + + QETH_CARD_TEXT(card, 2, "allcqdbf"); + +@@ -2682,18 +2676,12 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) + card->qdio.out_qs[i] = queue; + queue->card = card; + queue->queue_no = i; ++ INIT_LIST_HEAD(&queue->pending_bufs); + spin_lock_init(&queue->lock); + timer_setup(&queue->timer, qeth_tx_completion_timer, 0); + queue->coalesce_usecs = QETH_TX_COALESCE_USECS; + queue->max_coalesced_frames = QETH_TX_MAX_COALESCED_FRAMES; + queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT; +- +- /* give outbound qeth_qdio_buffers their qdio_buffers */ +- for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { +- WARN_ON(queue->bufs[j]); +- if (qeth_init_qdio_out_buf(queue, j)) +- goto out_freeoutqbufs; +- } + } + + /* completion */ +@@ -2702,13 +2690,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) + + return 0; + +-out_freeoutqbufs: +- while (j > 0) { +- --j; +- kmem_cache_free(qeth_qdio_outbuf_cache, +- card->qdio.out_qs[i]->bufs[j]); +- card->qdio.out_qs[i]->bufs[j] = NULL; +- } + out_freeoutq: + while (i > 0) { + qeth_free_output_queue(card->qdio.out_qs[--i]); +@@ -5871,9 +5852,13 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, + QDIO_OUTBUF_STATE_FLAG_PENDING)) { + WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED); + +- if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, +- QETH_QDIO_BUF_PENDING) == +- QETH_QDIO_BUF_PRIMED) { ++ QETH_CARD_TEXT_(card, 5, "pel%u", bidx); ++ ++ switch (atomic_cmpxchg(&buffer->state, ++ QETH_QDIO_BUF_PRIMED, ++ QETH_QDIO_BUF_PENDING)) { ++ case QETH_QDIO_BUF_PRIMED: ++ /* We have initial ownership, no QAOB (yet): */ + qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING); + + /* Handle race with qeth_qdio_handle_aob(): */ +@@ -5881,39 +5866,51 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, + QETH_QDIO_BUF_NEED_QAOB)) { + case QETH_QDIO_BUF_PENDING: + /* No concurrent QAOB notification. */ +- break; ++ ++ /* Prepare the queue slot for immediate re-use: */ ++ qeth_scrub_qdio_buffer(buffer->buffer, queue->max_elements); ++ if (qeth_init_qdio_out_buf(queue, bidx)) { ++ QETH_CARD_TEXT(card, 2, "outofbuf"); ++ qeth_schedule_recovery(card); ++ } ++ ++ list_add(&buffer->list_entry, ++ &queue->pending_bufs); ++ /* Skip clearing the buffer: */ ++ return; + case QETH_QDIO_BUF_QAOB_OK: + qeth_notify_skbs(queue, buffer, + TX_NOTIFY_DELAYED_OK); +- atomic_set(&buffer->state, +- QETH_QDIO_BUF_HANDLED_DELAYED); ++ error = false; + break; + case QETH_QDIO_BUF_QAOB_ERROR: + qeth_notify_skbs(queue, buffer, + TX_NOTIFY_DELAYED_GENERALERROR); +- atomic_set(&buffer->state, +- QETH_QDIO_BUF_HANDLED_DELAYED); ++ error = true; + break; + default: + WARN_ON_ONCE(1); + } +- } +- +- QETH_CARD_TEXT_(card, 5, "pel%u", bidx); + +- /* prepare the queue slot for re-use: */ +- qeth_scrub_qdio_buffer(buffer->buffer, queue->max_elements); +- if (qeth_init_qdio_out_buf(queue, bidx)) { +- QETH_CARD_TEXT(card, 2, "outofbuf"); +- qeth_schedule_recovery(card); ++ break; ++ case QETH_QDIO_BUF_QAOB_OK: ++ /* qeth_qdio_handle_aob() already received a QAOB: */ ++ qeth_notify_skbs(queue, buffer, TX_NOTIFY_OK); ++ error = false; ++ break; ++ case QETH_QDIO_BUF_QAOB_ERROR: ++ /* qeth_qdio_handle_aob() already received a QAOB: */ ++ qeth_notify_skbs(queue, buffer, TX_NOTIFY_GENERALERROR); ++ error = true; ++ break; ++ default: ++ WARN_ON_ONCE(1); + } +- +- return; +- } +- +- if (card->options.cq == QETH_CQ_ENABLED) ++ } else if (card->options.cq == QETH_CQ_ENABLED) { + qeth_notify_skbs(queue, buffer, + qeth_compute_cq_notification(sflags, 0)); ++ } ++ + qeth_clear_output_buffer(queue, buffer, error, budget); + } + +@@ -5934,6 +5931,8 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget) + unsigned int bytes = 0; + int completed; + ++ qeth_tx_complete_pending_bufs(card, queue, false); ++ + if (qeth_out_queue_is_empty(queue)) { + napi_complete(napi); + return 0; +@@ -5966,7 +5965,6 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget) + + qeth_handle_send_error(card, buffer, error); + qeth_iqd_tx_complete(queue, bidx, error, budget); +- qeth_cleanup_handled_pending(queue, bidx, false); + } + + netdev_tx_completed_queue(txq, packets, bytes); +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index 5125a6c7f70e9..41b8192d207d0 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1532,14 +1532,9 @@ check_mgmt: + } + rc = iscsi_prep_scsi_cmd_pdu(conn->task); + if (rc) { +- if (rc == -ENOMEM || rc == -EACCES) { +- spin_lock_bh(&conn->taskqueuelock); +- list_add_tail(&conn->task->running, +- &conn->cmdqueue); +- conn->task = NULL; +- spin_unlock_bh(&conn->taskqueuelock); +- goto done; +- } else ++ if (rc == -ENOMEM || rc == -EACCES) ++ fail_scsi_task(conn->task, DID_IMM_RETRY); ++ else + fail_scsi_task(conn->task, DID_ABORT); + spin_lock_bh(&conn->taskqueuelock); + continue; +diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c +index bdcd27faa0547..34b424ad96a20 100644 +--- a/drivers/scsi/ufs/ufs-sysfs.c ++++ b/drivers/scsi/ufs/ufs-sysfs.c +@@ -785,7 +785,8 @@ static ssize_t _pname##_show(struct device *dev, \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufs_hba *hba = shost_priv(sdev->host); \ + u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); \ +- if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun)) \ ++ if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun, \ ++ _duname##_DESC_PARAM##_puname)) \ + return -EINVAL; \ + return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname, \ + lun, _duname##_DESC_PARAM##_puname, buf, _size); \ +diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h +index f8ab16f30fdca..07ca39008b84b 100644 +--- a/drivers/scsi/ufs/ufs.h ++++ b/drivers/scsi/ufs/ufs.h +@@ -551,13 +551,15 @@ struct ufs_dev_info { + * @return: true if the lun has a matching unit descriptor, false otherwise + */ + static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info, +- u8 lun) ++ u8 lun, u8 param_offset) + { + if (!dev_info || !dev_info->max_lu_supported) { + pr_err("Max General LU supported by UFS isn't initialized\n"); + return false; + } +- ++ /* WB is available only for the logical unit from 0 to 7 */ ++ if (param_offset == UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS) ++ return lun < UFS_UPIU_MAX_WB_LUN_ID; + return lun == UFS_UPIU_RPMB_WLUN || (lun < dev_info->max_lu_supported); + } + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 5a7cc2e42ffdf..97d9d5d99adcc 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -3378,7 +3378,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba, + * Unit descriptors are only available for general purpose LUs (LUN id + * from 0 to 7) and RPMB Well known LU. + */ +- if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun)) ++ if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun, param_offset)) + return -EOPNOTSUPP; + + return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun, +diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c +index 6eeb39669a866..53c4311cc6ab5 100644 +--- a/drivers/spi/spi-stm32.c ++++ b/drivers/spi/spi-stm32.c +@@ -928,8 +928,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) + mask |= STM32H7_SPI_SR_RXP; + + if (!(sr & mask)) { +- dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", +- sr, ier); ++ dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", ++ sr, ier); + spin_unlock_irqrestore(&spi->lock, flags); + return IRQ_NONE; + } +@@ -956,15 +956,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) + } + + if (sr & STM32H7_SPI_SR_OVR) { +- dev_warn(spi->dev, "Overrun: received value discarded\n"); +- if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) +- stm32h7_spi_read_rxfifo(spi, false); +- /* +- * If overrun is detected while using DMA, it means that +- * something went wrong, so stop the current transfer +- */ +- if (spi->cur_usedma) +- end = true; ++ dev_err(spi->dev, "Overrun: RX data lost\n"); ++ end = true; + } + + if (sr & STM32H7_SPI_SR_EOT) { +diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c +index 35b75f0c9200b..81a246fbcc01f 100644 +--- a/drivers/staging/comedi/drivers/addi_apci_1032.c ++++ b/drivers/staging/comedi/drivers/addi_apci_1032.c +@@ -260,6 +260,7 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) + struct apci1032_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + unsigned int ctrl; ++ unsigned short val; + + /* check interrupt is from this device */ + if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & +@@ -275,7 +276,8 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) + outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); + + s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; +- comedi_buf_write_samples(s, &s->state, 1); ++ val = s->state; ++ comedi_buf_write_samples(s, &val, 1); + comedi_handle_events(dev, s); + + /* enable the interrupt */ +diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c +index 11efb21555e39..b04c15dcfb575 100644 +--- a/drivers/staging/comedi/drivers/addi_apci_1500.c ++++ b/drivers/staging/comedi/drivers/addi_apci_1500.c +@@ -208,7 +208,7 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) + struct comedi_device *dev = d; + struct apci1500_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; +- unsigned int status = 0; ++ unsigned short status = 0; + unsigned int val; + + val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); +@@ -238,14 +238,14 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) + * + * Mask Meaning + * ---------- ------------------------------------------ +- * 0x00000001 Event 1 has occurred +- * 0x00000010 Event 2 has occurred +- * 0x00000100 Counter/timer 1 has run down (not implemented) +- * 0x00001000 Counter/timer 2 has run down (not implemented) +- * 0x00010000 Counter 3 has run down (not implemented) +- * 0x00100000 Watchdog has run down (not implemented) +- * 0x01000000 Voltage error +- * 0x10000000 Short-circuit error ++ * 0b00000001 Event 1 has occurred ++ * 0b00000010 Event 2 has occurred ++ * 0b00000100 Counter/timer 1 has run down (not implemented) ++ * 0b00001000 Counter/timer 2 has run down (not implemented) ++ * 0b00010000 Counter 3 has run down (not implemented) ++ * 0b00100000 Watchdog has run down (not implemented) ++ * 0b01000000 Voltage error ++ * 0b10000000 Short-circuit error + */ + comedi_buf_write_samples(s, &status, 1); + comedi_handle_events(dev, s); +diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c +index 692893c7e5c3d..090607760be6b 100644 +--- a/drivers/staging/comedi/drivers/adv_pci1710.c ++++ b/drivers/staging/comedi/drivers/adv_pci1710.c +@@ -300,11 +300,11 @@ static int pci1710_ai_eoc(struct comedi_device *dev, + static int pci1710_ai_read_sample(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int cur_chan, +- unsigned int *val) ++ unsigned short *val) + { + const struct boardtype *board = dev->board_ptr; + struct pci1710_private *devpriv = dev->private; +- unsigned int sample; ++ unsigned short sample; + unsigned int chan; + + sample = inw(dev->iobase + PCI171X_AD_DATA_REG); +@@ -345,7 +345,7 @@ static int pci1710_ai_insn_read(struct comedi_device *dev, + pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); + + for (i = 0; i < insn->n; i++) { +- unsigned int val; ++ unsigned short val; + + /* start conversion */ + outw(0, dev->iobase + PCI171X_SOFTTRG_REG); +@@ -395,7 +395,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, + { + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int status; +- unsigned int val; ++ unsigned short val; + int ret; + + status = inw(dev->iobase + PCI171X_STATUS_REG); +@@ -455,7 +455,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev, + } + + for (i = 0; i < devpriv->max_samples; i++) { +- unsigned int val; ++ unsigned short val; + int ret; + + ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); +diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c +index 04e224f8b7793..96f4107b8054d 100644 +--- a/drivers/staging/comedi/drivers/das6402.c ++++ b/drivers/staging/comedi/drivers/das6402.c +@@ -186,7 +186,7 @@ static irqreturn_t das6402_interrupt(int irq, void *d) + if (status & DAS6402_STATUS_FFULL) { + async->events |= COMEDI_CB_OVERFLOW; + } else if (status & DAS6402_STATUS_FFNE) { +- unsigned int val; ++ unsigned short val; + + val = das6402_ai_read_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); +diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c +index 4ea100ff6930f..2881808d6606c 100644 +--- a/drivers/staging/comedi/drivers/das800.c ++++ b/drivers/staging/comedi/drivers/das800.c +@@ -427,7 +427,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) + struct comedi_cmd *cmd; + unsigned long irq_flags; + unsigned int status; +- unsigned int val; ++ unsigned short val; + bool fifo_empty; + bool fifo_overflow; + int i; +diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c +index 17e6018918bbf..56682f01242fd 100644 +--- a/drivers/staging/comedi/drivers/dmm32at.c ++++ b/drivers/staging/comedi/drivers/dmm32at.c +@@ -404,7 +404,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d) + { + struct comedi_device *dev = d; + unsigned char intstat; +- unsigned int val; ++ unsigned short val; + int i; + + if (!dev->attached) { +diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c +index 726e40dc17b62..0d3d4cafce2e8 100644 +--- a/drivers/staging/comedi/drivers/me4000.c ++++ b/drivers/staging/comedi/drivers/me4000.c +@@ -924,7 +924,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) + struct comedi_subdevice *s = dev->read_subdev; + int i; + int c = 0; +- unsigned int lval; ++ unsigned short lval; + + if (!dev->attached) + return IRQ_NONE; +diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c +index 2dbf69e309650..bd6f42fe9e3ca 100644 +--- a/drivers/staging/comedi/drivers/pcl711.c ++++ b/drivers/staging/comedi/drivers/pcl711.c +@@ -184,7 +184,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) + struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; +- unsigned int data; ++ unsigned short data; + + if (!dev->attached) { + dev_err(dev->class_dev, "spurious interrupt\n"); +diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c +index 63e3011158f23..f4b4a686c710f 100644 +--- a/drivers/staging/comedi/drivers/pcl818.c ++++ b/drivers/staging/comedi/drivers/pcl818.c +@@ -423,7 +423,7 @@ static int pcl818_ai_eoc(struct comedi_device *dev, + + static bool pcl818_ai_write_sample(struct comedi_device *dev, + struct comedi_subdevice *s, +- unsigned int chan, unsigned int val) ++ unsigned int chan, unsigned short val) + { + struct pcl818_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; +diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c +index dc09cc6e1c478..09e7b4cd0138c 100644 +--- a/drivers/staging/ks7010/ks_wlan_net.c ++++ b/drivers/staging/ks7010/ks_wlan_net.c +@@ -1120,6 +1120,7 @@ static int ks_wlan_set_scan(struct net_device *dev, + { + struct ks_wlan_private *priv = netdev_priv(dev); + struct iw_scan_req *req = NULL; ++ int len; + + if (priv->sleep_mode == SLP_SLEEP) + return -EPERM; +@@ -1129,8 +1130,9 @@ static int ks_wlan_set_scan(struct net_device *dev, + if (wrqu->data.length == sizeof(struct iw_scan_req) && + wrqu->data.flags & IW_SCAN_THIS_ESSID) { + req = (struct iw_scan_req *)extra; +- priv->scan_ssid_len = req->essid_len; +- memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); ++ len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); ++ priv->scan_ssid_len = len; ++ memcpy(priv->scan_ssid, req->essid, len); + } else { + priv->scan_ssid_len = 0; + } +diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c +index 986d293201e63..3eb3fb2d64bc1 100644 +--- a/drivers/staging/media/rkisp1/rkisp1-params.c ++++ b/drivers/staging/media/rkisp1/rkisp1-params.c +@@ -1291,7 +1291,6 @@ static void rkisp1_params_config_parameter(struct rkisp1_params *params) + memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); + rkisp1_hst_config(params, &hst); + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, +- ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK | + rkisp1_hst_params_default_config.mode); + + /* set the range */ +diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c +index 2078d87055bf6..d25a5734249f0 100644 +--- a/drivers/staging/rtl8188eu/core/rtw_ap.c ++++ b/drivers/staging/rtl8188eu/core/rtw_ap.c +@@ -791,6 +791,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, + pbss_network->ie_length - _BEACON_IE_OFFSET_); + if (p && ie_len > 0) { ++ ie_len = min_t(int, ie_len, sizeof(pbss_network->ssid.ssid)); + memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); + memcpy(pbss_network->ssid.ssid, p + 2, ie_len); + pbss_network->ssid.ssid_length = ie_len; +@@ -811,6 +812,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, + pbss_network->ie_length - _BEACON_IE_OFFSET_); + if (p) { ++ ie_len = min_t(int, ie_len, NDIS_802_11_LENGTH_RATES_EX); + memcpy(supportRate, p + 2, ie_len); + supportRateNum = ie_len; + } +@@ -819,6 +821,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, + &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_); + if (p) { ++ ie_len = min_t(int, ie_len, ++ NDIS_802_11_LENGTH_RATES_EX - supportRateNum); + memcpy(supportRate + supportRateNum, p + 2, ie_len); + supportRateNum += ie_len; + } +@@ -934,6 +938,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + + pht_cap->mcs.rx_mask[0] = 0xff; + pht_cap->mcs.rx_mask[1] = 0x0; ++ ie_len = min_t(int, ie_len, sizeof(pmlmepriv->htpriv.ht_cap)); + memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); + } + +diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +index 8e10462f1fbe5..d487528b5fc9a 100644 +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -1144,9 +1144,11 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + break; + } + sec_len = *(pos++); len -= 1; +- if (sec_len > 0 && sec_len <= len) { ++ if (sec_len > 0 && ++ sec_len <= len && ++ sec_len <= 32) { + ssid[ssid_index].ssid_length = sec_len; +- memcpy(ssid[ssid_index].ssid, pos, ssid[ssid_index].ssid_length); ++ memcpy(ssid[ssid_index].ssid, pos, sec_len); + ssid_index++; + } + pos += sec_len; +diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +index 16bcee13f64b5..407effde5e71a 100644 +--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c ++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +@@ -406,9 +406,10 @@ static int _rtl92e_wx_set_scan(struct net_device *dev, + struct iw_scan_req *req = (struct iw_scan_req *)b; + + if (req->essid_len) { +- ieee->current_network.ssid_len = req->essid_len; +- memcpy(ieee->current_network.ssid, req->essid, +- req->essid_len); ++ int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ ieee->current_network.ssid_len = len; ++ memcpy(ieee->current_network.ssid, req->essid, len); + } + } + +diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c +index d853586705fc9..77bf88696a844 100644 +--- a/drivers/staging/rtl8192u/r8192U_wx.c ++++ b/drivers/staging/rtl8192u/r8192U_wx.c +@@ -331,8 +331,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + struct iw_scan_req *req = (struct iw_scan_req *)b; + + if (req->essid_len) { +- ieee->current_network.ssid_len = req->essid_len; +- memcpy(ieee->current_network.ssid, req->essid, req->essid_len); ++ int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ ieee->current_network.ssid_len = len; ++ memcpy(ieee->current_network.ssid, req->essid, len); + } + } + +diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c +index 18116469bd316..75716f59044d9 100644 +--- a/drivers/staging/rtl8712/rtl871x_cmd.c ++++ b/drivers/staging/rtl8712/rtl871x_cmd.c +@@ -192,8 +192,10 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, + psurveyPara->ss_ssidlen = 0; + memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); + if (pssid && pssid->SsidLength) { +- memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength); +- psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength); ++ int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE); ++ ++ memcpy(psurveyPara->ss_ssid, pssid->Ssid, len); ++ psurveyPara->ss_ssidlen = cpu_to_le32(len); + } + set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + r8712_enqueue_cmd(pcmdpriv, ph2c); +diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +index cbaa7a4897483..2a661b04cd255 100644 +--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c ++++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +@@ -924,7 +924,7 @@ static int r871x_wx_set_priv(struct net_device *dev, + struct iw_point *dwrq = (struct iw_point *)awrq; + + len = dwrq->length; +- ext = memdup_user(dwrq->pointer, len); ++ ext = strndup_user(dwrq->pointer, len); + if (IS_ERR(ext)) + return PTR_ERR(ext); + +diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c +index 5f79ea05f9b81..b42193c554fb2 100644 +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -3738,6 +3738,7 @@ core_scsi3_pri_read_keys(struct se_cmd *cmd) + spin_unlock(&dev->t10_pr.registration_lock); + + put_unaligned_be32(add_len, &buf[4]); ++ target_set_cmd_data_length(cmd, 8 + add_len); + + transport_kunmap_data_sg(cmd); + +@@ -3756,7 +3757,7 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd) + struct t10_pr_registration *pr_reg; + unsigned char *buf; + u64 pr_res_key; +- u32 add_len = 16; /* Hardcoded to 16 when a reservation is held. */ ++ u32 add_len = 0; + + if (cmd->data_length < 8) { + pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" +@@ -3774,8 +3775,9 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd) + pr_reg = dev->dev_pr_res_holder; + if (pr_reg) { + /* +- * Set the hardcoded Additional Length ++ * Set the Additional Length to 16 when a reservation is held + */ ++ add_len = 16; + put_unaligned_be32(add_len, &buf[4]); + + if (cmd->data_length < 22) +@@ -3811,6 +3813,8 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd) + (pr_reg->pr_res_type & 0x0f); + } + ++ target_set_cmd_data_length(cmd, 8 + add_len); ++ + err: + spin_unlock(&dev->dev_reservation_lock); + transport_kunmap_data_sg(cmd); +@@ -3829,7 +3833,7 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd) + struct se_device *dev = cmd->se_dev; + struct t10_reservation *pr_tmpl = &dev->t10_pr; + unsigned char *buf; +- u16 add_len = 8; /* Hardcoded to 8. */ ++ u16 len = 8; /* Hardcoded to 8. */ + + if (cmd->data_length < 6) { + pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" +@@ -3841,7 +3845,7 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd) + if (!buf) + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + +- put_unaligned_be16(add_len, &buf[0]); ++ put_unaligned_be16(len, &buf[0]); + buf[2] |= 0x10; /* CRH: Compatible Reservation Hanlding bit. */ + buf[2] |= 0x08; /* SIP_C: Specify Initiator Ports Capable bit */ + buf[2] |= 0x04; /* ATP_C: All Target Ports Capable bit */ +@@ -3870,6 +3874,8 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd) + buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */ + buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */ + ++ target_set_cmd_data_length(cmd, len); ++ + transport_kunmap_data_sg(cmd); + + return 0; +@@ -4030,6 +4036,7 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd) + * Set ADDITIONAL_LENGTH + */ + put_unaligned_be32(add_len, &buf[4]); ++ target_set_cmd_data_length(cmd, 8 + add_len); + + transport_kunmap_data_sg(cmd); + +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index ff26ab0a5f600..484f0ba0a65bb 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -873,11 +873,9 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) + } + EXPORT_SYMBOL(target_complete_cmd); + +-void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length) ++void target_set_cmd_data_length(struct se_cmd *cmd, int length) + { +- if ((scsi_status == SAM_STAT_GOOD || +- cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) && +- length < cmd->data_length) { ++ if (length < cmd->data_length) { + if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { + cmd->residual_count += cmd->data_length - length; + } else { +@@ -887,6 +885,15 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len + + cmd->data_length = length; + } ++} ++EXPORT_SYMBOL(target_set_cmd_data_length); ++ ++void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length) ++{ ++ if (scsi_status == SAM_STAT_GOOD || ++ cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) { ++ target_set_cmd_data_length(cmd, length); ++ } + + target_complete_cmd(cmd, scsi_status); + } +diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c +index 21130af106bb6..8434bd5a8ec78 100644 +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_port *port) + max310x_port_update(port, MAX310X_MODE1_REG, + MAX310X_MODE1_TRNSCVCTRL_BIT, 0); + +- /* Reset FIFOs */ +- max310x_port_write(port, MAX310X_MODE2_REG, +- MAX310X_MODE2_FIFORST_BIT); ++ /* Configure MODE2 register & Reset FIFOs*/ ++ val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT; ++ max310x_port_write(port, MAX310X_MODE2_REG, val); + max310x_port_update(port, MAX310X_MODE2_REG, + MAX310X_MODE2_FIFORST_BIT, 0); + +@@ -1086,27 +1086,8 @@ static int max310x_startup(struct uart_port *port) + /* Clear IRQ status register */ + max310x_port_read(port, MAX310X_IRQSTS_REG); + +- /* +- * Let's ask for an interrupt after a timeout equivalent to +- * the receiving time of 4 characters after the last character +- * has been received. +- */ +- max310x_port_write(port, MAX310X_RXTO_REG, 4); +- +- /* +- * Make sure we also get RX interrupts when the RX FIFO is +- * filling up quickly, so get an interrupt when half of the RX +- * FIFO has been filled in. +- */ +- max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG, +- MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2)); +- +- /* Enable RX timeout interrupt in LSR */ +- max310x_port_write(port, MAX310X_LSR_IRQEN_REG, +- MAX310X_LSR_RXTO_BIT); +- +- /* Enable LSR, RX FIFO trigger, CTS change interrupts */ +- val = MAX310X_IRQ_LSR_BIT | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT; ++ /* Enable RX, TX, CTS change interrupts */ ++ val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT; + max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT); + + return 0; +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 781905745812e..2f4e5174e78c8 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1929,6 +1929,11 @@ static const struct usb_device_id acm_ids[] = { + .driver_info = SEND_ZERO_PACKET, + }, + ++ /* Exclude Goodix Fingerprint Reader */ ++ { USB_DEVICE(0x27c6, 0x5395), ++ .driver_info = IGNORE_DEVICE, ++ }, ++ + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, +diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c +index c9f6e97582885..f27b4aecff3d4 100644 +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -494,16 +494,24 @@ static int usblp_release(struct inode *inode, struct file *file) + /* No kernel lock - fine */ + static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait) + { +- __poll_t ret; ++ struct usblp *usblp = file->private_data; ++ __poll_t ret = 0; + unsigned long flags; + +- struct usblp *usblp = file->private_data; + /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */ + poll_wait(file, &usblp->rwait, wait); + poll_wait(file, &usblp->wwait, wait); ++ ++ mutex_lock(&usblp->mut); ++ if (!usblp->present) ++ ret |= EPOLLHUP; ++ mutex_unlock(&usblp->mut); ++ + spin_lock_irqsave(&usblp->lock, flags); +- ret = ((usblp->bidir && usblp->rcomplete) ? EPOLLIN | EPOLLRDNORM : 0) | +- ((usblp->no_paper || usblp->wcomplete) ? EPOLLOUT | EPOLLWRNORM : 0); ++ if (usblp->bidir && usblp->rcomplete) ++ ret |= EPOLLIN | EPOLLRDNORM; ++ if (usblp->no_paper || usblp->wcomplete) ++ ret |= EPOLLOUT | EPOLLWRNORM; + spin_unlock_irqrestore(&usblp->lock, flags); + return ret; + } +diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c +index 9b4ac4415f1a4..db4de5367737a 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -748,6 +748,38 @@ void usb_put_intf(struct usb_interface *intf) + } + EXPORT_SYMBOL_GPL(usb_put_intf); + ++/** ++ * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint ++ * @intf: the usb interface ++ * ++ * While a USB device cannot perform DMA operations by itself, many USB ++ * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint ++ * for the given USB interface, if any. The returned device structure must be ++ * released with put_device(). ++ * ++ * See also usb_get_dma_device(). ++ * ++ * Returns: A reference to the usb interface's DMA endpoint; or NULL if none ++ * exists. ++ */ ++struct device *usb_intf_get_dma_device(struct usb_interface *intf) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct device *dmadev; ++ ++ if (!udev->bus) ++ return NULL; ++ ++ dmadev = get_device(udev->bus->sysdev); ++ if (!dmadev || !dmadev->dma_mask) { ++ put_device(dmadev); ++ return NULL; ++ } ++ ++ return dmadev; ++} ++EXPORT_SYMBOL_GPL(usb_intf_get_dma_device); ++ + /* USB device locking + * + * USB devices and interfaces are locked using the semaphore in their +diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c +index c703d552bbcfc..c00c4fa139b88 100644 +--- a/drivers/usb/dwc3/dwc3-qcom.c ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -60,12 +60,14 @@ struct dwc3_acpi_pdata { + int dp_hs_phy_irq_index; + int dm_hs_phy_irq_index; + int ss_phy_irq_index; ++ bool is_urs; + }; + + struct dwc3_qcom { + struct device *dev; + void __iomem *qscratch_base; + struct platform_device *dwc3; ++ struct platform_device *urs_usb; + struct clk **clks; + int num_clocks; + struct reset_control *resets; +@@ -356,8 +358,10 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) + if (ret) + dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); + ++ if (device_may_wakeup(qcom->dev)) ++ dwc3_qcom_enable_interrupts(qcom); ++ + qcom->is_suspended = true; +- dwc3_qcom_enable_interrupts(qcom); + + return 0; + } +@@ -370,7 +374,8 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom) + if (!qcom->is_suspended) + return 0; + +- dwc3_qcom_disable_interrupts(qcom); ++ if (device_may_wakeup(qcom->dev)) ++ dwc3_qcom_disable_interrupts(qcom); + + for (i = 0; i < qcom->num_clocks; i++) { + ret = clk_prepare_enable(qcom->clks[i]); +@@ -429,13 +434,15 @@ static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom) + static int dwc3_qcom_get_irq(struct platform_device *pdev, + const char *name, int num) + { ++ struct dwc3_qcom *qcom = platform_get_drvdata(pdev); ++ struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev; + struct device_node *np = pdev->dev.of_node; + int ret; + + if (np) +- ret = platform_get_irq_byname(pdev, name); ++ ret = platform_get_irq_byname(pdev_irq, name); + else +- ret = platform_get_irq(pdev, num); ++ ret = platform_get_irq(pdev_irq, num); + + return ret; + } +@@ -568,6 +575,8 @@ static int dwc3_qcom_acpi_register_core(struct platform_device *pdev) + struct dwc3_qcom *qcom = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct resource *res, *child_res = NULL; ++ struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : ++ pdev; + int irq; + int ret; + +@@ -597,7 +606,7 @@ static int dwc3_qcom_acpi_register_core(struct platform_device *pdev) + child_res[0].end = child_res[0].start + + qcom->acpi_pdata->dwc3_core_base_size; + +- irq = platform_get_irq(pdev, 0); ++ irq = platform_get_irq(pdev_irq, 0); + child_res[1].flags = IORESOURCE_IRQ; + child_res[1].start = child_res[1].end = irq; + +@@ -639,16 +648,46 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) + ret = of_platform_populate(np, NULL, NULL, dev); + if (ret) { + dev_err(dev, "failed to register dwc3 core - %d\n", ret); +- return ret; ++ goto node_put; + } + + qcom->dwc3 = of_find_device_by_node(dwc3_np); + if (!qcom->dwc3) { ++ ret = -ENODEV; + dev_err(dev, "failed to get dwc3 platform device\n"); +- return -ENODEV; + } + +- return 0; ++node_put: ++ of_node_put(dwc3_np); ++ ++ return ret; ++} ++ ++static struct platform_device * ++dwc3_qcom_create_urs_usb_platdev(struct device *dev) ++{ ++ struct fwnode_handle *fwh; ++ struct acpi_device *adev; ++ char name[8]; ++ int ret; ++ int id; ++ ++ /* Figure out device id */ ++ ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id); ++ if (!ret) ++ return NULL; ++ ++ /* Find the child using name */ ++ snprintf(name, sizeof(name), "USB%d", id); ++ fwh = fwnode_get_named_child_node(dev->fwnode, name); ++ if (!fwh) ++ return NULL; ++ ++ adev = to_acpi_device_node(fwh); ++ if (!adev) ++ return NULL; ++ ++ return acpi_create_platform_device(adev, NULL); + } + + static int dwc3_qcom_probe(struct platform_device *pdev) +@@ -715,6 +754,14 @@ static int dwc3_qcom_probe(struct platform_device *pdev) + qcom->acpi_pdata->qscratch_base_offset; + parent_res->end = parent_res->start + + qcom->acpi_pdata->qscratch_base_size; ++ ++ if (qcom->acpi_pdata->is_urs) { ++ qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev); ++ if (!qcom->urs_usb) { ++ dev_err(dev, "failed to create URS USB platdev\n"); ++ return -ENODEV; ++ } ++ } + } + + qcom->qscratch_base = devm_ioremap_resource(dev, parent_res); +@@ -877,8 +924,22 @@ static const struct dwc3_acpi_pdata sdm845_acpi_pdata = { + .ss_phy_irq_index = 2 + }; + ++static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = { ++ .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET, ++ .qscratch_base_size = SDM845_QSCRATCH_SIZE, ++ .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE, ++ .hs_phy_irq_index = 1, ++ .dp_hs_phy_irq_index = 4, ++ .dm_hs_phy_irq_index = 3, ++ .ss_phy_irq_index = 2, ++ .is_urs = true, ++}; ++ + static const struct acpi_device_id dwc3_qcom_acpi_match[] = { + { "QCOM2430", (unsigned long)&sdm845_acpi_pdata }, ++ { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata }, ++ { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata }, ++ { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match); +diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c +index 00d346965f7a5..560382e0a8f38 100644 +--- a/drivers/usb/gadget/function/f_uac1.c ++++ b/drivers/usb/gadget/function/f_uac1.c +@@ -499,6 +499,7 @@ static void f_audio_disable(struct usb_function *f) + uac1->as_out_alt = 0; + uac1->as_in_alt = 0; + ++ u_audio_stop_playback(&uac1->g_audio); + u_audio_stop_capture(&uac1->g_audio); + } + +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index 5d960b6603b6f..6f03e944e0e31 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -478,7 +478,7 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + } + + max_size_bw = num_channels(chmask) * ssize * +- DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); ++ ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1); + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, + max_size_ep)); + +diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h +index bd92b57030131..f982e18a5a789 100644 +--- a/drivers/usb/gadget/function/u_ether_configfs.h ++++ b/drivers/usb/gadget/function/u_ether_configfs.h +@@ -169,12 +169,11 @@ out: \ + size_t len) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ +- int ret; \ ++ int ret = -EINVAL; \ + u8 val; \ + \ + mutex_lock(&opts->lock); \ +- ret = sscanf(page, "%02hhx", &val); \ +- if (ret > 0) { \ ++ if (sscanf(page, "%02hhx", &val) > 0) { \ + opts->_n_ = val; \ + ret = len; \ + } \ +diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c +index f1ea51476add0..1d3ebb07ccd4d 100644 +--- a/drivers/usb/gadget/udc/s3c2410_udc.c ++++ b/drivers/usb/gadget/udc/s3c2410_udc.c +@@ -1773,8 +1773,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev) + udc_info = dev_get_platdata(&pdev->dev); + + base_addr = devm_platform_ioremap_resource(pdev, 0); +- if (!base_addr) { +- retval = -ENOMEM; ++ if (IS_ERR(base_addr)) { ++ retval = PTR_ERR(base_addr); + goto err_mem; + } + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 84da8406d5b42..5bbccc9a0179f 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -66,6 +66,7 @@ + #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 + #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 + #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 ++#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 + + static const char hcd_name[] = "xhci_hcd"; + +@@ -276,11 +277,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) + xhci->quirks |= XHCI_BROKEN_STREAMS; + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && +- pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) ++ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) { + xhci->quirks |= XHCI_TRUST_TX_LENGTH; ++ xhci->quirks |= XHCI_NO_64BIT_SUPPORT; ++ } + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI || +- pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI)) ++ pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI || ++ pdev->device == PCI_DEVICE_ID_ASMEDIA_3242_XHCI)) + xhci->quirks |= XHCI_NO_64BIT_SUPPORT; + + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && +@@ -295,6 +299,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + pdev->device == 0x9026) + xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; + ++ if (pdev->vendor == PCI_VENDOR_ID_AMD && ++ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 || ++ pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4)) ++ xhci->quirks |= XHCI_NO_SOFT_RETRY; ++ + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, + "QUIRK: Resetting on resume"); +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 061d5c51405fb..054840a69eb4a 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2307,7 +2307,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, + remaining = 0; + break; + case COMP_USB_TRANSACTION_ERROR: +- if ((ep_ring->err_count++ > MAX_SOFT_RETRY) || ++ if (xhci->quirks & XHCI_NO_SOFT_RETRY || ++ (ep_ring->err_count++ > MAX_SOFT_RETRY) || + le32_to_cpu(slot_ctx->tt_info) & TT_SLOT) + break; + *status = 0; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index d17bbb162810a..c449de6164b18 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -883,44 +883,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) + xhci_set_cmd_ring_deq(xhci); + } + +-static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci) ++/* ++ * Disable port wake bits if do_wakeup is not set. ++ * ++ * Also clear a possible internal port wake state left hanging for ports that ++ * detected termination but never successfully enumerated (trained to 0U). ++ * Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done ++ * at enumeration clears this wake, force one here as well for unconnected ports ++ */ ++ ++static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci, ++ struct xhci_hub *rhub, ++ bool do_wakeup) + { +- struct xhci_port **ports; +- int port_index; + unsigned long flags; + u32 t1, t2, portsc; ++ int i; + + spin_lock_irqsave(&xhci->lock, flags); + +- /* disable usb3 ports Wake bits */ +- port_index = xhci->usb3_rhub.num_ports; +- ports = xhci->usb3_rhub.ports; +- while (port_index--) { +- t1 = readl(ports[port_index]->addr); +- portsc = t1; +- t1 = xhci_port_state_to_neutral(t1); +- t2 = t1 & ~PORT_WAKE_BITS; +- if (t1 != t2) { +- writel(t2, ports[port_index]->addr); +- xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n", +- xhci->usb3_rhub.hcd->self.busnum, +- port_index + 1, portsc, t2); +- } +- } ++ for (i = 0; i < rhub->num_ports; i++) { ++ portsc = readl(rhub->ports[i]->addr); ++ t1 = xhci_port_state_to_neutral(portsc); ++ t2 = t1; ++ ++ /* clear wake bits if do_wake is not set */ ++ if (!do_wakeup) ++ t2 &= ~PORT_WAKE_BITS; ++ ++ /* Don't touch csc bit if connected or connect change is set */ ++ if (!(portsc & (PORT_CSC | PORT_CONNECT))) ++ t2 |= PORT_CSC; + +- /* disable usb2 ports Wake bits */ +- port_index = xhci->usb2_rhub.num_ports; +- ports = xhci->usb2_rhub.ports; +- while (port_index--) { +- t1 = readl(ports[port_index]->addr); +- portsc = t1; +- t1 = xhci_port_state_to_neutral(t1); +- t2 = t1 & ~PORT_WAKE_BITS; + if (t1 != t2) { +- writel(t2, ports[port_index]->addr); +- xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n", +- xhci->usb2_rhub.hcd->self.busnum, +- port_index + 1, portsc, t2); ++ writel(t2, rhub->ports[i]->addr); ++ xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n", ++ rhub->hcd->self.busnum, i + 1, portsc, t2); + } + } + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) + return -EINVAL; + + /* Clear root port wake on bits if wakeup not allowed. */ +- if (!do_wakeup) +- xhci_disable_port_wake_on_bits(xhci); ++ xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup); ++ xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup); + + if (!HCD_HW_ACCESSIBLE(hcd)) + return 0; +@@ -1088,6 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + struct usb_hcd *secondary_hcd; + int retval = 0; + bool comp_timer_running = false; ++ bool pending_portevent = false; + + if (!hcd->state) + return 0; +@@ -1226,13 +1225,22 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + + done: + if (retval == 0) { +- /* Resume root hubs only when have pending events. */ +- if (xhci_pending_portevent(xhci)) { ++ /* ++ * Resume roothubs only if there are pending events. ++ * USB 3 devices resend U3 LFPS wake after a 100ms delay if ++ * the first wake signalling failed, give it that chance. ++ */ ++ pending_portevent = xhci_pending_portevent(xhci); ++ if (!pending_portevent) { ++ msleep(120); ++ pending_portevent = xhci_pending_portevent(xhci); ++ } ++ ++ if (pending_portevent) { + usb_hcd_resume_root_hub(xhci->shared_hcd); + usb_hcd_resume_root_hub(hcd); + } + } +- + /* + * If system is subject to the Quirk, Compliance Mode Timer needs to + * be re-initialized Always after a system resume. Ports are subject +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 045740ad9c1ec..d01241f1daf3b 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1879,6 +1879,7 @@ struct xhci_hcd { + #define XHCI_SKIP_PHY_INIT BIT_ULL(37) + #define XHCI_DISABLE_SPARSE BIT_ULL(38) + #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) ++#define XHCI_NO_SOFT_RETRY BIT_ULL(40) + + unsigned int num_active_eps; + unsigned int limit_active_eps; +diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c +index e7334b7fb3a62..75fff2e4cbc65 100644 +--- a/drivers/usb/renesas_usbhs/pipe.c ++++ b/drivers/usb/renesas_usbhs/pipe.c +@@ -746,6 +746,8 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, + + void usbhs_pipe_free(struct usbhs_pipe *pipe) + { ++ usbhsp_pipe_select(pipe); ++ usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0); + usbhsp_put_pipe(pipe); + } + +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index 28deaaec581f6..f26861246f653 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1a86, 0x7522) }, + { USB_DEVICE(0x1a86, 0x7523) }, + { USB_DEVICE(0x4348, 0x5523) }, ++ { USB_DEVICE(0x9986, 0x7523) }, + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index bf11f86896837..b5f4e584f3c9e 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -149,6 +149,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ + { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ ++ { USB_DEVICE(0x10C4, 0x88D8) }, /* Acuity Brands nLight Air Adapter */ + { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ +@@ -205,6 +206,8 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ + { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ + { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ ++ { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */ ++ { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */ + { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ + { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ + { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index ba5d8df695189..4b48ef4adbeb6 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -3003,26 +3003,32 @@ static int edge_startup(struct usb_serial *serial) + response = -ENODEV; + } + +- usb_free_urb(edge_serial->interrupt_read_urb); +- kfree(edge_serial->interrupt_in_buffer); +- +- usb_free_urb(edge_serial->read_urb); +- kfree(edge_serial->bulk_in_buffer); +- +- kfree(edge_serial); +- +- return response; ++ goto error; + } + + /* start interrupt read for this edgeport this interrupt will + * continue as long as the edgeport is connected */ + response = usb_submit_urb(edge_serial->interrupt_read_urb, + GFP_KERNEL); +- if (response) ++ if (response) { + dev_err(ddev, "%s - Error %d submitting control urb\n", + __func__, response); ++ ++ goto error; ++ } + } + return response; ++ ++error: ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ ++ kfree(edge_serial); ++ ++ return response; + } + + +diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c +index 2305d425e6c9a..8f1de1fbbeedf 100644 +--- a/drivers/usb/usbip/stub_dev.c ++++ b/drivers/usb/usbip/stub_dev.c +@@ -46,6 +46,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + int sockfd = 0; + struct socket *socket; + int rv; ++ struct task_struct *tcp_rx = NULL; ++ struct task_struct *tcp_tx = NULL; + + if (!sdev) { + dev_err(dev, "sdev is null\n"); +@@ -69,23 +71,47 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + } + + socket = sockfd_lookup(sockfd, &err); +- if (!socket) ++ if (!socket) { ++ dev_err(dev, "failed to lookup sock"); + goto err; ++ } + +- sdev->ud.tcp_socket = socket; +- sdev->ud.sockfd = sockfd; ++ if (socket->type != SOCK_STREAM) { ++ dev_err(dev, "Expecting SOCK_STREAM - found %d", ++ socket->type); ++ goto sock_err; ++ } + ++ /* unlock and create threads and get tasks */ + spin_unlock_irq(&sdev->ud.lock); ++ tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx"); ++ if (IS_ERR(tcp_rx)) { ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx"); ++ if (IS_ERR(tcp_tx)) { ++ kthread_stop(tcp_rx); ++ sockfd_put(socket); ++ return -EINVAL; ++ } + +- sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, +- "stub_rx"); +- sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, +- "stub_tx"); ++ /* get task structs now */ ++ get_task_struct(tcp_rx); ++ get_task_struct(tcp_tx); + ++ /* lock and update sdev->ud state */ + spin_lock_irq(&sdev->ud.lock); ++ sdev->ud.tcp_socket = socket; ++ sdev->ud.sockfd = sockfd; ++ sdev->ud.tcp_rx = tcp_rx; ++ sdev->ud.tcp_tx = tcp_tx; + sdev->ud.status = SDEV_ST_USED; + spin_unlock_irq(&sdev->ud.lock); + ++ wake_up_process(sdev->ud.tcp_rx); ++ wake_up_process(sdev->ud.tcp_tx); ++ + } else { + dev_info(dev, "stub down\n"); + +@@ -100,6 +126,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + + return count; + ++sock_err: ++ sockfd_put(socket); + err: + spin_unlock_irq(&sdev->ud.lock); + return -EINVAL; +diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c +index be37aec250c2b..e64ea314930be 100644 +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -312,6 +312,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, + struct vhci *vhci; + int err; + unsigned long flags; ++ struct task_struct *tcp_rx = NULL; ++ struct task_struct *tcp_tx = NULL; + + /* + * @rhport: port number of vhci_hcd +@@ -349,12 +351,35 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, + + /* Extract socket from fd. */ + socket = sockfd_lookup(sockfd, &err); +- if (!socket) ++ if (!socket) { ++ dev_err(dev, "failed to lookup sock"); + return -EINVAL; ++ } ++ if (socket->type != SOCK_STREAM) { ++ dev_err(dev, "Expecting SOCK_STREAM - found %d", ++ socket->type); ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ ++ /* create threads before locking */ ++ tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); ++ if (IS_ERR(tcp_rx)) { ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); ++ if (IS_ERR(tcp_tx)) { ++ kthread_stop(tcp_rx); ++ sockfd_put(socket); ++ return -EINVAL; ++ } + +- /* now need lock until setting vdev status as used */ ++ /* get task structs now */ ++ get_task_struct(tcp_rx); ++ get_task_struct(tcp_tx); + +- /* begin a lock */ ++ /* now begin lock until setting vdev status set */ + spin_lock_irqsave(&vhci->lock, flags); + spin_lock(&vdev->ud.lock); + +@@ -364,6 +389,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, + spin_unlock_irqrestore(&vhci->lock, flags); + + sockfd_put(socket); ++ kthread_stop_put(tcp_rx); ++ kthread_stop_put(tcp_tx); + + dev_err(dev, "port %d already used\n", rhport); + /* +@@ -382,14 +409,16 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr, + vdev->speed = speed; + vdev->ud.sockfd = sockfd; + vdev->ud.tcp_socket = socket; ++ vdev->ud.tcp_rx = tcp_rx; ++ vdev->ud.tcp_tx = tcp_tx; + vdev->ud.status = VDEV_ST_NOTASSIGNED; + + spin_unlock(&vdev->ud.lock); + spin_unlock_irqrestore(&vhci->lock, flags); + /* end the lock */ + +- vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); +- vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); ++ wake_up_process(vdev->ud.tcp_rx); ++ wake_up_process(vdev->ud.tcp_tx); + + rh_port_connect(vdev, speed); + +diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c +index 100f680c572ae..a3ec39fc61778 100644 +--- a/drivers/usb/usbip/vudc_sysfs.c ++++ b/drivers/usb/usbip/vudc_sysfs.c +@@ -90,8 +90,9 @@ unlock: + } + static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor)); + +-static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *attr, +- const char *in, size_t count) ++static ssize_t usbip_sockfd_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *in, size_t count) + { + struct vudc *udc = (struct vudc *) dev_get_drvdata(dev); + int rv; +@@ -100,6 +101,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + struct socket *socket; + unsigned long flags; + int ret; ++ struct task_struct *tcp_rx = NULL; ++ struct task_struct *tcp_tx = NULL; + + rv = kstrtoint(in, 0, &sockfd); + if (rv != 0) +@@ -138,24 +141,54 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + goto unlock_ud; + } + +- udc->ud.tcp_socket = socket; ++ if (socket->type != SOCK_STREAM) { ++ dev_err(dev, "Expecting SOCK_STREAM - found %d", ++ socket->type); ++ ret = -EINVAL; ++ goto sock_err; ++ } + ++ /* unlock and create threads and get tasks */ + spin_unlock_irq(&udc->ud.lock); + spin_unlock_irqrestore(&udc->lock, flags); + +- udc->ud.tcp_rx = kthread_get_run(&v_rx_loop, +- &udc->ud, "vudc_rx"); +- udc->ud.tcp_tx = kthread_get_run(&v_tx_loop, +- &udc->ud, "vudc_tx"); ++ tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx"); ++ if (IS_ERR(tcp_rx)) { ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ tcp_tx = kthread_create(&v_tx_loop, &udc->ud, "vudc_tx"); ++ if (IS_ERR(tcp_tx)) { ++ kthread_stop(tcp_rx); ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ ++ /* get task structs now */ ++ get_task_struct(tcp_rx); ++ get_task_struct(tcp_tx); + ++ /* lock and update udc->ud state */ + spin_lock_irqsave(&udc->lock, flags); + spin_lock_irq(&udc->ud.lock); ++ ++ udc->ud.tcp_socket = socket; ++ udc->ud.tcp_rx = tcp_rx; ++ udc->ud.tcp_rx = tcp_tx; + udc->ud.status = SDEV_ST_USED; ++ + spin_unlock_irq(&udc->ud.lock); + + ktime_get_ts64(&udc->start_time); + v_start_timer(udc); + udc->connected = 1; ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ wake_up_process(udc->ud.tcp_rx); ++ wake_up_process(udc->ud.tcp_tx); ++ return count; ++ + } else { + if (!udc->connected) { + dev_err(dev, "Device not connected"); +@@ -177,6 +210,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a + + return count; + ++sock_err: ++ sockfd_put(socket); + unlock_ud: + spin_unlock_irq(&udc->ud.lock); + unlock: +diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c +index da87f3a1e351b..b8f2f971c2f0f 100644 +--- a/drivers/xen/events/events_2l.c ++++ b/drivers/xen/events/events_2l.c +@@ -47,6 +47,11 @@ static unsigned evtchn_2l_max_channels(void) + return EVTCHN_2L_NR_CHANNELS; + } + ++static void evtchn_2l_remove(evtchn_port_t evtchn, unsigned int cpu) ++{ ++ clear_bit(evtchn, BM(per_cpu(cpu_evtchn_mask, cpu))); ++} ++ + static void evtchn_2l_bind_to_cpu(evtchn_port_t evtchn, unsigned int cpu, + unsigned int old_cpu) + { +@@ -72,12 +77,6 @@ static bool evtchn_2l_is_pending(evtchn_port_t port) + return sync_test_bit(port, BM(&s->evtchn_pending[0])); + } + +-static bool evtchn_2l_test_and_set_mask(evtchn_port_t port) +-{ +- struct shared_info *s = HYPERVISOR_shared_info; +- return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0])); +-} +- + static void evtchn_2l_mask(evtchn_port_t port) + { + struct shared_info *s = HYPERVISOR_shared_info; +@@ -355,18 +354,27 @@ static void evtchn_2l_resume(void) + EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); + } + ++static int evtchn_2l_percpu_deinit(unsigned int cpu) ++{ ++ memset(per_cpu(cpu_evtchn_mask, cpu), 0, sizeof(xen_ulong_t) * ++ EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); ++ ++ return 0; ++} ++ + static const struct evtchn_ops evtchn_ops_2l = { + .max_channels = evtchn_2l_max_channels, + .nr_channels = evtchn_2l_max_channels, ++ .remove = evtchn_2l_remove, + .bind_to_cpu = evtchn_2l_bind_to_cpu, + .clear_pending = evtchn_2l_clear_pending, + .set_pending = evtchn_2l_set_pending, + .is_pending = evtchn_2l_is_pending, +- .test_and_set_mask = evtchn_2l_test_and_set_mask, + .mask = evtchn_2l_mask, + .unmask = evtchn_2l_unmask, + .handle_events = evtchn_2l_handle_events, + .resume = evtchn_2l_resume, ++ .percpu_deinit = evtchn_2l_percpu_deinit, + }; + + void __init xen_evtchn_2l_init(void) +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index bbebe248b7264..7bd03f6e0422f 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -96,13 +96,19 @@ struct irq_info { + struct list_head eoi_list; + short refcnt; + short spurious_cnt; +- enum xen_irq_type type; /* type */ ++ short type; /* type */ ++ u8 mask_reason; /* Why is event channel masked */ ++#define EVT_MASK_REASON_EXPLICIT 0x01 ++#define EVT_MASK_REASON_TEMPORARY 0x02 ++#define EVT_MASK_REASON_EOI_PENDING 0x04 ++ u8 is_active; /* Is event just being handled? */ + unsigned irq; + evtchn_port_t evtchn; /* event channel */ + unsigned short cpu; /* cpu bound */ + unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */ + unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ + u64 eoi_time; /* Time in jiffies when to EOI. */ ++ spinlock_t lock; + + union { + unsigned short virq; +@@ -151,6 +157,7 @@ static DEFINE_RWLOCK(evtchn_rwlock); + * evtchn_rwlock + * IRQ-desc lock + * percpu eoi_list_lock ++ * irq_info->lock + */ + + static LIST_HEAD(xen_irq_list_head); +@@ -272,6 +279,8 @@ static int xen_irq_info_common_setup(struct irq_info *info, + info->irq = irq; + info->evtchn = evtchn; + info->cpu = cpu; ++ info->mask_reason = EVT_MASK_REASON_EXPLICIT; ++ spin_lock_init(&info->lock); + + ret = set_evtchn_to_irq(evtchn, irq); + if (ret < 0) +@@ -338,6 +347,7 @@ static int xen_irq_info_pirq_setup(unsigned irq, + static void xen_irq_info_cleanup(struct irq_info *info) + { + set_evtchn_to_irq(info->evtchn, -1); ++ xen_evtchn_port_remove(info->evtchn, info->cpu); + info->evtchn = 0; + } + +@@ -418,6 +428,34 @@ unsigned int cpu_from_evtchn(evtchn_port_t evtchn) + return ret; + } + ++static void do_mask(struct irq_info *info, u8 reason) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&info->lock, flags); ++ ++ if (!info->mask_reason) ++ mask_evtchn(info->evtchn); ++ ++ info->mask_reason |= reason; ++ ++ spin_unlock_irqrestore(&info->lock, flags); ++} ++ ++static void do_unmask(struct irq_info *info, u8 reason) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&info->lock, flags); ++ ++ info->mask_reason &= ~reason; ++ ++ if (!info->mask_reason) ++ unmask_evtchn(info->evtchn); ++ ++ spin_unlock_irqrestore(&info->lock, flags); ++} ++ + #ifdef CONFIG_X86 + static bool pirq_check_eoi_map(unsigned irq) + { +@@ -545,7 +583,7 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious) + } + + info->eoi_time = 0; +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EOI_PENDING); + } + + static void xen_irq_lateeoi_worker(struct work_struct *work) +@@ -714,6 +752,12 @@ static void xen_evtchn_close(evtchn_port_t port) + BUG(); + } + ++static void event_handler_exit(struct irq_info *info) ++{ ++ smp_store_release(&info->is_active, 0); ++ clear_evtchn(info->evtchn); ++} ++ + static void pirq_query_unmask(int irq) + { + struct physdev_irq_status_query irq_status; +@@ -732,7 +776,8 @@ static void pirq_query_unmask(int irq) + + static void eoi_pirq(struct irq_data *data) + { +- evtchn_port_t evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) }; + int rc = 0; + +@@ -741,16 +786,15 @@ static void eoi_pirq(struct irq_data *data) + + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { +- int masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + irq_move_masked_irq(data); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + } else +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + if (pirq_needs_eoi(data->irq)) { + rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); +@@ -801,7 +845,8 @@ static unsigned int __startup_pirq(unsigned int irq) + goto err; + + out: +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EXPLICIT); ++ + eoi_pirq(irq_get_irq_data(irq)); + + return 0; +@@ -828,7 +873,7 @@ static void shutdown_pirq(struct irq_data *data) + if (!VALID_EVTCHN(evtchn)) + return; + +- mask_evtchn(evtchn); ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); + xen_evtchn_close(evtchn); + xen_irq_info_cleanup(info); + } +@@ -1565,6 +1610,8 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) + } + + info = info_for_irq(irq); ++ if (xchg_acquire(&info->is_active, 1)) ++ return; + + if (ctrl->defer_eoi) { + info->eoi_cpu = smp_processor_id(); +@@ -1655,10 +1702,10 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) + } + + /* Rebind an evtchn so that it gets delivered to a specific cpu */ +-static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) ++static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu) + { + struct evtchn_bind_vcpu bind_vcpu; +- int masked; ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return -1; +@@ -1674,7 +1721,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) + * Mask the event while changing the VCPU binding to prevent + * it being delivered on an unexpected VCPU. + */ +- masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + + /* + * If this fails, it usually just indicates that we're dealing with a +@@ -1684,8 +1731,7 @@ static int xen_rebind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int tcpu) + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + bind_evtchn_to_cpu(evtchn, tcpu); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + + return 0; + } +@@ -1694,7 +1740,7 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, + bool force) + { + unsigned tcpu = cpumask_first_and(dest, cpu_online_mask); +- int ret = xen_rebind_evtchn_to_cpu(evtchn_from_irq(data->irq), tcpu); ++ int ret = xen_rebind_evtchn_to_cpu(info_for_irq(data->irq), tcpu); + + if (!ret) + irq_data_update_effective_affinity(data, cpumask_of(tcpu)); +@@ -1713,39 +1759,41 @@ EXPORT_SYMBOL_GPL(xen_set_affinity_evtchn); + + static void enable_dynirq(struct irq_data *data) + { +- evtchn_port_t evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EXPLICIT); + } + + static void disable_dynirq(struct irq_data *data) + { +- evtchn_port_t evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- mask_evtchn(evtchn); ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); + } + + static void ack_dynirq(struct irq_data *data) + { +- evtchn_port_t evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return; + + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { +- int masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + irq_move_masked_irq(data); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + } else +- clear_evtchn(evtchn); ++ event_handler_exit(info); + } + + static void mask_ack_dynirq(struct irq_data *data) +@@ -1754,18 +1802,39 @@ static void mask_ack_dynirq(struct irq_data *data) + ack_dynirq(data); + } + ++static void lateeoi_ack_dynirq(struct irq_data *data) ++{ ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; ++ ++ if (VALID_EVTCHN(evtchn)) { ++ do_mask(info, EVT_MASK_REASON_EOI_PENDING); ++ event_handler_exit(info); ++ } ++} ++ ++static void lateeoi_mask_ack_dynirq(struct irq_data *data) ++{ ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; ++ ++ if (VALID_EVTCHN(evtchn)) { ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); ++ event_handler_exit(info); ++ } ++} ++ + static int retrigger_dynirq(struct irq_data *data) + { +- evtchn_port_t evtchn = evtchn_from_irq(data->irq); +- int masked; ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return 0; + +- masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + set_evtchn(evtchn); +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + + return 1; + } +@@ -1862,10 +1931,11 @@ static void restore_cpu_ipis(unsigned int cpu) + /* Clear an irq's pending state, in preparation for polling on it */ + void xen_clear_irq_pending(int irq) + { +- evtchn_port_t evtchn = evtchn_from_irq(irq); ++ struct irq_info *info = info_for_irq(irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- clear_evtchn(evtchn); ++ event_handler_exit(info); + } + EXPORT_SYMBOL(xen_clear_irq_pending); + void xen_set_irq_pending(int irq) +@@ -1973,8 +2043,8 @@ static struct irq_chip xen_lateeoi_chip __read_mostly = { + .irq_mask = disable_dynirq, + .irq_unmask = enable_dynirq, + +- .irq_ack = mask_ack_dynirq, +- .irq_mask_ack = mask_ack_dynirq, ++ .irq_ack = lateeoi_ack_dynirq, ++ .irq_mask_ack = lateeoi_mask_ack_dynirq, + + .irq_set_affinity = set_affinity_irq, + .irq_retrigger = retrigger_dynirq, +diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c +index b234f1766810c..ad9fe51d3fb33 100644 +--- a/drivers/xen/events/events_fifo.c ++++ b/drivers/xen/events/events_fifo.c +@@ -209,12 +209,6 @@ static bool evtchn_fifo_is_pending(evtchn_port_t port) + return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); + } + +-static bool evtchn_fifo_test_and_set_mask(evtchn_port_t port) +-{ +- event_word_t *word = event_word_from_port(port); +- return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); +-} +- + static void evtchn_fifo_mask(evtchn_port_t port) + { + event_word_t *word = event_word_from_port(port); +@@ -423,7 +417,6 @@ static const struct evtchn_ops evtchn_ops_fifo = { + .clear_pending = evtchn_fifo_clear_pending, + .set_pending = evtchn_fifo_set_pending, + .is_pending = evtchn_fifo_is_pending, +- .test_and_set_mask = evtchn_fifo_test_and_set_mask, + .mask = evtchn_fifo_mask, + .unmask = evtchn_fifo_unmask, + .handle_events = evtchn_fifo_handle_events, +diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h +index 0a97c0549db76..4d3398eff9cdf 100644 +--- a/drivers/xen/events/events_internal.h ++++ b/drivers/xen/events/events_internal.h +@@ -14,13 +14,13 @@ struct evtchn_ops { + unsigned (*nr_channels)(void); + + int (*setup)(evtchn_port_t port); ++ void (*remove)(evtchn_port_t port, unsigned int cpu); + void (*bind_to_cpu)(evtchn_port_t evtchn, unsigned int cpu, + unsigned int old_cpu); + + void (*clear_pending)(evtchn_port_t port); + void (*set_pending)(evtchn_port_t port); + bool (*is_pending)(evtchn_port_t port); +- bool (*test_and_set_mask)(evtchn_port_t port); + void (*mask)(evtchn_port_t port); + void (*unmask)(evtchn_port_t port); + +@@ -54,6 +54,13 @@ static inline int xen_evtchn_port_setup(evtchn_port_t evtchn) + return 0; + } + ++static inline void xen_evtchn_port_remove(evtchn_port_t evtchn, ++ unsigned int cpu) ++{ ++ if (evtchn_ops->remove) ++ evtchn_ops->remove(evtchn, cpu); ++} ++ + static inline void xen_evtchn_port_bind_to_cpu(evtchn_port_t evtchn, + unsigned int cpu, + unsigned int old_cpu) +@@ -76,11 +83,6 @@ static inline bool test_evtchn(evtchn_port_t port) + return evtchn_ops->is_pending(port); + } + +-static inline bool test_and_set_mask(evtchn_port_t port) +-{ +- return evtchn_ops->test_and_set_mask(port); +-} +- + static inline void mask_evtchn(evtchn_port_t port) + { + return evtchn_ops->mask(port); +diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c +index 3880a82da1dc5..11b5bf2419555 100644 +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -647,12 +647,24 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, + struct super_block *sb = file_inode(file)->i_sb; + struct dentry *root = sb->s_root, *dentry; + int err = 0; ++ struct file *f = NULL; + + e = create_entry(buffer, count); + + if (IS_ERR(e)) + return PTR_ERR(e); + ++ if (e->flags & MISC_FMT_OPEN_FILE) { ++ f = open_exec(e->interpreter); ++ if (IS_ERR(f)) { ++ pr_notice("register: failed to install interpreter file %s\n", ++ e->interpreter); ++ kfree(e); ++ return PTR_ERR(f); ++ } ++ e->interp_file = f; ++ } ++ + inode_lock(d_inode(root)); + dentry = lookup_one_len(e->name, root, strlen(e->name)); + err = PTR_ERR(dentry); +@@ -676,21 +688,6 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, + goto out2; + } + +- if (e->flags & MISC_FMT_OPEN_FILE) { +- struct file *f; +- +- f = open_exec(e->interpreter); +- if (IS_ERR(f)) { +- err = PTR_ERR(f); +- pr_notice("register: failed to install interpreter file %s\n", e->interpreter); +- simple_release_fs(&bm_mnt, &entry_count); +- iput(inode); +- inode = NULL; +- goto out2; +- } +- e->interp_file = f; +- } +- + e->dentry = dget(dentry); + inode->i_private = e; + inode->i_fop = &bm_entry_operations; +@@ -707,6 +704,8 @@ out: + inode_unlock(d_inode(root)); + + if (err) { ++ if (f) ++ filp_close(f, NULL); + kfree(e); + return err; + } +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 2ea189c1b4ffe..fe201b757baa4 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -123,12 +123,21 @@ int truncate_bdev_range(struct block_device *bdev, fmode_t mode, + err = bd_prepare_to_claim(bdev, claimed_bdev, + truncate_bdev_range); + if (err) +- return err; ++ goto invalidate; + } + truncate_inode_pages_range(bdev->bd_inode->i_mapping, lstart, lend); + if (claimed_bdev) + bd_abort_claiming(bdev, claimed_bdev, truncate_bdev_range); + return 0; ++ ++invalidate: ++ /* ++ * Someone else has handle exclusively open. Try invalidating instead. ++ * The 'end' argument is inclusive so the rounding is safe. ++ */ ++ return invalidate_inode_pages2_range(bdev->bd_inode->i_mapping, ++ lstart >> PAGE_SHIFT, ++ lend >> PAGE_SHIFT); + } + EXPORT_SYMBOL(truncate_bdev_range); + +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 472cb7777e3e9..f0ed29a9a6f11 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -286,7 +286,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) + rc = server->ops->queryfs(xid, tcon, cifs_sb, buf); + + free_xid(xid); +- return 0; ++ return rc; + } + + static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 484ec2d8c5c95..3295516af2aec 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -256,7 +256,7 @@ struct smb_version_operations { + /* verify the message */ + int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); + bool (*is_oplock_break)(char *, struct TCP_Server_Info *); +- int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); ++ int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, + unsigned int epoch, bool *purge_cache); +@@ -1785,10 +1785,11 @@ static inline bool is_retryable_error(int error) + #define CIFS_NO_RSP_BUF 0x040 /* no response buffer required */ + + /* Type of request operation */ +-#define CIFS_ECHO_OP 0x080 /* echo request */ +-#define CIFS_OBREAK_OP 0x0100 /* oplock break request */ +-#define CIFS_NEG_OP 0x0200 /* negotiate request */ +-#define CIFS_OP_MASK 0x0380 /* mask request type */ ++#define CIFS_ECHO_OP 0x080 /* echo request */ ++#define CIFS_OBREAK_OP 0x0100 /* oplock break request */ ++#define CIFS_NEG_OP 0x0200 /* negotiate request */ ++#define CIFS_CP_CREATE_CLOSE_OP 0x0400 /* compound create+close request */ ++#define CIFS_OP_MASK 0x0780 /* mask request type */ + + #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ + #define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index ad3ecda1314d9..fa359f473e3db 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2629,6 +2629,11 @@ smbd_connected: + tcp_ses->min_offload = volume_info->min_offload; + tcp_ses->tcpStatus = CifsNeedNegotiate; + ++ if ((volume_info->max_credits < 20) || (volume_info->max_credits > 60000)) ++ tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; ++ else ++ tcp_ses->max_credits = volume_info->max_credits; ++ + tcp_ses->nr_targets = 1; + tcp_ses->ignore_signature = volume_info->ignore_signature; + /* thread spawned, put it on the list */ +@@ -4077,11 +4082,6 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, + + *nserver = server; + +- if ((vol->max_credits < 20) || (vol->max_credits > 60000)) +- server->max_credits = SMB2_MAX_CREDITS_AVAILABLE; +- else +- server->max_credits = vol->max_credits; +- + /* get a reference to a SMB session */ + ses = cifs_get_smb_ses(server, vol); + if (IS_ERR(ses)) { +diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c +index de564368a887c..c2fe85ca2ded3 100644 +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -224,6 +224,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) + vol.noautotune = ses->server->noautotune; + vol.sockopt_tcp_nodelay = ses->server->tcp_nodelay; + vol.echo_interval = ses->server->echo_interval / HZ; ++ vol.max_credits = ses->server->max_credits; + + /* + * This will be used for encoding/decoding user/domain/pw +diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c +index 1f900b81c34ae..a718dc77e604e 100644 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -358,6 +358,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + if (cfile) + goto after_close; + /* Close */ ++ flags |= CIFS_CP_CREATE_CLOSE_OP; + rqst[num_rqst].rq_iov = &vars->close_iov[0]; + rqst[num_rqst].rq_nvec = 1; + rc = SMB2_close_init(tcon, server, +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index 2da6b41cb5526..db22d686c61ff 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -835,14 +835,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, + } + + int +-smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) ++smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server) + { +- struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; +- struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; ++ struct smb2_sync_hdr *sync_hdr = mid->resp_buf; ++ struct smb2_create_rsp *rsp = mid->resp_buf; + struct cifs_tcon *tcon; + int rc; + +- if (sync_hdr->Command != SMB2_CREATE || ++ if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE || + sync_hdr->Status != STATUS_SUCCESS) + return 0; + +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 22f1d8dc12b00..02998c79bb907 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1137,7 +1137,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + struct TCP_Server_Info *server = cifs_pick_channel(ses); + __le16 *utf16_path = NULL; + int ea_name_len = strlen(ea_name); +- int flags = 0; ++ int flags = CIFS_CP_CREATE_CLOSE_OP; + int len; + struct smb_rqst rqst[3]; + int resp_buftype[3]; +@@ -1515,7 +1515,7 @@ smb2_ioctl_query_info(const unsigned int xid, + struct smb_query_info qi; + struct smb_query_info __user *pqi; + int rc = 0; +- int flags = 0; ++ int flags = CIFS_CP_CREATE_CLOSE_OP; + struct smb2_query_info_rsp *qi_rsp = NULL; + struct smb2_ioctl_rsp *io_rsp = NULL; + void *buffer = NULL; +@@ -2482,7 +2482,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, + { + struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = cifs_pick_channel(ses); +- int flags = 0; ++ int flags = CIFS_CP_CREATE_CLOSE_OP; + struct smb_rqst rqst[3]; + int resp_buftype[3]; + struct kvec rsp_iov[3]; +@@ -2880,7 +2880,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, + unsigned int sub_offset; + unsigned int print_len; + unsigned int print_offset; +- int flags = 0; ++ int flags = CIFS_CP_CREATE_CLOSE_OP; + struct smb_rqst rqst[3]; + int resp_buftype[3]; + struct kvec rsp_iov[3]; +@@ -3062,7 +3062,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_open_parms oparms; + struct cifs_fid fid; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); +- int flags = 0; ++ int flags = CIFS_CP_CREATE_CLOSE_OP; + struct smb_rqst rqst[3]; + int resp_buftype[3]; + struct kvec rsp_iov[3]; +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index d4110447ee3a8..4eb0ca84355a6 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -246,8 +246,7 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, + extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, + __u64 persistent_fid, + __u64 volatile_fid); +-extern int smb2_handle_cancelled_mid(char *buffer, +- struct TCP_Server_Info *server); ++extern int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server); + void smb2_cancelled_close_fid(struct work_struct *work); + extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id, +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 9391cd17a2b55..0b9f1a0cba1a3 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -101,7 +101,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) + if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && + midEntry->mid_state == MID_RESPONSE_RECEIVED && + server->ops->handle_cancelled_mid) +- server->ops->handle_cancelled_mid(midEntry->resp_buf, server); ++ server->ops->handle_cancelled_mid(midEntry, server); + + midEntry->mid_state = MID_FREE; + atomic_dec(&midCount); +diff --git a/fs/configfs/file.c b/fs/configfs/file.c +index 1f0270229d7b7..da8351d1e4552 100644 +--- a/fs/configfs/file.c ++++ b/fs/configfs/file.c +@@ -378,7 +378,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type + + attr = to_attr(dentry); + if (!attr) +- goto out_put_item; ++ goto out_free_buffer; + + if (type & CONFIGFS_ITEM_BIN_ATTR) { + buffer->bin_attr = to_bin_attr(dentry); +@@ -391,7 +391,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type + /* Grab the module reference for this attribute if we have one */ + error = -ENODEV; + if (!try_module_get(buffer->owner)) +- goto out_put_item; ++ goto out_free_buffer; + + error = -EACCES; + if (!buffer->item->ci_type) +@@ -435,8 +435,6 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type + + out_put_module: + module_put(buffer->owner); +-out_put_item: +- config_item_put(buffer->item); + out_free_buffer: + up_read(&frag->frag_sem); + kfree(buffer); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index ea5aefa23a20a..e30bf8f342c2a 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4876,7 +4876,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + + set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); + +- sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; + sbi->s_journal->j_submit_inode_data_buffers = + ext4_journal_submit_inode_data_buffers; + sbi->s_journal->j_finish_inode_data_buffers = +@@ -4993,6 +4992,14 @@ no_journal: + goto failed_mount5; + } + ++ /* ++ * We can only set up the journal commit callback once ++ * mballoc is initialized ++ */ ++ if (sbi->s_journal) ++ sbi->s_journal->j_commit_callback = ++ ext4_journal_commit_callback; ++ + block = ext4_count_free_clusters(sb); + ext4_free_blocks_count_set(sbi->s_es, + EXT4_C2B(sbi, block)); +diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c +index 4e011adaf9670..c837675cd395a 100644 +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1202,6 +1202,15 @@ out_force: + goto out; + } + ++static void nfs_mark_dir_for_revalidate(struct inode *inode) ++{ ++ struct nfs_inode *nfsi = NFS_I(inode); ++ ++ spin_lock(&inode->i_lock); ++ nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; ++ spin_unlock(&inode->i_lock); ++} ++ + /* + * We judge how long we want to trust negative + * dentries by looking at the parent inode mtime. +@@ -1236,19 +1245,14 @@ nfs_lookup_revalidate_done(struct inode *dir, struct dentry *dentry, + __func__, dentry); + return 1; + case 0: +- nfs_mark_for_revalidate(dir); +- if (inode && S_ISDIR(inode->i_mode)) { +- /* Purge readdir caches. */ +- nfs_zap_caches(inode); +- /* +- * We can't d_drop the root of a disconnected tree: +- * its d_hash is on the s_anon list and d_drop() would hide +- * it from shrink_dcache_for_unmount(), leading to busy +- * inodes on unmount and further oopses. +- */ +- if (IS_ROOT(dentry)) +- return 1; +- } ++ /* ++ * We can't d_drop the root of a disconnected tree: ++ * its d_hash is on the s_anon list and d_drop() would hide ++ * it from shrink_dcache_for_unmount(), leading to busy ++ * inodes on unmount and further oopses. ++ */ ++ if (inode && IS_ROOT(dentry)) ++ return 1; + dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", + __func__, dentry); + return 0; +@@ -1326,6 +1330,13 @@ out: + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); + nfs4_label_free(label); ++ ++ /* ++ * If the lookup failed despite the dentry change attribute being ++ * a match, then we should revalidate the directory cache. ++ */ ++ if (!ret && nfs_verify_change_attribute(dir, dentry->d_time)) ++ nfs_mark_dir_for_revalidate(dir); + return nfs_lookup_revalidate_done(dir, dentry, inode, ret); + } + +@@ -1368,7 +1379,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, + error = nfs_lookup_verify_inode(inode, flags); + if (error) { + if (error == -ESTALE) +- nfs_zap_caches(dir); ++ nfs_mark_dir_for_revalidate(dir); + goto out_bad; + } + nfs_advise_use_readdirplus(dir); +@@ -1865,7 +1876,6 @@ out: + dput(parent); + return d; + out_error: +- nfs_mark_for_revalidate(dir); + d = ERR_PTR(error); + goto out; + } +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index a811d42ffbd11..ba2dfba4854bf 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5967,7 +5967,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf, + return ret; + if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) + return -ENOENT; +- return 0; ++ return label.len; + } + + static int nfs4_get_security_label(struct inode *inode, void *buf, +diff --git a/fs/pnode.h b/fs/pnode.h +index 26f74e092bd98..988f1aa9b02ae 100644 +--- a/fs/pnode.h ++++ b/fs/pnode.h +@@ -12,7 +12,7 @@ + + #define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) + #define IS_MNT_SLAVE(m) ((m)->mnt_master) +-#define IS_MNT_NEW(m) (!(m)->mnt_ns) ++#define IS_MNT_NEW(m) (!(m)->mnt_ns || is_anon_ns((m)->mnt_ns)) + #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) + #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) + #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED) +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index bb89c3e43212b..0dd2f93ac0480 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -544,11 +544,14 @@ static int udf_do_extend_file(struct inode *inode, + + udf_write_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); ++ + /* +- * We've rewritten the last extent but there may be empty +- * indirect extent after it - enter it. ++ * We've rewritten the last extent. If we are going to add ++ * more extents, we may need to enter possible following ++ * empty indirect extent. + */ +- udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); ++ if (new_block_bytes || prealloc_len) ++ udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + } + + /* Managed to do everything necessary? */ +diff --git a/include/linux/acpi.h b/include/linux/acpi.h +index 5b1dc1ad4fb32..9e173c6f312dc 100644 +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -1072,19 +1072,25 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c + #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) + bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, + struct acpi_resource_gpio **agpio); +-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index); ++int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index); + #else + static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, + struct acpi_resource_gpio **agpio) + { + return false; + } +-static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) ++static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, ++ const char *name, int index) + { + return -ENXIO; + } + #endif + ++static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) ++{ ++ return acpi_dev_gpio_irq_get_by(adev, NULL, index); ++} ++ + /* Device properties */ + + #ifdef CONFIG_ACPI +diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h +index fc61cf4eff1c9..ce7393d397e18 100644 +--- a/include/linux/can/skb.h ++++ b/include/linux/can/skb.h +@@ -49,8 +49,12 @@ static inline void can_skb_reserve(struct sk_buff *skb) + + static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) + { +- if (sk) { +- sock_hold(sk); ++ /* If the socket has already been closed by user space, the ++ * refcount may already be 0 (and the socket will be freed ++ * after the last TX skb has been freed). So only increase ++ * socket refcount if the refcount is > 0. ++ */ ++ if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { + skb->destructor = sock_efree; + skb->sk = sk; + } +diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h +index 98cff1b4b088c..189149de77a9d 100644 +--- a/include/linux/compiler-clang.h ++++ b/include/linux/compiler-clang.h +@@ -41,6 +41,12 @@ + #define __no_sanitize_thread + #endif + ++#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) ++#define __HAVE_BUILTIN_BSWAP32__ ++#define __HAVE_BUILTIN_BSWAP64__ ++#define __HAVE_BUILTIN_BSWAP16__ ++#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ ++ + #if __has_feature(undefined_behavior_sanitizer) + /* GCC does not have __SANITIZE_UNDEFINED__ */ + #define __no_sanitize_undefined \ +diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h +index 474f29638d2c9..7dff07713a073 100644 +--- a/include/linux/entry-common.h ++++ b/include/linux/entry-common.h +@@ -341,8 +341,26 @@ void irqentry_enter_from_user_mode(struct pt_regs *regs); + void irqentry_exit_to_user_mode(struct pt_regs *regs); + + #ifndef irqentry_state ++/** ++ * struct irqentry_state - Opaque object for exception state storage ++ * @exit_rcu: Used exclusively in the irqentry_*() calls; signals whether the ++ * exit path has to invoke rcu_irq_exit(). ++ * @lockdep: Used exclusively in the irqentry_nmi_*() calls; ensures that ++ * lockdep state is restored correctly on exit from nmi. ++ * ++ * This opaque object is filled in by the irqentry_*_enter() functions and ++ * must be passed back into the corresponding irqentry_*_exit() functions ++ * when the exception is complete. ++ * ++ * Callers of irqentry_*_[enter|exit]() must consider this structure opaque ++ * and all members private. Descriptions of the members are provided to aid in ++ * the maintenance of the irqentry_*() functions. ++ */ + typedef struct irqentry_state { +- bool exit_rcu; ++ union { ++ bool exit_rcu; ++ bool lockdep; ++ }; + } irqentry_state_t; + #endif + +@@ -402,4 +420,23 @@ void irqentry_exit_cond_resched(void); + */ + void noinstr irqentry_exit(struct pt_regs *regs, irqentry_state_t state); + ++/** ++ * irqentry_nmi_enter - Handle NMI entry ++ * @regs: Pointer to currents pt_regs ++ * ++ * Similar to irqentry_enter() but taking care of the NMI constraints. ++ */ ++irqentry_state_t noinstr irqentry_nmi_enter(struct pt_regs *regs); ++ ++/** ++ * irqentry_nmi_exit - Handle return from NMI handling ++ * @regs: Pointer to pt_regs (NMI entry regs) ++ * @irq_state: Return value from matching call to irqentry_nmi_enter() ++ * ++ * Last action before returning to the low level assmenbly code. ++ * ++ * Counterpart to irqentry_nmi_enter(). ++ */ ++void noinstr irqentry_nmi_exit(struct pt_regs *regs, irqentry_state_t irq_state); ++ + #endif +diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h +index 901aab89d025f..79f450e93abfd 100644 +--- a/include/linux/gpio/consumer.h ++++ b/include/linux/gpio/consumer.h +@@ -674,6 +674,8 @@ struct acpi_gpio_mapping { + * get GpioIo type explicitly, this quirk may be used. + */ + #define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1) ++/* Use given pin as an absolute GPIO number in the system */ ++#define ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER BIT(2) + + unsigned int quirks; + }; +diff --git a/include/linux/memory.h b/include/linux/memory.h +index 439a89e758d87..4da95e684e20f 100644 +--- a/include/linux/memory.h ++++ b/include/linux/memory.h +@@ -27,9 +27,8 @@ struct memory_block { + unsigned long start_section_nr; + unsigned long state; /* serialized by the dev->lock */ + int online_type; /* for passing data to online routine */ +- int phys_device; /* to which fru does this belong? */ +- struct device dev; + int nid; /* NID for this memory block */ ++ struct device dev; + }; + + int arch_get_memory_phys_device(unsigned long start_pfn); +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 96450f6fb1de8..22ce0604b4480 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -606,6 +606,7 @@ struct swevent_hlist { + #define PERF_ATTACH_TASK 0x04 + #define PERF_ATTACH_TASK_DATA 0x08 + #define PERF_ATTACH_ITRACE 0x10 ++#define PERF_ATTACH_SCHED_CB 0x20 + + struct perf_cgroup; + struct perf_buffer; +@@ -872,6 +873,7 @@ struct perf_cpu_context { + struct list_head cgrp_cpuctx_entry; + #endif + ++ struct list_head sched_cb_entry; + int sched_cb_usage; + + int online; +diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h +index e237004d498d6..7c869ea8dffc8 100644 +--- a/include/linux/pgtable.h ++++ b/include/linux/pgtable.h +@@ -857,6 +857,10 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma, + #define pgprot_device pgprot_noncached + #endif + ++#ifndef pgprot_mhp ++#define pgprot_mhp(prot) (prot) ++#endif ++ + #ifdef CONFIG_MMU + #ifndef pgprot_modify + #define pgprot_modify pgprot_modify +diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h +index d5ece7a9a403f..dc1f4dcd9a825 100644 +--- a/include/linux/sched/mm.h ++++ b/include/linux/sched/mm.h +@@ -140,7 +140,8 @@ static inline bool in_vfork(struct task_struct *tsk) + * another oom-unkillable task does this it should blame itself. + */ + rcu_read_lock(); +- ret = tsk->vfork_done && tsk->real_parent->mm == tsk->mm; ++ ret = tsk->vfork_done && ++ rcu_dereference(tsk->real_parent)->mm == tsk->mm; + rcu_read_unlock(); + + return ret; +diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h +index cbfc78b92b654..1ac20d75b0618 100644 +--- a/include/linux/seqlock.h ++++ b/include/linux/seqlock.h +@@ -659,10 +659,7 @@ typedef struct { + * seqcount_latch_init() - runtime initializer for seqcount_latch_t + * @s: Pointer to the seqcount_latch_t instance + */ +-static inline void seqcount_latch_init(seqcount_latch_t *s) +-{ +- seqcount_init(&s->seqcount); +-} ++#define seqcount_latch_init(s) seqcount_init(&(s)->seqcount) + + /** + * raw_read_seqcount_latch() - pick even/odd latch data copy +diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h +index 76d8b09384a7a..63ea9aff368f0 100644 +--- a/include/linux/stop_machine.h ++++ b/include/linux/stop_machine.h +@@ -123,7 +123,7 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, + const struct cpumask *cpus); + #else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */ + +-static inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, ++static __always_inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, + const struct cpumask *cpus) + { + unsigned long flags; +@@ -134,14 +134,15 @@ static inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, + return ret; + } + +-static inline int stop_machine(cpu_stop_fn_t fn, void *data, +- const struct cpumask *cpus) ++static __always_inline int ++stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus) + { + return stop_machine_cpuslocked(fn, data, cpus); + } + +-static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, +- const struct cpumask *cpus) ++static __always_inline int ++stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, ++ const struct cpumask *cpus) + { + return stop_machine(fn, data, cpus); + } +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 7d72c4e0713c1..d6a41841b93e4 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -746,6 +746,8 @@ extern int usb_lock_device_for_reset(struct usb_device *udev, + extern int usb_reset_device(struct usb_device *dev); + extern void usb_queue_reset_device(struct usb_interface *dev); + ++extern struct device *usb_intf_get_dma_device(struct usb_interface *intf); ++ + #ifdef CONFIG_ACPI + extern int usb_acpi_set_power_state(struct usb_device *hdev, int index, + bool enable); +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index e8a924eeea3d0..6b5fcfa1e5553 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -79,8 +79,13 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + if (gso_type && skb->network_header) { + struct flow_keys_basic keys; + +- if (!skb->protocol) ++ if (!skb->protocol) { ++ __be16 protocol = dev_parse_header_protocol(skb); ++ + virtio_net_hdr_set_proto(skb, hdr); ++ if (protocol && protocol != skb->protocol) ++ return -EINVAL; ++ } + retry: + if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, + NULL, 0, 0, 0, +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 7dbb91c601a77..c3effcdf2a641 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -175,6 +175,13 @@ struct rc_map_list { + struct rc_map map; + }; + ++#ifdef CONFIG_MEDIA_CEC_RC ++/* ++ * rc_map_list from rc-cec.c ++ */ ++extern struct rc_map_list cec_map; ++#endif ++ + /* Routines from rc-map.c */ + + /** +diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h +index 6336780d83a75..ce2fba49c95da 100644 +--- a/include/target/target_core_backend.h ++++ b/include/target/target_core_backend.h +@@ -72,6 +72,7 @@ int transport_backend_register(const struct target_backend_ops *); + void target_backend_unregister(const struct target_backend_ops *); + + void target_complete_cmd(struct se_cmd *, u8); ++void target_set_cmd_data_length(struct se_cmd *, int); + void target_complete_cmd_with_length(struct se_cmd *, u8, int); + + void transport_copy_sense_to_cmd(struct se_cmd *, unsigned char *); +diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h +index 30c80d5ba4bfc..bab8c97086111 100644 +--- a/include/uapi/linux/l2tp.h ++++ b/include/uapi/linux/l2tp.h +@@ -145,6 +145,7 @@ enum { + L2TP_ATTR_RX_ERRORS, /* u64 */ + L2TP_ATTR_STATS_PAD, + L2TP_ATTR_RX_COOKIE_DISCARDS, /* u64 */ ++ L2TP_ATTR_RX_INVALID, /* u64 */ + __L2TP_ATTR_STATS_MAX, + }; + +diff --git a/include/uapi/linux/netfilter/nfnetlink_cthelper.h b/include/uapi/linux/netfilter/nfnetlink_cthelper.h +index a13137afc4299..70af02092d16e 100644 +--- a/include/uapi/linux/netfilter/nfnetlink_cthelper.h ++++ b/include/uapi/linux/netfilter/nfnetlink_cthelper.h +@@ -5,7 +5,7 @@ + #define NFCT_HELPER_STATUS_DISABLED 0 + #define NFCT_HELPER_STATUS_ENABLED 1 + +-enum nfnl_acct_msg_types { ++enum nfnl_cthelper_msg_types { + NFNL_MSG_CTHELPER_NEW, + NFNL_MSG_CTHELPER_GET, + NFNL_MSG_CTHELPER_DEL, +diff --git a/kernel/entry/common.c b/kernel/entry/common.c +index e9e2df3f3f9ee..e289e67732926 100644 +--- a/kernel/entry/common.c ++++ b/kernel/entry/common.c +@@ -397,3 +397,39 @@ noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state) + rcu_irq_exit(); + } + } ++ ++irqentry_state_t noinstr irqentry_nmi_enter(struct pt_regs *regs) ++{ ++ irqentry_state_t irq_state; ++ ++ irq_state.lockdep = lockdep_hardirqs_enabled(); ++ ++ __nmi_enter(); ++ lockdep_hardirqs_off(CALLER_ADDR0); ++ lockdep_hardirq_enter(); ++ rcu_nmi_enter(); ++ ++ instrumentation_begin(); ++ trace_hardirqs_off_finish(); ++ ftrace_nmi_enter(); ++ instrumentation_end(); ++ ++ return irq_state; ++} ++ ++void noinstr irqentry_nmi_exit(struct pt_regs *regs, irqentry_state_t irq_state) ++{ ++ instrumentation_begin(); ++ ftrace_nmi_exit(); ++ if (irq_state.lockdep) { ++ trace_hardirqs_on_prepare(); ++ lockdep_hardirqs_on_prepare(CALLER_ADDR0); ++ } ++ instrumentation_end(); ++ ++ rcu_nmi_exit(); ++ lockdep_hardirq_exit(); ++ if (irq_state.lockdep) ++ lockdep_hardirqs_on(CALLER_ADDR0); ++ __nmi_exit(); ++} +diff --git a/kernel/events/core.c b/kernel/events/core.c +index c3ba29d058b73..4af161b3f322f 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -383,6 +383,7 @@ static DEFINE_MUTEX(perf_sched_mutex); + static atomic_t perf_sched_count; + + static DEFINE_PER_CPU(atomic_t, perf_cgroup_events); ++static DEFINE_PER_CPU(int, perf_sched_cb_usages); + static DEFINE_PER_CPU(struct pmu_event_list, pmu_sb_events); + + static atomic_t nr_mmap_events __read_mostly; +@@ -3466,11 +3467,16 @@ unlock: + } + } + ++static DEFINE_PER_CPU(struct list_head, sched_cb_list); ++ + void perf_sched_cb_dec(struct pmu *pmu) + { + struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); + +- --cpuctx->sched_cb_usage; ++ this_cpu_dec(perf_sched_cb_usages); ++ ++ if (!--cpuctx->sched_cb_usage) ++ list_del(&cpuctx->sched_cb_entry); + } + + +@@ -3478,7 +3484,10 @@ void perf_sched_cb_inc(struct pmu *pmu) + { + struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); + +- cpuctx->sched_cb_usage++; ++ if (!cpuctx->sched_cb_usage++) ++ list_add(&cpuctx->sched_cb_entry, this_cpu_ptr(&sched_cb_list)); ++ ++ this_cpu_inc(perf_sched_cb_usages); + } + + /* +@@ -3507,6 +3516,24 @@ static void __perf_pmu_sched_task(struct perf_cpu_context *cpuctx, bool sched_in + perf_ctx_unlock(cpuctx, cpuctx->task_ctx); + } + ++static void perf_pmu_sched_task(struct task_struct *prev, ++ struct task_struct *next, ++ bool sched_in) ++{ ++ struct perf_cpu_context *cpuctx; ++ ++ if (prev == next) ++ return; ++ ++ list_for_each_entry(cpuctx, this_cpu_ptr(&sched_cb_list), sched_cb_entry) { ++ /* will be handled in perf_event_context_sched_in/out */ ++ if (cpuctx->task_ctx) ++ continue; ++ ++ __perf_pmu_sched_task(cpuctx, sched_in); ++ } ++} ++ + static void perf_event_switch(struct task_struct *task, + struct task_struct *next_prev, bool sched_in); + +@@ -3529,6 +3556,9 @@ void __perf_event_task_sched_out(struct task_struct *task, + { + int ctxn; + ++ if (__this_cpu_read(perf_sched_cb_usages)) ++ perf_pmu_sched_task(task, next, false); ++ + if (atomic_read(&nr_switch_events)) + perf_event_switch(task, next, false); + +@@ -3837,6 +3867,9 @@ void __perf_event_task_sched_in(struct task_struct *prev, + + if (atomic_read(&nr_switch_events)) + perf_event_switch(task, prev, true); ++ ++ if (__this_cpu_read(perf_sched_cb_usages)) ++ perf_pmu_sched_task(prev, task, true); + } + + static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count) +@@ -4661,7 +4694,7 @@ static void unaccount_event(struct perf_event *event) + if (event->parent) + return; + +- if (event->attach_state & PERF_ATTACH_TASK) ++ if (event->attach_state & (PERF_ATTACH_TASK | PERF_ATTACH_SCHED_CB)) + dec = true; + if (event->attr.mmap || event->attr.mmap_data) + atomic_dec(&nr_mmap_events); +@@ -11056,7 +11089,7 @@ static void account_event(struct perf_event *event) + if (event->parent) + return; + +- if (event->attach_state & PERF_ATTACH_TASK) ++ if (event->attach_state & (PERF_ATTACH_TASK | PERF_ATTACH_SCHED_CB)) + inc = true; + if (event->attr.mmap || event->attr.mmap_data) + atomic_inc(&nr_mmap_events); +@@ -12848,6 +12881,7 @@ static void __init perf_event_init_all_cpus(void) + #ifdef CONFIG_CGROUP_PERF + INIT_LIST_HEAD(&per_cpu(cgrp_cpuctx_list, cpu)); + #endif ++ INIT_LIST_HEAD(&per_cpu(sched_cb_list, cpu)); + } + } + +diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c +index 9d8df34bea75b..16f57e71f9c44 100644 +--- a/kernel/sched/membarrier.c ++++ b/kernel/sched/membarrier.c +@@ -332,9 +332,7 @@ static int sync_runqueues_membarrier_state(struct mm_struct *mm) + } + rcu_read_unlock(); + +- preempt_disable(); +- smp_call_function_many(tmpmask, ipi_sync_rq_state, mm, 1); +- preempt_enable(); ++ on_each_cpu_mask(tmpmask, ipi_sync_rq_state, mm, true); + + free_cpumask_var(tmpmask); + cpus_read_unlock(); +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index afad085960b81..b9306d2bb4269 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -2951,7 +2951,7 @@ static struct ctl_table vm_table[] = { + .data = &block_dump, + .maxlen = sizeof(block_dump), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + }, + { +@@ -2959,7 +2959,7 @@ static struct ctl_table vm_table[] = { + .data = &sysctl_vfs_cache_pressure, + .maxlen = sizeof(sysctl_vfs_cache_pressure), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + }, + #if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \ +@@ -2969,7 +2969,7 @@ static struct ctl_table vm_table[] = { + .data = &sysctl_legacy_va_layout, + .maxlen = sizeof(sysctl_legacy_va_layout), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + }, + #endif +@@ -2979,7 +2979,7 @@ static struct ctl_table vm_table[] = { + .data = &node_reclaim_mode, + .maxlen = sizeof(node_reclaim_mode), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + }, + { +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 387b4bef7dd14..4416f5d72c11e 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -546,8 +546,11 @@ static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, + } + + /* +- * Recomputes cpu_base::*next_timer and returns the earliest expires_next but +- * does not set cpu_base::*expires_next, that is done by hrtimer_reprogram. ++ * Recomputes cpu_base::*next_timer and returns the earliest expires_next ++ * but does not set cpu_base::*expires_next, that is done by ++ * hrtimer[_force]_reprogram and hrtimer_interrupt only. When updating ++ * cpu_base::*expires_next right away, reprogramming logic would no longer ++ * work. + * + * When a softirq is pending, we can ignore the HRTIMER_ACTIVE_SOFT bases, + * those timers will get run whenever the softirq gets handled, at the end of +@@ -588,6 +591,37 @@ __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_ + return expires_next; + } + ++static ktime_t hrtimer_update_next_event(struct hrtimer_cpu_base *cpu_base) ++{ ++ ktime_t expires_next, soft = KTIME_MAX; ++ ++ /* ++ * If the soft interrupt has already been activated, ignore the ++ * soft bases. They will be handled in the already raised soft ++ * interrupt. ++ */ ++ if (!cpu_base->softirq_activated) { ++ soft = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_SOFT); ++ /* ++ * Update the soft expiry time. clock_settime() might have ++ * affected it. ++ */ ++ cpu_base->softirq_expires_next = soft; ++ } ++ ++ expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_HARD); ++ /* ++ * If a softirq timer is expiring first, update cpu_base->next_timer ++ * and program the hardware with the soft expiry time. ++ */ ++ if (expires_next > soft) { ++ cpu_base->next_timer = cpu_base->softirq_next_timer; ++ expires_next = soft; ++ } ++ ++ return expires_next; ++} ++ + static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) + { + ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset; +@@ -628,23 +662,7 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) + { + ktime_t expires_next; + +- /* +- * Find the current next expiration time. +- */ +- expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL); +- +- if (cpu_base->next_timer && cpu_base->next_timer->is_soft) { +- /* +- * When the softirq is activated, hrtimer has to be +- * programmed with the first hard hrtimer because soft +- * timer interrupt could occur too late. +- */ +- if (cpu_base->softirq_activated) +- expires_next = __hrtimer_get_next_event(cpu_base, +- HRTIMER_ACTIVE_HARD); +- else +- cpu_base->softirq_expires_next = expires_next; +- } ++ expires_next = hrtimer_update_next_event(cpu_base); + + if (skip_equal && expires_next == cpu_base->expires_next) + return; +@@ -1644,8 +1662,8 @@ retry: + + __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); + +- /* Reevaluate the clock bases for the next expiry */ +- expires_next = __hrtimer_get_next_event(cpu_base, HRTIMER_ACTIVE_ALL); ++ /* Reevaluate the clock bases for the [soft] next expiry */ ++ expires_next = hrtimer_update_next_event(cpu_base); + /* + * Store the new expiry value so the migration code can verify + * against it. +diff --git a/lib/logic_pio.c b/lib/logic_pio.c +index f32fe481b4922..07b4b9a1f54b6 100644 +--- a/lib/logic_pio.c ++++ b/lib/logic_pio.c +@@ -28,6 +28,8 @@ static DEFINE_MUTEX(io_range_mutex); + * @new_range: pointer to the IO range to be registered. + * + * Returns 0 on success, the error code in case of failure. ++ * If the range already exists, -EEXIST will be returned, which should be ++ * considered a success. + * + * Register a new IO range node in the IO range list. + */ +@@ -51,6 +53,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) + list_for_each_entry(range, &io_range_list, list) { + if (range->fwnode == new_range->fwnode) { + /* range already there */ ++ ret = -EEXIST; + goto end_register; + } + if (range->flags == LOGIC_PIO_CPU_MMIO && +diff --git a/lib/test_kasan.c b/lib/test_kasan.c +index 662f862702fc8..400507f1e5db0 100644 +--- a/lib/test_kasan.c ++++ b/lib/test_kasan.c +@@ -737,13 +737,13 @@ static void kasan_bitops_tags(struct kunit *test) + return; + } + +- /* Allocation size will be rounded to up granule size, which is 16. */ +- bits = kzalloc(sizeof(*bits), GFP_KERNEL); ++ /* kmalloc-64 cache will be used and the last 16 bytes will be the redzone. */ ++ bits = kzalloc(48, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bits); + +- /* Do the accesses past the 16 allocated bytes. */ +- kasan_bitops_modify(test, BITS_PER_LONG, &bits[1]); +- kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, &bits[1]); ++ /* Do the accesses past the 48 allocated bytes, but within the redone. */ ++ kasan_bitops_modify(test, BITS_PER_LONG, (void *)bits + 48); ++ kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, (void *)bits + 48); + + kfree(bits); + } +diff --git a/mm/madvise.c b/mm/madvise.c +index 9abf4c5f2bce2..24abc79f8914e 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -1202,12 +1202,22 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, + goto release_task; + } + +- mm = mm_access(task, PTRACE_MODE_ATTACH_FSCREDS); ++ /* Require PTRACE_MODE_READ to avoid leaking ASLR metadata. */ ++ mm = mm_access(task, PTRACE_MODE_READ_FSCREDS); + if (IS_ERR_OR_NULL(mm)) { + ret = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; + goto release_task; + } + ++ /* ++ * Require CAP_SYS_NICE for influencing process performance. Note that ++ * only non-destructive hints are currently supported. ++ */ ++ if (!capable(CAP_SYS_NICE)) { ++ ret = -EPERM; ++ goto release_mm; ++ } ++ + total_len = iov_iter_count(&iter); + + while (iov_iter_count(&iter)) { +@@ -1222,6 +1232,7 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, + if (ret == 0) + ret = total_len - iov_iter_count(&iter); + ++release_mm: + mmput(mm); + release_task: + put_task_struct(task); +diff --git a/mm/memory.c b/mm/memory.c +index 827d42f9ebf7c..4d565d7c80169 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -3090,6 +3090,14 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf) + return handle_userfault(vmf, VM_UFFD_WP); + } + ++ /* ++ * Userfaultfd write-protect can defer flushes. Ensure the TLB ++ * is flushed in this case before copying. ++ */ ++ if (unlikely(userfaultfd_wp(vmf->vma) && ++ mm_tlb_flush_pending(vmf->vma->vm_mm))) ++ flush_tlb_page(vmf->vma, vmf->address); ++ + vmf->page = vm_normal_page(vma, vmf->address, vmf->orig_pte); + if (!vmf->page) { + /* +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index aa453a4331437..b9de2df5b8358 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1020,7 +1020,7 @@ static int online_memory_block(struct memory_block *mem, void *arg) + */ + int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags) + { +- struct mhp_params params = { .pgprot = PAGE_KERNEL }; ++ struct mhp_params params = { .pgprot = pgprot_mhp(PAGE_KERNEL) }; + u64 start, size; + bool new_node = false; + int ret; +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 88639706ae177..690f79c781cf7 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -6189,13 +6189,66 @@ static void __meminit zone_init_free_lists(struct zone *zone) + } + } + ++#if !defined(CONFIG_FLAT_NODE_MEM_MAP) ++/* ++ * Only struct pages that correspond to ranges defined by memblock.memory ++ * are zeroed and initialized by going through __init_single_page() during ++ * memmap_init_zone(). ++ * ++ * But, there could be struct pages that correspond to holes in ++ * memblock.memory. This can happen because of the following reasons: ++ * - physical memory bank size is not necessarily the exact multiple of the ++ * arbitrary section size ++ * - early reserved memory may not be listed in memblock.memory ++ * - memory layouts defined with memmap= kernel parameter may not align ++ * nicely with memmap sections ++ * ++ * Explicitly initialize those struct pages so that: ++ * - PG_Reserved is set ++ * - zone and node links point to zone and node that span the page if the ++ * hole is in the middle of a zone ++ * - zone and node links point to adjacent zone/node if the hole falls on ++ * the zone boundary; the pages in such holes will be prepended to the ++ * zone/node above the hole except for the trailing pages in the last ++ * section that will be appended to the zone/node below. ++ */ ++static u64 __meminit init_unavailable_range(unsigned long spfn, ++ unsigned long epfn, ++ int zone, int node) ++{ ++ unsigned long pfn; ++ u64 pgcnt = 0; ++ ++ for (pfn = spfn; pfn < epfn; pfn++) { ++ if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) { ++ pfn = ALIGN_DOWN(pfn, pageblock_nr_pages) ++ + pageblock_nr_pages - 1; ++ continue; ++ } ++ __init_single_page(pfn_to_page(pfn), pfn, zone, node); ++ __SetPageReserved(pfn_to_page(pfn)); ++ pgcnt++; ++ } ++ ++ return pgcnt; ++} ++#else ++static inline u64 init_unavailable_range(unsigned long spfn, unsigned long epfn, ++ int zone, int node) ++{ ++ return 0; ++} ++#endif ++ + void __meminit __weak memmap_init(unsigned long size, int nid, + unsigned long zone, + unsigned long range_start_pfn) + { ++ static unsigned long hole_pfn; + unsigned long start_pfn, end_pfn; + unsigned long range_end_pfn = range_start_pfn + size; + int i; ++ u64 pgcnt = 0; + + for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) { + start_pfn = clamp(start_pfn, range_start_pfn, range_end_pfn); +@@ -6206,7 +6259,29 @@ void __meminit __weak memmap_init(unsigned long size, int nid, + memmap_init_zone(size, nid, zone, start_pfn, range_end_pfn, + MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); + } ++ ++ if (hole_pfn < start_pfn) ++ pgcnt += init_unavailable_range(hole_pfn, start_pfn, ++ zone, nid); ++ hole_pfn = end_pfn; + } ++ ++#ifdef CONFIG_SPARSEMEM ++ /* ++ * Initialize the hole in the range [zone_end_pfn, section_end]. ++ * If zone boundary falls in the middle of a section, this hole ++ * will be re-initialized during the call to this function for the ++ * higher zone. ++ */ ++ end_pfn = round_up(range_end_pfn, PAGES_PER_SECTION); ++ if (hole_pfn < end_pfn) ++ pgcnt += init_unavailable_range(hole_pfn, end_pfn, ++ zone, nid); ++#endif ++ ++ if (pgcnt) ++ pr_info(" %s zone: %llu pages in unavailable ranges\n", ++ zone_names[zone], pgcnt); + } + + static int zone_batchsize(struct zone *zone) +@@ -6999,88 +7074,6 @@ void __init free_area_init_memoryless_node(int nid) + free_area_init_node(nid); + } + +-#if !defined(CONFIG_FLAT_NODE_MEM_MAP) +-/* +- * Initialize all valid struct pages in the range [spfn, epfn) and mark them +- * PageReserved(). Return the number of struct pages that were initialized. +- */ +-static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn) +-{ +- unsigned long pfn; +- u64 pgcnt = 0; +- +- for (pfn = spfn; pfn < epfn; pfn++) { +- if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) { +- pfn = ALIGN_DOWN(pfn, pageblock_nr_pages) +- + pageblock_nr_pages - 1; +- continue; +- } +- /* +- * Use a fake node/zone (0) for now. Some of these pages +- * (in memblock.reserved but not in memblock.memory) will +- * get re-initialized via reserve_bootmem_region() later. +- */ +- __init_single_page(pfn_to_page(pfn), pfn, 0, 0); +- __SetPageReserved(pfn_to_page(pfn)); +- pgcnt++; +- } +- +- return pgcnt; +-} +- +-/* +- * Only struct pages that are backed by physical memory are zeroed and +- * initialized by going through __init_single_page(). But, there are some +- * struct pages which are reserved in memblock allocator and their fields +- * may be accessed (for example page_to_pfn() on some configuration accesses +- * flags). We must explicitly initialize those struct pages. +- * +- * This function also addresses a similar issue where struct pages are left +- * uninitialized because the physical address range is not covered by +- * memblock.memory or memblock.reserved. That could happen when memblock +- * layout is manually configured via memmap=, or when the highest physical +- * address (max_pfn) does not end on a section boundary. +- */ +-static void __init init_unavailable_mem(void) +-{ +- phys_addr_t start, end; +- u64 i, pgcnt; +- phys_addr_t next = 0; +- +- /* +- * Loop through unavailable ranges not covered by memblock.memory. +- */ +- pgcnt = 0; +- for_each_mem_range(i, &start, &end) { +- if (next < start) +- pgcnt += init_unavailable_range(PFN_DOWN(next), +- PFN_UP(start)); +- next = end; +- } +- +- /* +- * Early sections always have a fully populated memmap for the whole +- * section - see pfn_valid(). If the last section has holes at the +- * end and that section is marked "online", the memmap will be +- * considered initialized. Make sure that memmap has a well defined +- * state. +- */ +- pgcnt += init_unavailable_range(PFN_DOWN(next), +- round_up(max_pfn, PAGES_PER_SECTION)); +- +- /* +- * Struct pages that do not have backing memory. This could be because +- * firmware is using some of this memory, or for some other reasons. +- */ +- if (pgcnt) +- pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt); +-} +-#else +-static inline void __init init_unavailable_mem(void) +-{ +-} +-#endif /* !CONFIG_FLAT_NODE_MEM_MAP */ +- + #if MAX_NUMNODES > 1 + /* + * Figure out the number of possible node ids. +@@ -7504,7 +7497,6 @@ void __init free_area_init(unsigned long *max_zone_pfn) + /* Initialise every node */ + mminit_verify_pageflags_layout(); + setup_nr_node_ids(); +- init_unavailable_mem(); + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); + free_area_init_node(nid); +diff --git a/mm/slub.c b/mm/slub.c +index 7b378e2ce270d..fbc415c340095 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1971,7 +1971,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, + + t = acquire_slab(s, n, page, object == NULL, &objects); + if (!t) +- continue; /* cmpxchg raced */ ++ break; + + available += objects; + if (!object) { +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 3bc5ca40c9fbb..c6806eef906f9 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev) + } + EXPORT_SYMBOL_GPL(dsa_enqueue_skb); + ++static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev) ++{ ++ int needed_headroom = dev->needed_headroom; ++ int needed_tailroom = dev->needed_tailroom; ++ ++ /* For tail taggers, we need to pad short frames ourselves, to ensure ++ * that the tail tag does not fail at its role of being at the end of ++ * the packet, once the master interface pads the frame. Account for ++ * that pad length here, and pad later. ++ */ ++ if (unlikely(needed_tailroom && skb->len < ETH_ZLEN)) ++ needed_tailroom += ETH_ZLEN - skb->len; ++ /* skb_headroom() returns unsigned int... */ ++ needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0); ++ needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0); ++ ++ if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb))) ++ /* No reallocation needed, yay! */ ++ return 0; ++ ++ return pskb_expand_head(skb, needed_headroom, needed_tailroom, ++ GFP_ATOMIC); ++} ++ + static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct dsa_slave_priv *p = netdev_priv(dev); +@@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) + */ + dsa_skb_tx_timestamp(p, skb); + ++ if (dsa_realloc_skb(skb, dev)) { ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; ++ } ++ ++ /* needed_tailroom should still be 'warm' in the cache line from ++ * dsa_realloc_skb(), which has also ensured that padding is safe. ++ */ ++ if (dev->needed_tailroom) ++ eth_skb_pad(skb); ++ + /* Transmit function may have to reallocate the original SKB, + * in which case it must have freed it. Only free it here on error. + */ +@@ -1791,6 +1826,16 @@ int dsa_slave_create(struct dsa_port *port) + slave_dev->netdev_ops = &dsa_slave_netdev_ops; + if (ds->ops->port_max_mtu) + slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); ++ if (cpu_dp->tag_ops->tail_tag) ++ slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead; ++ else ++ slave_dev->needed_headroom = cpu_dp->tag_ops->overhead; ++ /* Try to save one extra realloc later in the TX path (in the master) ++ * by also inheriting the master's needed headroom and tailroom. ++ * The 8021q driver also does this. ++ */ ++ slave_dev->needed_headroom += master->needed_headroom; ++ slave_dev->needed_tailroom += master->needed_tailroom; + SET_NETDEV_DEVTYPE(slave_dev, &dsa_type); + + netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, +diff --git a/net/dsa/tag_ar9331.c b/net/dsa/tag_ar9331.c +index 55b00694cdba1..002cf7f952e2d 100644 +--- a/net/dsa/tag_ar9331.c ++++ b/net/dsa/tag_ar9331.c +@@ -31,9 +31,6 @@ static struct sk_buff *ar9331_tag_xmit(struct sk_buff *skb, + __le16 *phdr; + u16 hdr; + +- if (skb_cow_head(skb, AR9331_HDR_LEN) < 0) +- return NULL; +- + phdr = skb_push(skb, AR9331_HDR_LEN); + + hdr = FIELD_PREP(AR9331_HDR_VERSION_MASK, AR9331_HDR_VERSION); +diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c +index ad72dff8d5242..e934dace39227 100644 +--- a/net/dsa/tag_brcm.c ++++ b/net/dsa/tag_brcm.c +@@ -66,9 +66,6 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, + u16 queue = skb_get_queue_mapping(skb); + u8 *brcm_tag; + +- if (skb_cow_head(skb, BRCM_TAG_LEN) < 0) +- return NULL; +- + /* The Ethernet switch we are interfaced with needs packets to be at + * least 64 bytes (including FCS) otherwise they will be discarded when + * they enter the switch port logic. When Broadcom tags are enabled, we +diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c +index 0b756fae68a5f..63d690a0fca6f 100644 +--- a/net/dsa/tag_dsa.c ++++ b/net/dsa/tag_dsa.c +@@ -23,9 +23,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) + * the ethertype field for untagged packets. + */ + if (skb->protocol == htons(ETH_P_8021Q)) { +- if (skb_cow_head(skb, 0) < 0) +- return NULL; +- + /* + * Construct tagged FROM_CPU DSA tag from 802.1q tag. + */ +@@ -41,8 +38,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) + dsa_header[2] &= ~0x10; + } + } else { +- if (skb_cow_head(skb, DSA_HLEN) < 0) +- return NULL; + skb_push(skb, DSA_HLEN); + + memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN); +diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c +index 1206142403197..abf70a29deb43 100644 +--- a/net/dsa/tag_edsa.c ++++ b/net/dsa/tag_edsa.c +@@ -35,8 +35,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) + * current ethertype field if the packet is untagged. + */ + if (skb->protocol == htons(ETH_P_8021Q)) { +- if (skb_cow_head(skb, DSA_HLEN) < 0) +- return NULL; + skb_push(skb, DSA_HLEN); + + memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN); +@@ -60,8 +58,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) + edsa_header[6] &= ~0x10; + } + } else { +- if (skb_cow_head(skb, EDSA_HLEN) < 0) +- return NULL; + skb_push(skb, EDSA_HLEN); + + memmove(skb->data, skb->data + EDSA_HLEN, 2 * ETH_ALEN); +diff --git a/net/dsa/tag_gswip.c b/net/dsa/tag_gswip.c +index 408d4af390a0e..2f5bd5e338ab5 100644 +--- a/net/dsa/tag_gswip.c ++++ b/net/dsa/tag_gswip.c +@@ -60,13 +60,8 @@ static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); +- int err; + u8 *gswip_tag; + +- err = skb_cow_head(skb, GSWIP_TX_HEADER_LEN); +- if (err) +- return NULL; +- + skb_push(skb, GSWIP_TX_HEADER_LEN); + + gswip_tag = skb->data; +diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c +index 0a5aa982c60d9..4820dbcedfa2d 100644 +--- a/net/dsa/tag_ksz.c ++++ b/net/dsa/tag_ksz.c +@@ -14,46 +14,6 @@ + #define KSZ_EGRESS_TAG_LEN 1 + #define KSZ_INGRESS_TAG_LEN 1 + +-static struct sk_buff *ksz_common_xmit(struct sk_buff *skb, +- struct net_device *dev, int len) +-{ +- struct sk_buff *nskb; +- int padlen; +- +- padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len; +- +- if (skb_tailroom(skb) >= padlen + len) { +- /* Let dsa_slave_xmit() free skb */ +- if (__skb_put_padto(skb, skb->len + padlen, false)) +- return NULL; +- +- nskb = skb; +- } else { +- nskb = alloc_skb(NET_IP_ALIGN + skb->len + +- padlen + len, GFP_ATOMIC); +- if (!nskb) +- return NULL; +- skb_reserve(nskb, NET_IP_ALIGN); +- +- skb_reset_mac_header(nskb); +- skb_set_network_header(nskb, +- skb_network_header(skb) - skb->head); +- skb_set_transport_header(nskb, +- skb_transport_header(skb) - skb->head); +- skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); +- +- /* Let skb_put_padto() free nskb, and let dsa_slave_xmit() free +- * skb +- */ +- if (skb_put_padto(nskb, nskb->len + padlen)) +- return NULL; +- +- consume_skb(skb); +- } +- +- return nskb; +-} +- + static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, + struct net_device *dev, + unsigned int port, unsigned int len) +@@ -90,23 +50,18 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, + static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); +- struct sk_buff *nskb; + u8 *tag; + u8 *addr; + +- nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN); +- if (!nskb) +- return NULL; +- + /* Tag encoding */ +- tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); +- addr = skb_mac_header(nskb); ++ tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); ++ addr = skb_mac_header(skb); + + *tag = 1 << dp->index; + if (is_link_local_ether_addr(addr)) + *tag |= KSZ8795_TAIL_TAG_OVERRIDE; + +- return nskb; ++ return skb; + } + + static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev, +@@ -156,18 +111,13 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); +- struct sk_buff *nskb; + __be16 *tag; + u8 *addr; + u16 val; + +- nskb = ksz_common_xmit(skb, dev, KSZ9477_INGRESS_TAG_LEN); +- if (!nskb) +- return NULL; +- + /* Tag encoding */ +- tag = skb_put(nskb, KSZ9477_INGRESS_TAG_LEN); +- addr = skb_mac_header(nskb); ++ tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); ++ addr = skb_mac_header(skb); + + val = BIT(dp->index); + +@@ -176,7 +126,7 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, + + *tag = cpu_to_be16(val); + +- return nskb; ++ return skb; + } + + static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev, +@@ -213,24 +163,19 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); +- struct sk_buff *nskb; + u8 *addr; + u8 *tag; + +- nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN); +- if (!nskb) +- return NULL; +- + /* Tag encoding */ +- tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); +- addr = skb_mac_header(nskb); ++ tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); ++ addr = skb_mac_header(skb); + + *tag = BIT(dp->index); + + if (is_link_local_ether_addr(addr)) + *tag |= KSZ9893_TAIL_TAG_OVERRIDE; + +- return nskb; ++ return skb; + } + + static const struct dsa_device_ops ksz9893_netdev_ops = { +diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c +index ccfb6f641bbfb..aa1318dccaf0a 100644 +--- a/net/dsa/tag_lan9303.c ++++ b/net/dsa/tag_lan9303.c +@@ -58,15 +58,6 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) + __be16 *lan9303_tag; + u16 tag; + +- /* insert a special VLAN tag between the MAC addresses +- * and the current ethertype field. +- */ +- if (skb_cow_head(skb, LAN9303_TAG_LEN) < 0) { +- dev_dbg(&dev->dev, +- "Cannot make room for the special tag. Dropping packet\n"); +- return NULL; +- } +- + /* provide 'LAN9303_TAG_LEN' bytes additional space */ + skb_push(skb, LAN9303_TAG_LEN); + +diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c +index 4cdd9cf428fbf..59748487664fe 100644 +--- a/net/dsa/tag_mtk.c ++++ b/net/dsa/tag_mtk.c +@@ -13,6 +13,7 @@ + #define MTK_HDR_LEN 4 + #define MTK_HDR_XMIT_UNTAGGED 0 + #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 ++#define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 + #define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) + #define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0) + #define MTK_HDR_XMIT_SA_DIS BIT(6) +@@ -21,8 +22,8 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); ++ u8 xmit_tpid; + u8 *mtk_tag; +- bool is_vlan_skb = true; + unsigned char *dest = eth_hdr(skb)->h_dest; + bool is_multicast_skb = is_multicast_ether_addr(dest) && + !is_broadcast_ether_addr(dest); +@@ -33,13 +34,17 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, + * the both special and VLAN tag at the same time and then look up VLAN + * table with VID. + */ +- if (!skb_vlan_tagged(skb)) { +- if (skb_cow_head(skb, MTK_HDR_LEN) < 0) +- return NULL; +- ++ switch (skb->protocol) { ++ case htons(ETH_P_8021Q): ++ xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100; ++ break; ++ case htons(ETH_P_8021AD): ++ xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8; ++ break; ++ default: ++ xmit_tpid = MTK_HDR_XMIT_UNTAGGED; + skb_push(skb, MTK_HDR_LEN); + memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); +- is_vlan_skb = false; + } + + mtk_tag = skb->data + 2 * ETH_ALEN; +@@ -47,8 +52,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, + /* Mark tag attribute on special tag insertion to notify hardware + * whether that's a combined special tag with 802.1Q header. + */ +- mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 : +- MTK_HDR_XMIT_UNTAGGED; ++ mtk_tag[0] = xmit_tpid; + mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; + + /* Disable SA learning for multicast frames */ +@@ -56,7 +60,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, + mtk_tag[1] |= MTK_HDR_XMIT_SA_DIS; + + /* Tag control information is kept for 802.1Q */ +- if (!is_vlan_skb) { ++ if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) { + mtk_tag[2] = 0; + mtk_tag[3] = 0; + } +diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c +index 3b468aca5c53f..16a1afd5b8e14 100644 +--- a/net/dsa/tag_ocelot.c ++++ b/net/dsa/tag_ocelot.c +@@ -143,13 +143,6 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb, + struct ocelot_port *ocelot_port; + u8 *prefix, *injection; + u64 qos_class, rew_op; +- int err; +- +- err = skb_cow_head(skb, OCELOT_TOTAL_TAG_LEN); +- if (unlikely(err < 0)) { +- netdev_err(netdev, "Cannot make room for tag.\n"); +- return NULL; +- } + + ocelot_port = ocelot->ports[dp->index]; + +diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c +index 1b9e8507112b5..88181b52f480b 100644 +--- a/net/dsa/tag_qca.c ++++ b/net/dsa/tag_qca.c +@@ -34,9 +34,6 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) + __be16 *phdr; + u16 hdr; + +- if (skb_cow_head(skb, QCA_HDR_LEN) < 0) +- return NULL; +- + skb_push(skb, QCA_HDR_LEN); + + memmove(skb->data, skb->data + QCA_HDR_LEN, 2 * ETH_ALEN); +diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c +index c17d39b4a1a04..e9176475bac89 100644 +--- a/net/dsa/tag_rtl4_a.c ++++ b/net/dsa/tag_rtl4_a.c +@@ -35,14 +35,12 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); ++ __be16 *p; + u8 *tag; +- u16 *p; + u16 out; + + /* Pad out to at least 60 bytes */ +- if (unlikely(eth_skb_pad(skb))) +- return NULL; +- if (skb_cow_head(skb, RTL4_A_HDR_LEN) < 0) ++ if (unlikely(__skb_put_padto(skb, ETH_ZLEN, false))) + return NULL; + + netdev_dbg(dev, "add realtek tag to package to port %d\n", +@@ -53,13 +51,13 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb, + tag = skb->data + 2 * ETH_ALEN; + + /* Set Ethertype */ +- p = (u16 *)tag; ++ p = (__be16 *)tag; + *p = htons(RTL4_A_ETHERTYPE); + + out = (RTL4_A_PROTOCOL_RTL8366RB << 12) | (2 << 8); +- /* The lower bits is the port numer */ ++ /* The lower bits is the port number */ + out |= (u8)dp->index; +- p = (u16 *)(tag + 2); ++ p = (__be16 *)(tag + 2); + *p = htons(out); + + return skb; +diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c +index 3a1cc24a4f0a5..5b97ede56a0fd 100644 +--- a/net/dsa/tag_trailer.c ++++ b/net/dsa/tag_trailer.c +@@ -13,42 +13,15 @@ + static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); +- struct sk_buff *nskb; +- int padlen; + u8 *trailer; + +- /* +- * We have to make sure that the trailer ends up as the very +- * last 4 bytes of the packet. This means that we have to pad +- * the packet to the minimum ethernet frame size, if necessary, +- * before adding the trailer. +- */ +- padlen = 0; +- if (skb->len < 60) +- padlen = 60 - skb->len; +- +- nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC); +- if (!nskb) +- return NULL; +- skb_reserve(nskb, NET_IP_ALIGN); +- +- skb_reset_mac_header(nskb); +- skb_set_network_header(nskb, skb_network_header(skb) - skb->head); +- skb_set_transport_header(nskb, skb_transport_header(skb) - skb->head); +- skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); +- consume_skb(skb); +- +- if (padlen) { +- skb_put_zero(nskb, padlen); +- } +- +- trailer = skb_put(nskb, 4); ++ trailer = skb_put(skb, 4); + trailer[0] = 0x80; + trailer[1] = 1 << dp->index; + trailer[2] = 0x10; + trailer[3] = 0x00; + +- return nskb; ++ return skb; + } + + static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev, +diff --git a/net/ethtool/channels.c b/net/ethtool/channels.c +index 25a9e566ef5cd..6a070dc8e4b0d 100644 +--- a/net/ethtool/channels.c ++++ b/net/ethtool/channels.c +@@ -116,10 +116,9 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info) + struct ethtool_channels channels = {}; + struct ethnl_req_info req_info = {}; + struct nlattr **tb = info->attrs; +- const struct nlattr *err_attr; ++ u32 err_attr, max_rx_in_use = 0; + const struct ethtool_ops *ops; + struct net_device *dev; +- u32 max_rx_in_use = 0; + int ret; + + ret = ethnl_parse_header_dev_get(&req_info, +@@ -157,34 +156,35 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info) + + /* ensure new channel counts are within limits */ + if (channels.rx_count > channels.max_rx) +- err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; + else if (channels.tx_count > channels.max_tx) +- err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; + else if (channels.other_count > channels.max_other) +- err_attr = tb[ETHTOOL_A_CHANNELS_OTHER_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_OTHER_COUNT; + else if (channels.combined_count > channels.max_combined) +- err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; + else +- err_attr = NULL; ++ err_attr = 0; + if (err_attr) { + ret = -EINVAL; +- NL_SET_ERR_MSG_ATTR(info->extack, err_attr, ++ NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], + "requested channel count exceeds maximum"); + goto out_ops; + } + + /* ensure there is at least one RX and one TX channel */ + if (!channels.combined_count && !channels.rx_count) +- err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; + else if (!channels.combined_count && !channels.tx_count) +- err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; + else +- err_attr = NULL; ++ err_attr = 0; + if (err_attr) { + if (mod_combined) +- err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; ++ err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; + ret = -EINVAL; +- NL_SET_ERR_MSG_ATTR(info->extack, err_attr, "requested channel counts would result in no RX or TX channel being configured"); ++ NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], ++ "requested channel counts would result in no RX or TX channel being configured"); + goto out_ops; + } + +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 471d33a0d095f..be09c7669a799 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -519,16 +519,10 @@ int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) + ret_val = -ENOENT; + goto doi_remove_return; + } +- if (!refcount_dec_and_test(&doi_def->refcount)) { +- spin_unlock(&cipso_v4_doi_list_lock); +- ret_val = -EBUSY; +- goto doi_remove_return; +- } + list_del_rcu(&doi_def->list); + spin_unlock(&cipso_v4_doi_list_lock); + +- cipso_v4_cache_invalidate(); +- call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); ++ cipso_v4_doi_putdef(doi_def); + ret_val = 0; + + doi_remove_return: +@@ -585,9 +579,6 @@ void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def) + + if (!refcount_dec_and_test(&doi_def->refcount)) + return; +- spin_lock(&cipso_v4_doi_list_lock); +- list_del_rcu(&doi_def->list); +- spin_unlock(&cipso_v4_doi_list_lock); + + cipso_v4_cache_invalidate(); + call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index 76a420c76f16e..f6cc26de5ed30 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -502,8 +502,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, + if (!skb_is_gso(skb) && + (inner_iph->frag_off & htons(IP_DF)) && + mtu < pkt_size) { +- memset(IPCB(skb), 0, sizeof(*IPCB(skb))); +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); + return -E2BIG; + } + } +@@ -527,7 +526,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, + + if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU && + mtu < pkt_size) { +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + return -E2BIG; + } + } +diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c +index b957cbee2cf7b..84a818b09beeb 100644 +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -238,13 +238,13 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, + if (skb->len > mtu) { + skb_dst_update_pmtu_no_confirm(skb, mtu); + if (skb->protocol == htons(ETH_P_IP)) { +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, +- htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(mtu)); + } else { + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + } + + dst_release(dst); +diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c +index f63f7ada51b36..f2d313c5900df 100644 +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -1182,7 +1182,7 @@ out: + + /* rtnl */ + /* remove all nexthops tied to a device being deleted */ +-static void nexthop_flush_dev(struct net_device *dev) ++static void nexthop_flush_dev(struct net_device *dev, unsigned long event) + { + unsigned int hash = nh_dev_hashfn(dev->ifindex); + struct net *net = dev_net(dev); +@@ -1194,6 +1194,10 @@ static void nexthop_flush_dev(struct net_device *dev) + if (nhi->fib_nhc.nhc_dev != dev) + continue; + ++ if (nhi->reject_nh && ++ (event == NETDEV_DOWN || event == NETDEV_CHANGE)) ++ continue; ++ + remove_nexthop(net, nhi->nh_parent, NULL); + } + } +@@ -1940,11 +1944,11 @@ static int nh_netdev_event(struct notifier_block *this, + switch (event) { + case NETDEV_DOWN: + case NETDEV_UNREGISTER: +- nexthop_flush_dev(dev); ++ nexthop_flush_dev(dev, event); + break; + case NETDEV_CHANGE: + if (!(dev_get_flags(dev) & (IFF_RUNNING | IFF_LOWER_UP))) +- nexthop_flush_dev(dev); ++ nexthop_flush_dev(dev, event); + break; + case NETDEV_CHANGEMTU: + info_ext = ptr; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 41d03683b13d6..2384ac048bead 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3164,16 +3164,23 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname, + break; + + case TCP_QUEUE_SEQ: +- if (sk->sk_state != TCP_CLOSE) ++ if (sk->sk_state != TCP_CLOSE) { + err = -EPERM; +- else if (tp->repair_queue == TCP_SEND_QUEUE) +- WRITE_ONCE(tp->write_seq, val); +- else if (tp->repair_queue == TCP_RECV_QUEUE) { +- WRITE_ONCE(tp->rcv_nxt, val); +- WRITE_ONCE(tp->copied_seq, val); +- } +- else ++ } else if (tp->repair_queue == TCP_SEND_QUEUE) { ++ if (!tcp_rtx_queue_empty(sk)) ++ err = -EPERM; ++ else ++ WRITE_ONCE(tp->write_seq, val); ++ } else if (tp->repair_queue == TCP_RECV_QUEUE) { ++ if (tp->rcv_nxt != tp->copied_seq) { ++ err = -EPERM; ++ } else { ++ WRITE_ONCE(tp->rcv_nxt, val); ++ WRITE_ONCE(tp->copied_seq, val); ++ } ++ } else { + err = -EINVAL; ++ } + break; + + case TCP_REPAIR_OPTIONS: +@@ -3829,7 +3836,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, + + if (get_user(len, optlen)) + return -EFAULT; +- if (len < offsetofend(struct tcp_zerocopy_receive, length)) ++ if (len < 0 || ++ len < offsetofend(struct tcp_zerocopy_receive, length)) + return -EINVAL; + if (len > sizeof(zc)) { + len = sizeof(zc); +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index cfdaac4a57e41..6e2b02cf78418 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -522,7 +522,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, + } + + if (!sk || NAPI_GRO_CB(skb)->encap_mark || +- (skb->ip_summed != CHECKSUM_PARTIAL && ++ (uh->check && skb->ip_summed != CHECKSUM_PARTIAL && + NAPI_GRO_CB(skb)->csum_cnt == 0 && + !NAPI_GRO_CB(skb)->csum_valid) || + !udp_sk(sk)->gro_receive) +diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c +index 78f766019b7e0..0ea66e9db2495 100644 +--- a/net/ipv6/calipso.c ++++ b/net/ipv6/calipso.c +@@ -83,6 +83,9 @@ struct calipso_map_cache_entry { + + static struct calipso_map_cache_bkt *calipso_cache; + ++static void calipso_cache_invalidate(void); ++static void calipso_doi_putdef(struct calipso_doi *doi_def); ++ + /* Label Mapping Cache Functions + */ + +@@ -444,15 +447,10 @@ static int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info) + ret_val = -ENOENT; + goto doi_remove_return; + } +- if (!refcount_dec_and_test(&doi_def->refcount)) { +- spin_unlock(&calipso_doi_list_lock); +- ret_val = -EBUSY; +- goto doi_remove_return; +- } + list_del_rcu(&doi_def->list); + spin_unlock(&calipso_doi_list_lock); + +- call_rcu(&doi_def->rcu, calipso_doi_free_rcu); ++ calipso_doi_putdef(doi_def); + ret_val = 0; + + doi_remove_return: +@@ -508,10 +506,8 @@ static void calipso_doi_putdef(struct calipso_doi *doi_def) + + if (!refcount_dec_and_test(&doi_def->refcount)) + return; +- spin_lock(&calipso_doi_list_lock); +- list_del_rcu(&doi_def->list); +- spin_unlock(&calipso_doi_list_lock); + ++ calipso_cache_invalidate(); + call_rcu(&doi_def->rcu, calipso_doi_free_rcu); + } + +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index cf6e1380b527c..640f71a7b29d9 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -678,8 +678,8 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb, + + tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; + if (tel->encap_limit == 0) { +- icmpv6_send(skb, ICMPV6_PARAMPROB, +- ICMPV6_HDR_FIELD, offset + 2); ++ icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, ++ ICMPV6_HDR_FIELD, offset + 2); + return -1; + } + *encap_limit = tel->encap_limit - 1; +@@ -805,8 +805,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) + if (err != 0) { + /* XXX: send ICMP error even if DF is not set. */ + if (err == -EMSGSIZE) +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, +- htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(mtu)); + return -1; + } + +@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) + &mtu, skb->protocol); + if (err != 0) { + if (err == -EMSGSIZE) +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + return -1; + } + +@@ -1063,10 +1063,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, + /* XXX: send ICMP error even if DF is not set. */ + if (err == -EMSGSIZE) { + if (skb->protocol == htons(ETH_P_IP)) +- icmp_send(skb, ICMP_DEST_UNREACH, +- ICMP_FRAG_NEEDED, htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ++ ICMP_FRAG_NEEDED, htonl(mtu)); + else +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + } + + goto tx_err; +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 648db3fe508f0..5d27b5c631217 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1363,8 +1363,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, + + tel = (void *)&skb_network_header(skb)[offset]; + if (tel->encap_limit == 0) { +- icmpv6_send(skb, ICMPV6_PARAMPROB, +- ICMPV6_HDR_FIELD, offset + 2); ++ icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, ++ ICMPV6_HDR_FIELD, offset + 2); + return -1; + } + encap_limit = tel->encap_limit - 1; +@@ -1416,11 +1416,11 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, + if (err == -EMSGSIZE) + switch (protocol) { + case IPPROTO_IPIP: +- icmp_send(skb, ICMP_DEST_UNREACH, +- ICMP_FRAG_NEEDED, htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ++ ICMP_FRAG_NEEDED, htonl(mtu)); + break; + case IPPROTO_IPV6: +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + break; + default: + break; +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index 5f9c4fdc120d6..ecfeffc06c55c 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -520,10 +520,10 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + } else { +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, +- htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(mtu)); + } + + err = -EMSGSIZE; +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index ff048cb8d8074..b26f469a3fb8c 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -987,7 +987,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, + skb_dst_update_pmtu_no_confirm(skb, mtu); + + if (skb->len > mtu && !skb_is_gso(skb)) { +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + ip_rt_put(rt); + goto tx_error; + } +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 7be5103ff2a84..203890e378cb0 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -649,9 +649,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + /* Parse and check optional cookie */ + if (session->peer_cookie_len > 0) { + if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { +- pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n", +- tunnel->name, tunnel->tunnel_id, +- session->session_id); ++ pr_debug_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n", ++ tunnel->name, tunnel->tunnel_id, ++ session->session_id); + atomic_long_inc(&session->stats.rx_cookie_discards); + goto discard; + } +@@ -702,8 +702,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + * If user has configured mandatory sequence numbers, discard. + */ + if (session->recv_seq) { +- pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", +- session->name); ++ pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", ++ session->name); + atomic_long_inc(&session->stats.rx_seq_discards); + goto discard; + } +@@ -718,8 +718,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + session->send_seq = 0; + l2tp_session_set_header_len(session, tunnel->version); + } else if (session->send_seq) { +- pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", +- session->name); ++ pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", ++ session->name); + atomic_long_inc(&session->stats.rx_seq_discards); + goto discard; + } +@@ -809,9 +809,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb) + + /* Short packet? */ + if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) { +- pr_warn_ratelimited("%s: recv short packet (len=%d)\n", +- tunnel->name, skb->len); +- goto error; ++ pr_debug_ratelimited("%s: recv short packet (len=%d)\n", ++ tunnel->name, skb->len); ++ goto invalid; + } + + /* Point to L2TP header */ +@@ -824,9 +824,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb) + /* Check protocol version */ + version = hdrflags & L2TP_HDR_VER_MASK; + if (version != tunnel->version) { +- pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n", +- tunnel->name, version, tunnel->version); +- goto error; ++ pr_debug_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n", ++ tunnel->name, version, tunnel->version); ++ goto invalid; + } + + /* Get length of L2TP packet */ +@@ -834,7 +834,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb) + + /* If type is control packet, it is handled by userspace. */ + if (hdrflags & L2TP_HDRFLAG_T) +- goto error; ++ goto pass; + + /* Skip flags */ + ptr += 2; +@@ -863,21 +863,24 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb) + l2tp_session_dec_refcount(session); + + /* Not found? Pass to userspace to deal with */ +- pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n", +- tunnel->name, tunnel_id, session_id); +- goto error; ++ pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n", ++ tunnel->name, tunnel_id, session_id); ++ goto pass; + } + + if (tunnel->version == L2TP_HDR_VER_3 && + l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) +- goto error; ++ goto invalid; + + l2tp_recv_common(session, skb, ptr, optr, hdrflags, length); + l2tp_session_dec_refcount(session); + + return 0; + +-error: ++invalid: ++ atomic_long_inc(&tunnel->stats.rx_invalid); ++ ++pass: + /* Put UDP header back */ + __skb_push(skb, sizeof(struct udphdr)); + +diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h +index cb21d906343e8..98ea98eb9567b 100644 +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -39,6 +39,7 @@ struct l2tp_stats { + atomic_long_t rx_oos_packets; + atomic_long_t rx_errors; + atomic_long_t rx_cookie_discards; ++ atomic_long_t rx_invalid; + }; + + struct l2tp_tunnel; +diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c +index 83956c9ee1fcc..96eb91be9238b 100644 +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -428,6 +428,9 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla + L2TP_ATTR_STATS_PAD) || + nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, + atomic_long_read(&tunnel->stats.rx_errors), ++ L2TP_ATTR_STATS_PAD) || ++ nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID, ++ atomic_long_read(&tunnel->stats.rx_invalid), + L2TP_ATTR_STATS_PAD)) + goto nla_put_failure; + nla_nest_end(skb, nest); +@@ -771,6 +774,9 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl + L2TP_ATTR_STATS_PAD) || + nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, + atomic_long_read(&session->stats.rx_errors), ++ L2TP_ATTR_STATS_PAD) || ++ nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID, ++ atomic_long_read(&session->stats.rx_invalid), + L2TP_ATTR_STATS_PAD)) + goto nla_put_failure; + nla_nest_end(skb, nest); +diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c +index b1690149b6fa0..1482259de9b5d 100644 +--- a/net/mpls/mpls_gso.c ++++ b/net/mpls/mpls_gso.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, + netdev_features_t features) +@@ -27,6 +28,8 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, + + skb_reset_network_header(skb); + mpls_hlen = skb_inner_network_header(skb) - skb_network_header(skb); ++ if (unlikely(!mpls_hlen || mpls_hlen % MPLS_HLEN)) ++ goto out; + if (unlikely(!pskb_may_pull(skb, mpls_hlen))) + goto out; + +diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c +index e87b6bd6b3cdb..4731d21fc3ad8 100644 +--- a/net/netfilter/nf_nat_proto.c ++++ b/net/netfilter/nf_nat_proto.c +@@ -646,8 +646,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb, + } + + static unsigned int +-nf_nat_ipv4_in(void *priv, struct sk_buff *skb, +- const struct nf_hook_state *state) ++nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb, ++ const struct nf_hook_state *state) + { + unsigned int ret; + __be32 daddr = ip_hdr(skb)->daddr; +@@ -659,6 +659,23 @@ nf_nat_ipv4_in(void *priv, struct sk_buff *skb, + return ret; + } + ++static unsigned int ++nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb, ++ const struct nf_hook_state *state) ++{ ++ __be32 saddr = ip_hdr(skb)->saddr; ++ struct sock *sk = skb->sk; ++ unsigned int ret; ++ ++ ret = nf_nat_ipv4_fn(priv, skb, state); ++ ++ if (ret == NF_ACCEPT && sk && saddr != ip_hdr(skb)->saddr && ++ !inet_sk_transparent(sk)) ++ skb_orphan(skb); /* TCP edemux obtained wrong socket */ ++ ++ return ret; ++} ++ + static unsigned int + nf_nat_ipv4_out(void *priv, struct sk_buff *skb, + const struct nf_hook_state *state) +@@ -736,7 +753,7 @@ nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb, + static const struct nf_hook_ops nf_nat_ipv4_ops[] = { + /* Before packet filtering, change destination */ + { +- .hook = nf_nat_ipv4_in, ++ .hook = nf_nat_ipv4_pre_routing, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP_PRI_NAT_DST, +@@ -757,7 +774,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = { + }, + /* After packet filtering, change source */ + { +- .hook = nf_nat_ipv4_fn, ++ .hook = nf_nat_ipv4_local_in, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_LOCAL_IN, + .priority = NF_IP_PRI_NAT_SRC, +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index acce622582e3d..bce6ca203d462 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -330,6 +330,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) + const struct xt_match *m; + int have_rev = 0; + ++ mutex_lock(&xt[af].mutex); + list_for_each_entry(m, &xt[af].match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision > *bestp) +@@ -338,6 +339,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) + have_rev = 1; + } + } ++ mutex_unlock(&xt[af].mutex); + + if (af != NFPROTO_UNSPEC && !have_rev) + return match_revfn(NFPROTO_UNSPEC, name, revision, bestp); +@@ -350,6 +352,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp) + const struct xt_target *t; + int have_rev = 0; + ++ mutex_lock(&xt[af].mutex); + list_for_each_entry(t, &xt[af].target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision > *bestp) +@@ -358,6 +361,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp) + have_rev = 1; + } + } ++ mutex_unlock(&xt[af].mutex); + + if (af != NFPROTO_UNSPEC && !have_rev) + return target_revfn(NFPROTO_UNSPEC, name, revision, bestp); +@@ -371,12 +375,10 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, + { + int have_rev, best = -1; + +- mutex_lock(&xt[af].mutex); + if (target == 1) + have_rev = target_revfn(af, name, revision, &best); + else + have_rev = match_revfn(af, name, revision, &best); +- mutex_unlock(&xt[af].mutex); + + /* Nothing at all? Return 0 to try loading module. */ + if (best == -1) { +diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c +index 726dda95934c6..4f50a64315cf0 100644 +--- a/net/netlabel/netlabel_cipso_v4.c ++++ b/net/netlabel/netlabel_cipso_v4.c +@@ -575,6 +575,7 @@ list_start: + + break; + } ++ cipso_v4_doi_putdef(doi_def); + rcu_read_unlock(); + + genlmsg_end(ans_skb, data); +@@ -583,12 +584,14 @@ list_start: + list_retry: + /* XXX - this limit is a guesstimate */ + if (nlsze_mult < 4) { ++ cipso_v4_doi_putdef(doi_def); + rcu_read_unlock(); + kfree_skb(ans_skb); + nlsze_mult *= 2; + goto list_start; + } + list_failure_lock: ++ cipso_v4_doi_putdef(doi_def); + rcu_read_unlock(); + list_failure: + kfree_skb(ans_skb); +diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c +index d7134c558993c..38de24af24c44 100644 +--- a/net/qrtr/qrtr.c ++++ b/net/qrtr/qrtr.c +@@ -935,8 +935,10 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + plen = (len + 3) & ~3; + skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE, + msg->msg_flags & MSG_DONTWAIT, &rc); +- if (!skb) ++ if (!skb) { ++ rc = -ENOMEM; + goto out_node; ++ } + + skb_reserve(skb, QRTR_HDR_MAX_SIZE); + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 5e8e49c4ab5ca..54a8c363bcdda 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -2167,7 +2167,7 @@ static int tc_dump_tclass_qdisc(struct Qdisc *q, struct sk_buff *skb, + + static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb, + struct tcmsg *tcm, struct netlink_callback *cb, +- int *t_p, int s_t) ++ int *t_p, int s_t, bool recur) + { + struct Qdisc *q; + int b; +@@ -2178,7 +2178,7 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb, + if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0) + return -1; + +- if (!qdisc_dev(root)) ++ if (!qdisc_dev(root) || !recur) + return 0; + + if (tcm->tcm_parent) { +@@ -2213,13 +2213,13 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) + s_t = cb->args[0]; + t = 0; + +- if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0) ++ if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t, true) < 0) + goto done; + + dev_queue = dev_ingress_queue(dev); + if (dev_queue && + tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, +- &t, s_t) < 0) ++ &t, s_t, false) < 0) + goto done; + + done: +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index cf702a5f7fe5d..39ed0e0afe6d9 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -963,8 +963,11 @@ void rpc_execute(struct rpc_task *task) + + rpc_set_active(task); + rpc_make_runnable(rpciod_workqueue, task); +- if (!is_async) ++ if (!is_async) { ++ unsigned int pflags = memalloc_nofs_save(); + __rpc_execute(task); ++ memalloc_nofs_restore(pflags); ++ } + } + + static void rpc_async_schedule(struct work_struct *work) +diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c +index 33c58de58626c..3edae90188936 100644 +--- a/samples/bpf/xdpsock_user.c ++++ b/samples/bpf/xdpsock_user.c +@@ -1543,5 +1543,7 @@ int main(int argc, char **argv) + + xdpsock_cleanup(); + ++ munmap(bufs, NUM_FRAMES * opt_xsk_frame_size); ++ + return 0; + } +diff --git a/security/commoncap.c b/security/commoncap.c +index b2a656947504d..a6c9bb4441d54 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -500,8 +500,7 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) + __u32 magic, nsmagic; + struct inode *inode = d_backing_inode(dentry); + struct user_namespace *task_ns = current_user_ns(), +- *fs_ns = inode->i_sb->s_user_ns, +- *ancestor; ++ *fs_ns = inode->i_sb->s_user_ns; + kuid_t rootid; + size_t newsize; + +@@ -524,15 +523,6 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) + if (nsrootid == -1) + return -EINVAL; + +- /* +- * Do not allow allow adding a v3 filesystem capability xattr +- * if the rootid field is ambiguous. +- */ +- for (ancestor = task_ns->parent; ancestor; ancestor = ancestor->parent) { +- if (from_kuid(ancestor, rootid) == 0) +- return -EINVAL; +- } +- + newsize = sizeof(struct vfs_ns_cap_data); + nscap = kmalloc(newsize, GFP_ATOMIC); + if (!nscap) +diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c +index 6a85645663759..17a25e453f60c 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -47,6 +47,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev) + if (codec->bus->shutdown) + return; + ++ /* ignore unsol events during system suspend/resume */ ++ if (codec->core.dev.power.power_state.event != PM_EVENT_ON) ++ return; ++ + if (codec->patch_ops.unsol_event) + codec->patch_ops.unsol_event(codec, ev); + } +diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c +index 80016b7b6849e..b972d59eb1ec2 100644 +--- a/sound/pci/hda/hda_controller.c ++++ b/sound/pci/hda/hda_controller.c +@@ -609,13 +609,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) + 20, + 178000000); + +- /* by some reason, the playback stream stalls on PulseAudio with +- * tsched=1 when a capture stream triggers. Until we figure out the +- * real cause, disable tsched mode by telling the PCM info flag. +- */ +- if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) +- runtime->hw.info |= SNDRV_PCM_INFO_BATCH; +- + if (chip->align_buffer_size) + /* constrain buffer sizes to be multiple of 128 + bytes. This is more efficient in terms of memory +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 145f4ff47d54f..d244616d28d88 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -1026,6 +1026,8 @@ static int azx_prepare(struct device *dev) + chip = card->private_data; + chip->pm_prepared = 1; + ++ flush_work(&azx_bus(chip)->unsol_work); ++ + /* HDA controller always requires different WAKEEN for runtime suspend + * and system suspend, so don't use direct-complete here. + */ +diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c +index ee500e46dd4f6..f774b2ac9720c 100644 +--- a/sound/pci/hda/patch_ca0132.c ++++ b/sound/pci/hda/patch_ca0132.c +@@ -1275,6 +1275,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = { + SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D), + SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D), + SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5), ++ SND_PCI_QUIRK(0x1102, 0x0191, "Sound Blaster AE-5 Plus", QUIRK_AE5), + SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7), + {} + }; +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index d49cc4409d59c..a980a4eda51c9 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -149,6 +149,21 @@ static int cx_auto_vmaster_mute_led(struct led_classdev *led_cdev, + return 0; + } + ++static void cxt_init_gpio_led(struct hda_codec *codec) ++{ ++ struct conexant_spec *spec = codec->spec; ++ unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask; ++ ++ if (mask) { ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, ++ mask); ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, ++ mask); ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, ++ spec->gpio_led); ++ } ++} ++ + static int cx_auto_init(struct hda_codec *codec) + { + struct conexant_spec *spec = codec->spec; +@@ -156,6 +171,7 @@ static int cx_auto_init(struct hda_codec *codec) + if (!spec->dynamic_eapd) + cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); + ++ cxt_init_gpio_led(codec); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return 0; +@@ -215,6 +231,7 @@ enum { + CXT_FIXUP_HP_SPECTRE, + CXT_FIXUP_HP_GATE_MIC, + CXT_FIXUP_MUTE_LED_GPIO, ++ CXT_FIXUP_HP_ZBOOK_MUTE_LED, + CXT_FIXUP_HEADSET_MIC, + CXT_FIXUP_HP_MIC_NO_PRESENCE, + }; +@@ -654,31 +671,36 @@ static int cxt_gpio_micmute_update(struct led_classdev *led_cdev, + return 0; + } + +- +-static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, +- const struct hda_fixup *fix, int action) ++static void cxt_setup_mute_led(struct hda_codec *codec, ++ unsigned int mute, unsigned int mic_mute) + { + struct conexant_spec *spec = codec->spec; +- static const struct hda_verb gpio_init[] = { +- { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 }, +- { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 }, +- {} +- }; + +- if (action == HDA_FIXUP_ACT_PRE_PROBE) { ++ spec->gpio_led = 0; ++ spec->mute_led_polarity = 0; ++ if (mute) { + snd_hda_gen_add_mute_led_cdev(codec, cxt_gpio_mute_update); +- spec->gpio_led = 0; +- spec->mute_led_polarity = 0; +- spec->gpio_mute_led_mask = 0x01; +- spec->gpio_mic_led_mask = 0x02; ++ spec->gpio_mute_led_mask = mute; ++ } ++ if (mic_mute) { + snd_hda_gen_add_micmute_led_cdev(codec, cxt_gpio_micmute_update); ++ spec->gpio_mic_led_mask = mic_mute; + } +- snd_hda_add_verbs(codec, gpio_init); +- if (spec->gpio_led) +- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, +- spec->gpio_led); + } + ++static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ cxt_setup_mute_led(codec, 0x01, 0x02); ++} ++ ++static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ cxt_setup_mute_led(codec, 0x10, 0x20); ++} + + /* ThinkPad X200 & co with cxt5051 */ + static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { +@@ -839,6 +861,10 @@ static const struct hda_fixup cxt_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_mute_led_gpio, + }, ++ [CXT_FIXUP_HP_ZBOOK_MUTE_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cxt_fixup_hp_zbook_mute_led, ++ }, + [CXT_FIXUP_HEADSET_MIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_headset_mic, +@@ -917,6 +943,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO), ++ SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8456, "HP Z2 G4 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), +@@ -956,6 +983,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { + { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, + { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, + { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, ++ { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, + { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, + {} + }; +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index c67d5915ce243..8c6f10cbced32 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -2475,6 +2475,18 @@ static void generic_hdmi_free(struct hda_codec *codec) + } + + #ifdef CONFIG_PM ++static int generic_hdmi_suspend(struct hda_codec *codec) ++{ ++ struct hdmi_spec *spec = codec->spec; ++ int pin_idx; ++ ++ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { ++ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); ++ cancel_delayed_work_sync(&per_pin->work); ++ } ++ return 0; ++} ++ + static int generic_hdmi_resume(struct hda_codec *codec) + { + struct hdmi_spec *spec = codec->spec; +@@ -2498,6 +2510,7 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { + .build_controls = generic_hdmi_build_controls, + .unsol_event = hdmi_unsol_event, + #ifdef CONFIG_PM ++ .suspend = generic_hdmi_suspend, + .resume = generic_hdmi_resume, + #endif + }; +diff --git a/sound/usb/card.c b/sound/usb/card.c +index 57d6d4ff01e08..fc7c359ae215a 100644 +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -830,6 +830,9 @@ static int usb_audio_probe(struct usb_interface *intf, + snd_media_device_create(chip, intf); + } + ++ if (quirk) ++ chip->quirk_type = quirk->type; ++ + usb_chip[chip->index] = chip; + chip->intf[chip->num_interfaces] = intf; + chip->num_interfaces++; +@@ -904,6 +907,9 @@ static void usb_audio_disconnect(struct usb_interface *intf) + } + } + ++ if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND) ++ usb_enable_autosuspend(interface_to_usbdev(intf)); ++ + chip->num_interfaces--; + if (chip->num_interfaces <= 0) { + usb_chip[chip->index] = NULL; +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index f82c2ab809c1d..10b3a8006bdb3 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -523,7 +523,7 @@ static int setup_disable_autosuspend(struct snd_usb_audio *chip, + struct usb_driver *driver, + const struct snd_usb_audio_quirk *quirk) + { +- driver->supports_autosuspend = 0; ++ usb_disable_autosuspend(interface_to_usbdev(iface)); + return 1; /* Continue with creating streams and mixer */ + } + +@@ -1520,6 +1520,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) + case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ + case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ + case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */ ++ case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */ + return true; + } + +@@ -1672,6 +1673,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, + && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) + msleep(20); + ++ /* ++ * Plantronics headsets (C320, C320-M, etc) need a delay to avoid ++ * random microhpone failures. ++ */ ++ if (USB_ID_VENDOR(chip->usb_id) == 0x047f && ++ (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) ++ msleep(20); ++ + /* Zoom R16/24, many Logitech(at least H650e/H570e/BCC950), + * Jabra 550a, Kingston HyperX needs a tiny delay here, + * otherwise requests like get/set frequency return +diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h +index 0805b7f21272f..9667060ff92be 100644 +--- a/sound/usb/usbaudio.h ++++ b/sound/usb/usbaudio.h +@@ -27,6 +27,7 @@ struct snd_usb_audio { + struct snd_card *card; + struct usb_interface *intf[MAX_CARD_INTERFACES]; + u32 usb_id; ++ uint16_t quirk_type; + struct mutex mutex; + unsigned int system_suspend; + atomic_t active; +diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c +index dfa540d8a02d6..d636643ddd358 100644 +--- a/tools/bpf/resolve_btfids/main.c ++++ b/tools/bpf/resolve_btfids/main.c +@@ -258,6 +258,11 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size) + return btf_id__add(root, id, false); + } + ++/* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */ ++#ifndef SHF_COMPRESSED ++#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ ++#endif ++ + /* + * The data of compressed section should be aligned to 4 + * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld +diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c +index 9bc537d0b92da..f6e8831673f9b 100644 +--- a/tools/lib/bpf/xsk.c ++++ b/tools/lib/bpf/xsk.c +@@ -535,15 +535,16 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk) + if (fd < 0) + continue; + ++ memset(&map_info, 0, map_len); + err = bpf_obj_get_info_by_fd(fd, &map_info, &map_len); + if (err) { + close(fd); + continue; + } + +- if (!strcmp(map_info.name, "xsks_map")) { ++ if (!strncmp(map_info.name, "xsks_map", sizeof(map_info.name))) { + ctx->xsks_map_fd = fd; +- continue; ++ break; + } + + close(fd); +diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf +index 62f3deb1d3a8b..e41a8f9b99d2d 100644 +--- a/tools/perf/Makefile.perf ++++ b/tools/perf/Makefile.perf +@@ -600,7 +600,7 @@ arch_errno_hdr_dir := $(srctree)/tools + arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh + + $(arch_errno_name_array): $(arch_errno_tbl) +- $(Q)$(SHELL) '$(arch_errno_tbl)' $(firstword $(CC)) $(arch_errno_hdr_dir) > $@ ++ $(Q)$(SHELL) '$(arch_errno_tbl)' '$(patsubst -%,,$(CC))' $(arch_errno_hdr_dir) > $@ + + sync_file_range_arrays := $(beauty_outdir)/sync_file_range_arrays.c + sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh +diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c +index d42339df20f8d..8a3b7d5a47376 100644 +--- a/tools/perf/util/sort.c ++++ b/tools/perf/util/sort.c +@@ -3003,7 +3003,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok) + if (strncasecmp(tok, sd->name, strlen(tok))) + continue; + +- if (sort__mode != SORT_MODE__MEMORY) ++ if (sort__mode != SORT_MODE__BRANCH) + return -EINVAL; + + return __sort_dimension__add_output(list, sd); +@@ -3015,7 +3015,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok) + if (strncasecmp(tok, sd->name, strlen(tok))) + continue; + +- if (sort__mode != SORT_MODE__BRANCH) ++ if (sort__mode != SORT_MODE__MEMORY) + return -EINVAL; + + return __sort_dimension__add_output(list, sd); +diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c +index f507dff713c9f..8a01af783310a 100644 +--- a/tools/perf/util/trace-event-read.c ++++ b/tools/perf/util/trace-event-read.c +@@ -361,6 +361,7 @@ static int read_saved_cmdline(struct tep_handle *pevent) + pr_debug("error reading saved cmdlines\n"); + goto out; + } ++ buf[ret] = '\0'; + + parse_saved_cmdline(pevent, buf, size); + ret = 0; +diff --git a/tools/testing/selftests/bpf/progs/netif_receive_skb.c b/tools/testing/selftests/bpf/progs/netif_receive_skb.c +index 6b670039ea679..1d8918dfbd3ff 100644 +--- a/tools/testing/selftests/bpf/progs/netif_receive_skb.c ++++ b/tools/testing/selftests/bpf/progs/netif_receive_skb.c +@@ -16,6 +16,13 @@ bool skip = false; + #define STRSIZE 2048 + #define EXPECTED_STRSIZE 256 + ++#if defined(bpf_target_s390) ++/* NULL points to a readable struct lowcore on s390, so take the last page */ ++#define BADPTR ((void *)0xFFFFFFFFFFFFF000ULL) ++#else ++#define BADPTR 0 ++#endif ++ + #ifndef ARRAY_SIZE + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + #endif +@@ -113,11 +120,11 @@ int BPF_PROG(trace_netif_receive_skb, struct sk_buff *skb) + } + + /* Check invalid ptr value */ +- p.ptr = 0; ++ p.ptr = BADPTR; + __ret = bpf_snprintf_btf(str, STRSIZE, &p, sizeof(p), 0); + if (__ret >= 0) { +- bpf_printk("printing NULL should generate error, got (%d)", +- __ret); ++ bpf_printk("printing %llx should generate error, got (%d)", ++ (unsigned long long)BADPTR, __ret); + ret = -ERANGE; + } + +diff --git a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +index a621b58ab079d..9afe947cfae95 100644 +--- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c ++++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +@@ -446,10 +446,8 @@ int _geneve_get_tunnel(struct __sk_buff *skb) + } + + ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt)); +- if (ret < 0) { +- ERROR(ret); +- return TC_ACT_SHOT; +- } ++ if (ret < 0) ++ gopt.opt_class = 0; + + bpf_trace_printk(fmt, sizeof(fmt), + key.tunnel_id, key.remote_ipv4, gopt.opt_class); +diff --git a/tools/testing/selftests/bpf/verifier/array_access.c b/tools/testing/selftests/bpf/verifier/array_access.c +index bed53b561e044..1b138cd2b187d 100644 +--- a/tools/testing/selftests/bpf/verifier/array_access.c ++++ b/tools/testing/selftests/bpf/verifier/array_access.c +@@ -250,12 +250,13 @@ + BPF_MOV64_IMM(BPF_REG_5, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, + BPF_FUNC_csum_diff), ++ BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + .fixup_map_array_ro = { 3 }, + .result = ACCEPT, +- .retval = -29, ++ .retval = 65507, + }, + { + "invalid write map access into a read-only array 1", +diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh +index 197e769c2ed16..f8cda822c1cec 100755 +--- a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh ++++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh +@@ -86,11 +86,20 @@ test_ip6gretap() + + test_gretap_stp() + { ++ # Sometimes after mirror installation, the neighbor's state is not valid. ++ # The reason is that there is no SW datapath activity related to the ++ # neighbor for the remote GRE address. Therefore whether the corresponding ++ # neighbor will be valid is a matter of luck, and the test is thus racy. ++ # Set the neighbor's state to permanent, so it would be always valid. ++ ip neigh replace 192.0.2.130 lladdr $(mac_get $h3) \ ++ nud permanent dev br2 + full_test_span_gre_stp gt4 $swp3.555 "mirror to gretap" + } + + test_ip6gretap_stp() + { ++ ip neigh replace 2001:db8:2::2 lladdr $(mac_get $h3) \ ++ nud permanent dev br2 + full_test_span_gre_stp gt6 $swp3.555 "mirror to ip6gretap" + } + diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.24-25.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.24-25.patch new file mode 100644 index 0000000000..c8ad2135c8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.24-25.patch @@ -0,0 +1,1108 @@ +diff --git a/Makefile b/Makefile +index 3a435c928e750..6858425cbe6c1 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 24 ++SUBLEVEL = 25 + EXTRAVERSION = + NAME = Dare mighty things + +diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S +index 1852b19a73a0a..57aef3f5a81e2 100644 +--- a/arch/x86/crypto/aesni-intel_asm.S ++++ b/arch/x86/crypto/aesni-intel_asm.S +@@ -318,7 +318,7 @@ _initial_blocks_\@: + + # Main loop - Encrypt/Decrypt remaining blocks + +- cmp $0, %r13 ++ test %r13, %r13 + je _zero_cipher_left_\@ + sub $64, %r13 + je _four_cipher_left_\@ +@@ -437,7 +437,7 @@ _multiple_of_16_bytes_\@: + + mov PBlockLen(%arg2), %r12 + +- cmp $0, %r12 ++ test %r12, %r12 + je _partial_done\@ + + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 +@@ -474,7 +474,7 @@ _T_8_\@: + add $8, %r10 + sub $8, %r11 + psrldq $8, %xmm0 +- cmp $0, %r11 ++ test %r11, %r11 + je _return_T_done_\@ + _T_4_\@: + movd %xmm0, %eax +@@ -482,7 +482,7 @@ _T_4_\@: + add $4, %r10 + sub $4, %r11 + psrldq $4, %xmm0 +- cmp $0, %r11 ++ test %r11, %r11 + je _return_T_done_\@ + _T_123_\@: + movd %xmm0, %eax +@@ -619,7 +619,7 @@ _get_AAD_blocks\@: + + /* read the last <16B of AAD */ + _get_AAD_rest\@: +- cmp $0, %r11 ++ test %r11, %r11 + je _get_AAD_done\@ + + READ_PARTIAL_BLOCK %r10, %r11, \TMP1, \TMP7 +@@ -640,7 +640,7 @@ _get_AAD_done\@: + .macro PARTIAL_BLOCK CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \ + AAD_HASH operation + mov PBlockLen(%arg2), %r13 +- cmp $0, %r13 ++ test %r13, %r13 + je _partial_block_done_\@ # Leave Macro if no partial blocks + # Read in input data without over reading + cmp $16, \PLAIN_CYPH_LEN +@@ -692,7 +692,7 @@ _no_extra_mask_1_\@: + pshufb %xmm2, %xmm3 + pxor %xmm3, \AAD_HASH + +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_incomplete_1_\@ + + # GHASH computation for the last <16 Byte block +@@ -727,7 +727,7 @@ _no_extra_mask_2_\@: + pshufb %xmm2, %xmm9 + pxor %xmm9, \AAD_HASH + +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_incomplete_2_\@ + + # GHASH computation for the last <16 Byte block +@@ -747,7 +747,7 @@ _encode_done_\@: + pshufb %xmm2, %xmm9 + .endif + # output encrypted Bytes +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_fill_\@ + mov %r13, %r12 + mov $16, %r13 +@@ -2715,25 +2715,18 @@ SYM_FUNC_END(aesni_ctr_enc) + pxor CTR, IV; + + /* +- * void aesni_xts_crypt8(const struct crypto_aes_ctx *ctx, u8 *dst, +- * const u8 *src, bool enc, le128 *iv) ++ * void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, ++ * const u8 *src, unsigned int len, le128 *iv) + */ +-SYM_FUNC_START(aesni_xts_crypt8) ++SYM_FUNC_START(aesni_xts_encrypt) + FRAME_BEGIN +- cmpb $0, %cl +- movl $0, %ecx +- movl $240, %r10d +- leaq _aesni_enc4, %r11 +- leaq _aesni_dec4, %rax +- cmovel %r10d, %ecx +- cmoveq %rax, %r11 + + movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK + movups (IVP), IV + + mov 480(KEYP), KLEN +- addq %rcx, KEYP + ++.Lxts_enc_loop4: + movdqa IV, STATE1 + movdqu 0x00(INP), INC + pxor INC, STATE1 +@@ -2757,71 +2750,103 @@ SYM_FUNC_START(aesni_xts_crypt8) + pxor INC, STATE4 + movdqu IV, 0x30(OUTP) + +- CALL_NOSPEC r11 ++ call _aesni_enc4 + + movdqu 0x00(OUTP), INC + pxor INC, STATE1 + movdqu STATE1, 0x00(OUTP) + +- _aesni_gf128mul_x_ble() +- movdqa IV, STATE1 +- movdqu 0x40(INP), INC +- pxor INC, STATE1 +- movdqu IV, 0x40(OUTP) +- + movdqu 0x10(OUTP), INC + pxor INC, STATE2 + movdqu STATE2, 0x10(OUTP) + +- _aesni_gf128mul_x_ble() +- movdqa IV, STATE2 +- movdqu 0x50(INP), INC +- pxor INC, STATE2 +- movdqu IV, 0x50(OUTP) +- + movdqu 0x20(OUTP), INC + pxor INC, STATE3 + movdqu STATE3, 0x20(OUTP) + +- _aesni_gf128mul_x_ble() +- movdqa IV, STATE3 +- movdqu 0x60(INP), INC +- pxor INC, STATE3 +- movdqu IV, 0x60(OUTP) +- + movdqu 0x30(OUTP), INC + pxor INC, STATE4 + movdqu STATE4, 0x30(OUTP) + + _aesni_gf128mul_x_ble() +- movdqa IV, STATE4 +- movdqu 0x70(INP), INC +- pxor INC, STATE4 +- movdqu IV, 0x70(OUTP) + +- _aesni_gf128mul_x_ble() ++ add $64, INP ++ add $64, OUTP ++ sub $64, LEN ++ ja .Lxts_enc_loop4 ++ + movups IV, (IVP) + +- CALL_NOSPEC r11 ++ FRAME_END ++ ret ++SYM_FUNC_END(aesni_xts_encrypt) ++ ++/* ++ * void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *dst, ++ * const u8 *src, unsigned int len, le128 *iv) ++ */ ++SYM_FUNC_START(aesni_xts_decrypt) ++ FRAME_BEGIN ++ ++ movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK ++ movups (IVP), IV ++ ++ mov 480(KEYP), KLEN ++ add $240, KEYP + +- movdqu 0x40(OUTP), INC ++.Lxts_dec_loop4: ++ movdqa IV, STATE1 ++ movdqu 0x00(INP), INC + pxor INC, STATE1 +- movdqu STATE1, 0x40(OUTP) ++ movdqu IV, 0x00(OUTP) + +- movdqu 0x50(OUTP), INC ++ _aesni_gf128mul_x_ble() ++ movdqa IV, STATE2 ++ movdqu 0x10(INP), INC ++ pxor INC, STATE2 ++ movdqu IV, 0x10(OUTP) ++ ++ _aesni_gf128mul_x_ble() ++ movdqa IV, STATE3 ++ movdqu 0x20(INP), INC ++ pxor INC, STATE3 ++ movdqu IV, 0x20(OUTP) ++ ++ _aesni_gf128mul_x_ble() ++ movdqa IV, STATE4 ++ movdqu 0x30(INP), INC ++ pxor INC, STATE4 ++ movdqu IV, 0x30(OUTP) ++ ++ call _aesni_dec4 ++ ++ movdqu 0x00(OUTP), INC ++ pxor INC, STATE1 ++ movdqu STATE1, 0x00(OUTP) ++ ++ movdqu 0x10(OUTP), INC + pxor INC, STATE2 +- movdqu STATE2, 0x50(OUTP) ++ movdqu STATE2, 0x10(OUTP) + +- movdqu 0x60(OUTP), INC ++ movdqu 0x20(OUTP), INC + pxor INC, STATE3 +- movdqu STATE3, 0x60(OUTP) ++ movdqu STATE3, 0x20(OUTP) + +- movdqu 0x70(OUTP), INC ++ movdqu 0x30(OUTP), INC + pxor INC, STATE4 +- movdqu STATE4, 0x70(OUTP) ++ movdqu STATE4, 0x30(OUTP) ++ ++ _aesni_gf128mul_x_ble() ++ ++ add $64, INP ++ add $64, OUTP ++ sub $64, LEN ++ ja .Lxts_dec_loop4 ++ ++ movups IV, (IVP) + + FRAME_END + ret +-SYM_FUNC_END(aesni_xts_crypt8) ++SYM_FUNC_END(aesni_xts_decrypt) + + #endif +diff --git a/arch/x86/crypto/aesni-intel_avx-x86_64.S b/arch/x86/crypto/aesni-intel_avx-x86_64.S +index 5fee47956f3bb..2cf8e94d986a5 100644 +--- a/arch/x86/crypto/aesni-intel_avx-x86_64.S ++++ b/arch/x86/crypto/aesni-intel_avx-x86_64.S +@@ -369,7 +369,7 @@ _initial_num_blocks_is_0\@: + + + _initial_blocks_encrypted\@: +- cmp $0, %r13 ++ test %r13, %r13 + je _zero_cipher_left\@ + + sub $128, %r13 +@@ -528,7 +528,7 @@ _multiple_of_16_bytes\@: + vmovdqu HashKey(arg2), %xmm13 + + mov PBlockLen(arg2), %r12 +- cmp $0, %r12 ++ test %r12, %r12 + je _partial_done\@ + + #GHASH computation for the last <16 Byte block +@@ -573,7 +573,7 @@ _T_8\@: + add $8, %r10 + sub $8, %r11 + vpsrldq $8, %xmm9, %xmm9 +- cmp $0, %r11 ++ test %r11, %r11 + je _return_T_done\@ + _T_4\@: + vmovd %xmm9, %eax +@@ -581,7 +581,7 @@ _T_4\@: + add $4, %r10 + sub $4, %r11 + vpsrldq $4, %xmm9, %xmm9 +- cmp $0, %r11 ++ test %r11, %r11 + je _return_T_done\@ + _T_123\@: + vmovd %xmm9, %eax +@@ -625,7 +625,7 @@ _get_AAD_blocks\@: + cmp $16, %r11 + jge _get_AAD_blocks\@ + vmovdqu \T8, \T7 +- cmp $0, %r11 ++ test %r11, %r11 + je _get_AAD_done\@ + + vpxor \T7, \T7, \T7 +@@ -644,7 +644,7 @@ _get_AAD_rest8\@: + vpxor \T1, \T7, \T7 + jmp _get_AAD_rest8\@ + _get_AAD_rest4\@: +- cmp $0, %r11 ++ test %r11, %r11 + jle _get_AAD_rest0\@ + mov (%r10), %eax + movq %rax, \T1 +@@ -749,7 +749,7 @@ _done_read_partial_block_\@: + .macro PARTIAL_BLOCK GHASH_MUL CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \ + AAD_HASH ENC_DEC + mov PBlockLen(arg2), %r13 +- cmp $0, %r13 ++ test %r13, %r13 + je _partial_block_done_\@ # Leave Macro if no partial blocks + # Read in input data without over reading + cmp $16, \PLAIN_CYPH_LEN +@@ -801,7 +801,7 @@ _no_extra_mask_1_\@: + vpshufb %xmm2, %xmm3, %xmm3 + vpxor %xmm3, \AAD_HASH, \AAD_HASH + +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_incomplete_1_\@ + + # GHASH computation for the last <16 Byte block +@@ -836,7 +836,7 @@ _no_extra_mask_2_\@: + vpshufb %xmm2, %xmm9, %xmm9 + vpxor %xmm9, \AAD_HASH, \AAD_HASH + +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_incomplete_2_\@ + + # GHASH computation for the last <16 Byte block +@@ -856,7 +856,7 @@ _encode_done_\@: + vpshufb %xmm2, %xmm9, %xmm9 + .endif + # output encrypted Bytes +- cmp $0, %r10 ++ test %r10, %r10 + jl _partial_fill_\@ + mov %r13, %r12 + mov $16, %r13 +diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c +index f9a1d98e75349..be891fdf8d174 100644 +--- a/arch/x86/crypto/aesni-intel_glue.c ++++ b/arch/x86/crypto/aesni-intel_glue.c +@@ -97,6 +97,12 @@ asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, + #define AVX_GEN2_OPTSIZE 640 + #define AVX_GEN4_OPTSIZE 4096 + ++asmlinkage void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, ++ const u8 *in, unsigned int len, u8 *iv); ++ ++asmlinkage void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *out, ++ const u8 *in, unsigned int len, u8 *iv); ++ + #ifdef CONFIG_X86_64 + + static void (*aesni_ctr_enc_tfm)(struct crypto_aes_ctx *ctx, u8 *out, +@@ -104,9 +110,6 @@ static void (*aesni_ctr_enc_tfm)(struct crypto_aes_ctx *ctx, u8 *out, + asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, + const u8 *in, unsigned int len, u8 *iv); + +-asmlinkage void aesni_xts_crypt8(const struct crypto_aes_ctx *ctx, u8 *out, +- const u8 *in, bool enc, le128 *iv); +- + /* asmlinkage void aesni_gcm_enc() + * void *ctx, AES Key schedule. Starts on a 16 byte boundary. + * struct gcm_context_data. May be uninitialized. +@@ -547,14 +550,14 @@ static void aesni_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) + glue_xts_crypt_128bit_one(ctx, dst, src, iv, aesni_dec); + } + +-static void aesni_xts_enc8(const void *ctx, u8 *dst, const u8 *src, le128 *iv) ++static void aesni_xts_enc32(const void *ctx, u8 *dst, const u8 *src, le128 *iv) + { +- aesni_xts_crypt8(ctx, dst, src, true, iv); ++ aesni_xts_encrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv); + } + +-static void aesni_xts_dec8(const void *ctx, u8 *dst, const u8 *src, le128 *iv) ++static void aesni_xts_dec32(const void *ctx, u8 *dst, const u8 *src, le128 *iv) + { +- aesni_xts_crypt8(ctx, dst, src, false, iv); ++ aesni_xts_decrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv); + } + + static const struct common_glue_ctx aesni_enc_xts = { +@@ -562,8 +565,8 @@ static const struct common_glue_ctx aesni_enc_xts = { + .fpu_blocks_limit = 1, + + .funcs = { { +- .num_blocks = 8, +- .fn_u = { .xts = aesni_xts_enc8 } ++ .num_blocks = 32, ++ .fn_u = { .xts = aesni_xts_enc32 } + }, { + .num_blocks = 1, + .fn_u = { .xts = aesni_xts_enc } +@@ -575,8 +578,8 @@ static const struct common_glue_ctx aesni_dec_xts = { + .fpu_blocks_limit = 1, + + .funcs = { { +- .num_blocks = 8, +- .fn_u = { .xts = aesni_xts_dec8 } ++ .num_blocks = 32, ++ .fn_u = { .xts = aesni_xts_dec32 } + }, { + .num_blocks = 1, + .fn_u = { .xts = aesni_xts_dec } +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index d8fcd21ab472f..a8f85993dab30 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -3624,7 +3624,7 @@ static ssize_t srp_create_target(struct device *dev, + struct srp_rdma_ch *ch; + struct srp_device *srp_dev = host->srp_dev; + struct ib_device *ibdev = srp_dev->dev; +- int ret, node_idx, node, cpu, i; ++ int ret, i, ch_idx; + unsigned int max_sectors_per_mr, mr_per_cmd = 0; + bool multich = false; + uint32_t max_iu_len; +@@ -3749,81 +3749,61 @@ static ssize_t srp_create_target(struct device *dev, + goto out; + + ret = -ENOMEM; +- if (target->ch_count == 0) ++ if (target->ch_count == 0) { + target->ch_count = +- max_t(unsigned int, num_online_nodes(), +- min(ch_count ?: +- min(4 * num_online_nodes(), +- ibdev->num_comp_vectors), +- num_online_cpus())); ++ min(ch_count ?: ++ max(4 * num_online_nodes(), ++ ibdev->num_comp_vectors), ++ num_online_cpus()); ++ } ++ + target->ch = kcalloc(target->ch_count, sizeof(*target->ch), + GFP_KERNEL); + if (!target->ch) + goto out; + +- node_idx = 0; +- for_each_online_node(node) { +- const int ch_start = (node_idx * target->ch_count / +- num_online_nodes()); +- const int ch_end = ((node_idx + 1) * target->ch_count / +- num_online_nodes()); +- const int cv_start = node_idx * ibdev->num_comp_vectors / +- num_online_nodes(); +- const int cv_end = (node_idx + 1) * ibdev->num_comp_vectors / +- num_online_nodes(); +- int cpu_idx = 0; +- +- for_each_online_cpu(cpu) { +- if (cpu_to_node(cpu) != node) +- continue; +- if (ch_start + cpu_idx >= ch_end) +- continue; +- ch = &target->ch[ch_start + cpu_idx]; +- ch->target = target; +- ch->comp_vector = cv_start == cv_end ? cv_start : +- cv_start + cpu_idx % (cv_end - cv_start); +- spin_lock_init(&ch->lock); +- INIT_LIST_HEAD(&ch->free_tx); +- ret = srp_new_cm_id(ch); +- if (ret) +- goto err_disconnect; ++ for (ch_idx = 0; ch_idx < target->ch_count; ++ch_idx) { ++ ch = &target->ch[ch_idx]; ++ ch->target = target; ++ ch->comp_vector = ch_idx % ibdev->num_comp_vectors; ++ spin_lock_init(&ch->lock); ++ INIT_LIST_HEAD(&ch->free_tx); ++ ret = srp_new_cm_id(ch); ++ if (ret) ++ goto err_disconnect; + +- ret = srp_create_ch_ib(ch); +- if (ret) +- goto err_disconnect; ++ ret = srp_create_ch_ib(ch); ++ if (ret) ++ goto err_disconnect; + +- ret = srp_alloc_req_data(ch); +- if (ret) +- goto err_disconnect; ++ ret = srp_alloc_req_data(ch); ++ if (ret) ++ goto err_disconnect; + +- ret = srp_connect_ch(ch, max_iu_len, multich); +- if (ret) { +- char dst[64]; +- +- if (target->using_rdma_cm) +- snprintf(dst, sizeof(dst), "%pIS", +- &target->rdma_cm.dst); +- else +- snprintf(dst, sizeof(dst), "%pI6", +- target->ib_cm.orig_dgid.raw); +- shost_printk(KERN_ERR, target->scsi_host, +- PFX "Connection %d/%d to %s failed\n", +- ch_start + cpu_idx, +- target->ch_count, dst); +- if (node_idx == 0 && cpu_idx == 0) { +- goto free_ch; +- } else { +- srp_free_ch_ib(target, ch); +- srp_free_req_data(target, ch); +- target->ch_count = ch - target->ch; +- goto connected; +- } +- } ++ ret = srp_connect_ch(ch, max_iu_len, multich); ++ if (ret) { ++ char dst[64]; + +- multich = true; +- cpu_idx++; ++ if (target->using_rdma_cm) ++ snprintf(dst, sizeof(dst), "%pIS", ++ &target->rdma_cm.dst); ++ else ++ snprintf(dst, sizeof(dst), "%pI6", ++ target->ib_cm.orig_dgid.raw); ++ shost_printk(KERN_ERR, target->scsi_host, ++ PFX "Connection %d/%d to %s failed\n", ++ ch_idx, ++ target->ch_count, dst); ++ if (ch_idx == 0) { ++ goto free_ch; ++ } else { ++ srp_free_ch_ib(target, ch); ++ srp_free_req_data(target, ch); ++ target->ch_count = ch - target->ch; ++ goto connected; ++ } + } +- node_idx++; ++ multich = true; + } + + connected: +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 95c7fa171e35a..f504b6858ed29 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -510,6 +510,19 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) + } + EXPORT_SYMBOL(b53_imp_vlan_setup); + ++static void b53_port_set_learning(struct b53_device *dev, int port, ++ bool learning) ++{ ++ u16 reg; ++ ++ b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, ®); ++ if (learning) ++ reg &= ~BIT(port); ++ else ++ reg |= BIT(port); ++ b53_write16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, reg); ++} ++ + int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) + { + struct b53_device *dev = ds->priv; +@@ -523,6 +536,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) + cpu_port = dsa_to_port(ds, port)->cpu_dp->index; + + b53_br_egress_floods(ds, port, true, true); ++ b53_port_set_learning(dev, port, false); + + if (dev->ops->irq_enable) + ret = dev->ops->irq_enable(dev, port); +@@ -656,6 +670,7 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port) + b53_brcm_hdr_setup(dev->ds, port); + + b53_br_egress_floods(dev->ds, port, true, true); ++ b53_port_set_learning(dev, port, false); + } + + static void b53_enable_mib(struct b53_device *dev) +@@ -1839,6 +1854,8 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); + dev->ports[port].vlan_ctl_mask = pvlan; + ++ b53_port_set_learning(dev, port, true); ++ + return 0; + } + EXPORT_SYMBOL(b53_br_join); +@@ -1886,6 +1903,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) + vl->untag |= BIT(port) | BIT(cpu_port); + b53_set_vlan_entry(dev, pvid, vl); + } ++ b53_port_set_learning(dev, port, false); + } + EXPORT_SYMBOL(b53_br_leave); + +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index c90985c294a2e..b2c539a421545 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -115,6 +115,7 @@ + #define B53_UC_FLOOD_MASK 0x32 + #define B53_MC_FLOOD_MASK 0x34 + #define B53_IPMC_FLOOD_MASK 0x36 ++#define B53_DIS_LEARNING 0x3c + + /* + * Override Ports 0-7 State on devices with xMII interfaces (8 bit) +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index 445226720ff29..edb0a1027b38f 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -222,23 +222,10 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, + reg &= ~P_TXQ_PSM_VDD(port); + core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); + +- /* Enable learning */ +- reg = core_readl(priv, CORE_DIS_LEARN); +- reg &= ~BIT(port); +- core_writel(priv, reg, CORE_DIS_LEARN); +- + /* Enable Broadcom tags for that port if requested */ +- if (priv->brcm_tag_mask & BIT(port)) { ++ if (priv->brcm_tag_mask & BIT(port)) + b53_brcm_hdr_setup(ds, port); + +- /* Disable learning on ASP port */ +- if (port == 7) { +- reg = core_readl(priv, CORE_DIS_LEARN); +- reg |= BIT(port); +- core_writel(priv, reg, CORE_DIS_LEARN); +- } +- } +- + /* Configure Traffic Class to QoS mapping, allow each priority to map + * to a different queue number + */ +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index 404d66f01e8d7..d64aee04e59a7 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -862,6 +862,7 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc) + + static inline void fuse_make_bad(struct inode *inode) + { ++ remove_inode_hash(inode); + set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); + } + +diff --git a/fs/locks.c b/fs/locks.c +index 1f84a03601fec..32c948fe29448 100644 +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -1808,9 +1808,6 @@ check_conflicting_open(struct file *filp, const long arg, int flags) + + if (flags & FL_LAYOUT) + return 0; +- if (flags & FL_DELEG) +- /* We leave these checks to the caller. */ +- return 0; + + if (arg == F_RDLCK) + return inode_is_open_for_write(inode) ? -EAGAIN : 0; +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 47006eec724e6..ee4e6e3b995d4 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4945,31 +4945,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, + return fl; + } + +-static int nfsd4_check_conflicting_opens(struct nfs4_client *clp, +- struct nfs4_file *fp) +-{ +- struct nfs4_clnt_odstate *co; +- struct file *f = fp->fi_deleg_file->nf_file; +- struct inode *ino = locks_inode(f); +- int writes = atomic_read(&ino->i_writecount); +- +- if (fp->fi_fds[O_WRONLY]) +- writes--; +- if (fp->fi_fds[O_RDWR]) +- writes--; +- if (writes > 0) +- return -EAGAIN; +- spin_lock(&fp->fi_lock); +- list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) { +- if (co->co_client != clp) { +- spin_unlock(&fp->fi_lock); +- return -EAGAIN; +- } +- } +- spin_unlock(&fp->fi_lock); +- return 0; +-} +- + static struct nfs4_delegation * + nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, + struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) +@@ -4989,12 +4964,9 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, + + nf = find_readable_file(fp); + if (!nf) { +- /* +- * We probably could attempt another open and get a read +- * delegation, but for now, don't bother until the +- * client actually sends us one. +- */ +- return ERR_PTR(-EAGAIN); ++ /* We should always have a readable file here */ ++ WARN_ON_ONCE(1); ++ return ERR_PTR(-EBADF); + } + spin_lock(&state_lock); + spin_lock(&fp->fi_lock); +@@ -5024,19 +4996,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, + if (!fl) + goto out_clnt_odstate; + +- status = nfsd4_check_conflicting_opens(clp, fp); +- if (status) { +- locks_free_lock(fl); +- goto out_clnt_odstate; +- } + status = vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_type, &fl, NULL); + if (fl) + locks_free_lock(fl); + if (status) + goto out_clnt_odstate; +- status = nfsd4_check_conflicting_opens(clp, fp); +- if (status) +- goto out_clnt_odstate; + + spin_lock(&state_lock); + spin_lock(&fp->fi_lock); +@@ -5118,6 +5082,17 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, + goto out_no_deleg; + if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) + goto out_no_deleg; ++ /* ++ * Also, if the file was opened for write or ++ * create, there's a good chance the client's ++ * about to write to it, resulting in an ++ * immediate recall (since we don't support ++ * write delegations): ++ */ ++ if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) ++ goto out_no_deleg; ++ if (open->op_create == NFS4_OPEN_CREATE) ++ goto out_no_deleg; + break; + default: + goto out_no_deleg; +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 6c2e4947beaeb..9a1aba2d00733 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -5333,10 +5333,14 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, + { + bool mask_to_left = (opcode == BPF_ADD && off_is_neg) || + (opcode == BPF_SUB && !off_is_neg); +- u32 off; ++ u32 off, max; + + switch (ptr_reg->type) { + case PTR_TO_STACK: ++ /* Offset 0 is out-of-bounds, but acceptable start for the ++ * left direction, see BPF_REG_FP. ++ */ ++ max = MAX_BPF_STACK + mask_to_left; + /* Indirect variable offset stack access is prohibited in + * unprivileged mode so it's not handled here. + */ +@@ -5344,16 +5348,17 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, + if (mask_to_left) + *ptr_limit = MAX_BPF_STACK + off; + else +- *ptr_limit = -off; +- return 0; ++ *ptr_limit = -off - 1; ++ return *ptr_limit >= max ? -ERANGE : 0; + case PTR_TO_MAP_VALUE: ++ max = ptr_reg->map_ptr->value_size; + if (mask_to_left) { + *ptr_limit = ptr_reg->umax_value + ptr_reg->off; + } else { + off = ptr_reg->smin_value + ptr_reg->off; +- *ptr_limit = ptr_reg->map_ptr->value_size - off; ++ *ptr_limit = ptr_reg->map_ptr->value_size - off - 1; + } +- return 0; ++ return *ptr_limit >= max ? -ERANGE : 0; + default: + return -EINVAL; + } +@@ -5406,6 +5411,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, + u32 alu_state, alu_limit; + struct bpf_reg_state tmp; + bool ret; ++ int err; + + if (can_skip_alu_sanitation(env, insn)) + return 0; +@@ -5421,10 +5427,13 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, + alu_state |= ptr_is_dst_reg ? + BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; + +- if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg)) +- return 0; +- if (update_alu_sanitation_state(aux, alu_state, alu_limit)) +- return -EACCES; ++ err = retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg); ++ if (err < 0) ++ return err; ++ ++ err = update_alu_sanitation_state(aux, alu_state, alu_limit); ++ if (err < 0) ++ return err; + do_sim: + /* Simulate and find potential out-of-bounds access under + * speculative execution from truncation as a result of +@@ -5540,7 +5549,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + case BPF_ADD: + ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); + if (ret < 0) { +- verbose(env, "R%d tried to add from different maps or paths\n", dst); ++ verbose(env, "R%d tried to add from different maps, paths, or prohibited types\n", dst); + return ret; + } + /* We can take a fixed offset as long as it doesn't overflow +@@ -5595,7 +5604,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + case BPF_SUB: + ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0); + if (ret < 0) { +- verbose(env, "R%d tried to sub from different maps or paths\n", dst); ++ verbose(env, "R%d tried to sub from different maps, paths, or prohibited types\n", dst); + return ret; + } + if (dst_reg == off_reg) { +@@ -10942,7 +10951,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) + off_reg = issrc ? insn->src_reg : insn->dst_reg; + if (isneg) + *patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1); +- *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit - 1); ++ *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit); + *patch++ = BPF_ALU64_REG(BPF_SUB, BPF_REG_AX, off_reg); + *patch++ = BPF_ALU64_REG(BPF_OR, BPF_REG_AX, off_reg); + *patch++ = BPF_ALU64_IMM(BPF_NEG, BPF_REG_AX, 0); +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index e2f9ce2f5b8b6..8527267725bb7 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -576,9 +576,6 @@ static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force) + { + unsigned int i; + +- if (!force && atomic_read(&ep->chip->shutdown)) /* to be sure... */ +- return -EBADFD; +- + clear_bit(EP_FLAG_RUNNING, &ep->flags); + + INIT_LIST_HEAD(&ep->ready_playback_urbs); +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index 1b08f52ef86f6..f4494d0549172 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -280,10 +280,7 @@ static int snd_usb_pcm_sync_stop(struct snd_pcm_substream *substream) + { + struct snd_usb_substream *subs = substream->runtime->private_data; + +- if (!snd_usb_lock_shutdown(subs->stream->chip)) { +- sync_pending_stops(subs); +- snd_usb_unlock_shutdown(subs->stream->chip); +- } ++ sync_pending_stops(subs); + return 0; + } + +diff --git a/tools/testing/selftests/bpf/verifier/bounds_deduction.c b/tools/testing/selftests/bpf/verifier/bounds_deduction.c +index 1fd07a4f27ac2..c162498a64fc6 100644 +--- a/tools/testing/selftests/bpf/verifier/bounds_deduction.c ++++ b/tools/testing/selftests/bpf/verifier/bounds_deduction.c +@@ -6,8 +6,9 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", + .errstr = "R0 tried to subtract pointer from scalar", ++ .result = REJECT, + }, + { + "check deducing bounds from const, 2", +@@ -20,6 +21,8 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 1, + }, +@@ -31,8 +34,9 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", + .errstr = "R0 tried to subtract pointer from scalar", ++ .result = REJECT, + }, + { + "check deducing bounds from const, 4", +@@ -45,6 +49,8 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +@@ -55,8 +61,9 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", + .errstr = "R0 tried to subtract pointer from scalar", ++ .result = REJECT, + }, + { + "check deducing bounds from const, 6", +@@ -67,8 +74,9 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", + .errstr = "R0 tried to subtract pointer from scalar", ++ .result = REJECT, + }, + { + "check deducing bounds from const, 7", +@@ -80,8 +88,9 @@ + offsetof(struct __sk_buff, mark)), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", + .errstr = "dereference of modified ctx ptr", ++ .result = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +@@ -94,8 +103,9 @@ + offsetof(struct __sk_buff, mark)), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", + .errstr = "dereference of modified ctx ptr", ++ .result = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, + }, + { +@@ -106,8 +116,9 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, ++ .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", + .errstr = "R0 tried to subtract pointer from scalar", ++ .result = REJECT, + }, + { + "check deducing bounds from const, 10", +@@ -119,6 +130,6 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .result = REJECT, + .errstr = "math between ctx pointer and register with unbounded min value is not allowed", ++ .result = REJECT, + }, +diff --git a/tools/testing/selftests/bpf/verifier/map_ptr.c b/tools/testing/selftests/bpf/verifier/map_ptr.c +index 637f9293bda84..92a1dc8e17462 100644 +--- a/tools/testing/selftests/bpf/verifier/map_ptr.c ++++ b/tools/testing/selftests/bpf/verifier/map_ptr.c +@@ -74,6 +74,8 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_16b = { 4 }, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", + .result = ACCEPT, + }, + { +@@ -90,5 +92,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_16b = { 4 }, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", + .result = ACCEPT, + }, +diff --git a/tools/testing/selftests/bpf/verifier/unpriv.c b/tools/testing/selftests/bpf/verifier/unpriv.c +index 91bb77c24a2ef..0d621c841db14 100644 +--- a/tools/testing/selftests/bpf/verifier/unpriv.c ++++ b/tools/testing/selftests/bpf/verifier/unpriv.c +@@ -495,7 +495,7 @@ + .result = ACCEPT, + }, + { +- "unpriv: adding of fp", ++ "unpriv: adding of fp, reg", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_1, 0), +@@ -503,6 +503,19 @@ + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++}, ++{ ++ "unpriv: adding of fp, imm", ++ .insns = { ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), ++ BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), ++ BPF_EXIT_INSN(), ++ }, + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", + .result_unpriv = REJECT, + .result = ACCEPT, +diff --git a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +index ed4e76b246499..feb91266db39a 100644 +--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c ++++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +@@ -169,7 +169,7 @@ + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R2 tried to add from different maps or paths", ++ .errstr_unpriv = "R2 tried to add from different maps, paths, or prohibited types", + .retval = 0, + }, + { +@@ -516,6 +516,27 @@ + .result = ACCEPT, + .retval = 0xabcdef12, + }, ++{ ++ "map access: value_ptr += N, value_ptr -= N known scalar", ++ .insns = { ++ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), ++ BPF_LD_MAP_FD(BPF_REG_1, 0), ++ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), ++ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), ++ BPF_MOV32_IMM(BPF_REG_1, 0x12345678), ++ BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2), ++ BPF_MOV64_IMM(BPF_REG_1, 2), ++ BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), ++ BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map_array_48b = { 3 }, ++ .result = ACCEPT, ++ .retval = 0x12345678, ++}, + { + "map access: unknown scalar += value_ptr, 1", + .insns = { diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.25-26.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.25-26.patch new file mode 100644 index 0000000000..b5ea9064e9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.25-26.patch @@ -0,0 +1,12913 @@ +diff --git a/Documentation/scsi/libsas.rst b/Documentation/scsi/libsas.rst +index f9b77c7879dbb..ea63ab3a92160 100644 +--- a/Documentation/scsi/libsas.rst ++++ b/Documentation/scsi/libsas.rst +@@ -189,12 +189,10 @@ num_phys + The event interface:: + + /* LLDD calls these to notify the class of an event. */ +- void (*notify_port_event)(struct sas_phy *, enum port_event); +- void (*notify_phy_event)(struct sas_phy *, enum phy_event); +- +-When sas_register_ha() returns, those are set and can be +-called by the LLDD to notify the SAS layer of such events +-the SAS layer. ++ void sas_notify_port_event(struct sas_phy *, enum port_event); ++ void sas_notify_phy_event(struct sas_phy *, enum phy_event); ++ void sas_notify_port_event_gfp(struct sas_phy *, enum port_event, gfp_t); ++ void sas_notify_phy_event_gfp(struct sas_phy *, enum phy_event, gfp_t); + + The port notification:: + +diff --git a/MAINTAINERS b/MAINTAINERS +index 281de213ef478..24cdfcf334ea1 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1155,7 +1155,7 @@ M: Joel Fernandes + M: Christian Brauner + M: Hridya Valsaraju + M: Suren Baghdasaryan +-L: devel@driverdev.osuosl.org ++L: linux-kernel@vger.kernel.org + S: Supported + T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git + F: drivers/android/ +@@ -8001,7 +8001,6 @@ F: drivers/crypto/hisilicon/sec2/sec_main.c + + HISILICON STAGING DRIVERS FOR HIKEY 960/970 + M: Mauro Carvalho Chehab +-L: devel@driverdev.osuosl.org + S: Maintained + F: drivers/staging/hikey9xx/ + +@@ -16665,7 +16664,7 @@ F: drivers/staging/vt665?/ + + STAGING SUBSYSTEM + M: Greg Kroah-Hartman +-L: devel@driverdev.osuosl.org ++L: linux-staging@lists.linux.dev + S: Supported + T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git + F: drivers/staging/ +@@ -18705,7 +18704,7 @@ VME SUBSYSTEM + M: Martyn Welch + M: Manohar Vanga + M: Greg Kroah-Hartman +-L: devel@driverdev.osuosl.org ++L: linux-kernel@vger.kernel.org + S: Maintained + T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git + F: Documentation/driver-api/vme.rst +diff --git a/Makefile b/Makefile +index 6858425cbe6c1..d4b87e604762a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 25 ++SUBLEVEL = 26 + EXTRAVERSION = + NAME = Dare mighty things + +@@ -1249,15 +1249,17 @@ endef + define filechk_version.h + if [ $(SUBLEVEL) -gt 255 ]; then \ + echo \#define LINUX_VERSION_CODE $(shell \ +- expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 255); \ ++ expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + 255); \ + else \ + echo \#define LINUX_VERSION_CODE $(shell \ +- expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \ ++ expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \ + fi; \ + echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + \ + ((c) > 255 ? 255 : (c)))' + endef + ++$(version_h): PATCHLEVEL := $(if $(PATCHLEVEL), $(PATCHLEVEL), 0) ++$(version_h): SUBLEVEL := $(if $(SUBLEVEL), $(SUBLEVEL), 0) + $(version_h): FORCE + $(call filechk,version.h) + $(Q)rm -f $(old_version_h) +diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile +index d66511825fe1e..337ab1d18cc1f 100644 +--- a/arch/mips/boot/compressed/Makefile ++++ b/arch/mips/boot/compressed/Makefile +@@ -36,6 +36,7 @@ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ + + # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. + KCOV_INSTRUMENT := n ++UBSAN_SANITIZE := n + + # decompressor objects (linked with vmlinuz) + vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o +diff --git a/arch/powerpc/include/asm/cpu_has_feature.h b/arch/powerpc/include/asm/cpu_has_feature.h +index 7897d16e09904..727d4b3219379 100644 +--- a/arch/powerpc/include/asm/cpu_has_feature.h ++++ b/arch/powerpc/include/asm/cpu_has_feature.h +@@ -7,7 +7,7 @@ + #include + #include + +-static inline bool early_cpu_has_feature(unsigned long feature) ++static __always_inline bool early_cpu_has_feature(unsigned long feature) + { + return !!((CPU_FTRS_ALWAYS & feature) || + (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); +@@ -46,7 +46,7 @@ static __always_inline bool cpu_has_feature(unsigned long feature) + return static_branch_likely(&cpu_feature_keys[i]); + } + #else +-static inline bool cpu_has_feature(unsigned long feature) ++static __always_inline bool cpu_has_feature(unsigned long feature) + { + return early_cpu_has_feature(feature); + } +diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c +index 242bdd8281e0f..a2e067f68dee8 100644 +--- a/arch/powerpc/lib/sstep.c ++++ b/arch/powerpc/lib/sstep.c +@@ -1853,7 +1853,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, + goto compute_done; + } + +- return -1; ++ goto unknown_opcode; + #ifdef __powerpc64__ + case 777: /* modsd */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) +@@ -2909,6 +2909,20 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, + + } + ++ if (OP_IS_LOAD_STORE(op->type) && (op->type & UPDATE)) { ++ switch (GETTYPE(op->type)) { ++ case LOAD: ++ if (ra == rd) ++ goto unknown_opcode; ++ fallthrough; ++ case STORE: ++ case LOAD_FP: ++ case STORE_FP: ++ if (ra == 0) ++ goto unknown_opcode; ++ } ++ } ++ + #ifdef CONFIG_VSX + if ((GETTYPE(op->type) == LOAD_VSX || + GETTYPE(op->type) == STORE_VSX) && +diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig +index 3474286e59db7..df7fccf76df69 100644 +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -84,7 +84,6 @@ config RISCV + select PCI_MSI if PCI + select RISCV_INTC + select RISCV_TIMER if RISCV_SBI +- select SPARSEMEM_STATIC if 32BIT + select SPARSE_IRQ + select SYSCTL_EXCEPTION_TRACE + select THREAD_INFO_IN_TASK +@@ -145,7 +144,8 @@ config ARCH_FLATMEM_ENABLE + config ARCH_SPARSEMEM_ENABLE + def_bool y + depends on MMU +- select SPARSEMEM_VMEMMAP_ENABLE ++ select SPARSEMEM_STATIC if 32BIT && SPARSMEM ++ select SPARSEMEM_VMEMMAP_ENABLE if 64BIT + + config ARCH_SELECT_MEMORY_MODEL + def_bool ARCH_SPARSEMEM_ENABLE +diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h +index 653edb25d4957..c0fdb05ffa0b2 100644 +--- a/arch/riscv/include/asm/sbi.h ++++ b/arch/riscv/include/asm/sbi.h +@@ -51,10 +51,10 @@ enum sbi_ext_rfence_fid { + SBI_EXT_RFENCE_REMOTE_FENCE_I = 0, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, +- SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, +- SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, ++ SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, ++ SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, + }; + + enum sbi_ext_hsm_fid { +diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h +index 212628932ddc1..a75d94a9bcb2f 100644 +--- a/arch/s390/include/asm/pci.h ++++ b/arch/s390/include/asm/pci.h +@@ -201,8 +201,8 @@ extern unsigned int s390_pci_no_rid; + Prototypes + ----------------------------------------------------------------------------- */ + /* Base stuff */ +-int zpci_create_device(struct zpci_dev *); +-void zpci_remove_device(struct zpci_dev *zdev); ++int zpci_create_device(u32 fid, u32 fh, enum zpci_state state); ++void zpci_remove_device(struct zpci_dev *zdev, bool set_error); + int zpci_enable_device(struct zpci_dev *); + int zpci_disable_device(struct zpci_dev *); + int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); +@@ -212,7 +212,7 @@ void zpci_remove_reserved_devices(void); + /* CLP */ + int clp_setup_writeback_mio(void); + int clp_scan_pci_devices(void); +-int clp_add_pci_device(u32, u32, int); ++int clp_query_pci_fn(struct zpci_dev *zdev); + int clp_enable_fh(struct zpci_dev *, u8); + int clp_disable_fh(struct zpci_dev *); + int clp_get_state(u32 fid, enum zpci_state *state); +diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c +index 7b3af2d6b9baa..579ec3a8c816f 100644 +--- a/arch/s390/kernel/vtime.c ++++ b/arch/s390/kernel/vtime.c +@@ -217,7 +217,7 @@ void vtime_flush(struct task_struct *tsk) + avg_steal = S390_lowcore.avg_steal_timer / 2; + if ((s64) steal > 0) { + S390_lowcore.steal_timer = 0; +- account_steal_time(steal); ++ account_steal_time(cputime_to_nsecs(steal)); + avg_steal += steal; + } + S390_lowcore.avg_steal_timer = avg_steal; +diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c +index 570016ae8bcd1..1ae7a76ae97b7 100644 +--- a/arch/s390/pci/pci.c ++++ b/arch/s390/pci/pci.c +@@ -682,56 +682,101 @@ int zpci_disable_device(struct zpci_dev *zdev) + } + EXPORT_SYMBOL_GPL(zpci_disable_device); + +-void zpci_remove_device(struct zpci_dev *zdev) ++/* zpci_remove_device - Removes the given zdev from the PCI core ++ * @zdev: the zdev to be removed from the PCI core ++ * @set_error: if true the device's error state is set to permanent failure ++ * ++ * Sets a zPCI device to a configured but offline state; the zPCI ++ * device is still accessible through its hotplug slot and the zPCI ++ * API but is removed from the common code PCI bus, making it ++ * no longer available to drivers. ++ */ ++void zpci_remove_device(struct zpci_dev *zdev, bool set_error) + { + struct zpci_bus *zbus = zdev->zbus; + struct pci_dev *pdev; + ++ if (!zdev->zbus->bus) ++ return; ++ + pdev = pci_get_slot(zbus->bus, zdev->devfn); + if (pdev) { +- if (pdev->is_virtfn) +- return zpci_iov_remove_virtfn(pdev, zdev->vfn); ++ if (set_error) ++ pdev->error_state = pci_channel_io_perm_failure; ++ if (pdev->is_virtfn) { ++ zpci_iov_remove_virtfn(pdev, zdev->vfn); ++ /* balance pci_get_slot */ ++ pci_dev_put(pdev); ++ return; ++ } + pci_stop_and_remove_bus_device_locked(pdev); ++ /* balance pci_get_slot */ ++ pci_dev_put(pdev); + } + } + +-int zpci_create_device(struct zpci_dev *zdev) ++/** ++ * zpci_create_device() - Create a new zpci_dev and add it to the zbus ++ * @fid: Function ID of the device to be created ++ * @fh: Current Function Handle of the device to be created ++ * @state: Initial state after creation either Standby or Configured ++ * ++ * Creates a new zpci device and adds it to its, possibly newly created, zbus ++ * as well as zpci_list. ++ * ++ * Returns: 0 on success, an error value otherwise ++ */ ++int zpci_create_device(u32 fid, u32 fh, enum zpci_state state) + { ++ struct zpci_dev *zdev; + int rc; + +- kref_init(&zdev->kref); ++ zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, state); ++ zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); ++ if (!zdev) ++ return -ENOMEM; + +- spin_lock(&zpci_list_lock); +- list_add_tail(&zdev->entry, &zpci_list); +- spin_unlock(&zpci_list_lock); ++ /* FID and Function Handle are the static/dynamic identifiers */ ++ zdev->fid = fid; ++ zdev->fh = fh; + +- rc = zpci_init_iommu(zdev); ++ /* Query function properties and update zdev */ ++ rc = clp_query_pci_fn(zdev); + if (rc) +- goto out; ++ goto error; ++ zdev->state = state; + ++ kref_init(&zdev->kref); + mutex_init(&zdev->lock); ++ ++ rc = zpci_init_iommu(zdev); ++ if (rc) ++ goto error; ++ + if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { + rc = zpci_enable_device(zdev); + if (rc) +- goto out_destroy_iommu; ++ goto error_destroy_iommu; + } + + rc = zpci_bus_device_register(zdev, &pci_root_ops); + if (rc) +- goto out_disable; ++ goto error_disable; ++ ++ spin_lock(&zpci_list_lock); ++ list_add_tail(&zdev->entry, &zpci_list); ++ spin_unlock(&zpci_list_lock); + + return 0; + +-out_disable: ++error_disable: + if (zdev->state == ZPCI_FN_STATE_ONLINE) + zpci_disable_device(zdev); +- +-out_destroy_iommu: ++error_destroy_iommu: + zpci_destroy_iommu(zdev); +-out: +- spin_lock(&zpci_list_lock); +- list_del(&zdev->entry); +- spin_unlock(&zpci_list_lock); ++error: ++ zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc); ++ kfree(zdev); + return rc; + } + +@@ -740,7 +785,7 @@ void zpci_release_device(struct kref *kref) + struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); + + if (zdev->zbus->bus) +- zpci_remove_device(zdev); ++ zpci_remove_device(zdev, false); + + switch (zdev->state) { + case ZPCI_FN_STATE_ONLINE: +diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c +index 153720d21ae7f..d3331596ddbe1 100644 +--- a/arch/s390/pci/pci_clp.c ++++ b/arch/s390/pci/pci_clp.c +@@ -181,7 +181,7 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev, + return 0; + } + +-static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) ++int clp_query_pci_fn(struct zpci_dev *zdev) + { + struct clp_req_rsp_query_pci *rrb; + int rc; +@@ -194,7 +194,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) + rrb->request.hdr.len = sizeof(rrb->request); + rrb->request.hdr.cmd = CLP_QUERY_PCI_FN; + rrb->response.hdr.len = sizeof(rrb->response); +- rrb->request.fh = fh; ++ rrb->request.fh = zdev->fh; + + rc = clp_req(rrb, CLP_LPS_PCI); + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) { +@@ -212,40 +212,6 @@ out: + return rc; + } + +-int clp_add_pci_device(u32 fid, u32 fh, int configured) +-{ +- struct zpci_dev *zdev; +- int rc = -ENOMEM; +- +- zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured); +- zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); +- if (!zdev) +- goto error; +- +- zdev->fh = fh; +- zdev->fid = fid; +- +- /* Query function properties and update zdev */ +- rc = clp_query_pci_fn(zdev, fh); +- if (rc) +- goto error; +- +- if (configured) +- zdev->state = ZPCI_FN_STATE_CONFIGURED; +- else +- zdev->state = ZPCI_FN_STATE_STANDBY; +- +- rc = zpci_create_device(zdev); +- if (rc) +- goto error; +- return 0; +- +-error: +- zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc); +- kfree(zdev); +- return rc; +-} +- + static int clp_refresh_fh(u32 fid); + /* + * Enable/Disable a given PCI function and update its function handle if +@@ -408,7 +374,7 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data) + + zdev = get_zdev_by_fid(entry->fid); + if (!zdev) +- clp_add_pci_device(entry->fid, entry->fh, entry->config_state); ++ zpci_create_device(entry->fid, entry->fh, entry->config_state); + } + + int clp_scan_pci_devices(void) +diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c +index 9a6bae503fe61..ac0c65cdd69d9 100644 +--- a/arch/s390/pci/pci_event.c ++++ b/arch/s390/pci/pci_event.c +@@ -76,20 +76,17 @@ void zpci_event_error(void *data) + static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) + { + struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); +- struct pci_dev *pdev = NULL; + enum zpci_state state; ++ struct pci_dev *pdev; + int ret; + +- if (zdev && zdev->zbus && zdev->zbus->bus) +- pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); +- + zpci_err("avail CCDF:\n"); + zpci_err_hex(ccdf, sizeof(*ccdf)); + + switch (ccdf->pec) { + case 0x0301: /* Reserved|Standby -> Configured */ + if (!zdev) { +- ret = clp_add_pci_device(ccdf->fid, ccdf->fh, 1); ++ zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED); + break; + } + /* the configuration request may be stale */ +@@ -116,7 +113,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) + break; + case 0x0302: /* Reserved -> Standby */ + if (!zdev) { +- clp_add_pci_device(ccdf->fid, ccdf->fh, 0); ++ zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY); + break; + } + zdev->fh = ccdf->fh; +@@ -124,8 +121,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) + case 0x0303: /* Deconfiguration requested */ + if (!zdev) + break; +- if (pdev) +- zpci_remove_device(zdev); ++ zpci_remove_device(zdev, false); + + ret = zpci_disable_device(zdev); + if (ret) +@@ -140,12 +136,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) + case 0x0304: /* Configured -> Standby|Reserved */ + if (!zdev) + break; +- if (pdev) { +- /* Give the driver a hint that the function is +- * already unusable. */ +- pdev->error_state = pci_channel_io_perm_failure; +- zpci_remove_device(zdev); +- } ++ /* Give the driver a hint that the function is ++ * already unusable. ++ */ ++ zpci_remove_device(zdev, true); + + zdev->fh = ccdf->fh; + zpci_disable_device(zdev); +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 4b05c876f9f69..e7dc13fe5e29f 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3562,6 +3562,9 @@ static int intel_pmu_hw_config(struct perf_event *event) + return ret; + + if (event->attr.precise_ip) { ++ if ((event->attr.config & INTEL_ARCH_EVENT_MASK) == INTEL_FIXED_VLBR_EVENT) ++ return -EINVAL; ++ + if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) { + event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; + if (!(event->attr.sample_type & +diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c +index 485c5066f8b8c..31a7a6566d077 100644 +--- a/arch/x86/events/intel/ds.c ++++ b/arch/x86/events/intel/ds.c +@@ -1894,7 +1894,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d + */ + if (!pebs_status && cpuc->pebs_enabled && + !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1))) +- pebs_status = cpuc->pebs_enabled; ++ pebs_status = p->status = cpuc->pebs_enabled; + + bit = find_first_bit((unsigned long *)&pebs_status, + x86_pmu.max_pebs_events); +diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h +index 82a08b5858182..50d02db723177 100644 +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -552,15 +552,6 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset, + *size = fpu_kernel_xstate_size; + } + +-/* +- * Thread-synchronous status. +- * +- * This is different from the flags in that nobody else +- * ever touches our thread-synchronous status, so we don't +- * have to worry about atomic accesses. +- */ +-#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ +- + static inline void + native_load_sp0(unsigned long sp0) + { +diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h +index 44733a4bfc429..e701f29b48817 100644 +--- a/arch/x86/include/asm/thread_info.h ++++ b/arch/x86/include/asm/thread_info.h +@@ -216,10 +216,31 @@ static inline int arch_within_stack_frames(const void * const stack, + + #endif + ++/* ++ * Thread-synchronous status. ++ * ++ * This is different from the flags in that nobody else ++ * ever touches our thread-synchronous status, so we don't ++ * have to worry about atomic accesses. ++ */ ++#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ ++ ++#ifndef __ASSEMBLY__ + #ifdef CONFIG_COMPAT + #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ ++#define TS_COMPAT_RESTART 0x0008 ++ ++#define arch_set_restart_data arch_set_restart_data ++ ++static inline void arch_set_restart_data(struct restart_block *restart) ++{ ++ struct thread_info *ti = current_thread_info(); ++ if (ti->status & TS_COMPAT) ++ ti->status |= TS_COMPAT_RESTART; ++ else ++ ti->status &= ~TS_COMPAT_RESTART; ++} + #endif +-#ifndef __ASSEMBLY__ + + #ifdef CONFIG_X86_32 + #define in_ia32_syscall() true +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index f4c0514fc5108..539f3e88ca7cd 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -2317,6 +2317,11 @@ static int cpuid_to_apicid[] = { + [0 ... NR_CPUS - 1] = -1, + }; + ++bool arch_match_cpu_phys_id(int cpu, u64 phys_id) ++{ ++ return phys_id == cpuid_to_apicid[cpu]; ++} ++ + #ifdef CONFIG_SMP + /** + * apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread +diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c +index 7b3c7e0d4a094..0d4818eab0da8 100644 +--- a/arch/x86/kernel/apic/io_apic.c ++++ b/arch/x86/kernel/apic/io_apic.c +@@ -1033,6 +1033,16 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, + if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { + irq = mp_irqs[idx].srcbusirq; + legacy = mp_is_legacy_irq(irq); ++ /* ++ * IRQ2 is unusable for historical reasons on systems which ++ * have a legacy PIC. See the comment vs. IRQ2 further down. ++ * ++ * If this gets removed at some point then the related code ++ * in lapic_assign_system_vectors() needs to be adjusted as ++ * well. ++ */ ++ if (legacy && irq == PIC_CASCADE_IR) ++ return -EINVAL; + } + + mutex_lock(&ioapic_mutex); +diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c +index be0d7d4152eca..f51cab3e983d8 100644 +--- a/arch/x86/kernel/signal.c ++++ b/arch/x86/kernel/signal.c +@@ -766,30 +766,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) + + static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) + { +- /* +- * This function is fundamentally broken as currently +- * implemented. +- * +- * The idea is that we want to trigger a call to the +- * restart_block() syscall and that we want in_ia32_syscall(), +- * in_x32_syscall(), etc. to match whatever they were in the +- * syscall being restarted. We assume that the syscall +- * instruction at (regs->ip - 2) matches whatever syscall +- * instruction we used to enter in the first place. +- * +- * The problem is that we can get here when ptrace pokes +- * syscall-like values into regs even if we're not in a syscall +- * at all. +- * +- * For now, we maintain historical behavior and guess based on +- * stored state. We could do better by saving the actual +- * syscall arch in restart_block or (with caveats on x32) by +- * checking if regs->ip points to 'int $0x80'. The current +- * behavior is incorrect if a tracer has a different bitness +- * than the tracee. +- */ + #ifdef CONFIG_IA32_EMULATION +- if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED)) ++ if (current_thread_info()->status & TS_COMPAT_RESTART) + return __NR_ia32_restart_syscall; + #endif + #ifdef CONFIG_X86_X32_ABI +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 87682dcb64ec3..bfda153b1a41d 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct device *dev) + static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + __releases(&dev->power.lock) __acquires(&dev->power.lock) + { +- bool use_links = dev->power.links_count > 0; +- bool get = false; + int retval, idx; +- bool put; ++ bool use_links = dev->power.links_count > 0; + + if (dev->power.irq_safe) { + spin_unlock(&dev->power.lock); +- } else if (!use_links) { +- spin_unlock_irq(&dev->power.lock); + } else { +- get = dev->power.runtime_status == RPM_RESUMING; +- + spin_unlock_irq(&dev->power.lock); + +- /* Resume suppliers if necessary. */ +- if (get) { ++ /* ++ * Resume suppliers if necessary. ++ * ++ * The device's runtime PM status cannot change until this ++ * routine returns, so it is safe to read the status outside of ++ * the lock. ++ */ ++ if (use_links && dev->power.runtime_status == RPM_RESUMING) { + idx = device_links_read_lock(); + + retval = rpm_get_suppliers(dev); +@@ -355,36 +355,24 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + + if (dev->power.irq_safe) { + spin_lock(&dev->power.lock); +- return retval; +- } +- +- spin_lock_irq(&dev->power.lock); +- +- if (!use_links) +- return retval; +- +- /* +- * If the device is suspending and the callback has returned success, +- * drop the usage counters of the suppliers that have been reference +- * counted on its resume. +- * +- * Do that if the resume fails too. +- */ +- put = dev->power.runtime_status == RPM_SUSPENDING && !retval; +- if (put) +- __update_runtime_status(dev, RPM_SUSPENDED); +- else +- put = get && retval; +- +- if (put) { +- spin_unlock_irq(&dev->power.lock); +- +- idx = device_links_read_lock(); ++ } else { ++ /* ++ * If the device is suspending and the callback has returned ++ * success, drop the usage counters of the suppliers that have ++ * been reference counted on its resume. ++ * ++ * Do that if resume fails too. ++ */ ++ if (use_links ++ && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) ++ || (dev->power.runtime_status == RPM_RESUMING && retval))) { ++ idx = device_links_read_lock(); + +-fail: +- rpm_put_suppliers(dev); ++ fail: ++ rpm_put_suppliers(dev); + +- device_links_read_unlock(idx); ++ device_links_read_unlock(idx); ++ } + + spin_lock_irq(&dev->power.lock); + } +diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c +index ef2a974a2f105..75bc401fdd189 100644 +--- a/drivers/counter/stm32-timer-cnt.c ++++ b/drivers/counter/stm32-timer-cnt.c +@@ -31,7 +31,7 @@ struct stm32_timer_cnt { + struct counter_device counter; + struct regmap *regmap; + struct clk *clk; +- u32 ceiling; ++ u32 max_arr; + bool enabled; + struct stm32_timer_regs bak; + }; +@@ -44,13 +44,14 @@ struct stm32_timer_cnt { + * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges + */ + enum stm32_count_function { +- STM32_COUNT_SLAVE_MODE_DISABLED = -1, ++ STM32_COUNT_SLAVE_MODE_DISABLED, + STM32_COUNT_ENCODER_MODE_1, + STM32_COUNT_ENCODER_MODE_2, + STM32_COUNT_ENCODER_MODE_3, + }; + + static enum counter_count_function stm32_count_functions[] = { ++ [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE, + [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, + [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, + [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, +@@ -73,8 +74,10 @@ static int stm32_count_write(struct counter_device *counter, + const unsigned long val) + { + struct stm32_timer_cnt *const priv = counter->priv; ++ u32 ceiling; + +- if (val > priv->ceiling) ++ regmap_read(priv->regmap, TIM_ARR, &ceiling); ++ if (val > ceiling) + return -EINVAL; + + return regmap_write(priv->regmap, TIM_CNT, val); +@@ -90,6 +93,9 @@ static int stm32_count_function_get(struct counter_device *counter, + regmap_read(priv->regmap, TIM_SMCR, &smcr); + + switch (smcr & TIM_SMCR_SMS) { ++ case 0: ++ *function = STM32_COUNT_SLAVE_MODE_DISABLED; ++ return 0; + case 1: + *function = STM32_COUNT_ENCODER_MODE_1; + return 0; +@@ -99,9 +105,9 @@ static int stm32_count_function_get(struct counter_device *counter, + case 3: + *function = STM32_COUNT_ENCODER_MODE_3; + return 0; ++ default: ++ return -EINVAL; + } +- +- return -EINVAL; + } + + static int stm32_count_function_set(struct counter_device *counter, +@@ -112,6 +118,9 @@ static int stm32_count_function_set(struct counter_device *counter, + u32 cr1, sms; + + switch (function) { ++ case STM32_COUNT_SLAVE_MODE_DISABLED: ++ sms = 0; ++ break; + case STM32_COUNT_ENCODER_MODE_1: + sms = 1; + break; +@@ -122,8 +131,7 @@ static int stm32_count_function_set(struct counter_device *counter, + sms = 3; + break; + default: +- sms = 0; +- break; ++ return -EINVAL; + } + + /* Store enable status */ +@@ -131,10 +139,6 @@ static int stm32_count_function_set(struct counter_device *counter, + + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + +- /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); +- regmap_write(priv->regmap, TIM_ARR, priv->ceiling); +- + regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); + + /* Make sure that registers are updated */ +@@ -185,11 +189,13 @@ static ssize_t stm32_count_ceiling_write(struct counter_device *counter, + if (ret) + return ret; + ++ if (ceiling > priv->max_arr) ++ return -ERANGE; ++ + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); + regmap_write(priv->regmap, TIM_ARR, ceiling); + +- priv->ceiling = ceiling; + return len; + } + +@@ -274,31 +280,36 @@ static int stm32_action_get(struct counter_device *counter, + size_t function; + int err; + +- /* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */ +- *action = STM32_SYNAPSE_ACTION_NONE; +- + err = stm32_count_function_get(counter, count, &function); + if (err) +- return 0; ++ return err; + + switch (function) { ++ case STM32_COUNT_SLAVE_MODE_DISABLED: ++ /* counts on internal clock when CEN=1 */ ++ *action = STM32_SYNAPSE_ACTION_NONE; ++ return 0; + case STM32_COUNT_ENCODER_MODE_1: + /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ + if (synapse->signal->id == count->synapses[0].signal->id) + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; +- break; ++ else ++ *action = STM32_SYNAPSE_ACTION_NONE; ++ return 0; + case STM32_COUNT_ENCODER_MODE_2: + /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ + if (synapse->signal->id == count->synapses[1].signal->id) + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; +- break; ++ else ++ *action = STM32_SYNAPSE_ACTION_NONE; ++ return 0; + case STM32_COUNT_ENCODER_MODE_3: + /* counts up/down on both TI1FP1 and TI2FP2 edges */ + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; +- break; ++ return 0; ++ default: ++ return -EINVAL; + } +- +- return 0; + } + + static const struct counter_ops stm32_timer_cnt_ops = { +@@ -359,7 +370,7 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) + + priv->regmap = ddata->regmap; + priv->clk = ddata->clk; +- priv->ceiling = ddata->max_arr; ++ priv->max_arr = ddata->max_arr; + + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index df3f9bcab581c..4b7ee3fa9224f 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -927,7 +927,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) + } + + /* first try to find a slot in an existing linked list entry */ +- for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) { ++ for (prsv = efi_memreserve_root->next; prsv; ) { + rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB); + index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); + if (index < rsv->size) { +@@ -937,6 +937,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) + memunmap(rsv); + return efi_mem_reserve_iomem(addr, size); + } ++ prsv = rsv->next; + memunmap(rsv); + } + +diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c +index 41c1d00bf933c..abdc8a6a39631 100644 +--- a/drivers/firmware/efi/vars.c ++++ b/drivers/firmware/efi/vars.c +@@ -484,6 +484,10 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), + } + } + ++ break; ++ case EFI_UNSUPPORTED: ++ err = -EOPNOTSUPP; ++ status = EFI_NOT_FOUND; + break; + case EFI_NOT_FOUND: + break; +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 7f557ea905424..0a2c4adcd833c 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -572,6 +572,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, + struct lock_class_key *lock_key, + struct lock_class_key *request_key) + { ++ struct fwnode_handle *fwnode = gc->parent ? dev_fwnode(gc->parent) : NULL; + unsigned long flags; + int ret = 0; + unsigned i; +@@ -601,6 +602,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, + gc->of_node = gdev->dev.of_node; + #endif + ++ /* ++ * Assign fwnode depending on the result of the previous calls, ++ * if none of them succeed, assign it to the parent's one. ++ */ ++ gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode; ++ + gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL); + if (gdev->id < 0) { + ret = gdev->id; +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index ea1ea147f6073..c07737c456776 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -1902,6 +1902,33 @@ cleanup: + return; + } + ++static void dm_set_dpms_off(struct dc_link *link) ++{ ++ struct dc_stream_state *stream_state; ++ struct amdgpu_dm_connector *aconnector = link->priv; ++ struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev); ++ struct dc_stream_update stream_update; ++ bool dpms_off = true; ++ ++ memset(&stream_update, 0, sizeof(stream_update)); ++ stream_update.dpms_off = &dpms_off; ++ ++ mutex_lock(&adev->dm.dc_lock); ++ stream_state = dc_stream_find_from_link(link); ++ ++ if (stream_state == NULL) { ++ DRM_DEBUG_DRIVER("Error finding stream state associated with link!\n"); ++ mutex_unlock(&adev->dm.dc_lock); ++ return; ++ } ++ ++ stream_update.stream = stream_state; ++ dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0, ++ stream_state, &stream_update, ++ stream_state->ctx->dc->current_state); ++ mutex_unlock(&adev->dm.dc_lock); ++} ++ + static int dm_resume(void *handle) + { + struct amdgpu_device *adev = handle; +@@ -2353,8 +2380,11 @@ static void handle_hpd_irq(void *param) + drm_kms_helper_hotplug_event(dev); + + } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) { +- amdgpu_dm_update_connector_after_detect(aconnector); ++ if (new_connection_type == dc_connection_none && ++ aconnector->dc_link->type == dc_connection_none) ++ dm_set_dpms_off(aconnector->dc_link); + ++ amdgpu_dm_update_connector_after_detect(aconnector); + + drm_modeset_lock_all(dev); + dm_restore_drm_connector_state(dev, connector); +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 45ad05f6e03b9..ffb21196bf599 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -2767,6 +2767,19 @@ struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i) + return NULL; + } + ++struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link) ++{ ++ uint8_t i; ++ struct dc_context *ctx = link->ctx; ++ ++ for (i = 0; i < ctx->dc->current_state->stream_count; i++) { ++ if (ctx->dc->current_state->streams[i]->link == link) ++ return ctx->dc->current_state->streams[i]; ++ } ++ ++ return NULL; ++} ++ + enum dc_irq_source dc_interrupt_to_irq_source( + struct dc *dc, + uint32_t src_id, +diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h +index c246af7c584b0..205bedd1b1966 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h +@@ -297,6 +297,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream); + + uint8_t dc_get_current_stream_count(struct dc *dc); + struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i); ++struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link); + + /* + * Return the current frame counter. +diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +index 41a1d0e9b7e20..e0df9b0065f9c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +@@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_format( + struct pwl_result_data *rgb_resulted; + struct pwl_result_data *rgb; + struct pwl_result_data *rgb_plus_1; ++ struct pwl_result_data *rgb_minus_1; + struct fixed31_32 end_value; + + int32_t region_start, region_end; +@@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_format( + region_start = -MAX_LOW_POINT; + region_end = NUMBER_REGIONS - MAX_LOW_POINT; + } else { +- /* 10 segments ++ /* 11 segments + * segment is from 2^-10 to 2^0 + * There are less than 256 points, for optimization + */ +@@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_format( + seg_distr[7] = 4; + seg_distr[8] = 4; + seg_distr[9] = 4; ++ seg_distr[10] = 1; + + region_start = -10; +- region_end = 0; ++ region_end = 1; + } + + for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) +@@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_format( + rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; + rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; + ++ rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; ++ rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; ++ rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; ++ + // All 3 color channels have same x + corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), + dc_fixpt_from_int(region_start)); +@@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_format( + + rgb = rgb_resulted; + rgb_plus_1 = rgb_resulted + 1; ++ rgb_minus_1 = rgb; + + i = 1; + while (i != hw_points + 1) { +- if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) +- rgb_plus_1->red = rgb->red; +- if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) +- rgb_plus_1->green = rgb->green; +- if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) +- rgb_plus_1->blue = rgb->blue; ++ if (i >= hw_points - 1) { ++ if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) ++ rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red); ++ if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) ++ rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green); ++ if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) ++ rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue); ++ } + + rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); + rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); +@@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_format( + } + + ++rgb_plus_1; ++ rgb_minus_1 = rgb; + ++rgb; + ++i; + } +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index 35629140fc7aa..c5223a9e0d891 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -4771,6 +4771,72 @@ static int smu7_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type + return 0; + } + ++static int smu7_get_sclks_with_latency(struct pp_hwmgr *hwmgr, ++ struct pp_clock_levels_with_latency *clocks) ++{ ++ struct phm_ppt_v1_information *table_info = ++ (struct phm_ppt_v1_information *)hwmgr->pptable; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table = ++ table_info->vdd_dep_on_sclk; ++ int i; ++ ++ clocks->num_levels = 0; ++ for (i = 0; i < dep_sclk_table->count; i++) { ++ if (dep_sclk_table->entries[i].clk) { ++ clocks->data[clocks->num_levels].clocks_in_khz = ++ dep_sclk_table->entries[i].clk * 10; ++ clocks->num_levels++; ++ } ++ } ++ ++ return 0; ++} ++ ++static int smu7_get_mclks_with_latency(struct pp_hwmgr *hwmgr, ++ struct pp_clock_levels_with_latency *clocks) ++{ ++ struct phm_ppt_v1_information *table_info = ++ (struct phm_ppt_v1_information *)hwmgr->pptable; ++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table = ++ table_info->vdd_dep_on_mclk; ++ int i; ++ ++ clocks->num_levels = 0; ++ for (i = 0; i < dep_mclk_table->count; i++) { ++ if (dep_mclk_table->entries[i].clk) { ++ clocks->data[clocks->num_levels].clocks_in_khz = ++ dep_mclk_table->entries[i].clk * 10; ++ clocks->data[clocks->num_levels].latency_in_us = ++ smu7_get_mem_latency(hwmgr, dep_mclk_table->entries[i].clk); ++ clocks->num_levels++; ++ } ++ } ++ ++ return 0; ++} ++ ++static int smu7_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, ++ enum amd_pp_clock_type type, ++ struct pp_clock_levels_with_latency *clocks) ++{ ++ if (!(hwmgr->chip_id >= CHIP_POLARIS10 && ++ hwmgr->chip_id <= CHIP_VEGAM)) ++ return -EINVAL; ++ ++ switch (type) { ++ case amd_pp_sys_clock: ++ smu7_get_sclks_with_latency(hwmgr, clocks); ++ break; ++ case amd_pp_mem_clock: ++ smu7_get_mclks_with_latency(hwmgr, clocks); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int smu7_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, + uint32_t virtual_addr_low, + uint32_t virtual_addr_hi, +@@ -5188,6 +5254,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { + .get_mclk_od = smu7_get_mclk_od, + .set_mclk_od = smu7_set_mclk_od, + .get_clock_by_type = smu7_get_clock_by_type, ++ .get_clock_by_type_with_latency = smu7_get_clock_by_type_with_latency, + .read_sensor = smu7_read_sensor, + .dynamic_state_management_disable = smu7_disable_dpm_tasks, + .avfs_control = smu7_avfs_control, +diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c +index 3640d0e229d22..74e66dea57086 100644 +--- a/drivers/gpu/drm/i915/i915_perf.c ++++ b/drivers/gpu/drm/i915/i915_perf.c +@@ -600,7 +600,6 @@ static int append_oa_sample(struct i915_perf_stream *stream, + { + int report_size = stream->oa_buffer.format_size; + struct drm_i915_perf_record_header header; +- u32 sample_flags = stream->sample_flags; + + header.type = DRM_I915_PERF_RECORD_SAMPLE; + header.pad = 0; +@@ -614,10 +613,8 @@ static int append_oa_sample(struct i915_perf_stream *stream, + return -EFAULT; + buf += sizeof(header); + +- if (sample_flags & SAMPLE_OA_REPORT) { +- if (copy_to_user(buf, report, report_size)) +- return -EFAULT; +- } ++ if (copy_to_user(buf, report, report_size)) ++ return -EFAULT; + + (*offset) += header.size; + +@@ -2676,7 +2673,7 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream) + + stream->perf->ops.oa_enable(stream); + +- if (stream->periodic) ++ if (stream->sample_flags & SAMPLE_OA_REPORT) + hrtimer_start(&stream->poll_check_timer, + ns_to_ktime(stream->poll_oa_period), + HRTIMER_MODE_REL_PINNED); +@@ -2739,7 +2736,7 @@ static void i915_oa_stream_disable(struct i915_perf_stream *stream) + { + stream->perf->ops.oa_disable(stream); + +- if (stream->periodic) ++ if (stream->sample_flags & SAMPLE_OA_REPORT) + hrtimer_cancel(&stream->poll_check_timer); + } + +@@ -3022,7 +3019,7 @@ static ssize_t i915_perf_read(struct file *file, + * disabled stream as an error. In particular it might otherwise lead + * to a deadlock for blocking file descriptors... + */ +- if (!stream->enabled) ++ if (!stream->enabled || !(stream->sample_flags & SAMPLE_OA_REPORT)) + return -EIO; + + if (!(file->f_flags & O_NONBLOCK)) { +diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig +index 17e9ceb9c6c48..86fda6182543b 100644 +--- a/drivers/iio/adc/Kconfig ++++ b/drivers/iio/adc/Kconfig +@@ -266,6 +266,8 @@ config ADI_AXI_ADC + select IIO_BUFFER + select IIO_BUFFER_HW_CONSUMER + select IIO_BUFFER_DMAENGINE ++ depends on HAS_IOMEM ++ depends on OF + help + Say yes here to build support for Analog Devices Generic + AXI ADC IP core. The IP core is used for interfacing with +@@ -912,6 +914,7 @@ config STM32_ADC_CORE + depends on ARCH_STM32 || COMPILE_TEST + depends on OF + depends on REGULATOR ++ depends on HAS_IOMEM + select IIO_BUFFER + select MFD_STM32_TIMERS + select IIO_STM32_TIMER_TRIGGER +diff --git a/drivers/iio/adc/ab8500-gpadc.c b/drivers/iio/adc/ab8500-gpadc.c +index 1bb987a4acbab..8d81505282dd3 100644 +--- a/drivers/iio/adc/ab8500-gpadc.c ++++ b/drivers/iio/adc/ab8500-gpadc.c +@@ -918,7 +918,7 @@ static int ab8500_gpadc_read_raw(struct iio_dev *indio_dev, + return processed; + + /* Return millivolt or milliamps or millicentigrades */ +- *val = processed * 1000; ++ *val = processed; + return IIO_VAL_INT; + } + +diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c +index 5d597e5050f68..1b4b3203e4285 100644 +--- a/drivers/iio/adc/ad7949.c ++++ b/drivers/iio/adc/ad7949.c +@@ -91,7 +91,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, + int ret; + int i; + int bits_per_word = ad7949_adc->resolution; +- int mask = GENMASK(ad7949_adc->resolution, 0); ++ int mask = GENMASK(ad7949_adc->resolution - 1, 0); + struct spi_message msg; + struct spi_transfer tx[] = { + { +diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c +index b0388f8a69f42..7e7d408452eca 100644 +--- a/drivers/iio/adc/qcom-spmi-vadc.c ++++ b/drivers/iio/adc/qcom-spmi-vadc.c +@@ -598,7 +598,7 @@ static const struct vadc_channels vadc_chans[] = { + VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) + + VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) +- VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0) ++ VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0, SCALE_DEFAULT) + VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) + VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) + VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) +diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c +index 00e58060968c9..8ea6c2aa6263d 100644 +--- a/drivers/iio/gyro/mpu3050-core.c ++++ b/drivers/iio/gyro/mpu3050-core.c +@@ -550,6 +550,8 @@ static irqreturn_t mpu3050_trigger_handler(int irq, void *p) + MPU3050_FIFO_R, + &fifo_values[offset], + toread); ++ if (ret) ++ goto out_trigger_unlock; + + dev_dbg(mpu3050->dev, + "%04x %04x %04x %04x %04x\n", +diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c +index 52f605114ef77..d62705448ae25 100644 +--- a/drivers/iio/humidity/hid-sensor-humidity.c ++++ b/drivers/iio/humidity/hid-sensor-humidity.c +@@ -15,7 +15,10 @@ + struct hid_humidity_state { + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info humidity_attr; +- s32 humidity_data; ++ struct { ++ s32 humidity_data; ++ u64 timestamp __aligned(8); ++ } scan; + int scale_pre_decml; + int scale_post_decml; + int scale_precision; +@@ -125,9 +128,8 @@ static int humidity_proc_event(struct hid_sensor_hub_device *hsdev, + struct hid_humidity_state *humid_st = iio_priv(indio_dev); + + if (atomic_read(&humid_st->common_attributes.data_ready)) +- iio_push_to_buffers_with_timestamp(indio_dev, +- &humid_st->humidity_data, +- iio_get_time_ns(indio_dev)); ++ iio_push_to_buffers_with_timestamp(indio_dev, &humid_st->scan, ++ iio_get_time_ns(indio_dev)); + + return 0; + } +@@ -142,7 +144,7 @@ static int humidity_capture_sample(struct hid_sensor_hub_device *hsdev, + + switch (usage_id) { + case HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY: +- humid_st->humidity_data = *(s32 *)raw_data; ++ humid_st->scan.humidity_data = *(s32 *)raw_data; + + return 0; + default: +diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c +index 54af2ed664f6f..785a4ce606d89 100644 +--- a/drivers/iio/imu/adis16400.c ++++ b/drivers/iio/imu/adis16400.c +@@ -462,8 +462,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) + if (ret) + goto err_ret; + +- ret = sscanf(indio_dev->name, "adis%u\n", &device_id); +- if (ret != 1) { ++ if (sscanf(indio_dev->name, "adis%u\n", &device_id) != 1) { + ret = -EINVAL; + goto err_ret; + } +diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c +index 330cf359e0b81..e9e00ce0c6d4d 100644 +--- a/drivers/iio/light/hid-sensor-prox.c ++++ b/drivers/iio/light/hid-sensor-prox.c +@@ -23,6 +23,9 @@ struct prox_state { + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info prox_attr; + u32 human_presence; ++ int scale_pre_decml; ++ int scale_post_decml; ++ int scale_precision; + }; + + /* Channel definitions */ +@@ -93,8 +96,9 @@ static int prox_read_raw(struct iio_dev *indio_dev, + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: +- *val = prox_state->prox_attr.units; +- ret_type = IIO_VAL_INT; ++ *val = prox_state->scale_pre_decml; ++ *val2 = prox_state->scale_post_decml; ++ ret_type = prox_state->scale_precision; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( +@@ -234,6 +238,11 @@ static int prox_parse_report(struct platform_device *pdev, + HID_USAGE_SENSOR_HUMAN_PRESENCE, + &st->common_attributes.sensitivity); + ++ st->scale_precision = hid_sensor_format_scale( ++ hsdev->usage, ++ &st->prox_attr, ++ &st->scale_pre_decml, &st->scale_post_decml); ++ + return ret; + } + +diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c +index 81688f1b932f1..da9a247097fa2 100644 +--- a/drivers/iio/temperature/hid-sensor-temperature.c ++++ b/drivers/iio/temperature/hid-sensor-temperature.c +@@ -15,7 +15,10 @@ + struct temperature_state { + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info temperature_attr; +- s32 temperature_data; ++ struct { ++ s32 temperature_data; ++ u64 timestamp __aligned(8); ++ } scan; + int scale_pre_decml; + int scale_post_decml; + int scale_precision; +@@ -32,7 +35,7 @@ static const struct iio_chan_spec temperature_channels[] = { + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + }, +- IIO_CHAN_SOFT_TIMESTAMP(3), ++ IIO_CHAN_SOFT_TIMESTAMP(1), + }; + + /* Adjust channel real bits based on report descriptor */ +@@ -123,9 +126,8 @@ static int temperature_proc_event(struct hid_sensor_hub_device *hsdev, + struct temperature_state *temp_st = iio_priv(indio_dev); + + if (atomic_read(&temp_st->common_attributes.data_ready)) +- iio_push_to_buffers_with_timestamp(indio_dev, +- &temp_st->temperature_data, +- iio_get_time_ns(indio_dev)); ++ iio_push_to_buffers_with_timestamp(indio_dev, &temp_st->scan, ++ iio_get_time_ns(indio_dev)); + + return 0; + } +@@ -140,7 +142,7 @@ static int temperature_capture_sample(struct hid_sensor_hub_device *hsdev, + + switch (usage_id) { + case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE: +- temp_st->temperature_data = *(s32 *)raw_data; ++ temp_st->scan.temperature_data = *(s32 *)raw_data; + return 0; + default: + return -EINVAL; +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 600e056798c0a..75caeec378bda 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -2458,8 +2458,6 @@ static int check_qp_type(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr, + case MLX5_IB_QPT_HW_GSI: + case IB_QPT_DRIVER: + case IB_QPT_GSI: +- if (dev->profile == &raw_eth_profile) +- goto out; + case IB_QPT_RAW_PACKET: + case IB_QPT_UD: + case MLX5_IB_QPT_REG_UMR: +@@ -2654,10 +2652,6 @@ static int process_create_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, + int create_flags = attr->create_flags; + bool cond; + +- if (qp->type == IB_QPT_UD && dev->profile == &raw_eth_profile) +- if (create_flags & ~MLX5_IB_QP_CREATE_WC_TEST) +- return -EINVAL; +- + if (qp_type == MLX5_IB_QPT_DCT) + return (create_flags) ? -EINVAL : 0; + +@@ -4235,6 +4229,23 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, + return 0; + } + ++static bool mlx5_ib_modify_qp_allowed(struct mlx5_ib_dev *dev, ++ struct mlx5_ib_qp *qp, ++ enum ib_qp_type qp_type) ++{ ++ if (dev->profile != &raw_eth_profile) ++ return true; ++ ++ if (qp_type == IB_QPT_RAW_PACKET || qp_type == MLX5_IB_QPT_REG_UMR) ++ return true; ++ ++ /* Internal QP used for wc testing, with NOPs in wq */ ++ if (qp->flags & MLX5_IB_QP_CREATE_WC_TEST) ++ return true; ++ ++ return false; ++} ++ + int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_udata *udata) + { +@@ -4247,6 +4258,9 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int err = -EINVAL; + int port; + ++ if (!mlx5_ib_modify_qp_allowed(dev, qp, ibqp->qp_type)) ++ return -EOPNOTSUPP; ++ + if (ibqp->rwq_ind_tbl) + return -ENOSYS; + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +index 5c2107ce7f6e1..6eb95e3c4c8a4 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -1237,8 +1237,7 @@ static void free_sess_reqs(struct rtrs_clt_sess *sess) + if (req->mr) + ib_dereg_mr(req->mr); + kfree(req->sge); +- rtrs_iu_free(req->iu, DMA_TO_DEVICE, +- sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(req->iu, sess->s.dev->ib_dev, 1); + } + kfree(sess->reqs); + sess->reqs = NULL; +@@ -1611,8 +1610,7 @@ static void destroy_con_cq_qp(struct rtrs_clt_con *con) + + rtrs_cq_qp_destroy(&con->c); + if (con->rsp_ius) { +- rtrs_iu_free(con->rsp_ius, DMA_FROM_DEVICE, +- sess->s.dev->ib_dev, con->queue_size); ++ rtrs_iu_free(con->rsp_ius, sess->s.dev->ib_dev, con->queue_size); + con->rsp_ius = NULL; + con->queue_size = 0; + } +@@ -2252,7 +2250,7 @@ static void rtrs_clt_info_req_done(struct ib_cq *cq, struct ib_wc *wc) + struct rtrs_iu *iu; + + iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe); +- rtrs_iu_free(iu, DMA_TO_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(iu, sess->s.dev->ib_dev, 1); + + if (unlikely(wc->status != IB_WC_SUCCESS)) { + rtrs_err(sess->clt, "Sess info request send failed: %s\n", +@@ -2381,7 +2379,7 @@ static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc) + + out: + rtrs_clt_update_wc_stats(con); +- rtrs_iu_free(iu, DMA_FROM_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(iu, sess->s.dev->ib_dev, 1); + rtrs_clt_change_state(sess, state); + } + +@@ -2443,9 +2441,9 @@ static int rtrs_send_sess_info(struct rtrs_clt_sess *sess) + + out: + if (tx_iu) +- rtrs_iu_free(tx_iu, DMA_TO_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(tx_iu, sess->s.dev->ib_dev, 1); + if (rx_iu) +- rtrs_iu_free(rx_iu, DMA_FROM_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(rx_iu, sess->s.dev->ib_dev, 1); + if (unlikely(err)) + /* If we've never taken async path because of malloc problems */ + rtrs_clt_change_state(sess, RTRS_CLT_CONNECTING_ERR); +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h +index 2e1d2f7e372ac..8caad0a2322bf 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h ++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h +@@ -289,8 +289,7 @@ struct rtrs_msg_rdma_hdr { + struct rtrs_iu *rtrs_iu_alloc(u32 queue_size, size_t size, gfp_t t, + struct ib_device *dev, enum dma_data_direction, + void (*done)(struct ib_cq *cq, struct ib_wc *wc)); +-void rtrs_iu_free(struct rtrs_iu *iu, enum dma_data_direction dir, +- struct ib_device *dev, u32 queue_size); ++void rtrs_iu_free(struct rtrs_iu *iu, struct ib_device *dev, u32 queue_size); + int rtrs_iu_post_recv(struct rtrs_con *con, struct rtrs_iu *iu); + int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size, + struct ib_send_wr *head); +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index b690a3b8f94d9..43806180f85ec 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -584,8 +584,7 @@ static void unmap_cont_bufs(struct rtrs_srv_sess *sess) + struct rtrs_srv_mr *srv_mr; + + srv_mr = &sess->mrs[i]; +- rtrs_iu_free(srv_mr->iu, DMA_TO_DEVICE, +- sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(srv_mr->iu, sess->s.dev->ib_dev, 1); + ib_dereg_mr(srv_mr->mr); + ib_dma_unmap_sg(sess->s.dev->ib_dev, srv_mr->sgt.sgl, + srv_mr->sgt.nents, DMA_BIDIRECTIONAL); +@@ -672,7 +671,7 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess) + if (!srv_mr->iu) { + err = -ENOMEM; + rtrs_err(ss, "rtrs_iu_alloc(), err: %d\n", err); +- goto free_iu; ++ goto dereg_mr; + } + } + /* Eventually dma addr for each chunk can be cached */ +@@ -688,9 +687,7 @@ err: + srv_mr = &sess->mrs[mri]; + sgt = &srv_mr->sgt; + mr = srv_mr->mr; +-free_iu: +- rtrs_iu_free(srv_mr->iu, DMA_TO_DEVICE, +- sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(srv_mr->iu, sess->s.dev->ib_dev, 1); + dereg_mr: + ib_dereg_mr(mr); + unmap_sg: +@@ -742,7 +739,7 @@ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc) + struct rtrs_iu *iu; + + iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe); +- rtrs_iu_free(iu, DMA_TO_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(iu, sess->s.dev->ib_dev, 1); + + if (unlikely(wc->status != IB_WC_SUCCESS)) { + rtrs_err(s, "Sess info response send failed: %s\n", +@@ -868,7 +865,7 @@ static int process_info_req(struct rtrs_srv_con *con, + if (unlikely(err)) { + rtrs_err(s, "rtrs_iu_post_send(), err: %d\n", err); + iu_free: +- rtrs_iu_free(tx_iu, DMA_TO_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(tx_iu, sess->s.dev->ib_dev, 1); + } + rwr_free: + kfree(rwr); +@@ -913,7 +910,7 @@ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc) + goto close; + + out: +- rtrs_iu_free(iu, DMA_FROM_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(iu, sess->s.dev->ib_dev, 1); + return; + close: + close_sess(sess); +@@ -936,7 +933,7 @@ static int post_recv_info_req(struct rtrs_srv_con *con) + err = rtrs_iu_post_recv(&con->c, rx_iu); + if (unlikely(err)) { + rtrs_err(s, "rtrs_iu_post_recv(), err: %d\n", err); +- rtrs_iu_free(rx_iu, DMA_FROM_DEVICE, sess->s.dev->ib_dev, 1); ++ rtrs_iu_free(rx_iu, sess->s.dev->ib_dev, 1); + return err; + } + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c +index a3e1a027f8081..d13aff0aa8165 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs.c +@@ -31,6 +31,7 @@ struct rtrs_iu *rtrs_iu_alloc(u32 queue_size, size_t size, gfp_t gfp_mask, + return NULL; + for (i = 0; i < queue_size; i++) { + iu = &ius[i]; ++ iu->direction = dir; + iu->buf = kzalloc(size, gfp_mask); + if (!iu->buf) + goto err; +@@ -41,17 +42,15 @@ struct rtrs_iu *rtrs_iu_alloc(u32 queue_size, size_t size, gfp_t gfp_mask, + + iu->cqe.done = done; + iu->size = size; +- iu->direction = dir; + } + return ius; + err: +- rtrs_iu_free(ius, dir, dma_dev, i); ++ rtrs_iu_free(ius, dma_dev, i); + return NULL; + } + EXPORT_SYMBOL_GPL(rtrs_iu_alloc); + +-void rtrs_iu_free(struct rtrs_iu *ius, enum dma_data_direction dir, +- struct ib_device *ibdev, u32 queue_size) ++void rtrs_iu_free(struct rtrs_iu *ius, struct ib_device *ibdev, u32 queue_size) + { + struct rtrs_iu *iu; + int i; +@@ -61,7 +60,7 @@ void rtrs_iu_free(struct rtrs_iu *ius, enum dma_data_direction dir, + + for (i = 0; i < queue_size; i++) { + iu = &ius[i]; +- ib_dma_unmap_single(ibdev, iu->dma_addr, iu->size, dir); ++ ib_dma_unmap_single(ibdev, iu->dma_addr, iu->size, iu->direction); + kfree(iu->buf); + } + kfree(ius); +@@ -105,6 +104,22 @@ int rtrs_post_recv_empty(struct rtrs_con *con, struct ib_cqe *cqe) + } + EXPORT_SYMBOL_GPL(rtrs_post_recv_empty); + ++static int rtrs_post_send(struct ib_qp *qp, struct ib_send_wr *head, ++ struct ib_send_wr *wr) ++{ ++ if (head) { ++ struct ib_send_wr *tail = head; ++ ++ while (tail->next) ++ tail = tail->next; ++ tail->next = wr; ++ } else { ++ head = wr; ++ } ++ ++ return ib_post_send(qp, head, NULL); ++} ++ + int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size, + struct ib_send_wr *head) + { +@@ -127,17 +142,7 @@ int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size, + .send_flags = IB_SEND_SIGNALED, + }; + +- if (head) { +- struct ib_send_wr *tail = head; +- +- while (tail->next) +- tail = tail->next; +- tail->next = ≀ +- } else { +- head = ≀ +- } +- +- return ib_post_send(con->qp, head, NULL); ++ return rtrs_post_send(con->qp, head, &wr); + } + EXPORT_SYMBOL_GPL(rtrs_iu_post_send); + +@@ -169,17 +174,7 @@ int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu, + if (WARN_ON(sge[i].length == 0)) + return -EINVAL; + +- if (head) { +- struct ib_send_wr *tail = head; +- +- while (tail->next) +- tail = tail->next; +- tail->next = &wr.wr; +- } else { +- head = &wr.wr; +- } +- +- return ib_post_send(con->qp, head, NULL); ++ return rtrs_post_send(con->qp, head, &wr.wr); + } + EXPORT_SYMBOL_GPL(rtrs_iu_post_rdma_write_imm); + +@@ -187,26 +182,16 @@ int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, + u32 imm_data, enum ib_send_flags flags, + struct ib_send_wr *head) + { +- struct ib_send_wr wr; ++ struct ib_rdma_wr wr; + +- wr = (struct ib_send_wr) { +- .wr_cqe = cqe, +- .send_flags = flags, +- .opcode = IB_WR_RDMA_WRITE_WITH_IMM, +- .ex.imm_data = cpu_to_be32(imm_data), ++ wr = (struct ib_rdma_wr) { ++ .wr.wr_cqe = cqe, ++ .wr.send_flags = flags, ++ .wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM, ++ .wr.ex.imm_data = cpu_to_be32(imm_data), + }; + +- if (head) { +- struct ib_send_wr *tail = head; +- +- while (tail->next) +- tail = tail->next; +- tail->next = ≀ +- } else { +- head = ≀ +- } +- +- return ib_post_send(con->qp, head, NULL); ++ return rtrs_post_send(con->qp, head, &wr.wr); + } + EXPORT_SYMBOL_GPL(rtrs_post_rdma_write_imm_empty); + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 47afc5938c26b..6d5a39af10978 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3918,11 +3918,15 @@ static int bond_neigh_init(struct neighbour *n) + + rcu_read_lock(); + slave = bond_first_slave_rcu(bond); +- if (!slave) ++ if (!slave) { ++ ret = -EINVAL; + goto out; ++ } + slave_ops = slave->dev->netdev_ops; +- if (!slave_ops->ndo_neigh_setup) ++ if (!slave_ops->ndo_neigh_setup) { ++ ret = -EINVAL; + goto out; ++ } + + /* TODO: find another way [1] to implement this. + * Passing a zeroed structure is fragile, +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index f184f4a79cc39..4a4cb62b73320 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -409,6 +409,8 @@ static void replenish_pools(struct ibmvnic_adapter *adapter) + if (adapter->rx_pool[i].active) + replenish_rx_pool(adapter, &adapter->rx_pool[i]); + } ++ ++ netdev_dbg(adapter->netdev, "Replenished %d pools\n", i); + } + + static void release_stats_buffers(struct ibmvnic_adapter *adapter) +@@ -914,6 +916,7 @@ static int ibmvnic_login(struct net_device *netdev) + + __ibmvnic_set_mac(netdev, adapter->mac_addr); + ++ netdev_dbg(netdev, "[S:%d] Login succeeded\n", adapter->state); + return 0; + } + +@@ -1343,6 +1346,10 @@ static int ibmvnic_close(struct net_device *netdev) + struct ibmvnic_adapter *adapter = netdev_priv(netdev); + int rc; + ++ netdev_dbg(netdev, "[S:%d FOP:%d FRR:%d] Closing\n", ++ adapter->state, adapter->failover_pending, ++ adapter->force_reset_recovery); ++ + /* If device failover is pending, just set device state and return. + * Device operation will be handled by reset routine. + */ +@@ -1937,8 +1944,10 @@ static int do_reset(struct ibmvnic_adapter *adapter, + struct net_device *netdev = adapter->netdev; + int i, rc; + +- netdev_dbg(adapter->netdev, "Re-setting driver (%d)\n", +- rwi->reset_reason); ++ netdev_dbg(adapter->netdev, ++ "[S:%d FOP:%d] Reset reason %d, reset_state %d\n", ++ adapter->state, adapter->failover_pending, ++ rwi->reset_reason, reset_state); + + rtnl_lock(); + /* +@@ -2097,6 +2106,8 @@ out: + adapter->state = reset_state; + rtnl_unlock(); + ++ netdev_dbg(adapter->netdev, "[S:%d FOP:%d] Reset done, rc %d\n", ++ adapter->state, adapter->failover_pending, rc); + return rc; + } + +@@ -2166,6 +2177,8 @@ out: + /* restore adapter state if reset failed */ + if (rc) + adapter->state = reset_state; ++ netdev_dbg(adapter->netdev, "[S:%d FOP:%d] Hard reset done, rc %d\n", ++ adapter->state, adapter->failover_pending, rc); + return rc; + } + +@@ -2275,6 +2288,11 @@ static void __ibmvnic_reset(struct work_struct *work) + } + + clear_bit_unlock(0, &adapter->resetting); ++ ++ netdev_dbg(adapter->netdev, ++ "[S:%d FRR:%d WFR:%d] Done processing resets\n", ++ adapter->state, adapter->force_reset_recovery, ++ adapter->wait_for_reset); + } + + static void __ibmvnic_delayed_reset(struct work_struct *work) +@@ -2295,6 +2313,8 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, + unsigned long flags; + int ret; + ++ spin_lock_irqsave(&adapter->rwi_lock, flags); ++ + /* + * If failover is pending don't schedule any other reset. + * Instead let the failover complete. If there is already a +@@ -2315,13 +2335,11 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, + goto err; + } + +- spin_lock_irqsave(&adapter->rwi_lock, flags); +- + list_for_each(entry, &adapter->rwi_list) { + tmp = list_entry(entry, struct ibmvnic_rwi, list); + if (tmp->reset_reason == reason) { +- netdev_dbg(netdev, "Skipping matching reset\n"); +- spin_unlock_irqrestore(&adapter->rwi_lock, flags); ++ netdev_dbg(netdev, "Skipping matching reset, reason=%d\n", ++ reason); + ret = EBUSY; + goto err; + } +@@ -2329,8 +2347,6 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, + + rwi = kzalloc(sizeof(*rwi), GFP_ATOMIC); + if (!rwi) { +- spin_unlock_irqrestore(&adapter->rwi_lock, flags); +- ibmvnic_close(netdev); + ret = ENOMEM; + goto err; + } +@@ -2343,12 +2359,17 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, + } + rwi->reset_reason = reason; + list_add_tail(&rwi->list, &adapter->rwi_list); +- spin_unlock_irqrestore(&adapter->rwi_lock, flags); + netdev_dbg(adapter->netdev, "Scheduling reset (reason %d)\n", reason); + schedule_work(&adapter->ibmvnic_reset); + +- return 0; ++ ret = 0; + err: ++ /* ibmvnic_close() below can block, so drop the lock first */ ++ spin_unlock_irqrestore(&adapter->rwi_lock, flags); ++ ++ if (ret == ENOMEM) ++ ibmvnic_close(netdev); ++ + return -ret; + } + +@@ -5359,7 +5380,18 @@ static int ibmvnic_remove(struct vio_dev *dev) + unsigned long flags; + + spin_lock_irqsave(&adapter->state_lock, flags); ++ ++ /* If ibmvnic_reset() is scheduling a reset, wait for it to ++ * finish. Then, set the state to REMOVING to prevent it from ++ * scheduling any more work and to have reset functions ignore ++ * any resets that have already been scheduled. Drop the lock ++ * after setting state, so __ibmvnic_reset() which is called ++ * from the flush_work() below, can make progress. ++ */ ++ spin_lock(&adapter->rwi_lock); + adapter->state = VNIC_REMOVING; ++ spin_unlock(&adapter->rwi_lock); ++ + spin_unlock_irqrestore(&adapter->state_lock, flags); + + flush_work(&adapter->ibmvnic_reset); +diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h +index 21e7ea858cda3..b27211063c643 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.h ++++ b/drivers/net/ethernet/ibm/ibmvnic.h +@@ -1080,6 +1080,7 @@ struct ibmvnic_adapter { + struct tasklet_struct tasklet; + enum vnic_state state; + enum ibmvnic_reset_reason reset_reason; ++ /* when taking both state and rwi locks, take state lock first */ + spinlock_t rwi_lock; + struct list_head rwi_list; + struct work_struct ibmvnic_reset; +@@ -1096,6 +1097,8 @@ struct ibmvnic_adapter { + struct ibmvnic_tunables desired; + struct ibmvnic_tunables fallback; + +- /* Used for serializatin of state field */ ++ /* Used for serialization of state field. When taking both state ++ * and rwi locks, take state lock first. ++ */ + spinlock_t state_lock; + }; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 3e4a4d6f0419c..4a2d03cada01e 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -5920,7 +5920,7 @@ static int i40e_add_channel(struct i40e_pf *pf, u16 uplink_seid, + ch->enabled_tc = !i40e_is_channel_macvlan(ch) && enabled_tc; + ch->seid = ctxt.seid; + ch->vsi_number = ctxt.vsi_number; +- ch->stat_counter_idx = cpu_to_le16(ctxt.info.stat_counter_idx); ++ ch->stat_counter_idx = le16_to_cpu(ctxt.info.stat_counter_idx); + + /* copy just the sections touched not the entire info + * since not all sections are valid as returned by +@@ -7599,8 +7599,8 @@ static inline void + i40e_set_cld_element(struct i40e_cloud_filter *filter, + struct i40e_aqc_cloud_filters_element_data *cld) + { +- int i, j; + u32 ipa; ++ int i; + + memset(cld, 0, sizeof(*cld)); + ether_addr_copy(cld->outer_mac, filter->dst_mac); +@@ -7611,14 +7611,14 @@ i40e_set_cld_element(struct i40e_cloud_filter *filter, + + if (filter->n_proto == ETH_P_IPV6) { + #define IPV6_MAX_INDEX (ARRAY_SIZE(filter->dst_ipv6) - 1) +- for (i = 0, j = 0; i < ARRAY_SIZE(filter->dst_ipv6); +- i++, j += 2) { ++ for (i = 0; i < ARRAY_SIZE(filter->dst_ipv6); i++) { + ipa = be32_to_cpu(filter->dst_ipv6[IPV6_MAX_INDEX - i]); +- ipa = cpu_to_le32(ipa); +- memcpy(&cld->ipaddr.raw_v6.data[j], &ipa, sizeof(ipa)); ++ ++ *(__le32 *)&cld->ipaddr.raw_v6.data[i * 2] = cpu_to_le32(ipa); + } + } else { + ipa = be32_to_cpu(filter->dst_ipv4); ++ + memcpy(&cld->ipaddr.v4.data, &ipa, sizeof(ipa)); + } + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +index 38dec49ac64d2..899714243af7a 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +@@ -1782,7 +1782,7 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring, + skb_record_rx_queue(skb, rx_ring->queue_index); + + if (qword & BIT(I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)) { +- u16 vlan_tag = rx_desc->wb.qword0.lo_dword.l2tag1; ++ __le16 vlan_tag = rx_desc->wb.qword0.lo_dword.l2tag1; + + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + le16_to_cpu(vlan_tag)); +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index a7f74b3b97af5..47ae1d1723c54 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -1263,6 +1263,7 @@ static struct phy_driver ksphy_driver[] = { + .probe = kszphy_probe, + .config_init = ksz8081_config_init, + .ack_interrupt = kszphy_ack_interrupt, ++ .soft_reset = genphy_soft_reset, + .config_intr = kszphy_config_intr, + .get_sset_count = kszphy_get_sset_count, + .get_strings = kszphy_get_strings, +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +index 92c50efd48fc3..39842bdef4b46 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +@@ -92,6 +92,7 @@ + #define IWL_SNJ_A_HR_B_FW_PRE "iwlwifi-SoSnj-a0-hr-b0-" + #define IWL_MA_A_GF_A_FW_PRE "iwlwifi-ma-a0-gf-a0-" + #define IWL_MA_A_MR_A_FW_PRE "iwlwifi-ma-a0-mr-a0-" ++#define IWL_SNJ_A_MR_A_FW_PRE "iwlwifi-SoSnj-a0-mr-a0-" + + #define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \ + IWL_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" +@@ -127,6 +128,8 @@ + IWL_MA_A_GF_A_FW_PRE __stringify(api) ".ucode" + #define IWL_MA_A_MR_A_FW_MODULE_FIRMWARE(api) \ + IWL_MA_A_MR_A_FW_PRE __stringify(api) ".ucode" ++#define IWL_SNJ_A_MR_A_MODULE_FIRMWARE(api) \ ++ IWL_SNJ_A_MR_A_FW_PRE __stringify(api) ".ucode" + + static const struct iwl_base_params iwl_22000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +@@ -672,6 +675,13 @@ const struct iwl_cfg iwl_cfg_ma_a0_mr_a0 = { + .num_rbds = IWL_NUM_RBDS_AX210_HE, + }; + ++const struct iwl_cfg iwl_cfg_snj_a0_mr_a0 = { ++ .fw_name_pre = IWL_SNJ_A_MR_A_FW_PRE, ++ .uhb_supported = true, ++ IWL_DEVICE_AX210, ++ .num_rbds = IWL_NUM_RBDS_AX210_HE, ++}; ++ + MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +@@ -689,3 +699,4 @@ MODULE_FIRMWARE(IWL_SNJ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_SNJ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_MA_A_GF_A_FW_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_MA_A_MR_A_FW_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); ++MODULE_FIRMWARE(IWL_SNJ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +index 9b91aa9b2e7f1..bd04e4fbbb8ab 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +@@ -472,6 +472,7 @@ struct iwl_cfg { + #define IWL_CFG_MAC_TYPE_QU 0x33 + #define IWL_CFG_MAC_TYPE_QUZ 0x35 + #define IWL_CFG_MAC_TYPE_QNJ 0x36 ++#define IWL_CFG_MAC_TYPE_SNJ 0x42 + #define IWL_CFG_MAC_TYPE_MA 0x44 + + #define IWL_CFG_RF_TYPE_TH 0x105 +@@ -656,6 +657,7 @@ extern const struct iwl_cfg iwlax211_cfg_snj_gf_a0; + extern const struct iwl_cfg iwlax201_cfg_snj_hr_b0; + extern const struct iwl_cfg iwl_cfg_ma_a0_gf_a0; + extern const struct iwl_cfg iwl_cfg_ma_a0_mr_a0; ++extern const struct iwl_cfg iwl_cfg_snj_a0_mr_a0; + #endif /* CONFIG_IWLMVM */ + + #endif /* __IWL_CONFIG_H__ */ +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 2823a1e81656d..fa32f9045c0cb 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1002,6 +1002,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { + IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_ma_a0_mr_a0, iwl_ma_name), ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_SNJ, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY, ++ IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_snj_a0_mr_a0, iwl_ma_name), ++ + + #endif /* CONFIG_IWLMVM */ + }; +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index e1e574ecf031b..de846aaa8728b 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1894,30 +1894,18 @@ static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns) + blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); + } + +-static void nvme_config_write_zeroes(struct gendisk *disk, struct nvme_ns *ns) ++/* ++ * Even though NVMe spec explicitly states that MDTS is not applicable to the ++ * write-zeroes, we are cautious and limit the size to the controllers ++ * max_hw_sectors value, which is based on the MDTS field and possibly other ++ * limiting factors. ++ */ ++static void nvme_config_write_zeroes(struct request_queue *q, ++ struct nvme_ctrl *ctrl) + { +- u64 max_blocks; +- +- if (!(ns->ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) || +- (ns->ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) +- return; +- /* +- * Even though NVMe spec explicitly states that MDTS is not +- * applicable to the write-zeroes:- "The restriction does not apply to +- * commands that do not transfer data between the host and the +- * controller (e.g., Write Uncorrectable ro Write Zeroes command).". +- * In order to be more cautious use controller's max_hw_sectors value +- * to configure the maximum sectors for the write-zeroes which is +- * configured based on the controller's MDTS field in the +- * nvme_init_identify() if available. +- */ +- if (ns->ctrl->max_hw_sectors == UINT_MAX) +- max_blocks = (u64)USHRT_MAX + 1; +- else +- max_blocks = ns->ctrl->max_hw_sectors + 1; +- +- blk_queue_max_write_zeroes_sectors(disk->queue, +- nvme_lba_to_sect(ns, max_blocks)); ++ if ((ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) && ++ !(ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) ++ blk_queue_max_write_zeroes_sectors(q, ctrl->max_hw_sectors); + } + + static bool nvme_ns_ids_valid(struct nvme_ns_ids *ids) +@@ -2089,7 +2077,7 @@ static void nvme_update_disk_info(struct gendisk *disk, + set_capacity_revalidate_and_notify(disk, capacity, false); + + nvme_config_discard(disk, ns); +- nvme_config_write_zeroes(disk, ns); ++ nvme_config_write_zeroes(disk->queue, ns->ctrl); + + if (id->nsattr & NVME_NS_ATTR_RO) + set_disk_ro(disk, true); +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index 1957030132722..8b326508a480e 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -736,8 +736,11 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl) + return ret; + + ctrl->ctrl.queue_count = nr_io_queues + 1; +- if (ctrl->ctrl.queue_count < 2) +- return 0; ++ if (ctrl->ctrl.queue_count < 2) { ++ dev_err(ctrl->ctrl.device, ++ "unable to set any I/O queues\n"); ++ return -ENOMEM; ++ } + + dev_info(ctrl->ctrl.device, + "creating %d I/O queues.\n", nr_io_queues); +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 739ac7deccd96..9444e5e2a95ba 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -287,7 +287,7 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, + * directly, otherwise queue io_work. Also, only do that if we + * are on the same cpu, so we don't introduce contention. + */ +- if (queue->io_cpu == __smp_processor_id() && ++ if (queue->io_cpu == raw_smp_processor_id() && + sync && empty && mutex_trylock(&queue->send_mutex)) { + queue->more_requests = !last; + nvme_tcp_send_all(queue); +@@ -568,6 +568,13 @@ static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req, + req->pdu_len = le32_to_cpu(pdu->r2t_length); + req->pdu_sent = 0; + ++ if (unlikely(!req->pdu_len)) { ++ dev_err(queue->ctrl->ctrl.device, ++ "req %d r2t len is %u, probably a bug...\n", ++ rq->tag, req->pdu_len); ++ return -EPROTO; ++ } ++ + if (unlikely(req->data_sent + req->pdu_len > req->data_len)) { + dev_err(queue->ctrl->ctrl.device, + "req %d r2t len %u exceeded data len %u (%zu sent)\n", +@@ -1748,8 +1755,11 @@ static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) + return ret; + + ctrl->queue_count = nr_io_queues + 1; +- if (ctrl->queue_count < 2) +- return 0; ++ if (ctrl->queue_count < 2) { ++ dev_err(ctrl->device, ++ "unable to set any I/O queues\n"); ++ return -ENOMEM; ++ } + + dev_info(ctrl->device, + "creating %d I/O queues.\n", nr_io_queues); +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 957b39a82431b..1e79d33c1df7e 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -1109,9 +1109,20 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl) + { + lockdep_assert_held(&ctrl->lock); + +- if (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || +- nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES || +- nvmet_cc_mps(ctrl->cc) != 0 || ++ /* ++ * Only I/O controllers should verify iosqes,iocqes. ++ * Strictly speaking, the spec says a discovery controller ++ * should verify iosqes,iocqes are zeroed, however that ++ * would break backwards compatibility, so don't enforce it. ++ */ ++ if (ctrl->subsys->type != NVME_NQN_DISC && ++ (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || ++ nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES)) { ++ ctrl->csts = NVME_CSTS_CFS; ++ return; ++ } ++ ++ if (nvmet_cc_mps(ctrl->cc) != 0 || + nvmet_cc_ams(ctrl->cc) != 0 || + nvmet_cc_css(ctrl->cc) != 0) { + ctrl->csts = NVME_CSTS_CFS; +diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c +index cdbfa5df3a51f..dbfa0b55d31a5 100644 +--- a/drivers/pci/hotplug/rpadlpar_sysfs.c ++++ b/drivers/pci/hotplug/rpadlpar_sysfs.c +@@ -34,12 +34,11 @@ static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, + if (nbytes >= MAX_DRC_NAME_LEN) + return 0; + +- memcpy(drc_name, buf, nbytes); ++ strscpy(drc_name, buf, nbytes + 1); + + end = strchr(drc_name, '\n'); +- if (!end) +- end = &drc_name[nbytes]; +- *end = '\0'; ++ if (end) ++ *end = '\0'; + + rc = dlpar_add_slot(drc_name); + if (rc) +@@ -65,12 +64,11 @@ static ssize_t remove_slot_store(struct kobject *kobj, + if (nbytes >= MAX_DRC_NAME_LEN) + return 0; + +- memcpy(drc_name, buf, nbytes); ++ strscpy(drc_name, buf, nbytes + 1); + + end = strchr(drc_name, '\n'); +- if (!end) +- end = &drc_name[nbytes]; +- *end = '\0'; ++ if (end) ++ *end = '\0'; + + rc = dlpar_remove_slot(drc_name); + if (rc) +diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c +index c9e790c74051f..a047c421debe2 100644 +--- a/drivers/pci/hotplug/s390_pci_hpc.c ++++ b/drivers/pci/hotplug/s390_pci_hpc.c +@@ -93,8 +93,9 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) + pci_dev_put(pdev); + return -EBUSY; + } ++ pci_dev_put(pdev); + +- zpci_remove_device(zdev); ++ zpci_remove_device(zdev, false); + + rc = zpci_disable_device(zdev); + if (rc) +diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c +index cb29421d745aa..d38109cc3a011 100644 +--- a/drivers/regulator/pca9450-regulator.c ++++ b/drivers/regulator/pca9450-regulator.c +@@ -5,6 +5,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -32,6 +33,7 @@ struct pca9450_regulator_desc { + struct pca9450 { + struct device *dev; + struct regmap *regmap; ++ struct gpio_desc *sd_vsel_gpio; + enum pca9450_chip_type type; + unsigned int rcnt; + int irq; +@@ -795,6 +797,34 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, + return ret; + } + ++ /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */ ++ ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS, ++ BUCK123_PRESET_EN); ++ if (ret) { ++ dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret); ++ return ret; ++ } ++ ++ /* Set reset behavior on assertion of WDOG_B signal */ ++ ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL, ++ WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12); ++ if (ret) { ++ dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n"); ++ return ret; ++ } ++ ++ /* ++ * The driver uses the LDO5CTRL_H register to control the LDO5 regulator. ++ * This is only valid if the SD_VSEL input of the PMIC is high. Let's ++ * check if the pin is available as GPIO and set it to high. ++ */ ++ pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH); ++ ++ if (IS_ERR(pca9450->sd_vsel_gpio)) { ++ dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); ++ return ret; ++ } ++ + dev_info(&i2c->dev, "%s probed.\n", + type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc"); + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 03f96177e58ee..4d51c4ace8ea3 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -470,6 +470,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, + struct qaob *aob; + struct qeth_qdio_out_buffer *buffer; + enum iucv_tx_notify notification; ++ struct qeth_qdio_out_q *queue; + unsigned int i; + + aob = (struct qaob *) phys_to_virt(phys_aob_addr); +@@ -511,7 +512,9 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, + kmem_cache_free(qeth_core_header_cache, data); + } + ++ queue = buffer->q; + atomic_set(&buffer->state, QETH_QDIO_BUF_EMPTY); ++ napi_schedule(&queue->napi); + break; + default: + WARN_ON_ONCE(1); +@@ -7013,9 +7016,7 @@ int qeth_open(struct net_device *dev) + card->data.state = CH_STATE_UP; + netif_tx_start_all_queues(dev); + +- napi_enable(&card->napi); + local_bh_disable(); +- napi_schedule(&card->napi); + if (IS_IQD(card)) { + struct qeth_qdio_out_q *queue; + unsigned int i; +@@ -7027,8 +7028,12 @@ int qeth_open(struct net_device *dev) + napi_schedule(&queue->napi); + } + } ++ ++ napi_enable(&card->napi); ++ napi_schedule(&card->napi); + /* kick-start the NAPI softirq: */ + local_bh_enable(); ++ + return 0; + } + EXPORT_SYMBOL_GPL(qeth_open); +@@ -7038,6 +7043,11 @@ int qeth_stop(struct net_device *dev) + struct qeth_card *card = dev->ml_priv; + + QETH_CARD_TEXT(card, 4, "qethstop"); ++ ++ napi_disable(&card->napi); ++ cancel_delayed_work_sync(&card->buffer_reclaim_work); ++ qdio_stop_irq(CARD_DDEV(card)); ++ + if (IS_IQD(card)) { + struct qeth_qdio_out_q *queue; + unsigned int i; +@@ -7058,10 +7068,6 @@ int qeth_stop(struct net_device *dev) + netif_tx_disable(dev); + } + +- napi_disable(&card->napi); +- cancel_delayed_work_sync(&card->buffer_reclaim_work); +- qdio_stop_irq(CARD_DDEV(card)); +- + return 0; + } + EXPORT_SYMBOL_GPL(qeth_stop); +diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c +index e2d880a5f3915..7b0566f6a97f2 100644 +--- a/drivers/scsi/aic94xx/aic94xx_scb.c ++++ b/drivers/scsi/aic94xx/aic94xx_scb.c +@@ -68,7 +68,6 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, + struct done_list_struct *dl) + { + struct asd_ha_struct *asd_ha = ascb->ha; +- struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; + int phy_id = dl->status_block[0] & DL_PHY_MASK; + struct asd_phy *phy = &asd_ha->phys[phy_id]; + +@@ -81,7 +80,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, + ASD_DPRINTK("phy%d: device unplugged\n", phy_id); + asd_turn_led(asd_ha, phy_id, 0); + sas_phy_disconnected(&phy->sas_phy); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); + break; + case CURRENT_OOB_DONE: + /* hot plugged device */ +@@ -89,12 +88,12 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, + get_lrate_mode(phy, oob_mode); + ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n", + phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + break; + case CURRENT_SPINUP_HOLD: + /* hot plug SATA, no COMWAKE sent */ + asd_turn_led(asd_ha, phy_id, 1); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + break; + case CURRENT_GTO_TIMEOUT: + case CURRENT_OOB_ERROR: +@@ -102,7 +101,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb, + dl->status_block[1]); + asd_turn_led(asd_ha, phy_id, 0); + sas_phy_disconnected(&phy->sas_phy); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + break; + } + } +@@ -222,7 +221,6 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, + int edb_el = edb_id + ascb->edb_index; + struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el]; + struct asd_phy *phy = &ascb->ha->phys[phy_id]; +- struct sas_ha_struct *sas_ha = phy->sas_phy.ha; + u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2]; + + size = min(size, (u16) sizeof(phy->frame_rcvd)); +@@ -234,7 +232,7 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, + spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); + asd_dump_frame_rcvd(phy, dl); + asd_form_port(ascb->ha, phy); +- sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); ++ sas_notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); + } + + static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, +@@ -270,7 +268,7 @@ static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, + asd_turn_led(asd_ha, phy_id, 0); + sas_phy_disconnected(sas_phy); + asd_deform_port(asd_ha, phy); +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + + if (retries_left == 0) { + int num = 1; +@@ -315,7 +313,7 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = ffs(cont); + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy,PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + + case LmUNKNOWNP: +@@ -336,7 +334,7 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, + /* The sequencer disables all phys on that port. + * We have to re-enable the phys ourselves. */ + asd_deform_port(asd_ha, phy); +- sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); ++ sas_notify_port_event(sas_phy, PORTE_HARD_RESET); + break; + + default: +@@ -567,7 +565,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, + /* the device is gone */ + sas_phy_disconnected(sas_phy); + asd_deform_port(asd_ha, phy); +- sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); ++ sas_notify_port_event(sas_phy, PORTE_TIMER_EVENT); + break; + default: + ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 274ccf18ce2db..1feca45384c7a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -622,7 +622,6 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sas_ha; + + if (!phy->phy_attached) + return; +@@ -633,8 +632,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) + return; + } + +- sas_ha = &hisi_hba->sha; +- sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(sas_phy, PHYE_OOB_DONE); + + if (sas_phy->phy) { + struct sas_phy *sphy = sas_phy->phy; +@@ -662,7 +660,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) + } + + sas_phy->frame_rcvd_size = phy->frame_rcvd_size; +- sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED); ++ sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED); + } + + static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) +@@ -1417,7 +1415,6 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) + + static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) + { +- struct sas_ha_struct *sas_ha = &hisi_hba->sha; + struct asd_sas_port *_sas_port = NULL; + int phy_no; + +@@ -1438,7 +1435,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) + _sas_port = sas_port; + + if (dev_is_expander(dev->dev_type)) +- sas_ha->notify_port_event(sas_phy, ++ sas_notify_port_event(sas_phy, + PORTE_BROADCAST_RCVD); + } + } else { +@@ -2200,7 +2197,6 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sas_ha = &hisi_hba->sha; + struct device *dev = hisi_hba->dev; + + if (rdy) { +@@ -2216,7 +2212,7 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) + return; + } + /* Phy down and not ready */ +- sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); ++ sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); + sas_phy_disconnected(sas_phy); + + if (port) { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 45e866cb9164d..22eecc89d41bd 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1408,7 +1408,6 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) + struct hisi_sas_phy *phy = p; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sha = &hisi_hba->sha; + struct device *dev = hisi_hba->dev; + int phy_no = sas_phy->id; + u32 irq_value; +@@ -1424,7 +1423,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) + } + + if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) +- sha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + + end: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index b57177b52facc..6ef8730c61a6e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2818,14 +2818,13 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sas_ha = &hisi_hba->sha; + u32 bcast_status; + + hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); + bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); + if ((bcast_status & RX_BCAST_CHG_MSK) && + !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, + CHL_INT0_SL_RX_BCST_ACK_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2cbd8a524edab..19170c7ac336f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1598,14 +1598,13 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sas_ha = &hisi_hba->sha; + u32 bcast_status; + + hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); + bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); + if ((bcast_status & RX_BCAST_CHG_MSK) && + !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, + CHL_INT0_SL_RX_BCST_ACK_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); +diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c +index 1df45f028ea75..e50c3b0deeb30 100644 +--- a/drivers/scsi/isci/port.c ++++ b/drivers/scsi/isci/port.c +@@ -164,7 +164,8 @@ static void isci_port_bc_change_received(struct isci_host *ihost, + "%s: isci_phy = %p, sas_phy = %p\n", + __func__, iphy, &iphy->sas_phy); + +- ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event_gfp(&iphy->sas_phy, ++ PORTE_BROADCAST_RCVD, GFP_ATOMIC); + sci_port_bcn_enable(iport); + } + +@@ -223,8 +224,8 @@ static void isci_port_link_up(struct isci_host *isci_host, + /* Notify libsas that we have an address frame, if indeed + * we've found an SSP, SMP, or STP target */ + if (success) +- isci_host->sas_ha.notify_port_event(&iphy->sas_phy, +- PORTE_BYTES_DMAED); ++ sas_notify_port_event_gfp(&iphy->sas_phy, ++ PORTE_BYTES_DMAED, GFP_ATOMIC); + } + + +@@ -270,8 +271,8 @@ static void isci_port_link_down(struct isci_host *isci_host, + * isci_port_deformed and isci_dev_gone functions. + */ + sas_phy_disconnected(&isci_phy->sas_phy); +- isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy, +- PHYE_LOSS_OF_SIGNAL); ++ sas_notify_phy_event_gfp(&isci_phy->sas_phy, ++ PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC); + + dev_dbg(&isci_host->pdev->dev, + "%s: isci_port = %p - Done\n", __func__, isci_port); +diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c +index a1852f6c042b9..ba266a17250ae 100644 +--- a/drivers/scsi/libsas/sas_event.c ++++ b/drivers/scsi/libsas/sas_event.c +@@ -109,7 +109,7 @@ void sas_enable_revalidation(struct sas_ha_struct *ha) + + sas_phy = container_of(port->phy_list.next, struct asd_sas_phy, + port_phy_el); +- ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + } + mutex_unlock(&ha->disco_mutex); + } +@@ -131,18 +131,15 @@ static void sas_phy_event_worker(struct work_struct *work) + sas_free_event(ev); + } + +-static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) ++static int __sas_notify_port_event(struct asd_sas_phy *phy, ++ enum port_event event, ++ struct asd_sas_event *ev) + { +- struct asd_sas_event *ev; + struct sas_ha_struct *ha = phy->ha; + int ret; + + BUG_ON(event >= PORT_NUM_EVENTS); + +- ev = sas_alloc_event(phy); +- if (!ev) +- return -ENOMEM; +- + INIT_SAS_EVENT(ev, sas_port_event_worker, phy, event); + + ret = sas_queue_event(event, &ev->work, ha); +@@ -152,18 +149,40 @@ static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) + return ret; + } + +-int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) ++int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, ++ gfp_t gfp_flags) + { + struct asd_sas_event *ev; +- struct sas_ha_struct *ha = phy->ha; +- int ret; + +- BUG_ON(event >= PHY_NUM_EVENTS); ++ ev = sas_alloc_event_gfp(phy, gfp_flags); ++ if (!ev) ++ return -ENOMEM; ++ ++ return __sas_notify_port_event(phy, event, ev); ++} ++EXPORT_SYMBOL_GPL(sas_notify_port_event_gfp); ++ ++int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event) ++{ ++ struct asd_sas_event *ev; + + ev = sas_alloc_event(phy); + if (!ev) + return -ENOMEM; + ++ return __sas_notify_port_event(phy, event, ev); ++} ++EXPORT_SYMBOL_GPL(sas_notify_port_event); ++ ++static inline int __sas_notify_phy_event(struct asd_sas_phy *phy, ++ enum phy_event event, ++ struct asd_sas_event *ev) ++{ ++ struct sas_ha_struct *ha = phy->ha; ++ int ret; ++ ++ BUG_ON(event >= PHY_NUM_EVENTS); ++ + INIT_SAS_EVENT(ev, sas_phy_event_worker, phy, event); + + ret = sas_queue_event(event, &ev->work, ha); +@@ -173,10 +192,27 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) + return ret; + } + +-int sas_init_events(struct sas_ha_struct *sas_ha) ++int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, ++ gfp_t gfp_flags) + { +- sas_ha->notify_port_event = sas_notify_port_event; +- sas_ha->notify_phy_event = sas_notify_phy_event; ++ struct asd_sas_event *ev; + +- return 0; ++ ev = sas_alloc_event_gfp(phy, gfp_flags); ++ if (!ev) ++ return -ENOMEM; ++ ++ return __sas_notify_phy_event(phy, event, ev); ++} ++EXPORT_SYMBOL_GPL(sas_notify_phy_event_gfp); ++ ++int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) ++{ ++ struct asd_sas_event *ev; ++ ++ ev = sas_alloc_event(phy); ++ if (!ev) ++ return -ENOMEM; ++ ++ return __sas_notify_phy_event(phy, event, ev); + } ++EXPORT_SYMBOL_GPL(sas_notify_phy_event); +diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c +index 21c43b18d5d5b..f8ae1f0f17d36 100644 +--- a/drivers/scsi/libsas/sas_init.c ++++ b/drivers/scsi/libsas/sas_init.c +@@ -123,12 +123,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) + goto Undo_phys; + } + +- error = sas_init_events(sas_ha); +- if (error) { +- pr_notice("couldn't start event thread:%d\n", error); +- goto Undo_ports; +- } +- + error = -ENOMEM; + snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev)); + sas_ha->event_q = create_singlethread_workqueue(name); +@@ -590,16 +584,15 @@ sas_domain_attach_transport(struct sas_domain_function_template *dft) + } + EXPORT_SYMBOL_GPL(sas_domain_attach_transport); + +- +-struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) ++static struct asd_sas_event *__sas_alloc_event(struct asd_sas_phy *phy, ++ gfp_t gfp_flags) + { + struct asd_sas_event *event; +- gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; + struct sas_ha_struct *sas_ha = phy->ha; + struct sas_internal *i = + to_sas_internal(sas_ha->core.shost->transportt); + +- event = kmem_cache_zalloc(sas_event_cache, flags); ++ event = kmem_cache_zalloc(sas_event_cache, gfp_flags); + if (!event) + return NULL; + +@@ -610,7 +603,8 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) + if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { + pr_notice("The phy%d bursting events, shut it down.\n", + phy->id); +- sas_notify_phy_event(phy, PHYE_SHUTDOWN); ++ sas_notify_phy_event_gfp(phy, PHYE_SHUTDOWN, ++ gfp_flags); + } + } else { + /* Do not support PHY control, stop allocating events */ +@@ -624,6 +618,17 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) + return event; + } + ++struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) ++{ ++ return __sas_alloc_event(phy, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); ++} ++ ++struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, ++ gfp_t gfp_flags) ++{ ++ return __sas_alloc_event(phy, gfp_flags); ++} ++ + void sas_free_event(struct asd_sas_event *event) + { + struct asd_sas_phy *phy = event->phy; +diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h +index 1f1d01901978c..52e09c3e2b50d 100644 +--- a/drivers/scsi/libsas/sas_internal.h ++++ b/drivers/scsi/libsas/sas_internal.h +@@ -49,12 +49,13 @@ int sas_register_phys(struct sas_ha_struct *sas_ha); + void sas_unregister_phys(struct sas_ha_struct *sas_ha); + + struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy); ++struct asd_sas_event *sas_alloc_event_gfp(struct asd_sas_phy *phy, ++ gfp_t gfp_flags); + void sas_free_event(struct asd_sas_event *event); + + int sas_register_ports(struct sas_ha_struct *sas_ha); + void sas_unregister_ports(struct sas_ha_struct *sas_ha); + +-int sas_init_events(struct sas_ha_struct *sas_ha); + void sas_disable_revalidation(struct sas_ha_struct *ha); + void sas_enable_revalidation(struct sas_ha_struct *ha); + void __sas_drain_work(struct sas_ha_struct *ha); +@@ -78,6 +79,8 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, + int sas_smp_get_phy_events(struct sas_phy *phy); + + int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); ++int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, ++ gfp_t flags); + void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); + struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); + struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); +diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c +index c9a327b13e5cf..b89c5513243e8 100644 +--- a/drivers/scsi/lpfc/lpfc_debugfs.c ++++ b/drivers/scsi/lpfc/lpfc_debugfs.c +@@ -2423,7 +2423,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, + memset(dstbuf, 0, 33); + size = (nbytes < 32) ? nbytes : 32; + if (copy_from_user(dstbuf, buf, size)) +- return 0; ++ return -EFAULT; + + if (dent == phba->debug_InjErrLBA) { + if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') && +@@ -2432,7 +2432,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, + } + + if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) +- return 0; ++ return -EINVAL; + + if (dent == phba->debug_writeGuard) + phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; +diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c +index a920eced92ecc..484e01428da28 100644 +--- a/drivers/scsi/mvsas/mv_sas.c ++++ b/drivers/scsi/mvsas/mv_sas.c +@@ -216,11 +216,11 @@ void mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo, + MVS_CHIP_DISP->write_port_cfg_data(mvi, port_id, hi); + } + +-static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) ++static void mvs_bytes_dmaed(struct mvs_info *mvi, int i, gfp_t gfp_flags) + { + struct mvs_phy *phy = &mvi->phy[i]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- struct sas_ha_struct *sas_ha; ++ + if (!phy->phy_attached) + return; + +@@ -229,8 +229,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) + return; + } + +- sas_ha = mvi->sas; +- sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event_gfp(sas_phy, PHYE_OOB_DONE, gfp_flags); + + if (sas_phy->phy) { + struct sas_phy *sphy = sas_phy->phy; +@@ -262,8 +261,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) + + sas_phy->frame_rcvd_size = phy->frame_rcvd_size; + +- mvi->sas->notify_port_event(sas_phy, +- PORTE_BYTES_DMAED); ++ sas_notify_port_event_gfp(sas_phy, PORTE_BYTES_DMAED, gfp_flags); + } + + void mvs_scan_start(struct Scsi_Host *shost) +@@ -279,7 +277,7 @@ void mvs_scan_start(struct Scsi_Host *shost) + for (j = 0; j < core_nr; j++) { + mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[j]; + for (i = 0; i < mvi->chip->n_phy; ++i) +- mvs_bytes_dmaed(mvi, i); ++ mvs_bytes_dmaed(mvi, i, GFP_KERNEL); + } + mvs_prv->scan_finished = 1; + } +@@ -1880,7 +1878,6 @@ static void mvs_work_queue(struct work_struct *work) + struct mvs_info *mvi = mwq->mvi; + unsigned long flags; + u32 phy_no = (unsigned long) mwq->data; +- struct sas_ha_struct *sas_ha = mvi->sas; + struct mvs_phy *phy = &mvi->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + +@@ -1895,21 +1892,21 @@ static void mvs_work_queue(struct work_struct *work) + if (!(tmp & PHY_READY_MASK)) { + sas_phy_disconnected(sas_phy); + mvs_phy_disconnected(phy); +- sas_ha->notify_phy_event(sas_phy, +- PHYE_LOSS_OF_SIGNAL); ++ sas_notify_phy_event_gfp(sas_phy, ++ PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC); + mv_dprintk("phy%d Removed Device\n", phy_no); + } else { + MVS_CHIP_DISP->detect_porttype(mvi, phy_no); + mvs_update_phyinfo(mvi, phy_no, 1); +- mvs_bytes_dmaed(mvi, phy_no); ++ mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC); + mvs_port_notify_formed(sas_phy, 0); + mv_dprintk("phy%d Attached Device\n", phy_no); + } + } + } else if (mwq->handler & EXP_BRCT_CHG) { + phy->phy_event &= ~EXP_BRCT_CHG; +- sas_ha->notify_port_event(sas_phy, +- PORTE_BROADCAST_RCVD); ++ sas_notify_port_event_gfp(sas_phy, ++ PORTE_BROADCAST_RCVD, GFP_ATOMIC); + mv_dprintk("phy%d Got Broadcast Change\n", phy_no); + } + list_del(&mwq->entry); +@@ -2026,7 +2023,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) + mdelay(10); + } + +- mvs_bytes_dmaed(mvi, phy_no); ++ mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC); + /* whether driver is going to handle hot plug */ + if (phy->phy_event & PHY_PLUG_OUT) { + mvs_port_notify_formed(&phy->sas_phy, 0); +diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c +index 7a3ade765ce3b..78c41bbf67562 100644 +--- a/drivers/scsi/myrs.c ++++ b/drivers/scsi/myrs.c +@@ -2274,12 +2274,12 @@ static void myrs_cleanup(struct myrs_hba *cs) + if (cs->mmio_base) { + cs->disable_intr(cs); + iounmap(cs->mmio_base); ++ cs->mmio_base = NULL; + } + if (cs->irq) + free_irq(cs->irq, cs); + if (cs->io_addr) + release_region(cs->io_addr, 0x80); +- iounmap(cs->mmio_base); + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + scsi_host_put(cs->host); +diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c +index 3587f7c8a4289..12035baf0997b 100644 +--- a/drivers/scsi/pm8001/pm8001_ctl.c ++++ b/drivers/scsi/pm8001/pm8001_ctl.c +@@ -841,10 +841,9 @@ static ssize_t pm8001_store_update_fw(struct device *cdev, + pm8001_ha->dev); + + if (ret) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk( +- "Failed to load firmware image file %s, error %d\n", +- filename_ptr, ret)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Failed to load firmware image file %s, error %d\n", ++ filename_ptr, ret); + pm8001_ha->fw_status = FAIL_OPEN_BIOS_FILE; + goto out; + } +diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c +index 2b7b2954ec31a..95ba1bd16db93 100644 +--- a/drivers/scsi/pm8001/pm8001_hwi.c ++++ b/drivers/scsi/pm8001/pm8001_hwi.c +@@ -400,9 +400,9 @@ int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) + } while ((regVal != shiftValue) && time_before(jiffies, start)); + + if (regVal != shiftValue) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW" +- " = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW = 0x%x\n", ++ regVal); + return -1; + } + return 0; +@@ -623,12 +623,10 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) + + value = pm8001_cr32(pm8001_ha, 0, 0x44); + offset = value & 0x03FFFFFF; +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Scratchpad 0 Offset: %x\n", offset)); ++ pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 Offset: %x\n", offset); + pcilogic = (value & 0xFC000000) >> 26; + pcibar = get_pci_bar_index(pcilogic); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Scratchpad 0 PCI BAR: %d\n", pcibar)); ++ pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar); + pm8001_ha->main_cfg_tbl_addr = base_addr = + pm8001_ha->io_mem[pcibar].memvirtaddr + offset; + pm8001_ha->general_stat_tbl_addr = +@@ -652,16 +650,15 @@ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) + * as this is shared with BIOS data */ + if (deviceid == 0x8081 || deviceid == 0x0042) { + if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- GSM_SM_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Shift Bar4 to 0x%x failed\n", ++ GSM_SM_BASE); + return -1; + } + } + /* check the firmware status */ + if (-1 == check_fw_ready(pm8001_ha)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Firmware is not ready!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Firmware is not ready!\n"); + return -EBUSY; + } + +@@ -686,8 +683,7 @@ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) + } + /* notify firmware update finished and check initialization status */ + if (0 == mpi_init_check(pm8001_ha)) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MPI initialize successful!\n")); ++ pm8001_dbg(pm8001_ha, INIT, "MPI initialize successful!\n"); + } else + return -EBUSY; + /*This register is a 16-bit timer with a resolution of 1us. This is the +@@ -709,9 +705,9 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) + pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); + if (deviceid == 0x8081 || deviceid == 0x0042) { + if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- GSM_SM_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Shift Bar4 to 0x%x failed\n", ++ GSM_SM_BASE); + return -1; + } + } +@@ -729,8 +725,8 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) + } while ((value != 0) && (--max_wait_count)); + + if (!max_wait_count) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT:IBDB value/=0x%x\n", value)); ++ pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:IBDB value/=0x%x\n", ++ value); + return -1; + } + +@@ -747,9 +743,8 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) + break; + } while (--max_wait_count); + if (!max_wait_count) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk(" TIME OUT MPI State = 0x%x\n", +- gst_len_mpistate & GST_MPI_STATE_MASK)); ++ pm8001_dbg(pm8001_ha, FAIL, " TIME OUT MPI State = 0x%x\n", ++ gst_len_mpistate & GST_MPI_STATE_MASK); + return -1; + } + return 0; +@@ -763,25 +758,23 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha) + { + u32 regVal, regVal1, regVal2; + if (mpi_uninit_check(pm8001_ha) != 0) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MPI state is not ready\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "MPI state is not ready\n"); + return -1; + } + /* read the scratch pad 2 register bit 2 */ + regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2) + & SCRATCH_PAD2_FWRDY_RST; + if (regVal == SCRATCH_PAD2_FWRDY_RST) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Firmware is ready for reset .\n")); ++ pm8001_dbg(pm8001_ha, INIT, "Firmware is ready for reset.\n"); + } else { + unsigned long flags; + /* Trigger NMI twice via RB6 */ + spin_lock_irqsave(&pm8001_ha->lock, flags); + if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- RB6_ACCESS_REG)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Shift Bar4 to 0x%x failed\n", ++ RB6_ACCESS_REG); + return -1; + } + pm8001_cw32(pm8001_ha, 2, SPC_RB6_OFFSET, +@@ -794,16 +787,14 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha) + if (regVal != SCRATCH_PAD2_FWRDY_RST) { + regVal1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); + regVal2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT:MSGU_SCRATCH_PAD1" +- "=0x%x, MSGU_SCRATCH_PAD2=0x%x\n", +- regVal1, regVal2)); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD0 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3))); ++ pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:MSGU_SCRATCH_PAD1=0x%x, MSGU_SCRATCH_PAD2=0x%x\n", ++ regVal1, regVal2); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SCRATCH_PAD0 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SCRATCH_PAD3 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + return -1; + } +@@ -828,7 +819,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + + /* step1: Check FW is ready for soft reset */ + if (soft_reset_ready_check(pm8001_ha) != 0) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("FW is not ready\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "FW is not ready\n"); + return -1; + } + +@@ -838,46 +829,43 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + spin_lock_irqsave(&pm8001_ha->lock, flags); + if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- MBIC_AAP1_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n", ++ MBIC_AAP1_ADDR_BASE); + return -1; + } + regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0); + /* map 0x70000 to BAR4(0x20), BAR2(win) */ + if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- MBIC_IOP_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n", ++ MBIC_IOP_ADDR_BASE); + return -1; + } + regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MBIC - NMI Enable VPE0 (AAP1)= 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "MBIC - NMI Enable VPE0 (AAP1)= 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1, 0x0); + + regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PCIE -Event Interrupt Enable = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "PCIE -Event Interrupt Enable = 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE, 0x0); + + regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PCIE - Event Interrupt = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "PCIE - Event Interrupt = 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT, regVal); + + regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PCIE -Error Interrupt Enable = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "PCIE -Error Interrupt Enable = 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE, 0x0); + + regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PCIE - Error Interrupt = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "PCIE - Error Interrupt = 0x%x\n", regVal); + pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT, regVal); + + /* read the scratch pad 1 register bit 2 */ +@@ -893,15 +881,13 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + /* map 0x0700000 to BAR4(0x20), BAR2(win) */ + if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- GSM_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n", ++ GSM_ADDR_BASE); + return -1; + } +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x0(0x00007b88)-GSM Configuration and" +- " Reset = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x0(0x00007b88)-GSM Configuration and Reset = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)); + + /* step 3: host read GSM Configuration and Reset register */ + regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET); +@@ -916,59 +902,52 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + regVal &= ~(0x00003b00); + /* host write GSM Configuration and Reset register */ + pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x0 (0x00007b88 ==> 0x00004088) - GSM " +- "Configuration and Reset is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x0 (0x00007b88 ==> 0x00004088) - GSM Configuration and Reset is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)); + + /* step 4: */ + /* disable GSM - Read Address Parity Check */ + regVal1 = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700038 - Read Address Parity Check " +- "Enable = 0x%x\n", regVal1)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700038 - Read Address Parity Check Enable = 0x%x\n", ++ regVal1); + pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, 0x0); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700038 - Read Address Parity Check Enable" +- "is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700038 - Read Address Parity Check Enable is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK)); + + /* disable GSM - Write Address Parity Check */ + regVal2 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700040 - Write Address Parity Check" +- " Enable = 0x%x\n", regVal2)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700040 - Write Address Parity Check Enable = 0x%x\n", ++ regVal2); + pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, 0x0); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700040 - Write Address Parity Check " +- "Enable is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700040 - Write Address Parity Check Enable is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK)); + + /* disable GSM - Write Data Parity Check */ + regVal3 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x300048 - Write Data Parity Check" +- " Enable = 0x%x\n", regVal3)); ++ pm8001_dbg(pm8001_ha, INIT, "GSM 0x300048 - Write Data Parity Check Enable = 0x%x\n", ++ regVal3); + pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, 0x0); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x300048 - Write Data Parity Check Enable" +- "is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x300048 - Write Data Parity Check Enable is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK)); + + /* step 5: delay 10 usec */ + udelay(10); + /* step 5-b: set GPIO-0 output control to tristate anyway */ + if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- GPIO_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, INIT, "Shift Bar4 to 0x%x failed\n", ++ GPIO_ADDR_BASE); + return -1; + } + regVal = pm8001_cr32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GPIO Output Control Register:" +- " = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "GPIO Output Control Register: = 0x%x\n", ++ regVal); + /* set GPIO-0 output control to tri-state */ + regVal &= 0xFFFFFFFC; + pm8001_cw32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET, regVal); +@@ -977,23 +956,20 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + /* map 0x00000 to BAR4(0x20), BAR2(win) */ + if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", +- SPC_TOP_LEVEL_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "SPC Shift Bar4 to 0x%x failed\n", ++ SPC_TOP_LEVEL_ADDR_BASE); + return -1; + } + regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Top Register before resetting IOP/AAP1" +- ":= 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "Top Register before resetting IOP/AAP1:= 0x%x\n", ++ regVal); + regVal &= ~(SPC_REG_RESET_PCS_IOP_SS | SPC_REG_RESET_PCS_AAP1_SS); + pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal); + + /* step 7: Reset the BDMA/OSSP */ + regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Top Register before resetting BDMA/OSSP" +- ": = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, "Top Register before resetting BDMA/OSSP: = 0x%x\n", ++ regVal); + regVal &= ~(SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP); + pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal); + +@@ -1002,9 +978,9 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + + /* step 9: bring the BDMA and OSSP out of reset */ + regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Top Register before bringing up BDMA/OSSP" +- ":= 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Top Register before bringing up BDMA/OSSP:= 0x%x\n", ++ regVal); + regVal |= (SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP); + pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal); + +@@ -1015,14 +991,13 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + /* map 0x0700000 to BAR4(0x20), BAR2(win) */ + if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SPC Shift Bar4 to 0x%x failed\n", +- GSM_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "SPC Shift Bar4 to 0x%x failed\n", ++ GSM_ADDR_BASE); + return -1; + } +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x0 (0x00007b88)-GSM Configuration and " +- "Reset = 0x%x\n", pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x0 (0x00007b88)-GSM Configuration and Reset = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)); + regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET); + /* Put those bits to high */ + /* GSM XCBI offset = 0x70 0000 +@@ -1034,44 +1009,37 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + */ + regVal |= (GSM_CONFIG_RESET_VALUE); + pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM (0x00004088 ==> 0x00007b88) - GSM" +- " Configuration and Reset is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET))); ++ pm8001_dbg(pm8001_ha, INIT, "GSM (0x00004088 ==> 0x00007b88) - GSM Configuration and Reset is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)); + + /* step 12: Restore GSM - Read Address Parity Check */ + regVal = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK); + /* just for debugging */ +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700038 - Read Address Parity Check Enable" +- " = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700038 - Read Address Parity Check Enable = 0x%x\n", ++ regVal); + pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, regVal1); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700038 - Read Address Parity" +- " Check Enable is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, "GSM 0x700038 - Read Address Parity Check Enable is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK)); + /* Restore GSM - Write Address Parity Check */ + regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK); + pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, regVal2); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700040 - Write Address Parity Check" +- " Enable is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700040 - Write Address Parity Check Enable is set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK)); + /* Restore GSM - Write Data Parity Check */ + regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK); + pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, regVal3); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GSM 0x700048 - Write Data Parity Check Enable" +- "is set to = 0x%x\n", +- pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "GSM 0x700048 - Write Data Parity Check Enableis set to = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK)); + + /* step 13: bring the IOP and AAP1 out of reset */ + /* map 0x00000 to BAR4(0x20), BAR2(win) */ + if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Shift Bar4 to 0x%x failed\n", +- SPC_TOP_LEVEL_ADDR_BASE)); ++ pm8001_dbg(pm8001_ha, FAIL, "Shift Bar4 to 0x%x failed\n", ++ SPC_TOP_LEVEL_ADDR_BASE); + return -1; + } + regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET); +@@ -1094,22 +1062,20 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + if (!max_wait_count) { + regVal = pm8001_cr32(pm8001_ha, 0, + MSGU_SCRATCH_PAD_1); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT : ToggleVal 0x%x," +- "MSGU_SCRATCH_PAD1 = 0x%x\n", +- toggleVal, regVal)); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD0 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, +- MSGU_SCRATCH_PAD_0))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD2 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, +- MSGU_SCRATCH_PAD_2))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, +- MSGU_SCRATCH_PAD_3))); ++ pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT : ToggleVal 0x%x,MSGU_SCRATCH_PAD1 = 0x%x\n", ++ toggleVal, regVal); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SCRATCH_PAD0 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, ++ MSGU_SCRATCH_PAD_0)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SCRATCH_PAD2 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, ++ MSGU_SCRATCH_PAD_2)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SCRATCH_PAD3 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, ++ MSGU_SCRATCH_PAD_3)); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + return -1; + } +@@ -1124,22 +1090,22 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + if (check_fw_ready(pm8001_ha) == -1) { + regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); + /* return error if MPI Configuration Table not ready */ +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("FW not ready SCRATCH_PAD1" +- " = 0x%x\n", regVal)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "FW not ready SCRATCH_PAD1 = 0x%x\n", ++ regVal); + regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2); + /* return error if MPI Configuration Table not ready */ +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("FW not ready SCRATCH_PAD2" +- " = 0x%x\n", regVal)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD0 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, +- MSGU_SCRATCH_PAD_0))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SCRATCH_PAD3 value = 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, +- MSGU_SCRATCH_PAD_3))); ++ pm8001_dbg(pm8001_ha, INIT, ++ "FW not ready SCRATCH_PAD2 = 0x%x\n", ++ regVal); ++ pm8001_dbg(pm8001_ha, INIT, ++ "SCRATCH_PAD0 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, ++ MSGU_SCRATCH_PAD_0)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "SCRATCH_PAD3 value = 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, ++ MSGU_SCRATCH_PAD_3)); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + return -1; + } +@@ -1147,8 +1113,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + pm8001_bar4_shift(pm8001_ha, 0); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SPC soft reset Complete\n")); ++ pm8001_dbg(pm8001_ha, INIT, "SPC soft reset Complete\n"); + return 0; + } + +@@ -1156,8 +1121,7 @@ static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) + { + u32 i; + u32 regVal; +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("chip reset start\n")); ++ pm8001_dbg(pm8001_ha, INIT, "chip reset start\n"); + + /* do SPC chip reset. */ + regVal = pm8001_cr32(pm8001_ha, 1, SPC_REG_RESET); +@@ -1181,8 +1145,7 @@ static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) + mdelay(1); + } while ((--i) != 0); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("chip reset finished\n")); ++ pm8001_dbg(pm8001_ha, INIT, "chip reset finished\n"); + } + + /** +@@ -1356,12 +1319,18 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, + { + u32 Header = 0, hpriority = 0, bc = 1, category = 0x02; + void *pMessage; +- +- if (pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size, +- &pMessage) < 0) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("No free mpi buffer\n")); +- return -ENOMEM; ++ unsigned long flags; ++ int q_index = circularQ - pm8001_ha->inbnd_q_tbl; ++ int rv = -1; ++ ++ WARN_ON(q_index >= PM8001_MAX_INB_NUM); ++ spin_lock_irqsave(&circularQ->iq_lock, flags); ++ rv = pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size, ++ &pMessage); ++ if (rv < 0) { ++ pm8001_dbg(pm8001_ha, IO, "No free mpi buffer\n"); ++ rv = -ENOMEM; ++ goto done; + } + + if (nb > (pm8001_ha->iomb_size - sizeof(struct mpi_msg_hdr))) +@@ -1380,11 +1349,13 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, + /*Update the PI to the firmware*/ + pm8001_cw32(pm8001_ha, circularQ->pi_pci_bar, + circularQ->pi_offset, circularQ->producer_idx); +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n", +- responseQueue, opCode, circularQ->producer_idx, +- circularQ->consumer_index)); +- return 0; ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n", ++ responseQueue, opCode, circularQ->producer_idx, ++ circularQ->consumer_index); ++done: ++ spin_unlock_irqrestore(&circularQ->iq_lock, flags); ++ return rv; + } + + u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, +@@ -1398,17 +1369,17 @@ u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, + pOutBoundMsgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt + + circularQ->consumer_idx * pm8001_ha->iomb_size); + if (pOutBoundMsgHeader != msgHeader) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("consumer_idx = %d msgHeader = %p\n", +- circularQ->consumer_idx, msgHeader)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "consumer_idx = %d msgHeader = %p\n", ++ circularQ->consumer_idx, msgHeader); + + /* Update the producer index from SPC */ + producer_index = pm8001_read_32(circularQ->pi_virt); + circularQ->producer_index = cpu_to_le32(producer_index); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("consumer_idx = %d producer_index = %d" +- "msgHeader = %p\n", circularQ->consumer_idx, +- circularQ->producer_index, msgHeader)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "consumer_idx = %d producer_index = %dmsgHeader = %p\n", ++ circularQ->consumer_idx, ++ circularQ->producer_index, msgHeader); + return 0; + } + /* free the circular queue buffer elements associated with the message*/ +@@ -1420,9 +1391,8 @@ u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, + /* Update the producer index from SPC*/ + producer_index = pm8001_read_32(circularQ->pi_virt); + circularQ->producer_index = cpu_to_le32(producer_index); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk(" CI=%d PI=%d\n", circularQ->consumer_idx, +- circularQ->producer_index)); ++ pm8001_dbg(pm8001_ha, IO, " CI=%d PI=%d\n", ++ circularQ->consumer_idx, circularQ->producer_index); + return 0; + } + +@@ -1452,10 +1422,10 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, + /* read header */ + header_tmp = pm8001_read_32(msgHeader); + msgHeader_tmp = cpu_to_le32(header_tmp); +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "outbound opcode msgheader:%x ci=%d pi=%d\n", +- msgHeader_tmp, circularQ->consumer_idx, +- circularQ->producer_index)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "outbound opcode msgheader:%x ci=%d pi=%d\n", ++ msgHeader_tmp, circularQ->consumer_idx, ++ circularQ->producer_index); + if (0 != (le32_to_cpu(msgHeader_tmp) & 0x80000000)) { + if (OPC_OUB_SKIP_ENTRY != + (le32_to_cpu(msgHeader_tmp) & 0xfff)) { +@@ -1464,12 +1434,11 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, + sizeof(struct mpi_msg_hdr); + *pBC = (u8)((le32_to_cpu(msgHeader_tmp) + >> 24) & 0x1f); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk(": CI=%d PI=%d " +- "msgHeader=%x\n", +- circularQ->consumer_idx, +- circularQ->producer_index, +- msgHeader_tmp)); ++ pm8001_dbg(pm8001_ha, IO, ++ ": CI=%d PI=%d msgHeader=%x\n", ++ circularQ->consumer_idx, ++ circularQ->producer_index, ++ msgHeader_tmp); + return MPI_IO_STATUS_SUCCESS; + } else { + circularQ->consumer_idx = +@@ -1578,17 +1547,15 @@ void pm8001_work_fn(struct work_struct *work) + ts->stat = SAS_QUEUE_FULL; + pm8001_dev = ccb->device; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + spin_lock_irqsave(&t->task_state_lock, flags1); + t->task_state_flags &= ~SAS_TASK_STATE_PENDING; + t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags1); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p" +- " done with event 0x%x resp 0x%x stat 0x%x but" +- " aborted by upper layer!\n", +- t, pw->handler, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, pw->handler, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + } else { +@@ -1608,26 +1575,16 @@ void pm8001_work_fn(struct work_struct *work) + unsigned long flags, flags1; + int i, ret = 0; + +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + + ret = pm8001_query_task(t); + +- PM8001_IO_DBG(pm8001_ha, +- switch (ret) { +- case TMF_RESP_FUNC_SUCC: +- pm8001_printk("...Task on lu\n"); +- break; +- +- case TMF_RESP_FUNC_COMPLETE: +- pm8001_printk("...Task NOT on lu\n"); +- break; +- +- default: +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "...query task failed!!!\n")); +- break; +- }); ++ if (ret == TMF_RESP_FUNC_SUCC) ++ pm8001_dbg(pm8001_ha, IO, "...Task on lu\n"); ++ else if (ret == TMF_RESP_FUNC_COMPLETE) ++ pm8001_dbg(pm8001_ha, IO, "...Task NOT on lu\n"); ++ else ++ pm8001_dbg(pm8001_ha, DEVIO, "...query task failed!!!\n"); + + spin_lock_irqsave(&pm8001_ha->lock, flags); + +@@ -1672,8 +1629,7 @@ void pm8001_work_fn(struct work_struct *work) + break; + default: /* device misbehavior */ + ret = TMF_RESP_FUNC_FAILED; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("...Reset phy\n")); ++ pm8001_dbg(pm8001_ha, IO, "...Reset phy\n"); + pm8001_I_T_nexus_reset(dev); + break; + } +@@ -1687,15 +1643,14 @@ void pm8001_work_fn(struct work_struct *work) + default: /* device misbehavior */ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + ret = TMF_RESP_FUNC_FAILED; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("...Reset phy\n")); ++ pm8001_dbg(pm8001_ha, IO, "...Reset phy\n"); + pm8001_I_T_nexus_reset(dev); + } + + if (ret == TMF_RESP_FUNC_FAILED) + t = NULL; + pm8001_open_reject_retry(pm8001_ha, t, pm8001_dev); +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("...Complete\n")); ++ pm8001_dbg(pm8001_ha, IO, "...Complete\n"); + } break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: + dev = pm8001_dev->sas_device; +@@ -1749,15 +1704,14 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, + int ret; + + if (!pm8001_ha_dev) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "dev is null\n"); + return; + } + + task = sas_alloc_slow_task(GFP_ATOMIC); + + if (!task) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot " +- "allocate task\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n"); + return; + } + +@@ -1802,8 +1756,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, + task = sas_alloc_slow_task(GFP_ATOMIC); + + if (!task) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("cannot allocate task !!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n"); + return; + } + task->task_done = pm8001_task_done; +@@ -1811,8 +1764,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, + res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); + if (res) { + sas_free_task(task); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("cannot allocate tag !!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n"); + return; + } + +@@ -1823,8 +1775,8 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, + if (!dev) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Domain device cannot be allocated\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Domain device cannot be allocated\n"); + return; + } + task->dev = dev; +@@ -1901,27 +1853,25 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + + if (status && status != IO_UNDERFLOW) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("sas IO status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", status); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + ts = &t->task_status; + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && + (status != IO_UNDERFLOW)) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive:" +- "%016llx", SAS_ADDR(t->dev->sas_addr))); ++ pm8001_dbg(pm8001_ha, FAIL, "SAS Address of IO Failure Drive:%016llx\n", ++ SAS_ADDR(t->dev->sas_addr)); + + if (status) +- PM8001_IOERR_DBG(pm8001_ha, pm8001_printk( +- "status:0x%x, tag:0x%x, task:0x%p\n", +- status, tag, t)); ++ pm8001_dbg(pm8001_ha, IOERR, ++ "status:0x%x, tag:0x%x, task:0x%p\n", ++ status, tag, t); + + switch (status) { + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS" +- ",param = %d\n", param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS,param = %d\n", ++ param); + if (param == 0) { + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; +@@ -1933,69 +1883,63 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + sas_ssp_task_response(pm8001_ha->dev, t, iu); + } + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB Tag\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; + break; + case IO_UNDERFLOW: + /* SSP Completion with error */ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW" +- ",param = %d\n", param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW,param = %d\n", ++ param); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + ts->residual = param; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + /* Force the midlayer to retry */ + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -2005,68 +1949,59 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_" +- "NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_ERROR_DMA: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + if (!t->uldd_task) +@@ -2075,51 +2010,44 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_DS_NON_OPERATIONAL); + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_TM_TAG_NOT_FOUND: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_TM_TAG_NOT_FOUND\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_TM_TAG_NOT_FOUND\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_SSP_EXT_IU_ZERO_LEN_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SSP_EXT_IU_ZERO_LEN_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + break; + } +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("scsi_status = %x\n ", +- psspPayload->ssp_resp_iu.status)); ++ pm8001_dbg(pm8001_ha, IO, "scsi_status = %x\n", ++ psspPayload->ssp_resp_iu.status); + spin_lock_irqsave(&t->task_state_lock, flags); + t->task_state_flags &= ~SAS_TASK_STATE_PENDING; + t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with" +- " io_status 0x%x resp 0x%x " +- "stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -2148,60 +2076,52 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + if (event) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("sas IO status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", event); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + ts = &t->task_status; +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("port_id = %x,device_id = %x\n", +- port_id, dev_id)); ++ pm8001_dbg(pm8001_ha, DEVIO, "port_id = %x,device_id = %x\n", ++ port_id, dev_id); + switch (event) { + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n");) ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK); + return; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT" +- "_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -2211,88 +2131,78 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_" +- "NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT); + return; + case IO_XFER_ERROR_UNEXPECTED_PHASE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_RDY_OVERRUN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_CMD_FRAME_ISSUED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk(" IO_XFER_CMD_FRAME_ISSUED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n"); + return; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", event); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; +@@ -2304,10 +2214,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with" +- " event 0x%x resp 0x%x " +- "stat 0x%x but aborted by upper layer!\n", +- t, event, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, event, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -2343,8 +2251,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + tag = le32_to_cpu(psataPayload->tag); + + if (!tag) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("tag null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "tag null\n"); + return; + } + ccb = &pm8001_ha->ccb_info[tag]; +@@ -2353,8 +2260,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("ccb null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "ccb null\n"); + return; + } + +@@ -2362,29 +2268,26 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + if (t->dev && (t->dev->lldd_dev)) + pm8001_dev = t->dev->lldd_dev; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "task null\n"); + return; + } + + if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG)) + && unlikely(!t || !t->lldd_task || !t->dev)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task or dev null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n"); + return; + } + + ts = &t->task_status; + if (!ts) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("ts null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "ts null\n"); + return; + } + + if (status) +- PM8001_IOERR_DBG(pm8001_ha, pm8001_printk( +- "status:0x%x, tag:0x%x, task::0x%p\n", +- status, tag, t)); ++ pm8001_dbg(pm8001_ha, IOERR, ++ "status:0x%x, tag:0x%x, task::0x%p\n", ++ status, tag, t); + + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && +@@ -2416,19 +2319,19 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + & 0xff000000)) + + pm8001_dev->attached_phy + + 0x10); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive:" +- "%08x%08x", temp_sata_addr_hi, +- temp_sata_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SAS Address of IO Failure Drive:%08x%08x\n", ++ temp_sata_addr_hi, ++ temp_sata_addr_low); + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive:" +- "%016llx", SAS_ADDR(t->dev->sas_addr))); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SAS Address of IO Failure Drive:%016llx\n", ++ SAS_ADDR(t->dev->sas_addr)); + } + } + switch (status) { + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n"); + if (param == 0) { + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; +@@ -2450,99 +2353,102 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PROTO_RESPONSE; + ts->residual = param; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("SAS_PROTO_RESPONSE len = %d\n", +- param)); ++ pm8001_dbg(pm8001_ha, IO, ++ "SAS_PROTO_RESPONSE len = %d\n", ++ param); + sata_resp = &psataPayload->sata_resp[0]; + resp = (struct ata_task_resp *)ts->buf; + if (t->ata_task.dma_xfer == 0 && + t->data_dir == DMA_FROM_DEVICE) { + len = sizeof(struct pio_setup_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("PIO read len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, ++ "PIO read len = %d\n", len); + } else if (t->ata_task.use_ncq) { + len = sizeof(struct set_dev_bits_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("FPDMA len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n", ++ len); + } else { + len = sizeof(struct dev_to_host_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("other len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, "other len = %d\n", ++ len); + } + if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { + resp->frame_len = len; + memcpy(&resp->ending_fis[0], sata_resp, len); + ts->buf_valid_size = sizeof(*resp); + } else +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("response to large\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "response too large\n"); + } + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB Tag\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + /* following cases are to do cases */ + case IO_UNDERFLOW: + /* SATA Completion with error */ +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_UNDERFLOW param = %d\n", param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW param = %d\n", param); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + ts->residual = param; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_INTERRUPTED; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT" +- "_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2556,8 +2462,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; +@@ -2572,17 +2478,15 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_" +- "NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_STP_RESOURCES" +- "_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2596,57 +2500,65 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_DMA: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_SATA_LINK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_SATA_LINK_TIMEOUT\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_REJECTED_NCQ_MODE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2659,14 +2571,14 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk(" IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, " IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_DS_IN_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2679,18 +2591,21 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + } + spin_lock_irqsave(&t->task_state_lock, flags); +@@ -2699,10 +2614,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p done with io_status 0x%x" +- " resp 0x%x stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -2731,12 +2645,10 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("No CCB !!!. returning\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "No CCB !!!. returning\n"); + } + if (event) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SATA EVENT 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", event); + + /* Check if this is NCQ error */ + if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) { +@@ -2752,61 +2664,54 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + if (event) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("sata IO status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, FAIL, "sata IO status 0x%x\n", event); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + ts = &t->task_status; +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n", +- port_id, dev_id, tag, event)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n", ++ port_id, dev_id, tag, event); + switch (event) { + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_INTERRUPTED; + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT" +- "_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2820,94 +2725,82 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_" +- "NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_ERROR_PEER_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PEER_ABORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PEER_ABORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_ERROR_REJECTED_NCQ_MODE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_UNEXPECTED_PHASE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_RDY_OVERRUN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_CMD_FRAME_ISSUED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n"); + break; + case IO_XFER_PIO_SETUP_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_PIO_SETUP_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_PIO_SETUP_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", event); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; +@@ -2919,10 +2812,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p done with io_status 0x%x" +- " resp 0x%x stat 0x%x but aborted by upper layer!\n", +- t, event, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, event, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -2952,86 +2844,79 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + ts = &t->task_status; + pm8001_dev = ccb->device; + if (status) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("smp IO status 0x%x\n", status)); +- PM8001_IOERR_DBG(pm8001_ha, +- pm8001_printk("status:0x%x, tag:0x%x, task:0x%p\n", +- status, tag, t)); ++ pm8001_dbg(pm8001_ha, FAIL, "smp IO status 0x%x\n", status); ++ pm8001_dbg(pm8001_ha, IOERR, ++ "status:0x%x, tag:0x%x, task:0x%p\n", ++ status, tag, t); + } + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + + switch (status) { + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PHY_DOWN; + break; + case IO_ERROR_HW_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ERROR_HW_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ERROR_HW_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -3040,76 +2925,67 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_" +- "NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_RX_FRAME: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_RX_FRAME\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_RX_FRAME\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_ERROR_INTERNAL_SMP_RESOURCE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ERROR_INTERNAL_SMP_RESOURCE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ERROR_INTERNAL_SMP_RESOURCE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_QUEUE_FULL; + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + /* not allowed case. Therefore, return failed status */ +@@ -3121,10 +2997,8 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with" +- " io_status 0x%x resp 0x%x " +- "stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -3146,9 +3020,8 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, + u32 device_id = le32_to_cpu(pPayload->device_id); + u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS; + u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS; +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set device id = 0x%x state " +- "from 0x%x to 0x%x status = 0x%x!\n", +- device_id, pds, nds, status)); ++ pm8001_dbg(pm8001_ha, MSG, "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n", ++ device_id, pds, nds, status); + complete(pm8001_dev->setds_completion); + ccb->task = NULL; + ccb->ccb_tag = 0xFFFFFFFF; +@@ -3163,10 +3036,9 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; + u32 dlen_status = le32_to_cpu(pPayload->dlen_status); + complete(pm8001_ha->nvmd_completion); +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n")); ++ pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); + if ((dlen_status & NVMD_STAT) != 0) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Set nvm data error!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error!\n"); + return; + } + ccb->task = NULL; +@@ -3188,26 +3060,22 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr; + fw_control_context = ccb->fw_control_context; + +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n")); ++ pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n"); + if ((dlen_status & NVMD_STAT) != 0) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Get nvm data error!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error!\n"); + complete(pm8001_ha->nvmd_completion); + return; + } + + if (ir_tds_bn_dps_das_nvm & IPMode) { + /* indirect mode - IR bit set */ +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Get NVMD success, IR=1\n")); ++ pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n"); + if ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == TWI_DEVICE) { + if (ir_tds_bn_dps_das_nvm == 0x80a80200) { + memcpy(pm8001_ha->sas_addr, + ((u8 *)virt_addr + 4), + SAS_ADDR_SIZE); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Get SAS address" +- " from VPD successfully!\n")); ++ pm8001_dbg(pm8001_ha, MSG, "Get SAS address from VPD successfully!\n"); + } + } else if (((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == C_SEEPROM) + || ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == VPD_FLASH) || +@@ -3218,14 +3086,14 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + ; + } else { + /* Should not be happened*/ +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("(IR=1)Wrong Device type 0x%x\n", +- ir_tds_bn_dps_das_nvm)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "(IR=1)Wrong Device type 0x%x\n", ++ ir_tds_bn_dps_das_nvm); + } + } else /* direct mode */{ +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n", +- (dlen_status & NVMD_LEN) >> 24)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Get NVMD success, IR=0, dataLen=%d\n", ++ (dlen_status & NVMD_LEN) >> 24); + } + /* Though fw_control_context is freed below, usrAddr still needs + * to be updated as this holds the response to the request function +@@ -3234,10 +3102,15 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + pm8001_ha->memoryMap.region[NVMD].virt_ptr, + fw_control_context->len); + kfree(ccb->fw_control_context); ++ /* To avoid race condition, complete should be ++ * called after the message is copied to ++ * fw_control_context->usrAddr ++ */ ++ complete(pm8001_ha->nvmd_completion); ++ pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); + ccb->task = NULL; + ccb->ccb_tag = 0xFFFFFFFF; + pm8001_tag_free(pm8001_ha, tag); +- complete(pm8001_ha->nvmd_completion); + } + + int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) +@@ -3250,13 +3123,13 @@ int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) + u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS; + tag = le32_to_cpu(pPayload->tag); + if (status != 0) { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("%x phy execute %x phy op failed!\n", +- phy_id, phy_op)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "%x phy execute %x phy op failed!\n", ++ phy_id, phy_op); + } else { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("%x phy execute %x phy op success!\n", +- phy_id, phy_op)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "%x phy execute %x phy op success!\n", ++ phy_id, phy_op); + pm8001_ha->phy[phy_id].reset_success = true; + } + if (pm8001_ha->phy[phy_id].enable_completion) { +@@ -3303,10 +3176,10 @@ void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) + } else if (phy->phy_type & PORT_TYPE_SATA) { + /*Nothing*/ + } +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("phy %d byte dmaded.\n", i)); ++ pm8001_dbg(pm8001_ha, MSG, "phy %d byte dmaded.\n", i); + + sas_phy->frame_rcvd_size = phy->frame_rcvd_size; +- pm8001_ha->sas->notify_port_event(sas_phy, PORTE_BYTES_DMAED); ++ sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED); + } + + /* Get the link rate speed */ +@@ -3420,43 +3293,39 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; +- struct sas_ha_struct *sas_ha = pm8001_ha->sas; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + unsigned long flags; + u8 deviceType = pPayload->sas_identify.dev_type; + port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", +- port_id, phy_id)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", ++ port_id, phy_id); + + switch (deviceType) { + case SAS_PHY_UNUSED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("device type no device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "device type no device.\n"); + break; + case SAS_END_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "end device.\n"); + pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, + PHY_NOTIFY_ENABLE_SPINUP); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + case SAS_EDGE_EXPANDER_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("expander device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "expander device.\n"); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + case SAS_FANOUT_EXPANDER_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("fanout expander device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "fanout expander device.\n"); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("unknown device type(%x)\n", deviceType)); ++ pm8001_dbg(pm8001_ha, DEVIO, "unknown device type(%x)\n", ++ deviceType); + break; + } + phy->phy_type |= PORT_TYPE_SAS; +@@ -3467,7 +3336,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + else if (phy->identify.device_type != SAS_PHY_UNUSED) + phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; + phy->sas_phy.oob_mode = SAS_OOB_MODE; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); + memcpy(phy->frame_rcvd, &pPayload->sas_identify, + sizeof(struct sas_identify_frame)-4); +@@ -3499,12 +3368,10 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; +- struct sas_ha_struct *sas_ha = pm8001_ha->sas; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + unsigned long flags; +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," +- " phy id = %d\n", port_id, phy_id)); ++ pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n", ++ port_id, phy_id); + port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; + port->port_attached = 1; +@@ -3512,7 +3379,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + phy->phy_type |= PORT_TYPE_SATA; + phy->phy_attached = 1; + phy->sas_phy.oob_mode = SATA_OOB_MODE; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); + memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), + sizeof(struct dev_to_host_fis)); +@@ -3552,37 +3419,35 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) + case PORT_VALID: + break; + case PORT_INVALID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" PortInvalid portID %d\n", port_id)); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Last phy Down and port invalid\n")); ++ pm8001_dbg(pm8001_ha, MSG, " PortInvalid portID %d\n", ++ port_id); ++ pm8001_dbg(pm8001_ha, MSG, ++ " Last phy Down and port invalid\n"); + port->port_attached = 0; + pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, + port_id, phy_id, 0, 0); + break; + case PORT_IN_RESET: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Port In Reset portID %d\n", port_id)); ++ pm8001_dbg(pm8001_ha, MSG, " Port In Reset portID %d\n", ++ port_id); + break; + case PORT_NOT_ESTABLISHED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ " phy Down and PORT_NOT_ESTABLISHED\n"); + port->port_attached = 0; + break; + case PORT_LOSTCOMM: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Last phy Down and port invalid\n")); ++ pm8001_dbg(pm8001_ha, MSG, " phy Down and PORT_LOSTCOMM\n"); ++ pm8001_dbg(pm8001_ha, MSG, ++ " Last phy Down and port invalid\n"); + port->port_attached = 0; + pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, + port_id, phy_id, 0, 0); + break; + default: + port->port_attached = 0; +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk(" phy Down and(default) = %x\n", +- portstate)); ++ pm8001_dbg(pm8001_ha, DEVIO, " phy Down and(default) = %x\n", ++ portstate); + break; + + } +@@ -3613,44 +3478,42 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + pm8001_dev = ccb->device; + status = le32_to_cpu(registerRespPayload->status); + device_id = le32_to_cpu(registerRespPayload->device_id); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" register device is status = %d\n", status)); ++ pm8001_dbg(pm8001_ha, MSG, " register device is status = %d\n", ++ status); + switch (status) { + case DEVREG_SUCCESS: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("DEVREG_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, MSG, "DEVREG_SUCCESS\n"); + pm8001_dev->device_id = device_id; + break; + case DEVREG_FAILURE_OUT_OF_RESOURCE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_OUT_OF_RESOURCE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "DEVREG_FAILURE_OUT_OF_RESOURCE\n"); + break; + case DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED\n"); + break; + case DEVREG_FAILURE_INVALID_PHY_ID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_INVALID_PHY_ID\n")); ++ pm8001_dbg(pm8001_ha, MSG, "DEVREG_FAILURE_INVALID_PHY_ID\n"); + break; + case DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED\n"); + break; + case DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE\n"); + break; + case DEVREG_FAILURE_PORT_NOT_VALID_STATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_PORT_NOT_VALID_STATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_PORT_NOT_VALID_STATE\n"); + break; + case DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID\n"); + break; + default: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("DEVREG_FAILURE_DEVICE_TYPE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "DEVREG_FAILURE_DEVICE_TYPE_NOT_SUPPORTED\n"); + break; + } + complete(pm8001_dev->dcompletion); +@@ -3670,9 +3533,9 @@ int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + status = le32_to_cpu(registerRespPayload->status); + device_id = le32_to_cpu(registerRespPayload->device_id); + if (status != 0) +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" deregister device failed ,status = %x" +- ", device_id = %x\n", status, device_id)); ++ pm8001_dbg(pm8001_ha, MSG, ++ " deregister device failed ,status = %x, device_id = %x\n", ++ status, device_id); + return 0; + } + +@@ -3692,44 +3555,37 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, + status = le32_to_cpu(ppayload->status); + switch (status) { + case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_COMPLETE_PENDING_REBOOT\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ ": FLASH_UPDATE_COMPLETE_PENDING_REBOOT\n"); + break; + case FLASH_UPDATE_IN_PROGRESS: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_IN_PROGRESS\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_IN_PROGRESS\n"); + break; + case FLASH_UPDATE_HDR_ERR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_HDR_ERR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_HDR_ERR\n"); + break; + case FLASH_UPDATE_OFFSET_ERR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_OFFSET_ERR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_OFFSET_ERR\n"); + break; + case FLASH_UPDATE_CRC_ERR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_CRC_ERR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_CRC_ERR\n"); + break; + case FLASH_UPDATE_LENGTH_ERR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_LENGTH_ERR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_LENGTH_ERR\n"); + break; + case FLASH_UPDATE_HW_ERR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_HW_ERR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_HW_ERR\n"); + break; + case FLASH_UPDATE_DNLD_NOT_SUPPORTED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_DNLD_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ ": FLASH_UPDATE_DNLD_NOT_SUPPORTED\n"); + break; + case FLASH_UPDATE_DISABLED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(": FLASH_UPDATE_DISABLED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ": FLASH_UPDATE_DISABLED\n"); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("No matched status = %d\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "No matched status = %d\n", ++ status); + break; + } + kfree(ccb->fw_control_context); +@@ -3747,12 +3603,11 @@ int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + struct general_event_resp *pPayload = + (struct general_event_resp *)(piomb + 4); + status = le32_to_cpu(pPayload->status); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" status = 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, MSG, " status = 0x%x\n", status); + for (i = 0; i < GENERAL_EVENT_PAYLOAD; i++) +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("inb_IOMB_payload[0x%x] 0x%x,\n", i, +- pPayload->inb_IOMB_payload[i])); ++ pm8001_dbg(pm8001_ha, MSG, "inb_IOMB_payload[0x%x] 0x%x,\n", ++ i, ++ pPayload->inb_IOMB_payload[i]); + return 0; + } + +@@ -3772,8 +3627,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + status = le32_to_cpu(pPayload->status); + tag = le32_to_cpu(pPayload->tag); + if (!tag) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk(" TAG NULL. RETURNING !!!")); ++ pm8001_dbg(pm8001_ha, FAIL, " TAG NULL. RETURNING !!!\n"); + return -1; + } + +@@ -3783,23 +3637,21 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + pm8001_dev = ccb->device; /* retrieve device */ + + if (!t) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk(" TASK NULL. RETURNING !!!")); ++ pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n"); + return -1; + } + ts = &t->task_status; + if (status != 0) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task abort failed status 0x%x ," +- "tag = 0x%x, scp= 0x%x\n", status, tag, scp)); ++ pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n", ++ status, tag, scp); + switch (status) { + case IO_SUCCESS: +- PM8001_EH_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, EH, "IO_SUCCESS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; + break; + case IO_NOT_VALID: +- PM8001_EH_DBG(pm8001_ha, pm8001_printk("IO_NOT_VALID\n")); ++ pm8001_dbg(pm8001_ha, EH, "IO_NOT_VALID\n"); + ts->resp = TMF_RESP_FUNC_FAILED; + break; + } +@@ -3844,14 +3696,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) + struct sas_ha_struct *sas_ha = pm8001_ha->sas; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n", +- port_id, phy_id, eventType, status)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n", ++ port_id, phy_id, eventType, status); + switch (eventType) { + case HW_EVENT_PHY_START_STATUS: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_START_STATUS" +- " status = %x\n", status)); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS status = %x\n", ++ status); + if (status == 0) { + phy->phy_state = 1; + if (pm8001_ha->flags == PM8001F_RUN_TIME && +@@ -3860,178 +3711,160 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) + } + break; + case HW_EVENT_SAS_PHY_UP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_START_STATUS\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS\n"); + hw_event_sas_phy_up(pm8001_ha, piomb); + break; + case HW_EVENT_SATA_PHY_UP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SATA_PHY_UP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_PHY_UP\n"); + hw_event_sata_phy_up(pm8001_ha, piomb); + break; + case HW_EVENT_PHY_STOP_STATUS: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_STOP_STATUS " +- "status = %x\n", status)); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_STOP_STATUS status = %x\n", ++ status); + if (status == 0) + phy->phy_state = 0; + break; + case HW_EVENT_SATA_SPINUP_HOLD: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD\n")); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n"); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + break; + case HW_EVENT_PHY_DOWN: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_DOWN\n")); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n"); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); + phy->phy_attached = 0; + phy->phy_state = 0; + hw_event_phy_down(pm8001_ha, piomb); + break; + case HW_EVENT_PORT_INVALID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_INVALID\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + /* the broadcast change primitive received, tell the LIBSAS this event + to revalidate the sas domain*/ + case HW_EVENT_BROADCAST_CHANGE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_CHANGE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_CHANGE\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE, + port_id, phy_id, 1, 0); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_PHY_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n"); + sas_phy_disconnected(&phy->sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + break; + case HW_EVENT_BROADCAST_EXP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_EXP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n"); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_LINK_ERR_INVALID_DWORD: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_INVALID_DWORD\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_INVALID_DWORD\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_LINK_ERR_DISPARITY_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_DISPARITY_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_DISPARITY_ERROR\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_DISPARITY_ERROR, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_LINK_ERR_CODE_VIOLATION: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_CODE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_CODE_VIOLATION\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_CODE_VIOLATION, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_MALFUNCTION: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_MALFUNCTION\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n"); + break; + case HW_EVENT_BROADCAST_SES: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_SES\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_SES\n"); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_SES; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_INBOUND_CRC_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_INBOUND_CRC_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_INBOUND_CRC_ERROR, + port_id, phy_id, 0, 0); + break; + case HW_EVENT_HARD_RESET_RECEIVED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_HARD_RESET_RECEIVED\n")); +- sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n"); ++ sas_notify_port_event(sas_phy, PORTE_HARD_RESET); + break; + case HW_EVENT_ID_FRAME_TIMEOUT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_ID_FRAME_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_LINK_ERR_PHY_RESET_FAILED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n"); + pm8001_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_PHY_RESET_FAILED, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_PORT_RESET_TIMER_TMO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_PORT_RECOVERY_TIMER_TMO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_PORT_RECOVERY_TIMER_TMO\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_PORT_RECOVER: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RECOVER\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n"); + break; + case HW_EVENT_PORT_RESET_COMPLETE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_COMPLETE\n"); + break; + case EVENT_BROADCAST_ASYNCH_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "EVENT_BROADCAST_ASYNCH_EVENT\n"); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown event type = %x\n", eventType)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown event type = %x\n", ++ eventType); + break; + } + return 0; +@@ -4047,163 +3880,132 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) + __le32 pHeader = *(__le32 *)piomb; + u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF); + +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:")); ++ pm8001_dbg(pm8001_ha, MSG, "process_one_iomb:\n"); + + switch (opc) { + case OPC_OUB_ECHO: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_ECHO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_ECHO\n"); + break; + case OPC_OUB_HW_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_HW_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_HW_EVENT\n"); + mpi_hw_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_COMP\n"); + mpi_ssp_completion(pm8001_ha, piomb); + break; + case OPC_OUB_SMP_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SMP_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_COMP\n"); + mpi_smp_completion(pm8001_ha, piomb); + break; + case OPC_OUB_LOCAL_PHY_CNTRL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_LOCAL_PHY_CNTRL\n"); + pm8001_mpi_local_phy_ctl(pm8001_ha, piomb); + break; + case OPC_OUB_DEV_REGIST: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEV_REGIST\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_REGIST\n"); + pm8001_mpi_reg_resp(pm8001_ha, piomb); + break; + case OPC_OUB_DEREG_DEV: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("unregister the device\n")); ++ pm8001_dbg(pm8001_ha, MSG, "unregister the device\n"); + pm8001_mpi_dereg_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_DEV_HANDLE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_DEV_HANDLE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEV_HANDLE\n"); + break; + case OPC_OUB_SATA_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_COMP\n"); + mpi_sata_completion(pm8001_ha, piomb); + break; + case OPC_OUB_SATA_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_EVENT\n"); + mpi_sata_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_EVENT\n"); + mpi_ssp_event(pm8001_ha, piomb); + break; + case OPC_OUB_DEV_HANDLE_ARRIV: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEV_HANDLE_ARRIV\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_HANDLE_ARRIV\n"); + /*This is for target*/ + break; + case OPC_OUB_SSP_RECV_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_RECV_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_RECV_EVENT\n"); + /*This is for target*/ + break; + case OPC_OUB_DEV_INFO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEV_INFO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_INFO\n"); + break; + case OPC_OUB_FW_FLASH_UPDATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_FW_FLASH_UPDATE\n"); + pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GPIO_RESPONSE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GPIO_RESPONSE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_RESPONSE\n"); + break; + case OPC_OUB_GPIO_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GPIO_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_EVENT\n"); + break; + case OPC_OUB_GENERAL_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GENERAL_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GENERAL_EVENT\n"); + pm8001_mpi_general_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SATA_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SAS_DIAG_MODE_START_END: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_DIAG_MODE_START_END\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_SAS_DIAG_MODE_START_END\n"); + break; + case OPC_OUB_SAS_DIAG_EXECUTE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_DIAG_EXECUTE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_DIAG_EXECUTE\n"); + break; + case OPC_OUB_GET_TIME_STAMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_TIME_STAMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_TIME_STAMP\n"); + break; + case OPC_OUB_SAS_HW_EVENT_ACK: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_HW_EVENT_ACK\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_HW_EVENT_ACK\n"); + break; + case OPC_OUB_PORT_CONTROL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_PORT_CONTROL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_PORT_CONTROL\n"); + break; + case OPC_OUB_SMP_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_NVMD_DATA: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_NVMD_DATA\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_NVMD_DATA\n"); + pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SET_NVMD_DATA: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_NVMD_DATA\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_NVMD_DATA\n"); + pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb); + break; + case OPC_OUB_DEVICE_HANDLE_REMOVAL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEVICE_HANDLE_REMOVAL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEVICE_HANDLE_REMOVAL\n"); + break; + case OPC_OUB_SET_DEVICE_STATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEVICE_STATE\n"); + pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_DEVICE_STATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_DEVICE_STATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEVICE_STATE\n"); + break; + case OPC_OUB_SET_DEV_INFO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_DEV_INFO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEV_INFO\n"); + break; + case OPC_OUB_SAS_RE_INITIALIZE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_RE_INITIALIZE\n"); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown outbound Queue IOMB OPC = %x\n", +- opc)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "Unknown outbound Queue IOMB OPC = %x\n", ++ opc); + break; + } + } +@@ -4416,19 +4218,19 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + circularQ = &pm8001_ha->inbnd_q_tbl[0]; + if (task->data_dir == DMA_NONE) { + ATAP = 0x04; /* no data*/ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("no data\n")); ++ pm8001_dbg(pm8001_ha, IO, "no data\n"); + } else if (likely(!task->ata_task.device_control_reg_update)) { + if (task->ata_task.dma_xfer) { + ATAP = 0x06; /* DMA */ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "DMA\n"); + } else { + ATAP = 0x05; /* PIO*/ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); ++ pm8001_dbg(pm8001_ha, IO, "PIO\n"); + } + if (task->ata_task.use_ncq && + dev->sata_dev.class != ATA_DEV_ATAPI) { + ATAP = 0x07; /* FPDMA */ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "FPDMA\n"); + } + } + if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) { +@@ -4485,10 +4287,10 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&task->task_state_lock, + flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p resp 0x%x " +- " stat 0x%x but aborted by upper layer " +- "\n", task, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p resp 0x%x stat 0x%x but aborted by upper layer\n", ++ task, ts->resp, ++ ts->stat); + pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); + } else { + spin_unlock_irqrestore(&task->task_state_lock, +@@ -4637,8 +4439,8 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, + memset(&payload, 0, sizeof(payload)); + payload.tag = cpu_to_le32(1); + payload.device_id = cpu_to_le32(device_id); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("unregister device device_id = %d\n", device_id)); ++ pm8001_dbg(pm8001_ha, MSG, "unregister device device_id = %d\n", ++ device_id); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); + return ret; +@@ -4690,9 +4492,9 @@ static irqreturn_t + pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) + { + pm8001_chip_interrupt_disable(pm8001_ha, vec); +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "irq vec %d, ODMR:0x%x\n", +- vec, pm8001_cr32(pm8001_ha, 0, 0x30))); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "irq vec %d, ODMR:0x%x\n", ++ vec, pm8001_cr32(pm8001_ha, 0, 0x30)); + process_oq(pm8001_ha, vec); + pm8001_chip_interrupt_enable(pm8001_ha, vec); + return IRQ_HANDLED; +@@ -4729,9 +4531,8 @@ int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, + { + u32 opc, device_id; + int rc = TMF_RESP_FUNC_FAILED; +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("cmd_tag = %x, abort task tag = 0x%x", +- cmd_tag, task_tag)); ++ pm8001_dbg(pm8001_ha, EH, "cmd_tag = %x, abort task tag = 0x%x\n", ++ cmd_tag, task_tag); + if (pm8001_dev->dev_type == SAS_END_DEVICE) + opc = OPC_INB_SSP_ABORT; + else if (pm8001_dev->dev_type == SAS_SATA_DEV) +@@ -4742,7 +4543,7 @@ int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, + rc = send_task_abort(pm8001_ha, opc, device_id, flag, + task_tag, cmd_tag); + if (rc != TMF_RESP_FUNC_COMPLETE) +- PM8001_EH_DBG(pm8001_ha, pm8001_printk("rc= %d\n", rc)); ++ pm8001_dbg(pm8001_ha, EH, "rc= %d\n", rc); + return rc; + } + +@@ -5008,8 +4809,9 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, + if (!fw_control_context) + return -ENOMEM; + fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "dma fw_control context input length :%x\n", fw_control->len)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "dma fw_control context input length :%x\n", ++ fw_control->len); + memcpy(buffer, fw_control->buffer, fw_control->len); + flash_update_info.sgl.addr = cpu_to_le64(phys_addr); + flash_update_info.sgl.im_len.len = cpu_to_le32(fw_control->len); +diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c +index 2025361b36e96..7657d68e12d5f 100644 +--- a/drivers/scsi/pm8001/pm8001_init.c ++++ b/drivers/scsi/pm8001/pm8001_init.c +@@ -271,15 +271,14 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, + + spin_lock_init(&pm8001_ha->lock); + spin_lock_init(&pm8001_ha->bitmap_lock); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("pm8001_alloc: PHY:%x\n", +- pm8001_ha->chip->n_phy)); ++ pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n", ++ pm8001_ha->chip->n_phy); + + /* Setup Interrupt */ + rc = pm8001_setup_irq(pm8001_ha); + if (rc) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "pm8001_setup_irq failed [ret: %d]\n", rc)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "pm8001_setup_irq failed [ret: %d]\n", rc); + goto err_out_shost; + } + /* Request Interrupt */ +@@ -394,9 +393,9 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, + &pm8001_ha->memoryMap.region[i].phys_addr_lo, + pm8001_ha->memoryMap.region[i].total_len, + pm8001_ha->memoryMap.region[i].alignment) != 0) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Mem%d alloc failed\n", +- i)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Mem%d alloc failed\n", ++ i); + goto err_out; + } + } +@@ -412,7 +411,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, + pm8001_ha->devices[i].dev_type = SAS_PHY_UNUSED; + pm8001_ha->devices[i].id = i; + pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES; +- pm8001_ha->devices[i].running_req = 0; ++ atomic_set(&pm8001_ha->devices[i].running_req, 0); + } + pm8001_ha->flags = PM8001F_INIT_TIME; + /* Initialize tags */ +@@ -467,15 +466,15 @@ static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha) + pm8001_ha->io_mem[logicalBar].memvirtaddr = + ioremap(pm8001_ha->io_mem[logicalBar].membase, + pm8001_ha->io_mem[logicalBar].memsize); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PCI: bar %d, logicalBar %d ", +- bar, logicalBar)); +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "base addr %llx virt_addr=%llx len=%d\n", +- (u64)pm8001_ha->io_mem[logicalBar].membase, +- (u64)(unsigned long) +- pm8001_ha->io_mem[logicalBar].memvirtaddr, +- pm8001_ha->io_mem[logicalBar].memsize)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "PCI: bar %d, logicalBar %d\n", ++ bar, logicalBar); ++ pm8001_dbg(pm8001_ha, INIT, ++ "base addr %llx virt_addr=%llx len=%d\n", ++ (u64)pm8001_ha->io_mem[logicalBar].membase, ++ (u64)(unsigned long) ++ pm8001_ha->io_mem[logicalBar].memvirtaddr, ++ pm8001_ha->io_mem[logicalBar].memsize); + } else { + pm8001_ha->io_mem[logicalBar].membase = 0; + pm8001_ha->io_mem[logicalBar].memsize = 0; +@@ -520,8 +519,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, + else { + pm8001_ha->link_rate = LINKRATE_15 | LINKRATE_30 | + LINKRATE_60 | LINKRATE_120; +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "Setting link rate to default value\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Setting link rate to default value\n"); + } + sprintf(pm8001_ha->name, "%s%d", DRV_NAME, pm8001_ha->id); + /* IOMB size is 128 for 8088/89 controllers */ +@@ -684,13 +683,13 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) + payload.offset = 0; + payload.func_specific = kzalloc(payload.rd_length, GFP_KERNEL); + if (!payload.func_specific) { +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("mem alloc fail\n")); ++ pm8001_dbg(pm8001_ha, INIT, "mem alloc fail\n"); + return; + } + rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + if (rc) { + kfree(payload.func_specific); +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n")); ++ pm8001_dbg(pm8001_ha, INIT, "nvmd failed\n"); + return; + } + wait_for_completion(&completion); +@@ -718,9 +717,8 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) + sas_add[7] = sas_add[7] + 4; + memcpy(&pm8001_ha->phy[i].dev_sas_addr, + sas_add, SAS_ADDR_SIZE); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("phy %d sas_addr = %016llx\n", i, +- pm8001_ha->phy[i].dev_sas_addr)); ++ pm8001_dbg(pm8001_ha, INIT, "phy %d sas_addr = %016llx\n", i, ++ pm8001_ha->phy[i].dev_sas_addr); + } + kfree(payload.func_specific); + #else +@@ -760,7 +758,7 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) + rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + if (rc) { + kfree(payload.func_specific); +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n")); ++ pm8001_dbg(pm8001_ha, INIT, "nvmd failed\n"); + return -ENOMEM; + } + wait_for_completion(&completion); +@@ -854,9 +852,9 @@ void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask) + break; + + default: +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Unknown subsystem device=0x%.04x", +- pm8001_ha->pdev->subsystem_device)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Unknown subsystem device=0x%.04x\n", ++ pm8001_ha->pdev->subsystem_device); + } + } + +@@ -950,9 +948,9 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) + /* Maximum queue number updating in HBA structure */ + pm8001_ha->max_q_num = number_of_intr; + +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "pci_alloc_irq_vectors request ret:%d no of intr %d\n", +- rc, pm8001_ha->number_of_intr)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "pci_alloc_irq_vectors request ret:%d no of intr %d\n", ++ rc, pm8001_ha->number_of_intr); + return 0; + } + +@@ -964,9 +962,9 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) + if (pm8001_ha->chip_id != chip_8001) + flag &= ~IRQF_SHARED; + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("pci_enable_msix request number of intr %d\n", +- pm8001_ha->number_of_intr)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "pci_enable_msix request number of intr %d\n", ++ pm8001_ha->number_of_intr); + + for (i = 0; i < pm8001_ha->number_of_intr; i++) { + snprintf(pm8001_ha->intr_drvname[i], +@@ -1002,8 +1000,7 @@ static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha) + #ifdef PM8001_USE_MSIX + if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) + return pm8001_setup_msix(pm8001_ha); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MSIX not supported!!!\n")); ++ pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); + #endif + return 0; + } +@@ -1023,8 +1020,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) + if (pdev->msix_cap && pci_msi_enabled()) + return pm8001_request_msix(pm8001_ha); + else { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MSIX not supported!!!\n")); ++ pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); + goto intx; + } + #endif +@@ -1108,8 +1104,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev, + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); + rc = PM8001_CHIP_DISP->chip_init(pm8001_ha); + if (rc) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "chip_init failed [ret: %d]\n", rc)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "chip_init failed [ret: %d]\n", rc); + goto err_out_ha_free; + } + +@@ -1138,8 +1134,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev, + pm8001_post_sas_ha_init(shost, chip); + rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); + if (rc) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "sas_register_ha failed [ret: %d]\n", rc)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "sas_register_ha failed [ret: %d]\n", rc); + goto err_out_shost; + } + list_add_tail(&pm8001_ha->list, &hba_list); +@@ -1191,8 +1187,8 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, + pm8001_ha->ccb_info = (struct pm8001_ccb_info *) + kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL); + if (!pm8001_ha->ccb_info) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk +- ("Unable to allocate memory for ccb\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Unable to allocate memory for ccb\n"); + goto err_out_noccb; + } + for (i = 0; i < ccb_count; i++) { +@@ -1200,8 +1196,8 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, + sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG, + &pm8001_ha->ccb_info[i].ccb_dma_handle); + if (!pm8001_ha->ccb_info[i].buf_prd) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk +- ("pm80xx: ccb prd memory allocation error\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "pm80xx: ccb prd memory allocation error\n"); + goto err_out; + } + pm8001_ha->ccb_info[i].task = NULL; +@@ -1345,8 +1341,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev) + /* chip soft rst only for spc */ + if (pm8001_ha->chip_id == chip_8001) { + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("chip soft reset successful\n")); ++ pm8001_dbg(pm8001_ha, INIT, "chip soft reset successful\n"); + } + rc = PM8001_CHIP_DISP->chip_init(pm8001_ha); + if (rc) +diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c +index 9889bab7d31c1..474468df2a78d 100644 +--- a/drivers/scsi/pm8001/pm8001_sas.c ++++ b/drivers/scsi/pm8001/pm8001_sas.c +@@ -158,7 +158,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + int rc = 0, phy_id = sas_phy->id; + struct pm8001_hba_info *pm8001_ha = NULL; + struct sas_phy_linkrates *rates; +- struct sas_ha_struct *sas_ha; + struct pm8001_phy *phy; + DECLARE_COMPLETION_ONSTACK(completion); + unsigned long flags; +@@ -207,18 +206,16 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + if (pm8001_ha->chip_id != chip_8001) { + if (pm8001_ha->phy[phy_id].phy_state == + PHY_STATE_LINK_UP_SPCV) { +- sas_ha = pm8001_ha->sas; + sas_phy_disconnected(&phy->sas_phy); +- sas_ha->notify_phy_event(&phy->sas_phy, ++ sas_notify_phy_event(&phy->sas_phy, + PHYE_LOSS_OF_SIGNAL); + phy->phy_attached = 0; + } + } else { + if (pm8001_ha->phy[phy_id].phy_state == + PHY_STATE_LINK_UP_SPC) { +- sas_ha = pm8001_ha->sas; + sas_phy_disconnected(&phy->sas_phy); +- sas_ha->notify_phy_event(&phy->sas_phy, ++ sas_notify_phy_event(&phy->sas_phy, + PHYE_LOSS_OF_SIGNAL); + phy->phy_attached = 0; + } +@@ -250,8 +247,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + return 0; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("func 0x%x\n", func)); ++ pm8001_dbg(pm8001_ha, DEVIO, "func 0x%x\n", func); + rc = -EOPNOTSUPP; + } + msleep(300); +@@ -405,7 +401,7 @@ static int pm8001_task_exec(struct sas_task *task, + t->task_done(t); + return 0; + } +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("pm8001_task_exec device \n ")); ++ pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec device\n"); + spin_lock_irqsave(&pm8001_ha->lock, flags); + do { + dev = t->dev; +@@ -456,9 +452,11 @@ static int pm8001_task_exec(struct sas_task *task, + ccb->device = pm8001_dev; + switch (task_proto) { + case SAS_PROTOCOL_SMP: ++ atomic_inc(&pm8001_dev->running_req); + rc = pm8001_task_prep_smp(pm8001_ha, ccb); + break; + case SAS_PROTOCOL_SSP: ++ atomic_inc(&pm8001_dev->running_req); + if (is_tmf) + rc = pm8001_task_prep_ssp_tm(pm8001_ha, + ccb, tmf); +@@ -467,6 +465,7 @@ static int pm8001_task_exec(struct sas_task *task, + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: ++ atomic_inc(&pm8001_dev->running_req); + rc = pm8001_task_prep_ata(pm8001_ha, ccb); + break; + default: +@@ -477,15 +476,14 @@ static int pm8001_task_exec(struct sas_task *task, + } + + if (rc) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("rc is %x\n", rc)); ++ pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc); ++ atomic_dec(&pm8001_dev->running_req); + goto err_out_tag; + } + /* TODO: select normal or high priority */ + spin_lock(&t->task_state_lock); + t->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock(&t->task_state_lock); +- pm8001_dev->running_req++; + } while (0); + rc = 0; + goto out_done; +@@ -567,9 +565,9 @@ static struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha) + } + } + if (dev == PM8001_MAX_DEVICES) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("max support %d devices, ignore ..\n", +- PM8001_MAX_DEVICES)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "max support %d devices, ignore ..\n", ++ PM8001_MAX_DEVICES); + } + return NULL; + } +@@ -587,8 +585,7 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, + return &pm8001_ha->devices[dev]; + } + if (dev == PM8001_MAX_DEVICES) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("NO MATCHING " +- "DEVICE FOUND !!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "NO MATCHING DEVICE FOUND !!!\n"); + } + return NULL; + } +@@ -649,10 +646,10 @@ static int pm8001_dev_found_notify(struct domain_device *dev) + } + } + if (phy_id == parent_dev->ex_dev.num_phys) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Error: no attached dev:%016llx" +- " at ex:%016llx.\n", SAS_ADDR(dev->sas_addr), +- SAS_ADDR(parent_dev->sas_addr))); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Error: no attached dev:%016llx at ex:%016llx.\n", ++ SAS_ADDR(dev->sas_addr), ++ SAS_ADDR(parent_dev->sas_addr)); + res = -1; + } + } else { +@@ -662,7 +659,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) + flag = 1; /* directly sata */ + } + } /*register this device to HBA*/ +- PM8001_DISC_DBG(pm8001_ha, pm8001_printk("Found device\n")); ++ pm8001_dbg(pm8001_ha, DISC, "Found device\n"); + PM8001_CHIP_DISP->reg_dev_req(pm8001_ha, pm8001_device, flag); + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + wait_for_completion(&completion); +@@ -734,9 +731,7 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, + + if (res) { + del_timer(&task->slow_task->timer); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Executing internal task " +- "failed\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n"); + goto ex_err; + } + wait_for_completion(&task->slow_task->completion); +@@ -750,9 +745,9 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, + /* Even TMF timed out, return direct. */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TMF task[%x]timeout.\n", +- tmf->tmf)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "TMF task[%x]timeout.\n", ++ tmf->tmf); + goto ex_err; + } + } +@@ -773,17 +768,15 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, + + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAS_DATA_OVERRUN) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Blocked task error.\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Blocked task error.\n"); + res = -EMSGSIZE; + break; + } else { +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk(" Task to dev %016llx response:" +- "0x%x status 0x%x\n", +- SAS_ADDR(dev->sas_addr), +- task->task_status.resp, +- task->task_status.stat)); ++ pm8001_dbg(pm8001_ha, EH, ++ " Task to dev %016llx response:0x%x status 0x%x\n", ++ SAS_ADDR(dev->sas_addr), ++ task->task_status.resp, ++ task->task_status.stat); + sas_free_task(task); + task = NULL; + } +@@ -830,9 +823,7 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, + + if (res) { + del_timer(&task->slow_task->timer); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Executing internal task " +- "failed\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n"); + goto ex_err; + } + wait_for_completion(&task->slow_task->completion); +@@ -840,8 +831,8 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, + /* Even TMF timed out, return direct. */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TMF task timeout.\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "TMF task timeout.\n"); + goto ex_err; + } + } +@@ -852,12 +843,11 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, + break; + + } else { +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk(" Task to dev %016llx response: " +- "0x%x status 0x%x\n", +- SAS_ADDR(dev->sas_addr), +- task->task_status.resp, +- task->task_status.stat)); ++ pm8001_dbg(pm8001_ha, EH, ++ " Task to dev %016llx response: 0x%x status 0x%x\n", ++ SAS_ADDR(dev->sas_addr), ++ task->task_status.resp, ++ task->task_status.stat); + sas_free_task(task); + task = NULL; + } +@@ -883,22 +873,20 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) + if (pm8001_dev) { + u32 device_id = pm8001_dev->device_id; + +- PM8001_DISC_DBG(pm8001_ha, +- pm8001_printk("found dev[%d:%x] is gone.\n", +- pm8001_dev->device_id, pm8001_dev->dev_type)); +- if (pm8001_dev->running_req) { ++ pm8001_dbg(pm8001_ha, DISC, "found dev[%d:%x] is gone.\n", ++ pm8001_dev->device_id, pm8001_dev->dev_type); ++ if (atomic_read(&pm8001_dev->running_req)) { + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , + dev, 1, 0); +- while (pm8001_dev->running_req) ++ while (atomic_read(&pm8001_dev->running_req)) + msleep(20); + spin_lock_irqsave(&pm8001_ha->lock, flags); + } + PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); + pm8001_free_dev(pm8001_dev); + } else { +- PM8001_DISC_DBG(pm8001_ha, +- pm8001_printk("Found dev has gone.\n")); ++ pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n"); + } + dev->lldd_dev = NULL; + spin_unlock_irqrestore(&pm8001_ha->lock, flags); +@@ -968,7 +956,7 @@ void pm8001_open_reject_retry( + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + spin_lock_irqsave(&task->task_state_lock, flags1); + task->task_state_flags &= ~SAS_TASK_STATE_PENDING; + task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; +@@ -1018,9 +1006,9 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) + } + rc = sas_phy_reset(phy, 1); + if (rc) { +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("phy reset failed for device %x\n" +- "with rc %d\n", pm8001_dev->device_id, rc)); ++ pm8001_dbg(pm8001_ha, EH, ++ "phy reset failed for device %x\n" ++ "with rc %d\n", pm8001_dev->device_id, rc); + rc = TMF_RESP_FUNC_FAILED; + goto out; + } +@@ -1028,17 +1016,16 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) + rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , + dev, 1, 0); + if (rc) { +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("task abort failed %x\n" +- "with rc %d\n", pm8001_dev->device_id, rc)); ++ pm8001_dbg(pm8001_ha, EH, "task abort failed %x\n" ++ "with rc %d\n", pm8001_dev->device_id, rc); + rc = TMF_RESP_FUNC_FAILED; + } + } else { + rc = sas_phy_reset(phy, 1); + msleep(2000); + } +- PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n", +- pm8001_dev->device_id, rc)); ++ pm8001_dbg(pm8001_ha, EH, " for device[%x]:rc=%d\n", ++ pm8001_dev->device_id, rc); + out: + sas_put_local_phy(phy); + return rc; +@@ -1061,8 +1048,7 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev) + pm8001_dev = dev->lldd_dev; + pm8001_ha = pm8001_find_ha_by_dev(dev); + +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("I_T_Nexus handler invoked !!")); ++ pm8001_dbg(pm8001_ha, EH, "I_T_Nexus handler invoked !!\n"); + + phy = sas_get_local_phy(dev); + +@@ -1101,8 +1087,8 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev) + rc = sas_phy_reset(phy, 1); + msleep(2000); + } +- PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n", +- pm8001_dev->device_id, rc)); ++ pm8001_dbg(pm8001_ha, EH, " for device[%x]:rc=%d\n", ++ pm8001_dev->device_id, rc); + out: + sas_put_local_phy(phy); + +@@ -1131,8 +1117,8 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) + rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task); + } + /* If failed, fall-through I_T_Nexus reset */ +- PM8001_EH_DBG(pm8001_ha, pm8001_printk("for device[%x]:rc=%d\n", +- pm8001_dev->device_id, rc)); ++ pm8001_dbg(pm8001_ha, EH, "for device[%x]:rc=%d\n", ++ pm8001_dev->device_id, rc); + return rc; + } + +@@ -1140,7 +1126,6 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) + int pm8001_query_task(struct sas_task *task) + { + u32 tag = 0xdeadbeef; +- int i = 0; + struct scsi_lun lun; + struct pm8001_tmf_task tmf_task; + int rc = TMF_RESP_FUNC_FAILED; +@@ -1159,10 +1144,7 @@ int pm8001_query_task(struct sas_task *task) + rc = TMF_RESP_FUNC_FAILED; + return rc; + } +- PM8001_EH_DBG(pm8001_ha, pm8001_printk("Query:[")); +- for (i = 0; i < 16; i++) +- printk(KERN_INFO "%02x ", cmnd->cmnd[i]); +- printk(KERN_INFO "]\n"); ++ pm8001_dbg(pm8001_ha, EH, "Query:[%16ph]\n", cmnd->cmnd); + tmf_task.tmf = TMF_QUERY_TASK; + tmf_task.tag_of_task_to_be_managed = tag; + +@@ -1170,15 +1152,14 @@ int pm8001_query_task(struct sas_task *task) + switch (rc) { + /* The task is still in Lun, release it then */ + case TMF_RESP_FUNC_SUCC: +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("The task is still in Lun\n")); ++ pm8001_dbg(pm8001_ha, EH, ++ "The task is still in Lun\n"); + break; + /* The task is not in Lun or failed, reset the phy */ + case TMF_RESP_FUNC_FAILED: + case TMF_RESP_FUNC_COMPLETE: +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("The task is not in Lun or failed," +- " reset the phy\n")); ++ pm8001_dbg(pm8001_ha, EH, ++ "The task is not in Lun or failed, reset the phy\n"); + break; + } + } +@@ -1264,8 +1245,8 @@ int pm8001_abort_task(struct sas_task *task) + * leaking the task in libsas or losing the race and + * getting a double free. + */ +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Waiting for local phy ctl\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Waiting for local phy ctl\n"); + ret = wait_for_completion_timeout(&completion, + PM8001_TASK_TIMEOUT * HZ); + if (!ret || !phy->reset_success) { +@@ -1275,8 +1256,8 @@ int pm8001_abort_task(struct sas_task *task) + /* 3. Wait for Port Reset complete or + * Port reset TMO + */ +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Waiting for Port reset\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Waiting for Port reset\n"); + ret = wait_for_completion_timeout( + &completion_reset, + PM8001_TASK_TIMEOUT * HZ); +@@ -1355,9 +1336,8 @@ int pm8001_clear_task_set(struct domain_device *dev, u8 *lun) + struct pm8001_device *pm8001_dev = dev->lldd_dev; + struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); + +- PM8001_EH_DBG(pm8001_ha, +- pm8001_printk("I_T_L_Q clear task set[%x]\n", +- pm8001_dev->device_id)); ++ pm8001_dbg(pm8001_ha, EH, "I_T_L_Q clear task set[%x]\n", ++ pm8001_dev->device_id); + tmf_task.tmf = TMF_CLEAR_TASK_SET; + return pm8001_issue_ssp_tmf(dev, lun, &tmf_task); + } +diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h +index 95663e1380833..5cd6fe6a7d2d9 100644 +--- a/drivers/scsi/pm8001/pm8001_sas.h ++++ b/drivers/scsi/pm8001/pm8001_sas.h +@@ -69,45 +69,16 @@ + #define PM8001_DEV_LOGGING 0x80 /* development message logging */ + #define PM8001_DEVIO_LOGGING 0x100 /* development io message logging */ + #define PM8001_IOERR_LOGGING 0x200 /* development io err message logging */ +-#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \ +- format, pm8001_ha->name, __func__, __LINE__, ## arg) +-#define PM8001_CHECK_LOGGING(HBA, LEVEL, CMD) \ +-do { \ +- if (unlikely(HBA->logging_level & LEVEL)) \ +- do { \ +- CMD; \ +- } while (0); \ +-} while (0); + +-#define PM8001_EH_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_EH_LOGGING, CMD) ++#define pm8001_printk(fmt, ...) \ ++ pr_info("%s:: %s %d:" fmt, \ ++ pm8001_ha->name, __func__, __LINE__, ##__VA_ARGS__) + +-#define PM8001_INIT_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_INIT_LOGGING, CMD) +- +-#define PM8001_DISC_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_DISC_LOGGING, CMD) +- +-#define PM8001_IO_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_IO_LOGGING, CMD) +- +-#define PM8001_FAIL_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_FAIL_LOGGING, CMD) +- +-#define PM8001_IOCTL_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_IOCTL_LOGGING, CMD) +- +-#define PM8001_MSG_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_MSG_LOGGING, CMD) +- +-#define PM8001_DEV_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_DEV_LOGGING, CMD) +- +-#define PM8001_DEVIO_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_DEVIO_LOGGING, CMD) +- +-#define PM8001_IOERR_DBG(HBA, CMD) \ +- PM8001_CHECK_LOGGING(HBA, PM8001_IOERR_LOGGING, CMD) ++#define pm8001_dbg(HBA, level, fmt, ...) \ ++do { \ ++ if (unlikely((HBA)->logging_level & PM8001_##level##_LOGGING)) \ ++ pm8001_printk(fmt, ##__VA_ARGS__); \ ++} while (0) + + #define PM8001_USE_TASKLET + #define PM8001_USE_MSIX +@@ -293,7 +264,7 @@ struct pm8001_device { + struct completion *dcompletion; + struct completion *setds_completion; + u32 device_id; +- u32 running_req; ++ atomic_t running_req; + }; + + struct pm8001_prd_imt { +diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c +index 155382ce84698..055f7649676ec 100644 +--- a/drivers/scsi/pm8001/pm80xx_hwi.c ++++ b/drivers/scsi/pm8001/pm80xx_hwi.c +@@ -58,9 +58,8 @@ int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value) + reg_val = pm8001_cr32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER); + } while ((reg_val != shift_value) && time_before(jiffies, start)); + if (reg_val != shift_value) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +- " = 0x%x\n", reg_val)); ++ pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:MEMBASE_II_SHIFT_REGISTER = 0x%x\n", ++ reg_val); + return -1; + } + return 0; +@@ -109,8 +108,8 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, + } + /* initialize variables for very first call from host application */ + if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("forensic_info TYPE_NON_FATAL..............\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "forensic_info TYPE_NON_FATAL..............\n"); + direct_data = (u8 *)fatal_error_data; + pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL; + pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET; +@@ -123,17 +122,13 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, + MPI_FATAL_EDUMP_TABLE_SIGNATURE, 0x1234abcd); + + pm8001_ha->forensic_info.data_buf.direct_data = direct_data; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("ossaHwCB: status1 %d\n", status)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("ossaHwCB: read_len 0x%x\n", +- pm8001_ha->forensic_info.data_buf.read_len)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("ossaHwCB: direct_len 0x%x\n", +- pm8001_ha->forensic_info.data_buf.direct_len)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("ossaHwCB: direct_offset 0x%x\n", +- pm8001_ha->forensic_info.data_buf.direct_offset)); ++ pm8001_dbg(pm8001_ha, IO, "ossaHwCB: status1 %d\n", status); ++ pm8001_dbg(pm8001_ha, IO, "ossaHwCB: read_len 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.read_len); ++ pm8001_dbg(pm8001_ha, IO, "ossaHwCB: direct_len 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.direct_len); ++ pm8001_dbg(pm8001_ha, IO, "ossaHwCB: direct_offset 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.direct_offset); + } + if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) { + /* start to get data */ +@@ -153,29 +148,24 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, + */ + length_to_read = + accum_len - pm8001_ha->forensic_preserved_accumulated_transfer; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: accum_len 0x%x\n", accum_len)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: length_to_read 0x%x\n", +- length_to_read)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: last_offset 0x%x\n", +- pm8001_ha->forensic_last_offset)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: read_len 0x%x\n", +- pm8001_ha->forensic_info.data_buf.read_len)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv:: direct_len 0x%x\n", +- pm8001_ha->forensic_info.data_buf.direct_len)); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv:: direct_offset 0x%x\n", +- pm8001_ha->forensic_info.data_buf.direct_offset)); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: accum_len 0x%x\n", ++ accum_len); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: length_to_read 0x%x\n", ++ length_to_read); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: last_offset 0x%x\n", ++ pm8001_ha->forensic_last_offset); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: read_len 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.read_len); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv:: direct_len 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.direct_len); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv:: direct_offset 0x%x\n", ++ pm8001_ha->forensic_info.data_buf.direct_offset); + + /* If accumulated length failed to read correctly fail the attempt.*/ + if (accum_len == 0xFFFFFFFF) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("Possible PCI issue 0x%x not expected\n", +- accum_len)); ++ pm8001_dbg(pm8001_ha, IO, ++ "Possible PCI issue 0x%x not expected\n", ++ accum_len); + return status; + } + /* If accumulated length is zero fail the attempt */ +@@ -239,8 +229,8 @@ moreData: + offset = (int) + ((char *)pm8001_ha->forensic_info.data_buf.direct_data + - (char *)buf); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv:return1 0x%x\n", offset)); ++ pm8001_dbg(pm8001_ha, IO, ++ "get_fatal_spcv:return1 0x%x\n", offset); + return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; +@@ -262,8 +252,8 @@ moreData: + offset = (int) + ((char *)pm8001_ha->forensic_info.data_buf.direct_data + - (char *)buf); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv:return2 0x%x\n", offset)); ++ pm8001_dbg(pm8001_ha, IO, ++ "get_fatal_spcv:return2 0x%x\n", offset); + return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; +@@ -289,8 +279,8 @@ moreData: + offset = (int) + ((char *)pm8001_ha->forensic_info.data_buf.direct_data + - (char *)buf); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: return3 0x%x\n", offset)); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return3 0x%x\n", ++ offset); + return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +@@ -327,9 +317,9 @@ moreData: + } while ((reg_val) && time_before(jiffies, start)); + + if (reg_val != 0) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "TIMEOUT:MPI_FATAL_EDUMP_TABLE_HDSHAKE 0x%x\n", +- reg_val)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "TIMEOUT:MPI_FATAL_EDUMP_TABLE_HDSHAKE 0x%x\n", ++ reg_val); + /* Fail the dump if a timeout occurs */ + pm8001_ha->forensic_info.data_buf.direct_data += + sprintf( +@@ -351,9 +341,9 @@ moreData: + time_before(jiffies, start)); + + if (reg_val < 2) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "TIMEOUT:MPI_FATAL_EDUMP_TABLE_STATUS = 0x%x\n", +- reg_val)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "TIMEOUT:MPI_FATAL_EDUMP_TABLE_STATUS = 0x%x\n", ++ reg_val); + /* Fail the dump if a timeout occurs */ + pm8001_ha->forensic_info.data_buf.direct_data += + sprintf( +@@ -387,8 +377,7 @@ moreData: + } + offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data + - (char *)buf); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("get_fatal_spcv: return4 0x%x\n", offset)); ++ pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset); + return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +@@ -419,8 +408,7 @@ ssize_t pm80xx_get_non_fatal_dump(struct device *cdev, + PAGE_SIZE, "Not supported for SPC controller"); + return 0; + } +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("forensic_info TYPE_NON_FATAL...\n")); ++ pm8001_dbg(pm8001_ha, IO, "forensic_info TYPE_NON_FATAL...\n"); + /* + * Step 1: Write the host buffer parameters in the MPI Fatal and + * Non-Fatal Error Dump Capture Table.This is the buffer +@@ -581,24 +569,24 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) + pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version = + pm8001_mr32(address, MAIN_MPI_INACTIVE_FW_VERSION); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Main cfg table: sign:%x interface rev:%x fw_rev:%x\n", +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev)); +- +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "table offset: gst:%x iq:%x oq:%x int vec:%x phy attr:%x\n", +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.outbound_queue_offset, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset)); +- +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Main cfg table; ila rev:%x Inactive fw rev:%x\n", +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version, +- pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "Main cfg table: sign:%x interface rev:%x fw_rev:%x\n", ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev); ++ ++ pm8001_dbg(pm8001_ha, DEV, ++ "table offset: gst:%x iq:%x oq:%x int vec:%x phy attr:%x\n", ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.outbound_queue_offset, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset); ++ ++ pm8001_dbg(pm8001_ha, DEV, ++ "Main cfg table; ila rev:%x Inactive fw rev:%x\n", ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version, ++ pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version); + } + + /** +@@ -808,10 +796,10 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) + pm8001_ha->inbnd_q_tbl[i].producer_idx = 0; + pm8001_ha->inbnd_q_tbl[i].consumer_index = 0; + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "IQ %d pi_bar 0x%x pi_offset 0x%x\n", i, +- pm8001_ha->inbnd_q_tbl[i].pi_pci_bar, +- pm8001_ha->inbnd_q_tbl[i].pi_offset)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "IQ %d pi_bar 0x%x pi_offset 0x%x\n", i, ++ pm8001_ha->inbnd_q_tbl[i].pi_pci_bar, ++ pm8001_ha->inbnd_q_tbl[i].pi_offset); + } + for (i = 0; i < pm8001_ha->max_q_num; i++) { + pm8001_ha->outbnd_q_tbl[i].element_size_cnt = +@@ -841,10 +829,10 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) + pm8001_ha->outbnd_q_tbl[i].consumer_idx = 0; + pm8001_ha->outbnd_q_tbl[i].producer_index = 0; + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "OQ %d ci_bar 0x%x ci_offset 0x%x\n", i, +- pm8001_ha->outbnd_q_tbl[i].ci_pci_bar, +- pm8001_ha->outbnd_q_tbl[i].ci_offset)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "OQ %d ci_bar 0x%x ci_offset 0x%x\n", i, ++ pm8001_ha->outbnd_q_tbl[i].ci_pci_bar, ++ pm8001_ha->outbnd_q_tbl[i].ci_offset); + } + } + +@@ -878,9 +866,9 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) + ((pm8001_ha->max_q_num - 1) << 8); + pm8001_mw32(address, MAIN_FATAL_ERROR_INTERRUPT, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt); +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Updated Fatal error interrupt vector 0x%x\n", +- pm8001_mr32(address, MAIN_FATAL_ERROR_INTERRUPT))); ++ pm8001_dbg(pm8001_ha, DEV, ++ "Updated Fatal error interrupt vector 0x%x\n", ++ pm8001_mr32(address, MAIN_FATAL_ERROR_INTERRUPT)); + + pm8001_mw32(address, MAIN_EVENT_CRC_CHECK, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump); +@@ -891,9 +879,9 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) + pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping |= 0x20000000; + pm8001_mw32(address, MAIN_GPIO_LED_FLAGS_OFFSET, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping); +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Programming DW 0x21 in main cfg table with 0x%x\n", +- pm8001_mr32(address, MAIN_GPIO_LED_FLAGS_OFFSET))); ++ pm8001_dbg(pm8001_ha, DEV, ++ "Programming DW 0x21 in main cfg table with 0x%x\n", ++ pm8001_mr32(address, MAIN_GPIO_LED_FLAGS_OFFSET)); + + pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer); +@@ -934,20 +922,20 @@ static void update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha, + pm8001_mw32(address, offset + IB_CI_BASE_ADDR_LO_OFFSET, + pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "IQ %d: Element pri size 0x%x\n", +- number, +- pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "IQ %d: Element pri size 0x%x\n", ++ number, ++ pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "IQ upr base addr 0x%x IQ lwr base addr 0x%x\n", +- pm8001_ha->inbnd_q_tbl[number].upper_base_addr, +- pm8001_ha->inbnd_q_tbl[number].lower_base_addr)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "IQ upr base addr 0x%x IQ lwr base addr 0x%x\n", ++ pm8001_ha->inbnd_q_tbl[number].upper_base_addr, ++ pm8001_ha->inbnd_q_tbl[number].lower_base_addr); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "CI upper base addr 0x%x CI lower base addr 0x%x\n", +- pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr, +- pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "CI upper base addr 0x%x CI lower base addr 0x%x\n", ++ pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr, ++ pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr); + } + + /** +@@ -973,20 +961,20 @@ static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, + pm8001_mw32(address, offset + OB_INTERRUPT_COALES_OFFSET, + pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "OQ %d: Element pri size 0x%x\n", +- number, +- pm8001_ha->outbnd_q_tbl[number].element_size_cnt)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "OQ %d: Element pri size 0x%x\n", ++ number, ++ pm8001_ha->outbnd_q_tbl[number].element_size_cnt); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "OQ upr base addr 0x%x OQ lwr base addr 0x%x\n", +- pm8001_ha->outbnd_q_tbl[number].upper_base_addr, +- pm8001_ha->outbnd_q_tbl[number].lower_base_addr)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "OQ upr base addr 0x%x OQ lwr base addr 0x%x\n", ++ pm8001_ha->outbnd_q_tbl[number].upper_base_addr, ++ pm8001_ha->outbnd_q_tbl[number].lower_base_addr); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "PI upper base addr 0x%x PI lower base addr 0x%x\n", +- pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr, +- pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "PI upper base addr 0x%x PI lower base addr 0x%x\n", ++ pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr, ++ pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr); + } + + /** +@@ -1016,8 +1004,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) + + if (!max_wait_count) { + /* additional check */ +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "Inb doorbell clear not toggled[value:%x]\n", value)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Inb doorbell clear not toggled[value:%x]\n", ++ value); + return -EBUSY; + } + /* check the MPI-State for initialization upto 100ms*/ +@@ -1068,9 +1057,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) + if (!max_wait_count) + ret = -1; + else { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" ila ready status in %d millisec\n", +- (max_wait_time - max_wait_count))); ++ pm8001_dbg(pm8001_ha, MSG, ++ " ila ready status in %d millisec\n", ++ (max_wait_time - max_wait_count)); + } + + /* check RAAE status */ +@@ -1083,9 +1072,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) + if (!max_wait_count) + ret = -1; + else { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" raae ready status in %d millisec\n", +- (max_wait_time - max_wait_count))); ++ pm8001_dbg(pm8001_ha, MSG, ++ " raae ready status in %d millisec\n", ++ (max_wait_time - max_wait_count)); + } + + /* check iop0 status */ +@@ -1098,9 +1087,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) + if (!max_wait_count) + ret = -1; + else { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" iop0 ready status in %d millisec\n", +- (max_wait_time - max_wait_count))); ++ pm8001_dbg(pm8001_ha, MSG, ++ " iop0 ready status in %d millisec\n", ++ (max_wait_time - max_wait_count)); + } + + /* check iop1 status only for 16 port controllers */ +@@ -1116,9 +1105,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) + if (!max_wait_count) + ret = -1; + else { +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "iop1 ready status in %d millisec\n", +- (max_wait_time - max_wait_count))); ++ pm8001_dbg(pm8001_ha, MSG, ++ "iop1 ready status in %d millisec\n", ++ (max_wait_time - max_wait_count)); + } + } + +@@ -1136,13 +1125,11 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) + value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0); + offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */ + +- PM8001_DEV_DBG(pm8001_ha, +- pm8001_printk("Scratchpad 0 Offset: 0x%x value 0x%x\n", +- offset, value)); ++ pm8001_dbg(pm8001_ha, DEV, "Scratchpad 0 Offset: 0x%x value 0x%x\n", ++ offset, value); + pcilogic = (value & 0xFC000000) >> 26; + pcibar = get_pci_bar_index(pcilogic); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Scratchpad 0 PCI BAR: %d\n", pcibar)); ++ pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar); + pm8001_ha->main_cfg_tbl_addr = base_addr = + pm8001_ha->io_mem[pcibar].memvirtaddr + offset; + pm8001_ha->general_stat_tbl_addr = +@@ -1164,33 +1151,25 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) + base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0xA0) & + 0xFFFFFF); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("GST OFFSET 0x%x\n", +- pm8001_cr32(pm8001_ha, pcibar, offset + 0x18))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("INBND OFFSET 0x%x\n", +- pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("OBND OFFSET 0x%x\n", +- pm8001_cr32(pm8001_ha, pcibar, offset + 0x20))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("IVT OFFSET 0x%x\n", +- pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PSPA OFFSET 0x%x\n", +- pm8001_cr32(pm8001_ha, pcibar, offset + 0x90))); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("addr - main cfg %p general status %p\n", +- pm8001_ha->main_cfg_tbl_addr, +- pm8001_ha->general_stat_tbl_addr)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("addr - inbnd %p obnd %p\n", +- pm8001_ha->inbnd_q_tbl_addr, +- pm8001_ha->outbnd_q_tbl_addr)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("addr - pspa %p ivt %p\n", +- pm8001_ha->pspa_q_tbl_addr, +- pm8001_ha->ivt_tbl_addr)); ++ pm8001_dbg(pm8001_ha, INIT, "GST OFFSET 0x%x\n", ++ pm8001_cr32(pm8001_ha, pcibar, offset + 0x18)); ++ pm8001_dbg(pm8001_ha, INIT, "INBND OFFSET 0x%x\n", ++ pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C)); ++ pm8001_dbg(pm8001_ha, INIT, "OBND OFFSET 0x%x\n", ++ pm8001_cr32(pm8001_ha, pcibar, offset + 0x20)); ++ pm8001_dbg(pm8001_ha, INIT, "IVT OFFSET 0x%x\n", ++ pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C)); ++ pm8001_dbg(pm8001_ha, INIT, "PSPA OFFSET 0x%x\n", ++ pm8001_cr32(pm8001_ha, pcibar, offset + 0x90)); ++ pm8001_dbg(pm8001_ha, INIT, "addr - main cfg %p general status %p\n", ++ pm8001_ha->main_cfg_tbl_addr, ++ pm8001_ha->general_stat_tbl_addr); ++ pm8001_dbg(pm8001_ha, INIT, "addr - inbnd %p obnd %p\n", ++ pm8001_ha->inbnd_q_tbl_addr, ++ pm8001_ha->outbnd_q_tbl_addr); ++ pm8001_dbg(pm8001_ha, INIT, "addr - pspa %p ivt %p\n", ++ pm8001_ha->pspa_q_tbl_addr, ++ pm8001_ha->ivt_tbl_addr); + } + + /** +@@ -1224,9 +1203,9 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha) + (THERMAL_ENABLE << 8) | page_code; + payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n", +- payload.cfg_pg[0], payload.cfg_pg[1])); ++ pm8001_dbg(pm8001_ha, DEV, ++ "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n", ++ payload.cfg_pg[0], payload.cfg_pg[1]); + + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); +@@ -1281,32 +1260,24 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha) + | SAS_COPNRJT_RTRY_THR; + SASConfigPage.MAX_AIP = SAS_MAX_AIP; + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.pageCode " +- "0x%08x\n", SASConfigPage.pageCode)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.MST_MSI " +- " 0x%08x\n", SASConfigPage.MST_MSI)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.STP_SSP_MCT_TMO " +- " 0x%08x\n", SASConfigPage.STP_SSP_MCT_TMO)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.STP_FRM_TMO " +- " 0x%08x\n", SASConfigPage.STP_FRM_TMO)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.STP_IDLE_TMO " +- " 0x%08x\n", SASConfigPage.STP_IDLE_TMO)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.OPNRJT_RTRY_INTVL " +- " 0x%08x\n", SASConfigPage.OPNRJT_RTRY_INTVL)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO " +- " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR " +- " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR)); +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MAX_AIP " +- " 0x%08x\n", SASConfigPage.MAX_AIP)); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.pageCode 0x%08x\n", ++ SASConfigPage.pageCode); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MST_MSI 0x%08x\n", ++ SASConfigPage.MST_MSI); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_SSP_MCT_TMO 0x%08x\n", ++ SASConfigPage.STP_SSP_MCT_TMO); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_FRM_TMO 0x%08x\n", ++ SASConfigPage.STP_FRM_TMO); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_IDLE_TMO 0x%08x\n", ++ SASConfigPage.STP_IDLE_TMO); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.OPNRJT_RTRY_INTVL 0x%08x\n", ++ SASConfigPage.OPNRJT_RTRY_INTVL); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO 0x%08x\n", ++ SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR 0x%08x\n", ++ SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR); ++ pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MAX_AIP 0x%08x\n", ++ SASConfigPage.MAX_AIP); + + memcpy(&payload.cfg_pg, &SASConfigPage, + sizeof(SASProtocolTimerConfig_t)); +@@ -1346,18 +1317,18 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha) + SCRATCH_PAD3_SMB_ENABLED) + pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; + pm8001_ha->encrypt_info.status = 0; +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "Encryption: SCRATCH_PAD3_ENC_READY 0x%08X." +- "Cipher mode 0x%x Sec mode 0x%x status 0x%x\n", +- scratch3_value, pm8001_ha->encrypt_info.cipher_mode, +- pm8001_ha->encrypt_info.sec_mode, +- pm8001_ha->encrypt_info.status)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Encryption: SCRATCH_PAD3_ENC_READY 0x%08X.Cipher mode 0x%x Sec mode 0x%x status 0x%x\n", ++ scratch3_value, ++ pm8001_ha->encrypt_info.cipher_mode, ++ pm8001_ha->encrypt_info.sec_mode, ++ pm8001_ha->encrypt_info.status); + ret = 0; + } else if ((scratch3_value & SCRATCH_PAD3_ENC_READY) == + SCRATCH_PAD3_ENC_DISABLED) { +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "Encryption: SCRATCH_PAD3_ENC_DISABLED 0x%08X\n", +- scratch3_value)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Encryption: SCRATCH_PAD3_ENC_DISABLED 0x%08X\n", ++ scratch3_value); + pm8001_ha->encrypt_info.status = 0xFFFFFFFF; + pm8001_ha->encrypt_info.cipher_mode = 0; + pm8001_ha->encrypt_info.sec_mode = 0; +@@ -1377,12 +1348,12 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha) + if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == + SCRATCH_PAD3_SMB_ENABLED) + pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "Encryption: SCRATCH_PAD3_DIS_ERR 0x%08X." +- "Cipher mode 0x%x sec mode 0x%x status 0x%x\n", +- scratch3_value, pm8001_ha->encrypt_info.cipher_mode, +- pm8001_ha->encrypt_info.sec_mode, +- pm8001_ha->encrypt_info.status)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Encryption: SCRATCH_PAD3_DIS_ERR 0x%08X.Cipher mode 0x%x sec mode 0x%x status 0x%x\n", ++ scratch3_value, ++ pm8001_ha->encrypt_info.cipher_mode, ++ pm8001_ha->encrypt_info.sec_mode, ++ pm8001_ha->encrypt_info.status); + } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == + SCRATCH_PAD3_ENC_ENA_ERR) { + +@@ -1400,12 +1371,12 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha) + SCRATCH_PAD3_SMB_ENABLED) + pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; + +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "Encryption: SCRATCH_PAD3_ENA_ERR 0x%08X." +- "Cipher mode 0x%x sec mode 0x%x status 0x%x\n", +- scratch3_value, pm8001_ha->encrypt_info.cipher_mode, +- pm8001_ha->encrypt_info.sec_mode, +- pm8001_ha->encrypt_info.status)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Encryption: SCRATCH_PAD3_ENA_ERR 0x%08X.Cipher mode 0x%x sec mode 0x%x status 0x%x\n", ++ scratch3_value, ++ pm8001_ha->encrypt_info.cipher_mode, ++ pm8001_ha->encrypt_info.sec_mode, ++ pm8001_ha->encrypt_info.status); + } + return ret; + } +@@ -1435,9 +1406,9 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha) + payload.new_curidx_ksop = ((1 << 24) | (1 << 16) | (1 << 8) | + KEK_MGMT_SUBOP_KEYCARDUPDATE); + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "Saving Encryption info to flash. payload 0x%x\n", +- payload.new_curidx_ksop)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "Saving Encryption info to flash. payload 0x%x\n", ++ payload.new_curidx_ksop); + + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); +@@ -1458,8 +1429,7 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) + + /* check the firmware status */ + if (-1 == check_fw_ready(pm8001_ha)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Firmware is not ready!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Firmware is not ready!\n"); + return -EBUSY; + } + +@@ -1483,8 +1453,7 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) + } + /* notify firmware update finished and check initialization status */ + if (0 == mpi_init_check(pm8001_ha)) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("MPI initialize successful!\n")); ++ pm8001_dbg(pm8001_ha, INIT, "MPI initialize successful!\n"); + } else + return -EBUSY; + +@@ -1493,16 +1462,13 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) + + /* Check for encryption */ + if (pm8001_ha->chip->encrypt) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Checking for encryption\n")); ++ pm8001_dbg(pm8001_ha, INIT, "Checking for encryption\n"); + ret = pm80xx_get_encrypt_info(pm8001_ha); + if (ret == -1) { +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("Encryption error !!\n")); ++ pm8001_dbg(pm8001_ha, INIT, "Encryption error !!\n"); + if (pm8001_ha->encrypt_info.status == 0x81) { +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk( +- "Encryption enabled with error." +- "Saving encryption key to flash\n")); ++ pm8001_dbg(pm8001_ha, INIT, ++ "Encryption enabled with error.Saving encryption key to flash\n"); + pm80xx_encrypt_update(pm8001_ha); + } + } +@@ -1533,8 +1499,7 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) + } while ((value != 0) && (--max_wait_count)); + + if (!max_wait_count) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("TIMEOUT:IBDB value/=%x\n", value)); ++ pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:IBDB value/=%x\n", value); + return -1; + } + +@@ -1551,9 +1516,8 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) + break; + } while (--max_wait_count); + if (!max_wait_count) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk(" TIME OUT MPI State = 0x%x\n", +- gst_len_mpistate & GST_MPI_STATE_MASK)); ++ pm8001_dbg(pm8001_ha, FAIL, " TIME OUT MPI State = 0x%x\n", ++ gst_len_mpistate & GST_MPI_STATE_MASK); + return -1; + } + +@@ -1581,9 +1545,9 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + u32 r1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); + u32 r2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2); + u32 r3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "MPI state is not ready scratch: %x:%x:%x:%x\n", +- r0, r1, r2, r3)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "MPI state is not ready scratch: %x:%x:%x:%x\n", ++ r0, r1, r2, r3); + /* if things aren't ready but the bootloader is ok then + * try the reset anyway. + */ +@@ -1593,25 +1557,25 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + } + /* checked for reset register normal state; 0x0 */ + regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("reset register before write : 0x%x\n", regval)); ++ pm8001_dbg(pm8001_ha, INIT, "reset register before write : 0x%x\n", ++ regval); + + pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, SPCv_NORMAL_RESET_VALUE); + msleep(500); + + regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("reset register after write 0x%x\n", regval)); ++ pm8001_dbg(pm8001_ha, INIT, "reset register after write 0x%x\n", ++ regval); + + if ((regval & SPCv_SOFT_RESET_READ_MASK) == + SPCv_SOFT_RESET_NORMAL_RESET_OCCURED) { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" soft reset successful [regval: 0x%x]\n", +- regval)); ++ pm8001_dbg(pm8001_ha, MSG, ++ " soft reset successful [regval: 0x%x]\n", ++ regval); + } else { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" soft reset failed [regval: 0x%x]\n", +- regval)); ++ pm8001_dbg(pm8001_ha, MSG, ++ " soft reset failed [regval: 0x%x]\n", ++ regval); + + /* check bootloader is successfully executed or in HDA mode */ + bootloader_state = +@@ -1619,28 +1583,27 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + SCRATCH_PAD1_BOOTSTATE_MASK; + + if (bootloader_state == SCRATCH_PAD1_BOOTSTATE_HDA_SEEPROM) { +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "Bootloader state - HDA mode SEEPROM\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Bootloader state - HDA mode SEEPROM\n"); + } else if (bootloader_state == + SCRATCH_PAD1_BOOTSTATE_HDA_BOOTSTRAP) { +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "Bootloader state - HDA mode Bootstrap Pin\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Bootloader state - HDA mode Bootstrap Pin\n"); + } else if (bootloader_state == + SCRATCH_PAD1_BOOTSTATE_HDA_SOFTRESET) { +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "Bootloader state - HDA mode soft reset\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Bootloader state - HDA mode soft reset\n"); + } else if (bootloader_state == + SCRATCH_PAD1_BOOTSTATE_CRIT_ERROR) { +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "Bootloader state-HDA mode critical error\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "Bootloader state-HDA mode critical error\n"); + } + return -EBUSY; + } + + /* check the firmware status after reset */ + if (-1 == check_fw_ready(pm8001_ha)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Firmware is not ready!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Firmware is not ready!\n"); + /* check iButton feature support for motherboard controller */ + if (pm8001_ha->pdev->subsystem_vendor != + PCI_VENDOR_ID_ADAPTEC2 && +@@ -1652,21 +1615,18 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) + ibutton1 = pm8001_cr32(pm8001_ha, 0, + MSGU_HOST_SCRATCH_PAD_7); + if (!ibutton0 && !ibutton1) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("iButton Feature is" +- " not Available!!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "iButton Feature is not Available!!!\n"); + return -EBUSY; + } + if (ibutton0 == 0xdeadbeef && ibutton1 == 0xdeadbeef) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("CRC Check for iButton" +- " Feature Failed!!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "CRC Check for iButton Feature Failed!!!\n"); + return -EBUSY; + } + } + } +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SPCv soft reset Complete\n")); ++ pm8001_dbg(pm8001_ha, INIT, "SPCv soft reset Complete\n"); + return 0; + } + +@@ -1674,13 +1634,11 @@ static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) + { + u32 i; + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("chip reset start\n")); ++ pm8001_dbg(pm8001_ha, INIT, "chip reset start\n"); + + /* do SPCv chip reset. */ + pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, 0x11); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("SPC soft reset Complete\n")); ++ pm8001_dbg(pm8001_ha, INIT, "SPC soft reset Complete\n"); + + /* Check this ..whether delay is required or no */ + /* delay 10 usec */ +@@ -1692,8 +1650,7 @@ static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) + mdelay(1); + } while ((--i) != 0); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("chip reset finished\n")); ++ pm8001_dbg(pm8001_ha, INIT, "chip reset finished\n"); + } + + /** +@@ -1769,15 +1726,14 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha, + int ret; + + if (!pm8001_ha_dev) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "dev is null\n"); + return; + } + + task = sas_alloc_slow_task(GFP_ATOMIC); + + if (!task) { +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot " +- "allocate task\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n"); + return; + } + +@@ -1803,8 +1759,7 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha, + + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, + sizeof(task_abort), 0); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Executing abort task end\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n"); + if (ret) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); +@@ -1827,8 +1782,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, + task = sas_alloc_slow_task(GFP_ATOMIC); + + if (!task) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("cannot allocate task !!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n"); + return; + } + task->task_done = pm8001_task_done; +@@ -1836,8 +1790,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, + res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); + if (res) { + sas_free_task(task); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("cannot allocate tag !!!\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n"); + return; + } + +@@ -1848,8 +1801,8 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, + if (!dev) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Domain device cannot be allocated\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Domain device cannot be allocated\n"); + return; + } + +@@ -1882,7 +1835,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, + + res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, + sizeof(sata_cmd), 0); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Executing read log end\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n"); + if (res) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); +@@ -1928,27 +1881,24 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + + if (status && status != IO_UNDERFLOW) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("sas IO status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", status); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + ts = &t->task_status; + +- PM8001_DEV_DBG(pm8001_ha, pm8001_printk( +- "tag::0x%x, status::0x%x task::0x%p\n", tag, status, t)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "tag::0x%x, status::0x%x task::0x%p\n", tag, status, t); + + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && + (status != IO_UNDERFLOW)) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive" +- ":%016llx", SAS_ADDR(t->dev->sas_addr))); ++ pm8001_dbg(pm8001_ha, FAIL, "SAS Address of IO Failure Drive:%016llx\n", ++ SAS_ADDR(t->dev->sas_addr)); + + switch (status) { + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_SUCCESS ,param = 0x%x\n", +- param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS ,param = 0x%x\n", ++ param); + if (param == 0) { + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; +@@ -1960,73 +1910,83 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + sas_ssp_task_response(pm8001_ha->dev, t, iu); + } + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB Tag\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_UNDERFLOW: + /* SSP Completion with error */ +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_UNDERFLOW ,param = 0x%x\n", +- param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW ,param = 0x%x\n", ++ param); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + ts->residual = param; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + /* Force the midlayer to retry */ + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_INVALID_SSP_RSP_FRAME: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_INVALID_SSP_RSP_FRAME\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_INVALID_SSP_RSP_FRAME\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: + case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: +@@ -2034,8 +1994,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -2045,67 +2004,78 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_DMA: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + if (!t->uldd_task) +@@ -2114,51 +2084,55 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_DS_NON_OPERATIONAL); + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_TM_TAG_NOT_FOUND: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_TM_TAG_NOT_FOUND\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_TM_TAG_NOT_FOUND\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_SSP_EXT_IU_ZERO_LEN_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SSP_EXT_IU_ZERO_LEN_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + } +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("scsi_status = 0x%x\n ", +- psspPayload->ssp_resp_iu.status)); ++ pm8001_dbg(pm8001_ha, IO, "scsi_status = 0x%x\n ", ++ psspPayload->ssp_resp_iu.status); + spin_lock_irqsave(&t->task_state_lock, flags); + t->task_state_flags &= ~SAS_TASK_STATE_PENDING; + t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "task 0x%p done with io_status 0x%x resp 0x%x " +- "stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + if (t->slow_task) + complete(&t->slow_task->completion); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); +@@ -2188,52 +2162,47 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + if (event) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("sas IO status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, FAIL, "sas IO status 0x%x\n", event); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + ts = &t->task_status; +- PM8001_IOERR_DBG(pm8001_ha, +- pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n", +- port_id, tag, event)); ++ pm8001_dbg(pm8001_ha, IOERR, "port_id:0x%x, tag:0x%x, event:0x%x\n", ++ port_id, tag, event); + switch (event) { + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n");) ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK); + return; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; +@@ -2244,8 +2213,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -2255,94 +2223,86 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT); + return; + case IO_XFER_ERROR_UNEXPECTED_PHASE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_RDY_OVERRUN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_ERROR_INTERNAL_CRC_ERROR: +- PM8001_IOERR_DBG(pm8001_ha, +- pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IOERR, ++ "IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"); + /* TBC: used default set values */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + break; + case IO_XFER_CMD_FRAME_ISSUED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n"); + return; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", event); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; +@@ -2354,10 +2314,9 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "task 0x%p done with event 0x%x resp 0x%x " +- "stat 0x%x but aborted by upper layer!\n", +- t, event, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, event, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -2392,8 +2351,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + tag = le32_to_cpu(psataPayload->tag); + + if (!tag) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("tag null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "tag null\n"); + return; + } + ccb = &pm8001_ha->ccb_info[tag]; +@@ -2402,8 +2360,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("ccb null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "ccb null\n"); + return; + } + +@@ -2411,29 +2368,26 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + if (t->dev && (t->dev->lldd_dev)) + pm8001_dev = t->dev->lldd_dev; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "task null\n"); + return; + } + + if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG)) + && unlikely(!t || !t->lldd_task || !t->dev)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task or dev null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n"); + return; + } + + ts = &t->task_status; + if (!ts) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("ts null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "ts null\n"); + return; + } + + if (unlikely(status)) +- PM8001_IOERR_DBG(pm8001_ha, pm8001_printk( +- "status:0x%x, tag:0x%x, task::0x%p\n", +- status, tag, t)); ++ pm8001_dbg(pm8001_ha, IOERR, ++ "status:0x%x, tag:0x%x, task::0x%p\n", ++ status, tag, t); + + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && +@@ -2465,20 +2419,20 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + & 0xff000000)) + + pm8001_dev->attached_phy + + 0x10); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive:" +- "%08x%08x", temp_sata_addr_hi, +- temp_sata_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SAS Address of IO Failure Drive:%08x%08x\n", ++ temp_sata_addr_hi, ++ temp_sata_addr_low); + + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SAS Address of IO Failure Drive:" +- "%016llx", SAS_ADDR(t->dev->sas_addr))); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "SAS Address of IO Failure Drive:%016llx\n", ++ SAS_ADDR(t->dev->sas_addr)); + } + } + switch (status) { + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n"); + if (param == 0) { + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; +@@ -2500,94 +2454,100 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PROTO_RESPONSE; + ts->residual = param; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("SAS_PROTO_RESPONSE len = %d\n", +- param)); ++ pm8001_dbg(pm8001_ha, IO, ++ "SAS_PROTO_RESPONSE len = %d\n", ++ param); + sata_resp = &psataPayload->sata_resp[0]; + resp = (struct ata_task_resp *)ts->buf; + if (t->ata_task.dma_xfer == 0 && + t->data_dir == DMA_FROM_DEVICE) { + len = sizeof(struct pio_setup_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("PIO read len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, ++ "PIO read len = %d\n", len); + } else if (t->ata_task.use_ncq) { + len = sizeof(struct set_dev_bits_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("FPDMA len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n", ++ len); + } else { + len = sizeof(struct dev_to_host_fis); +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("other len = %d\n", len)); ++ pm8001_dbg(pm8001_ha, IO, "other len = %d\n", ++ len); + } + if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { + resp->frame_len = len; + memcpy(&resp->ending_fis[0], sata_resp, len); + ts->buf_valid_size = sizeof(*resp); + } else +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("response too large\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "response too large\n"); + } + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB Tag\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB Tag\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + /* following cases are to do cases */ + case IO_UNDERFLOW: + /* SATA Completion with error */ +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_UNDERFLOW param = %d\n", param)); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW param = %d\n", param); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + ts->residual = param; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_INTERRUPTED; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: + case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: +@@ -2595,8 +2555,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2610,8 +2569,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; +@@ -2626,15 +2585,17 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2648,57 +2609,65 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_ACK_NAK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_DMA: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_DMA\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_SATA_LINK_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_SATA_LINK_TIMEOUT\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_REJECTED_NCQ_MODE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2711,14 +2680,14 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_DS_IN_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2731,18 +2700,21 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; ++ if (pm8001_dev) ++ atomic_dec(&pm8001_dev->running_req); + break; + } + spin_lock_irqsave(&t->task_state_lock, flags); +@@ -2751,10 +2723,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p done with io_status 0x%x" +- " resp 0x%x stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + if (t->slow_task) + complete(&t->slow_task->completion); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); +@@ -2785,13 +2756,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t = ccb->task; + pm8001_dev = ccb->device; + } else { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("No CCB !!!. returning\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "No CCB !!!. returning\n"); + return; + } + if (event) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("SATA EVENT 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, FAIL, "SATA EVENT 0x%x\n", event); + + /* Check if this is NCQ error */ + if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) { +@@ -2804,54 +2773,49 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + } + + if (unlikely(!t || !t->lldd_task || !t->dev)) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task or dev null\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n"); + return; + } + + ts = &t->task_status; +- PM8001_IOERR_DBG(pm8001_ha, +- pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n", +- port_id, tag, event)); ++ pm8001_dbg(pm8001_ha, IOERR, "port_id:0x%x, tag:0x%x, event:0x%x\n", ++ port_id, tag, event); + switch (event) { + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_INTERRUPTED; + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_EPROTO; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; +@@ -2862,8 +2826,8 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_DEV_NO_RESPONSE; + if (!t->uldd_task) { +@@ -2877,107 +2841,96 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + } + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_NAK_RECEIVED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_NAK_RECEIVED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_ERROR_PEER_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PEER_ABORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PEER_ABORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_NAK_R_ERR; + break; + case IO_XFER_ERROR_REJECTED_NCQ_MODE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_REJECTED_NCQ_MODE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_UNDERRUN; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_UNEXPECTED_PHASE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_UNEXPECTED_PHASE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_RDY_OVERRUN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_XFER_RDY_OVERRUN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_OFFSET_MISMATCH: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_OFFSET_MISMATCH\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_CMD_FRAME_ISSUED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_CMD_FRAME_ISSUED\n"); + break; + case IO_XFER_PIO_SETUP_ERROR: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_PIO_SETUP_ERROR\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_PIO_SETUP_ERROR\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_ERROR_INTERNAL_CRC_ERROR: +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n")); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"); + /* TBC: used default set values */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + case IO_XFER_DMA_ACTIVATE_TIMEOUT: +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("IO_XFR_DMA_ACTIVATE_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "IO_XFR_DMA_ACTIVATE_TIMEOUT\n"); + /* TBC: used default set values */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; + break; + default: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", event)); ++ pm8001_dbg(pm8001_ha, IO, "Unknown status 0x%x\n", event); + /* not allowed case. Therefore, return failed status */ + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_TO; +@@ -2989,10 +2942,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p done with io_status 0x%x" +- " resp 0x%x stat 0x%x but aborted by upper layer!\n", +- t, event, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", ++ t, event, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -3025,94 +2977,87 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + ts = &t->task_status; + pm8001_dev = ccb->device; + if (status) +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("smp IO status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, FAIL, "smp IO status 0x%x\n", status); + if (unlikely(!t || !t->lldd_task || !t->dev)) + return; + +- PM8001_DEV_DBG(pm8001_ha, +- pm8001_printk("tag::0x%x status::0x%x\n", tag, status)); ++ pm8001_dbg(pm8001_ha, DEV, "tag::0x%x status::0x%x\n", tag, status); + + switch (status) { + + case IO_SUCCESS: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_GOOD; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + if (pm8001_ha->smp_exp_mode == SMP_DIRECT) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("DIRECT RESPONSE Length:%d\n", +- param)); ++ pm8001_dbg(pm8001_ha, IO, ++ "DIRECT RESPONSE Length:%d\n", ++ param); + pdma_respaddr = (char *)(phys_to_virt(cpu_to_le64 + ((u64)sg_dma_address + (&t->smp_task.smp_resp)))); + for (i = 0; i < param; i++) { + *(pdma_respaddr+i) = psmpPayload->_r_a[i]; +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "SMP Byte%d DMA data 0x%x psmp 0x%x\n", +- i, *(pdma_respaddr+i), +- psmpPayload->_r_a[i])); ++ pm8001_dbg(pm8001_ha, IO, ++ "SMP Byte%d DMA data 0x%x psmp 0x%x\n", ++ i, *(pdma_respaddr + i), ++ psmpPayload->_r_a[i]); + } + } + break; + case IO_ABORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ABORTED IOMB\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ABORTED IOMB\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_OVERFLOW: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_UNDERFLOW\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DATA_OVERRUN; + ts->residual = 0; + if (pm8001_dev) +- pm8001_dev->running_req--; ++ atomic_dec(&pm8001_dev->running_req); + break; + case IO_NO_DEVICE: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_NO_DEVICE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_PHY_DOWN; + break; + case IO_ERROR_HW_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ERROR_HW_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ERROR_HW_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_XFER_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_XFER_ERROR_PHY_NOT_READY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAM_STAT_BUSY; + break; + case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; + break; + case IO_OPEN_CNX_ERROR_BREAK: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_BREAK\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; +@@ -3123,8 +3068,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: + case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_UNKNOWN; +@@ -3133,75 +3077,68 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); + break; + case IO_OPEN_CNX_ERROR_BAD_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_BAD_DEST; + break; + case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: +- PM8001_IO_DBG(pm8001_ha, pm8001_printk(\ +- "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_CONN_RATE; + break; + case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + break; + case IO_XFER_ERROR_RX_FRAME: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_ERROR_RX_FRAME\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_RX_FRAME\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + break; + case IO_XFER_OPEN_RETRY_TIMEOUT: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_XFER_OPEN_RETRY_TIMEOUT\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_ERROR_INTERNAL_SMP_RESOURCE: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_ERROR_INTERNAL_SMP_RESOURCE\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_ERROR_INTERNAL_SMP_RESOURCE\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_QUEUE_FULL; + break; + case IO_PORT_IN_RESET: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_PORT_IN_RESET\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_PORT_IN_RESET\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_DS_NON_OPERATIONAL: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_NON_OPERATIONAL\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_NON_OPERATIONAL\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + break; + case IO_DS_IN_RECOVERY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_DS_IN_RECOVERY\n")); ++ pm8001_dbg(pm8001_ha, IO, "IO_DS_IN_RECOVERY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); ++ pm8001_dbg(pm8001_ha, IO, ++ "IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_OPEN_REJECT; + ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown status 0x%x\n", status)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status); + ts->resp = SAS_TASK_COMPLETE; + ts->stat = SAS_DEV_NO_RESPONSE; + /* not allowed case. Therefore, return failed status */ +@@ -3213,10 +3150,9 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) + t->task_state_flags |= SAS_TASK_STATE_DONE; + if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&t->task_state_lock, flags); +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "task 0x%p done with io_status 0x%x resp 0x%x" +- "stat 0x%x but aborted by upper layer!\n", +- t, status, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p done with io_status 0x%x resp 0x%xstat 0x%x but aborted by upper layer!\n", ++ t, status, ts->resp, ts->stat); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + } else { + spin_unlock_irqrestore(&t->task_state_lock, flags); +@@ -3306,45 +3242,40 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); + + struct pm8001_port *port = &pm8001_ha->port[port_id]; +- struct sas_ha_struct *sas_ha = pm8001_ha->sas; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + unsigned long flags; + u8 deviceType = pPayload->sas_identify.dev_type; + port->port_state = portstate; + port->wide_port_phymap |= (1U << phy_id); + phy->phy_state = PHY_STATE_LINK_UP_SPCV; +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "portid:%d; phyid:%d; linkrate:%d; " +- "portstate:%x; devicetype:%x\n", +- port_id, phy_id, link_rate, portstate, deviceType)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "portid:%d; phyid:%d; linkrate:%d; portstate:%x; devicetype:%x\n", ++ port_id, phy_id, link_rate, portstate, deviceType); + + switch (deviceType) { + case SAS_PHY_UNUSED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("device type no device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "device type no device.\n"); + break; + case SAS_END_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "end device.\n"); + pm80xx_chip_phy_ctl_req(pm8001_ha, phy_id, + PHY_NOTIFY_ENABLE_SPINUP); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + case SAS_EDGE_EXPANDER_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("expander device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "expander device.\n"); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + case SAS_FANOUT_EXPANDER_DEVICE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("fanout expander device.\n")); ++ pm8001_dbg(pm8001_ha, MSG, "fanout expander device.\n"); + port->port_attached = 1; + pm8001_get_lrate_mode(phy, link_rate); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("unknown device type(%x)\n", deviceType)); ++ pm8001_dbg(pm8001_ha, DEVIO, "unknown device type(%x)\n", ++ deviceType); + break; + } + phy->phy_type |= PORT_TYPE_SAS; +@@ -3355,7 +3286,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + else if (phy->identify.device_type != SAS_PHY_UNUSED) + phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; + phy->sas_phy.oob_mode = SAS_OOB_MODE; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); + memcpy(phy->frame_rcvd, &pPayload->sas_identify, + sizeof(struct sas_identify_frame)-4); +@@ -3389,12 +3320,11 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); + + struct pm8001_port *port = &pm8001_ha->port[port_id]; +- struct sas_ha_struct *sas_ha = pm8001_ha->sas; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + unsigned long flags; +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "port id %d, phy id %d link_rate %d portstate 0x%x\n", +- port_id, phy_id, link_rate, portstate)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "port id %d, phy id %d link_rate %d portstate 0x%x\n", ++ port_id, phy_id, link_rate, portstate); + + port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPCV; +@@ -3403,7 +3333,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) + phy->phy_type |= PORT_TYPE_SATA; + phy->phy_attached = 1; + phy->sas_phy.oob_mode = SATA_OOB_MODE; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); + spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); + memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), + sizeof(struct dev_to_host_fis)); +@@ -3444,10 +3374,10 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) + case PORT_VALID: + break; + case PORT_INVALID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" PortInvalid portID %d\n", port_id)); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Last phy Down and port invalid\n")); ++ pm8001_dbg(pm8001_ha, MSG, " PortInvalid portID %d\n", ++ port_id); ++ pm8001_dbg(pm8001_ha, MSG, ++ " Last phy Down and port invalid\n"); + if (port_sata) { + phy->phy_type = 0; + port->port_attached = 0; +@@ -3457,19 +3387,18 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) + sas_phy_disconnected(&phy->sas_phy); + break; + case PORT_IN_RESET: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Port In Reset portID %d\n", port_id)); ++ pm8001_dbg(pm8001_ha, MSG, " Port In Reset portID %d\n", ++ port_id); + break; + case PORT_NOT_ESTABLISHED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Phy Down and PORT_NOT_ESTABLISHED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ " Phy Down and PORT_NOT_ESTABLISHED\n"); + port->port_attached = 0; + break; + case PORT_LOSTCOMM: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Phy Down and PORT_LOSTCOMM\n")); +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" Last phy Down and port invalid\n")); ++ pm8001_dbg(pm8001_ha, MSG, " Phy Down and PORT_LOSTCOMM\n"); ++ pm8001_dbg(pm8001_ha, MSG, ++ " Last phy Down and port invalid\n"); + if (port_sata) { + port->port_attached = 0; + phy->phy_type = 0; +@@ -3480,17 +3409,14 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) + break; + default: + port->port_attached = 0; +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk(" Phy Down and(default) = 0x%x\n", +- portstate)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ " Phy Down and(default) = 0x%x\n", ++ portstate); + break; + + } +- if (port_sata && (portstate != PORT_IN_RESET)) { +- struct sas_ha_struct *sas_ha = pm8001_ha->sas; +- +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); +- } ++ if (port_sata && (portstate != PORT_IN_RESET)) ++ sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); + } + + static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +@@ -3503,9 +3429,9 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + le32_to_cpu(pPayload->phyid); + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n", +- status, phy_id)); ++ pm8001_dbg(pm8001_ha, INIT, ++ "phy start resp status:0x%x, phyid:0x%x\n", ++ status, phy_id); + if (status == 0) { + phy->phy_state = PHY_LINK_DOWN; + if (pm8001_ha->flags == PM8001F_RUN_TIME && +@@ -3532,18 +3458,18 @@ static int mpi_thermal_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) + u32 rht_lht = le32_to_cpu(pPayload->rht_lht); + + if (thermal_event & 0x40) { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Thermal Event: Local high temperature violated!\n")); +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Thermal Event: Measured local high temperature %d\n", +- ((rht_lht & 0xFF00) >> 8))); ++ pm8001_dbg(pm8001_ha, IO, ++ "Thermal Event: Local high temperature violated!\n"); ++ pm8001_dbg(pm8001_ha, IO, ++ "Thermal Event: Measured local high temperature %d\n", ++ ((rht_lht & 0xFF00) >> 8)); + } + if (thermal_event & 0x10) { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Thermal Event: Remote high temperature violated!\n")); +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Thermal Event: Measured remote high temperature %d\n", +- ((rht_lht & 0xFF000000) >> 24))); ++ pm8001_dbg(pm8001_ha, IO, ++ "Thermal Event: Remote high temperature violated!\n"); ++ pm8001_dbg(pm8001_ha, IO, ++ "Thermal Event: Measured remote high temperature %d\n", ++ ((rht_lht & 0xFF000000) >> 24)); + } + return 0; + } +@@ -3572,149 +3498,134 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + struct pm8001_port *port = &pm8001_ha->port[port_id]; + struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; +- PM8001_DEV_DBG(pm8001_ha, +- pm8001_printk("portid:%d phyid:%d event:0x%x status:0x%x\n", +- port_id, phy_id, eventType, status)); ++ pm8001_dbg(pm8001_ha, DEV, ++ "portid:%d phyid:%d event:0x%x status:0x%x\n", ++ port_id, phy_id, eventType, status); + + switch (eventType) { + + case HW_EVENT_SAS_PHY_UP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_START_STATUS\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS\n"); + hw_event_sas_phy_up(pm8001_ha, piomb); + break; + case HW_EVENT_SATA_PHY_UP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SATA_PHY_UP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_PHY_UP\n"); + hw_event_sata_phy_up(pm8001_ha, piomb); + break; + case HW_EVENT_SATA_SPINUP_HOLD: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD\n")); +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n"); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); + break; + case HW_EVENT_PHY_DOWN: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_DOWN\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n"); + hw_event_phy_down(pm8001_ha, piomb); + if (pm8001_ha->reset_in_progress) { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("Reset in progress\n")); ++ pm8001_dbg(pm8001_ha, MSG, "Reset in progress\n"); + return 0; + } + phy->phy_attached = 0; + phy->phy_state = PHY_LINK_DISABLE; + break; + case HW_EVENT_PORT_INVALID: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_INVALID\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + /* the broadcast change primitive received, tell the LIBSAS this event + to revalidate the sas domain*/ + case HW_EVENT_BROADCAST_CHANGE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_CHANGE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_CHANGE\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE, + port_id, phy_id, 1, 0); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_PHY_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PHY_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n"); + sas_phy_disconnected(&phy->sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); ++ sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); + break; + case HW_EVENT_BROADCAST_EXP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_EXP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n"); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_LINK_ERR_INVALID_DWORD: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_INVALID_DWORD\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_INVALID_DWORD\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0); + break; + case HW_EVENT_LINK_ERR_DISPARITY_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_DISPARITY_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_DISPARITY_ERROR\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_DISPARITY_ERROR, + port_id, phy_id, 0, 0); + break; + case HW_EVENT_LINK_ERR_CODE_VIOLATION: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_CODE_VIOLATION\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_CODE_VIOLATION\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_CODE_VIOLATION, + port_id, phy_id, 0, 0); + break; + case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH, + port_id, phy_id, 0, 0); + break; + case HW_EVENT_MALFUNCTION: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_MALFUNCTION\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n"); + break; + case HW_EVENT_BROADCAST_SES: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_BROADCAST_SES\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_SES\n"); + spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); + sas_phy->sas_prim = HW_EVENT_BROADCAST_SES; + spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); +- sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); ++ sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); + break; + case HW_EVENT_INBOUND_CRC_ERROR: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_INBOUND_CRC_ERROR\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_INBOUND_CRC_ERROR, + port_id, phy_id, 0, 0); + break; + case HW_EVENT_HARD_RESET_RECEIVED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_HARD_RESET_RECEIVED\n")); +- sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n"); ++ sas_notify_port_event(sas_phy, PORTE_HARD_RESET); + break; + case HW_EVENT_ID_FRAME_TIMEOUT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_ID_FRAME_TIMEOUT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n"); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_LINK_ERR_PHY_RESET_FAILED: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_LINK_ERR_PHY_RESET_FAILED, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + break; + case HW_EVENT_PORT_RESET_TIMER_TMO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, + port_id, phy_id, 0, 0); + sas_phy_disconnected(sas_phy); + phy->phy_attached = 0; +- sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); ++ sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); + if (pm8001_ha->phy[phy_id].reset_completion) { + pm8001_ha->phy[phy_id].port_reset_status = + PORT_RESET_TMO; +@@ -3723,28 +3634,26 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case HW_EVENT_PORT_RECOVERY_TIMER_TMO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "HW_EVENT_PORT_RECOVERY_TIMER_TMO\n"); + pm80xx_hw_event_ack_req(pm8001_ha, 0, + HW_EVENT_PORT_RECOVERY_TIMER_TMO, + port_id, phy_id, 0, 0); + for (i = 0; i < pm8001_ha->chip->n_phy; i++) { + if (port->wide_port_phymap & (1 << i)) { + phy = &pm8001_ha->phy[i]; +- sas_ha->notify_phy_event(&phy->sas_phy, ++ sas_notify_phy_event(&phy->sas_phy, + PHYE_LOSS_OF_SIGNAL); + port->wide_port_phymap &= ~(1 << i); + } + } + break; + case HW_EVENT_PORT_RECOVER: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RECOVER\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n"); + hw_event_port_recover(pm8001_ha, piomb); + break; + case HW_EVENT_PORT_RESET_COMPLETE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_COMPLETE\n"); + if (pm8001_ha->phy[phy_id].reset_completion) { + pm8001_ha->phy[phy_id].port_reset_status = + PORT_RESET_SUCCESS; +@@ -3753,12 +3662,11 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) + } + break; + case EVENT_BROADCAST_ASYNCH_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "EVENT_BROADCAST_ASYNCH_EVENT\n"); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, +- pm8001_printk("Unknown event type 0x%x\n", eventType)); ++ pm8001_dbg(pm8001_ha, DEVIO, "Unknown event type 0x%x\n", ++ eventType); + break; + } + return 0; +@@ -3778,9 +3686,8 @@ static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + u32 phyid = + le32_to_cpu(pPayload->phyid) & 0xFF; + struct pm8001_phy *phy = &pm8001_ha->phy[phyid]; +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("phy:0x%x status:0x%x\n", +- phyid, status)); ++ pm8001_dbg(pm8001_ha, MSG, "phy:0x%x status:0x%x\n", ++ phyid, status); + if (status == PHY_STOP_SUCCESS || + status == PHY_STOP_ERR_DEVICE_ATTACHED) + phy->phy_state = PHY_LINK_DISABLE; +@@ -3800,9 +3707,9 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, + u32 status = le32_to_cpu(pPayload->status); + u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); + +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", +- status, err_qlfr_pgcd)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", ++ status, err_qlfr_pgcd); + + return 0; + } +@@ -3815,8 +3722,7 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, + static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha, + void *piomb) + { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" pm80xx_addition_functionality\n")); ++ pm8001_dbg(pm8001_ha, MSG, " pm80xx_addition_functionality\n"); + + return 0; + } +@@ -3829,8 +3735,7 @@ static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha, + static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, + void *piomb) + { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" pm80xx_addition_functionality\n")); ++ pm8001_dbg(pm8001_ha, MSG, " pm80xx_addition_functionality\n"); + + return 0; + } +@@ -3842,8 +3747,7 @@ static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, + */ + static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) + { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" pm80xx_addition_functionality\n")); ++ pm8001_dbg(pm8001_ha, MSG, " pm80xx_addition_functionality\n"); + + return 0; + } +@@ -3868,15 +3772,14 @@ static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, + page_code = (u8)((ppc_phyid & 0xFF00) >> 8); + if (status) { + /* status is FAILED */ +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("PhyProfile command failed with status " +- "0x%08X \n", status)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "PhyProfile command failed with status 0x%08X\n", ++ status); + rc = -1; + } else { + if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("Invalid page code 0x%X\n", +- page_code)); ++ pm8001_dbg(pm8001_ha, FAIL, "Invalid page code 0x%X\n", ++ page_code); + rc = -1; + } + } +@@ -3898,9 +3801,9 @@ static int mpi_kek_management_resp(struct pm8001_hba_info *pm8001_ha, + u32 kidx_new_curr_ksop = le32_to_cpu(pPayload->kidx_new_curr_ksop); + u32 err_qlfr = le32_to_cpu(pPayload->err_qlfr); + +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "KEK MGMT RESP. Status 0x%x idx_ksop 0x%x err_qlfr 0x%x\n", +- status, kidx_new_curr_ksop, err_qlfr)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "KEK MGMT RESP. Status 0x%x idx_ksop 0x%x err_qlfr 0x%x\n", ++ status, kidx_new_curr_ksop, err_qlfr); + + return 0; + } +@@ -3913,8 +3816,7 @@ static int mpi_kek_management_resp(struct pm8001_hba_info *pm8001_ha, + static int mpi_dek_management_resp(struct pm8001_hba_info *pm8001_ha, + void *piomb) + { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" pm80xx_addition_functionality\n")); ++ pm8001_dbg(pm8001_ha, MSG, " pm80xx_addition_functionality\n"); + + return 0; + } +@@ -3927,8 +3829,7 @@ static int mpi_dek_management_resp(struct pm8001_hba_info *pm8001_ha, + static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha, + void *piomb) + { +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk(" pm80xx_addition_functionality\n")); ++ pm8001_dbg(pm8001_ha, MSG, " pm80xx_addition_functionality\n"); + + return 0; + } +@@ -3945,248 +3846,206 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) + + switch (opc) { + case OPC_OUB_ECHO: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_ECHO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_ECHO\n"); + break; + case OPC_OUB_HW_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_HW_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_HW_EVENT\n"); + mpi_hw_event(pm8001_ha, piomb); + break; + case OPC_OUB_THERM_HW_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_THERMAL_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_THERMAL_EVENT\n"); + mpi_thermal_hw_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_COMP\n"); + mpi_ssp_completion(pm8001_ha, piomb); + break; + case OPC_OUB_SMP_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SMP_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_COMP\n"); + mpi_smp_completion(pm8001_ha, piomb); + break; + case OPC_OUB_LOCAL_PHY_CNTRL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_LOCAL_PHY_CNTRL\n"); + pm8001_mpi_local_phy_ctl(pm8001_ha, piomb); + break; + case OPC_OUB_DEV_REGIST: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEV_REGIST\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_REGIST\n"); + pm8001_mpi_reg_resp(pm8001_ha, piomb); + break; + case OPC_OUB_DEREG_DEV: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("unregister the device\n")); ++ pm8001_dbg(pm8001_ha, MSG, "unregister the device\n"); + pm8001_mpi_dereg_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_DEV_HANDLE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_DEV_HANDLE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEV_HANDLE\n"); + break; + case OPC_OUB_SATA_COMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_COMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_COMP\n"); + mpi_sata_completion(pm8001_ha, piomb); + break; + case OPC_OUB_SATA_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_EVENT\n"); + mpi_sata_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_EVENT\n"); + mpi_ssp_event(pm8001_ha, piomb); + break; + case OPC_OUB_DEV_HANDLE_ARRIV: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEV_HANDLE_ARRIV\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEV_HANDLE_ARRIV\n"); + /*This is for target*/ + break; + case OPC_OUB_SSP_RECV_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_RECV_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_RECV_EVENT\n"); + /*This is for target*/ + break; + case OPC_OUB_FW_FLASH_UPDATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_FW_FLASH_UPDATE\n"); + pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GPIO_RESPONSE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GPIO_RESPONSE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_RESPONSE\n"); + break; + case OPC_OUB_GPIO_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GPIO_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GPIO_EVENT\n"); + break; + case OPC_OUB_GENERAL_EVENT: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GENERAL_EVENT\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GENERAL_EVENT\n"); + pm8001_mpi_general_event(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SATA_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SAS_DIAG_MODE_START_END: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_DIAG_MODE_START_END\n")); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_SAS_DIAG_MODE_START_END\n"); + break; + case OPC_OUB_SAS_DIAG_EXECUTE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_DIAG_EXECUTE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_DIAG_EXECUTE\n"); + break; + case OPC_OUB_GET_TIME_STAMP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_TIME_STAMP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_TIME_STAMP\n"); + break; + case OPC_OUB_SAS_HW_EVENT_ACK: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SAS_HW_EVENT_ACK\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SAS_HW_EVENT_ACK\n"); + break; + case OPC_OUB_PORT_CONTROL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_PORT_CONTROL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_PORT_CONTROL\n"); + break; + case OPC_OUB_SMP_ABORT_RSP: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SMP_ABORT_RSP\n"); + pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_NVMD_DATA: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_NVMD_DATA\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_NVMD_DATA\n"); + pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SET_NVMD_DATA: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_NVMD_DATA\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_NVMD_DATA\n"); + pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb); + break; + case OPC_OUB_DEVICE_HANDLE_REMOVAL: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_DEVICE_HANDLE_REMOVAL\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_DEVICE_HANDLE_REMOVAL\n"); + break; + case OPC_OUB_SET_DEVICE_STATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEVICE_STATE\n"); + pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_DEVICE_STATE: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_GET_DEVICE_STATE\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_GET_DEVICE_STATE\n"); + break; + case OPC_OUB_SET_DEV_INFO: +- PM8001_MSG_DBG(pm8001_ha, +- pm8001_printk("OPC_OUB_SET_DEV_INFO\n")); ++ pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEV_INFO\n"); + break; + /* spcv specifc commands */ + case OPC_OUB_PHY_START_RESP: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_PHY_START_RESP opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_PHY_START_RESP opcode:%x\n", opc); + mpi_phy_start_resp(pm8001_ha, piomb); + break; + case OPC_OUB_PHY_STOP_RESP: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_PHY_STOP_RESP opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_PHY_STOP_RESP opcode:%x\n", opc); + mpi_phy_stop_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SET_CONTROLLER_CONFIG: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_SET_CONTROLLER_CONFIG opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_SET_CONTROLLER_CONFIG opcode:%x\n", opc); + mpi_set_controller_config_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_CONTROLLER_CONFIG: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_GET_CONTROLLER_CONFIG opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_GET_CONTROLLER_CONFIG opcode:%x\n", opc); + mpi_get_controller_config_resp(pm8001_ha, piomb); + break; + case OPC_OUB_GET_PHY_PROFILE: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_GET_PHY_PROFILE opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_GET_PHY_PROFILE opcode:%x\n", opc); + mpi_get_phy_profile_resp(pm8001_ha, piomb); + break; + case OPC_OUB_FLASH_OP_EXT: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_FLASH_OP_EXT opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_FLASH_OP_EXT opcode:%x\n", opc); + mpi_flash_op_ext_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SET_PHY_PROFILE: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_SET_PHY_PROFILE opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_SET_PHY_PROFILE opcode:%x\n", opc); + mpi_set_phy_profile_resp(pm8001_ha, piomb); + break; + case OPC_OUB_KEK_MANAGEMENT_RESP: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_KEK_MANAGEMENT_RESP opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_KEK_MANAGEMENT_RESP opcode:%x\n", opc); + mpi_kek_management_resp(pm8001_ha, piomb); + break; + case OPC_OUB_DEK_MANAGEMENT_RESP: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_DEK_MANAGEMENT_RESP opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_DEK_MANAGEMENT_RESP opcode:%x\n", opc); + mpi_dek_management_resp(pm8001_ha, piomb); + break; + case OPC_OUB_SSP_COALESCED_COMP_RESP: +- PM8001_MSG_DBG(pm8001_ha, pm8001_printk( +- "OPC_OUB_SSP_COALESCED_COMP_RESP opcode:%x\n", opc)); ++ pm8001_dbg(pm8001_ha, MSG, ++ "OPC_OUB_SSP_COALESCED_COMP_RESP opcode:%x\n", opc); + ssp_coalesced_comp_resp(pm8001_ha, piomb); + break; + default: +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "Unknown outbound Queue IOMB OPC = 0x%x\n", opc)); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "Unknown outbound Queue IOMB OPC = 0x%x\n", opc); + break; + } + } + + static void print_scratchpad_registers(struct pm8001_hba_info *pm8001_ha) + { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_SCRATCH_PAD_0: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_SCRATCH_PAD_1:0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_SCRATCH_PAD_2: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_SCRATCH_PAD_3: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_0: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_0))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_1: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_1))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_2: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_2))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_3: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_3))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_4: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_4))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_HOST_SCRATCH_PAD_5: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_5))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_RSVD_SCRATCH_PAD_0: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_6))); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("MSGU_RSVD_SCRATCH_PAD_1: 0x%x\n", +- pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_7))); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_SCRATCH_PAD_0: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_SCRATCH_PAD_1:0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_SCRATCH_PAD_2: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_SCRATCH_PAD_3: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_0: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_0)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_1: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_1)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_2: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_2)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_3: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_3)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_4: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_4)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_HOST_SCRATCH_PAD_5: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_5)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_RSVD_SCRATCH_PAD_0: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_6)); ++ pm8001_dbg(pm8001_ha, FAIL, "MSGU_RSVD_SCRATCH_PAD_1: 0x%x\n", ++ pm8001_cr32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_7)); + } + + static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) +@@ -4203,8 +4062,9 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) + if ((regval & SCRATCH_PAD_MIPSALL_READY) != + SCRATCH_PAD_MIPSALL_READY) { + pm8001_ha->controller_fatal_error = true; +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( +- "Firmware Fatal error! Regval:0x%x\n", regval)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "Firmware Fatal error! Regval:0x%x\n", ++ regval); + print_scratchpad_registers(pm8001_ha); + return ret; + } +@@ -4281,7 +4141,6 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, + char *preq_dma_addr = NULL; + __le64 tmp_addr; + u32 i, length; +- unsigned long flags; + + memset(&smp_cmd, 0, sizeof(smp_cmd)); + /* +@@ -4311,8 +4170,7 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, + smp_cmd.tag = cpu_to_le32(ccb->ccb_tag); + + length = sg_req->length; +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("SMP Frame Length %d\n", sg_req->length)); ++ pm8001_dbg(pm8001_ha, IO, "SMP Frame Length %d\n", sg_req->length); + if (!(length - 8)) + pm8001_ha->smp_exp_mode = SMP_DIRECT; + else +@@ -4324,8 +4182,7 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, + + /* INDIRECT MODE command settings. Use DMA */ + if (pm8001_ha->smp_exp_mode == SMP_INDIRECT) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("SMP REQUEST INDIRECT MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "SMP REQUEST INDIRECT MODE\n"); + /* for SPCv indirect mode. Place the top 4 bytes of + * SMP Request header here. */ + for (i = 0; i < 4; i++) +@@ -4357,30 +4214,27 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, + ((u32)sg_dma_len(&task->smp_task.smp_resp)-4); + } + if (pm8001_ha->smp_exp_mode == SMP_DIRECT) { +- PM8001_IO_DBG(pm8001_ha, +- pm8001_printk("SMP REQUEST DIRECT MODE\n")); ++ pm8001_dbg(pm8001_ha, IO, "SMP REQUEST DIRECT MODE\n"); + for (i = 0; i < length; i++) + if (i < 16) { + smp_cmd.smp_req16[i] = *(preq_dma_addr+i); +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Byte[%d]:%x (DMA data:%x)\n", +- i, smp_cmd.smp_req16[i], +- *(preq_dma_addr))); ++ pm8001_dbg(pm8001_ha, IO, ++ "Byte[%d]:%x (DMA data:%x)\n", ++ i, smp_cmd.smp_req16[i], ++ *(preq_dma_addr)); + } else { + smp_cmd.smp_req[i] = *(preq_dma_addr+i); +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Byte[%d]:%x (DMA data:%x)\n", +- i, smp_cmd.smp_req[i], +- *(preq_dma_addr))); ++ pm8001_dbg(pm8001_ha, IO, ++ "Byte[%d]:%x (DMA data:%x)\n", ++ i, smp_cmd.smp_req[i], ++ *(preq_dma_addr)); + } + } + + build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, + &smp_cmd, pm8001_ha->smp_exp_mode, length); +- spin_lock_irqsave(&circularQ->iq_lock, flags); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &smp_cmd, + sizeof(smp_cmd), 0); +- spin_unlock_irqrestore(&circularQ->iq_lock, flags); + if (rc) + goto err_out_2; + return 0; +@@ -4444,7 +4298,6 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + u64 phys_addr, start_addr, end_addr; + u32 end_addr_high, end_addr_low; + struct inbound_queue_table *circularQ; +- unsigned long flags; + u32 q_index, cpu_id; + u32 opc = OPC_INB_SSPINIIOSTART; + memset(&ssp_cmd, 0, sizeof(ssp_cmd)); +@@ -4471,9 +4324,9 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + /* Check if encryption is set */ + if (pm8001_ha->chip->encrypt && + !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Encryption enabled.Sending Encrypt SAS command 0x%x\n", +- task->ssp_task.cmd->cmnd[0])); ++ pm8001_dbg(pm8001_ha, IO, ++ "Encryption enabled.Sending Encrypt SAS command 0x%x\n", ++ task->ssp_task.cmd->cmnd[0]); + opc = OPC_INB_SSP_INI_DIF_ENC_IO; + /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ + ssp_cmd.dad_dir_m_tlr = cpu_to_le32 +@@ -4503,13 +4356,10 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); + end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); + if (end_addr_high != ssp_cmd.enc_addr_high) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("The sg list address " +- "start_addr=0x%016llx data_len=0x%x " +- "end_addr_high=0x%08x end_addr_low=" +- "0x%08x has crossed 4G boundary\n", +- start_addr, ssp_cmd.enc_len, +- end_addr_high, end_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", ++ start_addr, ssp_cmd.enc_len, ++ end_addr_high, end_addr_low); + pm8001_chip_make_sg(task->scatter, 1, + ccb->buf_prd); + phys_addr = ccb->ccb_dma_handle; +@@ -4533,9 +4383,9 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + (task->ssp_task.cmd->cmnd[4] << 8) | + (task->ssp_task.cmd->cmnd[5])); + } else { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Sending Normal SAS command 0x%x inb q %x\n", +- task->ssp_task.cmd->cmnd[0], q_index)); ++ pm8001_dbg(pm8001_ha, IO, ++ "Sending Normal SAS command 0x%x inb q %x\n", ++ task->ssp_task.cmd->cmnd[0], q_index); + /* fill in PRD (scatter/gather) table, if any */ + if (task->num_scatter > 1) { + pm8001_chip_make_sg(task->scatter, ccb->n_elem, +@@ -4559,13 +4409,10 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); + end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); + if (end_addr_high != ssp_cmd.addr_high) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("The sg list address " +- "start_addr=0x%016llx data_len=0x%x " +- "end_addr_high=0x%08x end_addr_low=" +- "0x%08x has crossed 4G boundary\n", +- start_addr, ssp_cmd.len, +- end_addr_high, end_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", ++ start_addr, ssp_cmd.len, ++ end_addr_high, end_addr_low); + pm8001_chip_make_sg(task->scatter, 1, + ccb->buf_prd); + phys_addr = ccb->ccb_dma_handle; +@@ -4582,10 +4429,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, + ssp_cmd.esgl = 0; + } + } +- spin_lock_irqsave(&circularQ->iq_lock, flags); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, + &ssp_cmd, sizeof(ssp_cmd), q_index); +- spin_unlock_irqrestore(&circularQ->iq_lock, flags); + return ret; + } + +@@ -4614,19 +4459,19 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + + if (task->data_dir == DMA_NONE) { + ATAP = 0x04; /* no data*/ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("no data\n")); ++ pm8001_dbg(pm8001_ha, IO, "no data\n"); + } else if (likely(!task->ata_task.device_control_reg_update)) { + if (task->ata_task.dma_xfer) { + ATAP = 0x06; /* DMA */ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("DMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "DMA\n"); + } else { + ATAP = 0x05; /* PIO*/ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); ++ pm8001_dbg(pm8001_ha, IO, "PIO\n"); + } + if (task->ata_task.use_ncq && + dev->sata_dev.class != ATA_DEV_ATAPI) { + ATAP = 0x07; /* FPDMA */ +- PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); ++ pm8001_dbg(pm8001_ha, IO, "FPDMA\n"); + } + } + if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) { +@@ -4646,9 +4491,9 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + /* Check if encryption is set */ + if (pm8001_ha->chip->encrypt && + !(pm8001_ha->encrypt_info.status) && check_enc_sat_cmd(task)) { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Encryption enabled.Sending Encrypt SATA cmd 0x%x\n", +- sata_cmd.sata_fis.command)); ++ pm8001_dbg(pm8001_ha, IO, ++ "Encryption enabled.Sending Encrypt SATA cmd 0x%x\n", ++ sata_cmd.sata_fis.command); + opc = OPC_INB_SATA_DIF_ENC_IO; + + /* set encryption bit */ +@@ -4676,13 +4521,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); + end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); + if (end_addr_high != sata_cmd.enc_addr_high) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("The sg list address " +- "start_addr=0x%016llx data_len=0x%x " +- "end_addr_high=0x%08x end_addr_low" +- "=0x%08x has crossed 4G boundary\n", +- start_addr, sata_cmd.enc_len, +- end_addr_high, end_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", ++ start_addr, sata_cmd.enc_len, ++ end_addr_high, end_addr_low); + pm8001_chip_make_sg(task->scatter, 1, + ccb->buf_prd); + phys_addr = ccb->ccb_dma_handle; +@@ -4711,9 +4553,9 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + cpu_to_le32((sata_cmd.sata_fis.lbah_exp << 8) | + (sata_cmd.sata_fis.lbam_exp)); + } else { +- PM8001_IO_DBG(pm8001_ha, pm8001_printk( +- "Sending Normal SATA command 0x%x inb %x\n", +- sata_cmd.sata_fis.command, q_index)); ++ pm8001_dbg(pm8001_ha, IO, ++ "Sending Normal SATA command 0x%x inb %x\n", ++ sata_cmd.sata_fis.command, q_index); + /* dad (bit 0-1) is 0 */ + sata_cmd.ncqtag_atap_dir_m_dad = + cpu_to_le32(((ncg_tag & 0xff)<<16) | +@@ -4739,13 +4581,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); + end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); + if (end_addr_high != sata_cmd.addr_high) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("The sg list address " +- "start_addr=0x%016llx data_len=0x%x" +- "end_addr_high=0x%08x end_addr_low=" +- "0x%08x has crossed 4G boundary\n", +- start_addr, sata_cmd.len, +- end_addr_high, end_addr_low)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "The sg list address start_addr=0x%016llx data_len=0x%xend_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", ++ start_addr, sata_cmd.len, ++ end_addr_high, end_addr_low); + pm8001_chip_make_sg(task->scatter, 1, + ccb->buf_prd); + phys_addr = ccb->ccb_dma_handle; +@@ -4804,10 +4643,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + SAS_TASK_STATE_ABORTED))) { + spin_unlock_irqrestore(&task->task_state_lock, + flags); +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk("task 0x%p resp 0x%x " +- " stat 0x%x but aborted by upper layer " +- "\n", task, ts->resp, ts->stat)); ++ pm8001_dbg(pm8001_ha, FAIL, ++ "task 0x%p resp 0x%x stat 0x%x but aborted by upper layer\n", ++ task, ts->resp, ++ ts->stat); + pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); + return 0; + } else { +@@ -4815,14 +4654,13 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, + flags); + pm8001_ccb_task_free_done(pm8001_ha, task, + ccb, tag); ++ atomic_dec(&pm8001_ha_dev->running_req); + return 0; + } + } + } +- spin_lock_irqsave(&circularQ->iq_lock, flags); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, + &sata_cmd, sizeof(sata_cmd), q_index); +- spin_unlock_irqrestore(&circularQ->iq_lock, flags); + return ret; + } + +@@ -4843,8 +4681,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) + memset(&payload, 0, sizeof(payload)); + payload.tag = cpu_to_le32(tag); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PHY START REQ for phy_id %d\n", phy_id)); ++ pm8001_dbg(pm8001_ha, INIT, "PHY START REQ for phy_id %d\n", phy_id); + + payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE | + LINKMODE_AUTO | pm8001_ha->link_rate | phy_id); +@@ -5008,9 +4845,9 @@ static irqreturn_t + pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) + { + pm80xx_chip_interrupt_disable(pm8001_ha, vec); +- PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( +- "irq vec %d, ODMR:0x%x\n", +- vec, pm8001_cr32(pm8001_ha, 0, 0x30))); ++ pm8001_dbg(pm8001_ha, DEVIO, ++ "irq vec %d, ODMR:0x%x\n", ++ vec, pm8001_cr32(pm8001_ha, 0, 0x30)); + process_oq(pm8001_ha, vec); + pm80xx_chip_interrupt_enable(pm8001_ha, vec); + return IRQ_HANDLED; +@@ -5029,13 +4866,13 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha, + memset(&payload, 0, sizeof(payload)); + rc = pm8001_tag_alloc(pm8001_ha, &tag); + if (rc) +- PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n")); ++ pm8001_dbg(pm8001_ha, FAIL, "Invalid tag\n"); + circularQ = &pm8001_ha->inbnd_q_tbl[0]; + payload.tag = cpu_to_le32(tag); + payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid & 0xFF)); +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk(" phy profile command for phy %x ,length is %d\n", +- payload.ppc_phyid, length)); ++ pm8001_dbg(pm8001_ha, INIT, ++ " phy profile command for phy %x ,length is %d\n", ++ payload.ppc_phyid, length); + for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) { + payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i)); + j++; +@@ -5056,7 +4893,7 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha, + SAS_PHY_ANALOG_SETTINGS_PAGE, i, length, (u32 *)buf); + length = length + PHY_DWORD_LENGTH; + } +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n")); ++ pm8001_dbg(pm8001_ha, INIT, "phy settings completed\n"); + } + + void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha, +@@ -5071,7 +4908,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha, + + rc = pm8001_tag_alloc(pm8001_ha, &tag); + if (rc) +- PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Invalid tag")); ++ pm8001_dbg(pm8001_ha, INIT, "Invalid tag\n"); + + circularQ = &pm8001_ha->inbnd_q_tbl[0]; + opc = OPC_INB_SET_PHY_PROFILE; +@@ -5088,8 +4925,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha, + if (rc) + pm8001_tag_free(pm8001_ha, tag); + +- PM8001_INIT_DBG(pm8001_ha, +- pm8001_printk("PHY %d settings applied", phy)); ++ pm8001_dbg(pm8001_ha, INIT, "PHY %d settings applied\n", phy); + } + const struct pm8001_dispatch pm8001_80xx_dispatch = { + .name = "pmc80xx", +diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c +index 934713472ebce..09d2ac20508b5 100644 +--- a/drivers/scsi/ufs/ufs-mediatek.c ++++ b/drivers/scsi/ufs/ufs-mediatek.c +@@ -813,7 +813,7 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm) + if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc) + return; + +- if (lpm & !hba->vreg_info.vcc->enabled) ++ if (lpm && !hba->vreg_info.vcc->enabled) + regulator_set_mode(hba->vreg_info.vccq2->reg, + REGULATOR_MODE_IDLE); + else if (!lpm) +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index 826b01f346246..2e1255bf1b429 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -1198,6 +1198,7 @@ static int cqspi_probe(struct platform_device *pdev) + cqspi = spi_master_get_devdata(master); + + cqspi->pdev = pdev; ++ platform_set_drvdata(pdev, cqspi); + + /* Obtain configuration from OF. */ + ret = cqspi_of_get_pdata(cqspi); +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c +index e0e35502e34a3..1dd833757c4ee 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -103,6 +103,25 @@ static const struct cedrus_control cedrus_controls[] = { + .codec = CEDRUS_CODEC_H264, + .required = false, + }, ++ /* ++ * We only expose supported profiles information, ++ * and not levels as it's not clear what is supported ++ * for each hardware/core version. ++ * In any case, TRY/S_FMT will clamp the format resolution ++ * to the maximum supported. ++ */ ++ { ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, ++ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, ++ .def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, ++ .max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, ++ .menu_skip_mask = ++ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED), ++ }, ++ .codec = CEDRUS_CODEC_H264, ++ .required = false, ++ }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index c73bbfe69ba16..9a272a516b2d7 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -761,12 +761,6 @@ static int tb_init_port(struct tb_port *port) + + tb_dump_port(port->sw->tb, &port->config); + +- /* Control port does not need HopID allocation */ +- if (port->port) { +- ida_init(&port->in_hopids); +- ida_init(&port->out_hopids); +- } +- + INIT_LIST_HEAD(&port->list); + return 0; + +@@ -1764,10 +1758,8 @@ static void tb_switch_release(struct device *dev) + dma_port_free(sw->dma_port); + + tb_switch_for_each_port(sw, port) { +- if (!port->disabled) { +- ida_destroy(&port->in_hopids); +- ida_destroy(&port->out_hopids); +- } ++ ida_destroy(&port->in_hopids); ++ ida_destroy(&port->out_hopids); + } + + kfree(sw->uuid); +@@ -1947,6 +1939,12 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, + /* minimum setup for tb_find_cap and tb_drom_read to work */ + sw->ports[i].sw = sw; + sw->ports[i].port = i; ++ ++ /* Control port does not need HopID allocation */ ++ if (i) { ++ ida_init(&sw->ports[i].in_hopids); ++ ida_init(&sw->ports[i].out_hopids); ++ } + } + + ret = tb_switch_find_vse_cap(sw, TB_VSE_CAP_PLUG_EVENTS); +diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c +index 214fbc92c1b7d..a56ea540af00b 100644 +--- a/drivers/thunderbolt/tb.c ++++ b/drivers/thunderbolt/tb.c +@@ -138,6 +138,10 @@ static void tb_discover_tunnels(struct tb_switch *sw) + parent->boot = true; + parent = tb_switch_parent(parent); + } ++ } else if (tb_tunnel_is_dp(tunnel)) { ++ /* Keep the domain from powering down */ ++ pm_runtime_get_sync(&tunnel->src_port->sw->dev); ++ pm_runtime_get_sync(&tunnel->dst_port->sw->dev); + } + + list_add_tail(&tunnel->list, &tcm->tunnel_list); +diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c +index ee6c7762d3559..6248304a001f4 100644 +--- a/drivers/tty/serial/stm32-usart.c ++++ b/drivers/tty/serial/stm32-usart.c +@@ -350,7 +350,6 @@ static void stm32_transmit_chars_dma(struct uart_port *port) + struct stm32_usart_offsets *ofs = &stm32port->info->ofs; + struct circ_buf *xmit = &port->state->xmit; + struct dma_async_tx_descriptor *desc = NULL; +- dma_cookie_t cookie; + unsigned int count, i; + + if (stm32port->tx_dma_busy) +@@ -384,17 +383,18 @@ static void stm32_transmit_chars_dma(struct uart_port *port) + DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT); + +- if (!desc) { +- for (i = count; i > 0; i--) +- stm32_transmit_chars_pio(port); +- return; +- } ++ if (!desc) ++ goto fallback_err; + + desc->callback = stm32_tx_dma_complete; + desc->callback_param = port; + + /* Push current DMA TX transaction in the pending queue */ +- cookie = dmaengine_submit(desc); ++ if (dma_submit_error(dmaengine_submit(desc))) { ++ /* dma no yet started, safe to free resources */ ++ dmaengine_terminate_async(stm32port->tx_ch); ++ goto fallback_err; ++ } + + /* Issue pending DMA TX requests */ + dma_async_issue_pending(stm32port->tx_ch); +@@ -403,6 +403,11 @@ static void stm32_transmit_chars_dma(struct uart_port *port) + + xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); + port->icount.tx += count; ++ return; ++ ++fallback_err: ++ for (i = count; i > 0; i--) ++ stm32_transmit_chars_pio(port); + } + + static void stm32_transmit_chars(struct uart_port *port) +@@ -1087,7 +1092,6 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port, + struct device *dev = &pdev->dev; + struct dma_slave_config config; + struct dma_async_tx_descriptor *desc = NULL; +- dma_cookie_t cookie; + int ret; + + /* Request DMA RX channel */ +@@ -1132,7 +1136,11 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port, + desc->callback_param = NULL; + + /* Push current DMA transaction in the pending queue */ +- cookie = dmaengine_submit(desc); ++ ret = dma_submit_error(dmaengine_submit(desc)); ++ if (ret) { ++ dmaengine_terminate_sync(stm32port->rx_ch); ++ goto config_err; ++ } + + /* Issue pending DMA requests */ + dma_async_issue_pending(stm32port->rx_ch); +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 56f7235bc068c..2a86ad4b12b34 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -783,8 +783,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) + + trace_dwc3_gadget_ep_disable(dep); + +- dwc3_remove_requests(dwc, dep); +- + /* make sure HW endpoint isn't stalled */ + if (dep->flags & DWC3_EP_STALL) + __dwc3_gadget_ep_set_halt(dep, 0, false); +@@ -803,6 +801,8 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) + dep->endpoint.desc = NULL; + } + ++ dwc3_remove_requests(dwc, dep); ++ + return 0; + } + +@@ -1617,7 +1617,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) + { + struct dwc3 *dwc = dep->dwc; + +- if (!dep->endpoint.desc || !dwc->pullups_connected) { ++ if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) { + dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", + dep->name); + return -ESHUTDOWN; +@@ -2125,6 +2125,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + } + } + ++ /* ++ * Check the return value for successful resume, or error. For a ++ * successful resume, the DWC3 runtime PM resume routine will handle ++ * the run stop sequence, so avoid duplicate operations here. ++ */ ++ ret = pm_runtime_get_sync(dwc->dev); ++ if (!ret || ret < 0) { ++ pm_runtime_put(dwc->dev); ++ return 0; ++ } ++ + /* + * Synchronize any pending event handling before executing the controller + * halt routine. +@@ -2139,6 +2150,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + if (!is_on) { + u32 count; + ++ dwc->connected = false; + /* + * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a + * Section 4.1.8 Table 4-7, it states that for a device-initiated +@@ -2169,6 +2181,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + + ret = dwc3_gadget_run_stop(dwc, is_on, false); + spin_unlock_irqrestore(&dwc->lock, flags); ++ pm_runtime_put(dwc->dev); + + return ret; + } +@@ -3254,8 +3267,6 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) + { + u32 reg; + +- dwc->connected = true; +- + /* + * WORKAROUND: DWC3 revisions <1.88a have an issue which + * would cause a missing Disconnect Event if there's a +@@ -3295,6 +3306,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) + * transfers." + */ + dwc3_stop_active_transfers(dwc); ++ dwc->connected = true; + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= ~DWC3_DCTL_TSTCTRL_MASK; +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 36ffb43f9c1a0..9b7fa53d6642b 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -97,6 +97,8 @@ struct gadget_config_name { + struct list_head list; + }; + ++#define USB_MAX_STRING_WITH_NULL_LEN (USB_MAX_STRING_LEN+1) ++ + static int usb_string_copy(const char *s, char **s_copy) + { + int ret; +@@ -106,12 +108,16 @@ static int usb_string_copy(const char *s, char **s_copy) + if (ret > USB_MAX_STRING_LEN) + return -EOVERFLOW; + +- str = kstrdup(s, GFP_KERNEL); +- if (!str) +- return -ENOMEM; ++ if (copy) { ++ str = copy; ++ } else { ++ str = kmalloc(USB_MAX_STRING_WITH_NULL_LEN, GFP_KERNEL); ++ if (!str) ++ return -ENOMEM; ++ } ++ strcpy(str, s); + if (str[ret - 1] == '\n') + str[ret - 1] = '\0'; +- kfree(copy); + *s_copy = str; + return 0; + } +diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c +index 238a8088e17f6..7cc8813f5d8cb 100644 +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -651,6 +651,13 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) + need_auto_sense = 1; + } + ++ /* Some devices (Kindle) require another command after SYNC CACHE */ ++ if ((us->fflags & US_FL_SENSE_AFTER_SYNC) && ++ srb->cmnd[0] == SYNCHRONIZE_CACHE) { ++ usb_stor_dbg(us, "-- sense after SYNC CACHE\n"); ++ need_auto_sense = 1; ++ } ++ + /* + * If we have a failure, we're going to do a REQUEST_SENSE + * automatically. Note that we differentiate between a command +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 5732e9691f08f..efa972be2ee34 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2211,6 +2211,18 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_DISC_INFO ), + ++/* ++ * Reported by Matthias Schwarzott ++ * The Amazon Kindle treats SYNCHRONIZE CACHE as an indication that ++ * the host may be finished with it, and automatically ejects its ++ * emulated media unless it receives another command within one second. ++ */ ++UNUSUAL_DEV( 0x1949, 0x0004, 0x0000, 0x9999, ++ "Amazon", ++ "Kindle", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_SENSE_AFTER_SYNC ), ++ + /* + * Reported by Oliver Neukum + * This device morphes spontaneously into another device if the access +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index a6fae1f865051..563658096b675 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -785,6 +785,7 @@ static int tcpm_set_current_limit(struct tcpm_port *port, u32 max_ma, u32 mv) + + port->supply_voltage = mv; + port->current_limit = max_ma; ++ power_supply_changed(port->psy); + + if (port->tcpc->set_current_limit) + ret = port->tcpc->set_current_limit(port->tcpc, max_ma, mv); +@@ -2300,6 +2301,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, + + port->pps_data.supported = false; + port->usb_type = POWER_SUPPLY_USB_TYPE_PD; ++ power_supply_changed(port->psy); + + /* + * Select the source PDO providing the most power which has a +@@ -2324,6 +2326,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, + port->pps_data.supported = true; + port->usb_type = + POWER_SUPPLY_USB_TYPE_PD_PPS; ++ power_supply_changed(port->psy); + } + continue; + default: +@@ -2481,6 +2484,7 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) + port->pps_data.out_volt)); + port->pps_data.op_curr = min(port->pps_data.max_curr, + port->pps_data.op_curr); ++ power_supply_changed(port->psy); + } + + return src_pdo; +@@ -2716,6 +2720,7 @@ static int tcpm_set_charge(struct tcpm_port *port, bool charge) + return ret; + } + port->vbus_charge = charge; ++ power_supply_changed(port->psy); + return 0; + } + +@@ -2880,6 +2885,7 @@ static void tcpm_reset_port(struct tcpm_port *port) + port->try_src_count = 0; + port->try_snk_count = 0; + port->usb_type = POWER_SUPPLY_USB_TYPE_C; ++ power_supply_changed(port->psy); + port->nr_sink_caps = 0; + port->sink_cap_done = false; + if (port->tcpc->enable_frs) +@@ -4982,7 +4988,7 @@ static int tcpm_psy_set_prop(struct power_supply *psy, + ret = -EINVAL; + break; + } +- ++ power_supply_changed(port->psy); + return ret; + } + +@@ -5134,6 +5140,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) + err = devm_tcpm_psy_register(port); + if (err) + goto out_role_sw_put; ++ power_supply_changed(port->psy); + + port->typec_port = typec_register_port(port->dev, &port->typec_caps); + if (IS_ERR(port->typec_port)) { +diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c +index 3db33bb622c38..d8e4594fe0090 100644 +--- a/drivers/usb/typec/tps6598x.c ++++ b/drivers/usb/typec/tps6598x.c +@@ -62,7 +62,6 @@ enum { + struct tps6598x_rx_identity_reg { + u8 status; + struct usb_pd_identity identity; +- u32 vdo[3]; + } __packed; + + /* Standard Task return codes */ +diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c +index a3ec39fc61778..7383a543c6d12 100644 +--- a/drivers/usb/usbip/vudc_sysfs.c ++++ b/drivers/usb/usbip/vudc_sysfs.c +@@ -174,7 +174,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, + + udc->ud.tcp_socket = socket; + udc->ud.tcp_rx = tcp_rx; +- udc->ud.tcp_rx = tcp_tx; ++ udc->ud.tcp_tx = tcp_tx; + udc->ud.status = SDEV_ST_USED; + + spin_unlock_irq(&udc->ud.lock); +diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig +index 5533df91b257d..90c0525b1e0cf 100644 +--- a/drivers/vfio/Kconfig ++++ b/drivers/vfio/Kconfig +@@ -21,7 +21,7 @@ config VFIO_VIRQFD + + menuconfig VFIO + tristate "VFIO Non-Privileged userspace driver framework" +- depends on IOMMU_API ++ select IOMMU_API + select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64) + help + VFIO provides a framework for secure userspace device drivers. +diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c +index 29ed4173f04e6..fc5707ada024e 100644 +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -312,8 +312,10 @@ static long vhost_vdpa_get_vring_num(struct vhost_vdpa *v, u16 __user *argp) + + static void vhost_vdpa_config_put(struct vhost_vdpa *v) + { +- if (v->config_ctx) ++ if (v->config_ctx) { + eventfd_ctx_put(v->config_ctx); ++ v->config_ctx = NULL; ++ } + } + + static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) +@@ -333,8 +335,12 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) + if (!IS_ERR_OR_NULL(ctx)) + eventfd_ctx_put(ctx); + +- if (IS_ERR(v->config_ctx)) +- return PTR_ERR(v->config_ctx); ++ if (IS_ERR(v->config_ctx)) { ++ long ret = PTR_ERR(v->config_ctx); ++ ++ v->config_ctx = NULL; ++ return ret; ++ } + + v->vdpa->config->set_config_cb(v->vdpa, &cb); + +@@ -904,14 +910,10 @@ err: + + static void vhost_vdpa_clean_irq(struct vhost_vdpa *v) + { +- struct vhost_virtqueue *vq; + int i; + +- for (i = 0; i < v->nvqs; i++) { +- vq = &v->vqs[i]; +- if (vq->call_ctx.producer.irq) +- irq_bypass_unregister_producer(&vq->call_ctx.producer); +- } ++ for (i = 0; i < v->nvqs; i++) ++ vhost_vdpa_unsetup_vq_irq(v, i); + } + + static int vhost_vdpa_release(struct inode *inode, struct file *filep) +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index 9068d5578a26f..9dc6f4b1c4177 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -69,7 +69,6 @@ const struct inode_operations afs_dir_inode_operations = { + .permission = afs_permission, + .getattr = afs_getattr, + .setattr = afs_setattr, +- .listxattr = afs_listxattr, + }; + + const struct address_space_operations afs_dir_aops = { +diff --git a/fs/afs/file.c b/fs/afs/file.c +index 85f5adf21aa08..960b64268623e 100644 +--- a/fs/afs/file.c ++++ b/fs/afs/file.c +@@ -43,7 +43,6 @@ const struct inode_operations afs_file_inode_operations = { + .getattr = afs_getattr, + .setattr = afs_setattr, + .permission = afs_permission, +- .listxattr = afs_listxattr, + }; + + const struct address_space_operations afs_fs_aops = { +diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c +index 97cab12b0a6c2..71c58723763d2 100644 +--- a/fs/afs/fs_operation.c ++++ b/fs/afs/fs_operation.c +@@ -181,10 +181,13 @@ void afs_wait_for_operation(struct afs_operation *op) + if (test_bit(AFS_SERVER_FL_IS_YFS, &op->server->flags) && + op->ops->issue_yfs_rpc) + op->ops->issue_yfs_rpc(op); +- else ++ else if (op->ops->issue_afs_rpc) + op->ops->issue_afs_rpc(op); ++ else ++ op->ac.error = -ENOTSUPP; + +- op->error = afs_wait_for_call_to_complete(op->call, &op->ac); ++ if (op->call) ++ op->error = afs_wait_for_call_to_complete(op->call, &op->ac); + } + + switch (op->error) { +diff --git a/fs/afs/inode.c b/fs/afs/inode.c +index b0d7b892090da..1d03eb1920ec0 100644 +--- a/fs/afs/inode.c ++++ b/fs/afs/inode.c +@@ -27,7 +27,6 @@ + + static const struct inode_operations afs_symlink_inode_operations = { + .get_link = page_get_link, +- .listxattr = afs_listxattr, + }; + + static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode) +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 0d150a29e39ec..525ef075fcd90 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -1508,7 +1508,6 @@ extern int afs_launder_page(struct page *); + * xattr.c + */ + extern const struct xattr_handler *afs_xattr_handlers[]; +-extern ssize_t afs_listxattr(struct dentry *, char *, size_t); + + /* + * yfsclient.c +diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c +index 052dab2f5c03a..bbb2c210d139d 100644 +--- a/fs/afs/mntpt.c ++++ b/fs/afs/mntpt.c +@@ -32,7 +32,6 @@ const struct inode_operations afs_mntpt_inode_operations = { + .lookup = afs_mntpt_lookup, + .readlink = page_readlink, + .getattr = afs_getattr, +- .listxattr = afs_listxattr, + }; + + const struct inode_operations afs_autocell_inode_operations = { +diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c +index 95c573dcda116..6a29337bd562f 100644 +--- a/fs/afs/xattr.c ++++ b/fs/afs/xattr.c +@@ -11,29 +11,6 @@ + #include + #include "internal.h" + +-static const char afs_xattr_list[] = +- "afs.acl\0" +- "afs.cell\0" +- "afs.fid\0" +- "afs.volume\0" +- "afs.yfs.acl\0" +- "afs.yfs.acl_inherited\0" +- "afs.yfs.acl_num_cleaned\0" +- "afs.yfs.vol_acl"; +- +-/* +- * Retrieve a list of the supported xattrs. +- */ +-ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) +-{ +- if (size == 0) +- return sizeof(afs_xattr_list); +- if (size < sizeof(afs_xattr_list)) +- return -ERANGE; +- memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list)); +- return sizeof(afs_xattr_list); +-} +- + /* + * Deal with the result of a successful fetch ACL operation. + */ +@@ -230,6 +207,8 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, + else + ret = -ERANGE; + } ++ } else if (ret == -ENOTSUPP) { ++ ret = -ENODATA; + } + + error_yacl: +@@ -254,6 +233,7 @@ static int afs_xattr_set_yfs(const struct xattr_handler *handler, + { + struct afs_operation *op; + struct afs_vnode *vnode = AFS_FS_I(inode); ++ int ret; + + if (flags == XATTR_CREATE || + strcmp(name, "acl") != 0) +@@ -268,7 +248,10 @@ static int afs_xattr_set_yfs(const struct xattr_handler *handler, + return afs_put_operation(op); + + op->ops = &yfs_store_opaque_acl2_operation; +- return afs_do_sync_operation(op); ++ ret = afs_do_sync_operation(op); ++ if (ret == -ENOTSUPP) ++ ret = -ENODATA; ++ return ret; + } + + static const struct xattr_handler afs_xattr_yfs_handler = { +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index f2f6f65038923..9faf15bd5a548 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -1367,7 +1367,9 @@ get_old_root(struct btrfs_root *root, u64 time_seq) + "failed to read tree block %llu from get_old_root", + logical); + } else { ++ btrfs_tree_read_lock(old); + eb = btrfs_clone_extent_buffer(old); ++ btrfs_tree_read_unlock(old); + free_extent_buffer(old); + } + } else if (old_root) { +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index cbeb0cdaca7af..4162ef602a024 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -8811,7 +8811,7 @@ int __init btrfs_init_cachep(void) + + btrfs_free_space_bitmap_cachep = kmem_cache_create("btrfs_free_space_bitmap", + PAGE_SIZE, PAGE_SIZE, +- SLAB_RED_ZONE, NULL); ++ SLAB_MEM_SPREAD, NULL); + if (!btrfs_free_space_bitmap_cachep) + goto fail; + +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 9ee5f304592f1..b1f0c05d6eaf8 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -2375,7 +2375,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat, + * We need to be sure that all dirty pages are written and the server + * has actual ctime, mtime and file length. + */ +- if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE)) && ++ if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE | STATX_BLOCKS)) && + !CIFS_CACHE_READ(CIFS_I(inode)) && + inode->i_mapping && inode->i_mapping->nrpages != 0) { + rc = filemap_fdatawait(inode->i_mapping); +@@ -2565,6 +2565,14 @@ set_size_out: + if (rc == 0) { + cifsInode->server_eof = attrs->ia_size; + cifs_setsize(inode, attrs->ia_size); ++ /* ++ * i_blocks is not related to (i_size / i_blksize), but instead ++ * 512 byte (2**9) size is required for calculating num blocks. ++ * Until we can query the server for actual allocation size, ++ * this is best estimate we have for blocks allocated for a file ++ * Number of blocks must be rounded up so size 1 is not 0 blocks ++ */ ++ inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9; + + /* + * The man page of truncate says if the size changed, +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 0b9f1a0cba1a3..7b45b3b79df56 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -1156,9 +1156,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, + /* + * Compounding is never used during session establish. + */ +- if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) ++ if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) { ++ mutex_lock(&server->srv_mutex); + smb311_update_preauth_hash(ses, rqst[0].rq_iov, + rqst[0].rq_nvec); ++ mutex_unlock(&server->srv_mutex); ++ } + + for (i = 0; i < num_rqst; i++) { + rc = wait_for_response(server, midQ[i]); +@@ -1226,7 +1229,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, + .iov_base = resp_iov[0].iov_base, + .iov_len = resp_iov[0].iov_len + }; ++ mutex_lock(&server->srv_mutex); + smb311_update_preauth_hash(ses, &iov, 1); ++ mutex_unlock(&server->srv_mutex); + } + + out: +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 65ecaf96d0a4d..b92acb6603139 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2762,6 +2762,8 @@ void __ext4_fc_track_link(handle_t *handle, struct inode *inode, + struct dentry *dentry); + void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry); + void ext4_fc_track_link(handle_t *handle, struct dentry *dentry); ++void __ext4_fc_track_create(handle_t *handle, struct inode *inode, ++ struct dentry *dentry); + void ext4_fc_track_create(handle_t *handle, struct dentry *dentry); + void ext4_fc_track_inode(handle_t *handle, struct inode *inode); + void ext4_fc_mark_ineligible(struct super_block *sb, int reason); +diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c +index a1dd7ca962c3f..4008a674250cf 100644 +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -452,10 +452,10 @@ void ext4_fc_track_link(handle_t *handle, struct dentry *dentry) + __ext4_fc_track_link(handle, d_inode(dentry), dentry); + } + +-void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) ++void __ext4_fc_track_create(handle_t *handle, struct inode *inode, ++ struct dentry *dentry) + { + struct __track_dentry_update_args args; +- struct inode *inode = d_inode(dentry); + int ret; + + args.dentry = dentry; +@@ -466,6 +466,11 @@ void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) + trace_ext4_fc_track_create(inode, dentry, ret); + } + ++void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) ++{ ++ __ext4_fc_track_create(handle, d_inode(dentry), dentry); ++} ++ + /* __track_fn for inode tracking */ + static int __track_inode(struct inode *inode, void *arg, bool update) + { +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 0afab6d5c65bd..c2b8ba343bb4b 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5029,7 +5029,7 @@ static int ext4_do_update_inode(handle_t *handle, + struct ext4_inode_info *ei = EXT4_I(inode); + struct buffer_head *bh = iloc->bh; + struct super_block *sb = inode->i_sb; +- int err = 0, rc, block; ++ int err = 0, block; + int need_datasync = 0, set_large_file = 0; + uid_t i_uid; + gid_t i_gid; +@@ -5141,9 +5141,9 @@ static int ext4_do_update_inode(handle_t *handle, + bh->b_data); + + BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); +- rc = ext4_handle_dirty_metadata(handle, NULL, bh); +- if (!err) +- err = rc; ++ err = ext4_handle_dirty_metadata(handle, NULL, bh); ++ if (err) ++ goto out_brelse; + ext4_clear_inode_state(inode, EXT4_STATE_NEW); + if (set_large_file) { + BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access"); +@@ -5385,8 +5385,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) + inode->i_gid = attr->ia_gid; + error = ext4_mark_inode_dirty(handle, inode); + ext4_journal_stop(handle); +- if (unlikely(error)) ++ if (unlikely(error)) { ++ ext4_fc_stop_update(inode); + return error; ++ } + } + + if (attr->ia_valid & ATTR_SIZE) { +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 14783f7dcbe98..6c7eba426a678 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3604,6 +3604,31 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, + return retval; + } + ++static void ext4_resetent(handle_t *handle, struct ext4_renament *ent, ++ unsigned ino, unsigned file_type) ++{ ++ struct ext4_renament old = *ent; ++ int retval = 0; ++ ++ /* ++ * old->de could have moved from under us during make indexed dir, ++ * so the old->de may no longer valid and need to find it again ++ * before reset old inode info. ++ */ ++ old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); ++ if (IS_ERR(old.bh)) ++ retval = PTR_ERR(old.bh); ++ if (!old.bh) ++ retval = -ENOENT; ++ if (retval) { ++ ext4_std_error(old.dir->i_sb, retval); ++ return; ++ } ++ ++ ext4_setent(handle, &old, ino, file_type); ++ brelse(old.bh); ++} ++ + static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, + const struct qstr *d_name) + { +@@ -3839,6 +3864,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + retval = ext4_mark_inode_dirty(handle, whiteout); + if (unlikely(retval)) + goto end_rename; ++ + } + if (!new.bh) { + retval = ext4_add_entry(handle, new.dentry, old.inode); +@@ -3912,6 +3938,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + ext4_fc_track_unlink(handle, new.dentry); + __ext4_fc_track_link(handle, old.inode, new.dentry); + __ext4_fc_track_unlink(handle, old.inode, old.dentry); ++ if (whiteout) ++ __ext4_fc_track_create(handle, whiteout, old.dentry); + } + + if (new.inode) { +@@ -3926,8 +3954,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + end_rename: + if (whiteout) { + if (retval) { +- ext4_setent(handle, &old, +- old.inode->i_ino, old_file_type); ++ ext4_resetent(handle, &old, ++ old.inode->i_ino, old_file_type); + drop_nlink(whiteout); + } + unlock_new_inode(whiteout); +diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c +index 5b7ba8f711538..00e3cbde472e4 100644 +--- a/fs/ext4/verity.c ++++ b/fs/ext4/verity.c +@@ -201,55 +201,76 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc, + struct inode *inode = file_inode(filp); + const int credits = 2; /* superblock and inode for ext4_orphan_del() */ + handle_t *handle; ++ struct ext4_iloc iloc; + int err = 0; +- int err2; + +- if (desc != NULL) { +- /* Succeeded; write the verity descriptor. */ +- err = ext4_write_verity_descriptor(inode, desc, desc_size, +- merkle_tree_size); +- +- /* Write all pages before clearing VERITY_IN_PROGRESS. */ +- if (!err) +- err = filemap_write_and_wait(inode->i_mapping); +- } ++ /* ++ * If an error already occurred (which fs/verity/ signals by passing ++ * desc == NULL), then only clean-up is needed. ++ */ ++ if (desc == NULL) ++ goto cleanup; + +- /* If we failed, truncate anything we wrote past i_size. */ +- if (desc == NULL || err) +- ext4_truncate(inode); ++ /* Append the verity descriptor. */ ++ err = ext4_write_verity_descriptor(inode, desc, desc_size, ++ merkle_tree_size); ++ if (err) ++ goto cleanup; + + /* +- * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and +- * deleting the inode from the orphan list, even if something failed. +- * If everything succeeded, we'll also set the verity bit in the same +- * transaction. ++ * Write all pages (both data and verity metadata). Note that this must ++ * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages ++ * beyond i_size won't be written properly. For crash consistency, this ++ * also must happen before the verity inode flag gets persisted. + */ ++ err = filemap_write_and_wait(inode->i_mapping); ++ if (err) ++ goto cleanup; + +- ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); ++ /* ++ * Finally, set the verity inode flag and remove the inode from the ++ * orphan list (in a single transaction). ++ */ + + handle = ext4_journal_start(inode, EXT4_HT_INODE, credits); + if (IS_ERR(handle)) { +- ext4_orphan_del(NULL, inode); +- return PTR_ERR(handle); ++ err = PTR_ERR(handle); ++ goto cleanup; + } + +- err2 = ext4_orphan_del(handle, inode); +- if (err2) +- goto out_stop; ++ err = ext4_orphan_del(handle, inode); ++ if (err) ++ goto stop_and_cleanup; + +- if (desc != NULL && !err) { +- struct ext4_iloc iloc; ++ err = ext4_reserve_inode_write(handle, inode, &iloc); ++ if (err) ++ goto stop_and_cleanup; + +- err = ext4_reserve_inode_write(handle, inode, &iloc); +- if (err) +- goto out_stop; +- ext4_set_inode_flag(inode, EXT4_INODE_VERITY); +- ext4_set_inode_flags(inode, false); +- err = ext4_mark_iloc_dirty(handle, inode, &iloc); +- } +-out_stop: ++ ext4_set_inode_flag(inode, EXT4_INODE_VERITY); ++ ext4_set_inode_flags(inode, false); ++ err = ext4_mark_iloc_dirty(handle, inode, &iloc); ++ if (err) ++ goto stop_and_cleanup; ++ ++ ext4_journal_stop(handle); ++ ++ ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); ++ return 0; ++ ++stop_and_cleanup: + ext4_journal_stop(handle); +- return err ?: err2; ++cleanup: ++ /* ++ * Verity failed to be enabled, so clean up by truncating any verity ++ * metadata that was written beyond i_size (both from cache and from ++ * disk), removing the inode from the orphan list (if it wasn't done ++ * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS. ++ */ ++ truncate_inode_pages(inode->i_mapping, inode->i_size); ++ ext4_truncate(inode); ++ ext4_orphan_del(NULL, inode); ++ ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); ++ return err; + } + + static int ext4_get_verity_descriptor_location(struct inode *inode, +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 6127e94ea4f5d..4698471795732 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -2398,7 +2398,7 @@ retry_inode: + * external inode if possible. + */ + if (ext4_has_feature_ea_inode(inode->i_sb) && +- !i.in_inode) { ++ i.value_len && !i.in_inode) { + i.in_inode = 1; + goto retry_inode; + } +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index 61fce59cb4d38..f2c6bbe5cdb81 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -1084,6 +1084,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) + int silent = fc->sb_flags & SB_SILENT; + struct gfs2_sbd *sdp; + struct gfs2_holder mount_gh; ++ struct gfs2_holder freeze_gh; + int error; + + sdp = init_sbd(sb); +@@ -1195,25 +1196,18 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) + goto fail_per_node; + } + +- if (sb_rdonly(sb)) { +- struct gfs2_holder freeze_gh; ++ error = gfs2_freeze_lock(sdp, &freeze_gh, 0); ++ if (error) ++ goto fail_per_node; + +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, +- LM_FLAG_NOEXP | GL_EXACT, +- &freeze_gh); +- if (error) { +- fs_err(sdp, "can't make FS RO: %d\n", error); +- goto fail_per_node; +- } +- gfs2_glock_dq_uninit(&freeze_gh); +- } else { ++ if (!sb_rdonly(sb)) + error = gfs2_make_fs_rw(sdp); +- if (error) { +- fs_err(sdp, "can't make FS RW: %d\n", error); +- goto fail_per_node; +- } +- } + ++ gfs2_freeze_unlock(&freeze_gh); ++ if (error) { ++ fs_err(sdp, "can't make FS RW: %d\n", error); ++ goto fail_per_node; ++ } + gfs2_glock_dq_uninit(&mount_gh); + gfs2_online_uevent(sdp); + return 0; +@@ -1514,6 +1508,12 @@ static int gfs2_reconfigure(struct fs_context *fc) + fc->sb_flags |= SB_RDONLY; + + if ((sb->s_flags ^ fc->sb_flags) & SB_RDONLY) { ++ struct gfs2_holder freeze_gh; ++ ++ error = gfs2_freeze_lock(sdp, &freeze_gh, 0); ++ if (error) ++ return -EINVAL; ++ + if (fc->sb_flags & SB_RDONLY) { + error = gfs2_make_fs_ro(sdp); + if (error) +@@ -1523,6 +1523,7 @@ static int gfs2_reconfigure(struct fs_context *fc) + if (error) + errorfc(fc, "unable to remount read-write"); + } ++ gfs2_freeze_unlock(&freeze_gh); + } + sdp->sd_args = *newargs; + +diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c +index a3c1911862f01..8f9c6480a5df4 100644 +--- a/fs/gfs2/recovery.c ++++ b/fs/gfs2/recovery.c +@@ -470,9 +470,7 @@ void gfs2_recover_func(struct work_struct *work) + + /* Acquire a shared hold on the freeze lock */ + +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, +- LM_FLAG_NOEXP | LM_FLAG_PRIORITY | +- GL_EXACT, &thaw_gh); ++ error = gfs2_freeze_lock(sdp, &thaw_gh, LM_FLAG_PRIORITY); + if (error) + goto fail_gunlock_ji; + +@@ -524,7 +522,7 @@ void gfs2_recover_func(struct work_struct *work) + clean_journal(jd, &head); + up_read(&sdp->sd_log_flush_lock); + +- gfs2_glock_dq_uninit(&thaw_gh); ++ gfs2_freeze_unlock(&thaw_gh); + t_rep = ktime_get(); + fs_info(sdp, "jid=%u: Journal replayed in %lldms [jlck:%lldms, " + "jhead:%lldms, tlck:%lldms, replay:%lldms]\n", +@@ -546,7 +544,7 @@ void gfs2_recover_func(struct work_struct *work) + goto done; + + fail_gunlock_thaw: +- gfs2_glock_dq_uninit(&thaw_gh); ++ gfs2_freeze_unlock(&thaw_gh); + fail_gunlock_ji: + if (jlocked) { + gfs2_glock_dq_uninit(&ji_gh); +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index b3d951ab80680..ddd40c96f7a23 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -165,7 +165,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) + { + struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); + struct gfs2_glock *j_gl = ip->i_gl; +- struct gfs2_holder freeze_gh; + struct gfs2_log_header_host head; + int error; + +@@ -173,12 +172,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) + if (error) + return error; + +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, +- LM_FLAG_NOEXP | GL_EXACT, +- &freeze_gh); +- if (error) +- goto fail_threads; +- + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); + if (gfs2_withdrawn(sdp)) { + error = -EIO; +@@ -205,13 +198,9 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) + + set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + +- gfs2_glock_dq_uninit(&freeze_gh); +- + return 0; + + fail: +- gfs2_glock_dq_uninit(&freeze_gh); +-fail_threads: + if (sdp->sd_quotad_process) + kthread_stop(sdp->sd_quotad_process); + sdp->sd_quotad_process = NULL; +@@ -454,7 +443,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp) + } + + if (error) +- gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); ++ gfs2_freeze_unlock(&sdp->sd_freeze_gh); + + out: + while (!list_empty(&list)) { +@@ -611,30 +600,9 @@ out: + + int gfs2_make_fs_ro(struct gfs2_sbd *sdp) + { +- struct gfs2_holder freeze_gh; + int error = 0; + int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + +- gfs2_holder_mark_uninitialized(&freeze_gh); +- if (sdp->sd_freeze_gl && +- !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) { +- if (!log_write_allowed) { +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, +- LM_ST_SHARED, LM_FLAG_TRY | +- LM_FLAG_NOEXP | GL_EXACT, +- &freeze_gh); +- if (error == GLR_TRYFAILED) +- error = 0; +- } else { +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, +- LM_ST_SHARED, +- LM_FLAG_NOEXP | GL_EXACT, +- &freeze_gh); +- if (error && !gfs2_withdrawn(sdp)) +- return error; +- } +- } +- + gfs2_flush_delete_work(sdp); + if (!log_write_allowed && current == sdp->sd_quotad_process) + fs_warn(sdp, "The quotad daemon is withdrawing.\n"); +@@ -663,9 +631,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) + atomic_read(&sdp->sd_reserving_log) == 0, + HZ * 5); + } +- if (gfs2_holder_initialized(&freeze_gh)) +- gfs2_glock_dq_uninit(&freeze_gh); +- + gfs2_quota_cleanup(sdp); + + if (!log_write_allowed) +@@ -774,10 +739,8 @@ void gfs2_freeze_func(struct work_struct *work) + struct super_block *sb = sdp->sd_vfs; + + atomic_inc(&sb->s_active); +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, +- LM_FLAG_NOEXP | GL_EXACT, &freeze_gh); ++ error = gfs2_freeze_lock(sdp, &freeze_gh, 0); + if (error) { +- fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error); + gfs2_assert_withdraw(sdp, 0); + } else { + atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN); +@@ -787,7 +750,7 @@ void gfs2_freeze_func(struct work_struct *work) + error); + gfs2_assert_withdraw(sdp, 0); + } +- gfs2_glock_dq_uninit(&freeze_gh); ++ gfs2_freeze_unlock(&freeze_gh); + } + deactivate_super(sb); + clear_bit_unlock(SDF_FS_FROZEN, &sdp->sd_flags); +@@ -855,7 +818,7 @@ static int gfs2_unfreeze(struct super_block *sb) + return 0; + } + +- gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); ++ gfs2_freeze_unlock(&sdp->sd_freeze_gh); + mutex_unlock(&sdp->sd_freeze_mutex); + return wait_on_bit(&sdp->sd_flags, SDF_FS_FROZEN, TASK_INTERRUPTIBLE); + } +diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c +index b7d4e4550880d..3ece99e6490c2 100644 +--- a/fs/gfs2/util.c ++++ b/fs/gfs2/util.c +@@ -91,19 +91,50 @@ out_unlock: + return error; + } + ++/** ++ * gfs2_freeze_lock - hold the freeze glock ++ * @sdp: the superblock ++ * @freeze_gh: pointer to the requested holder ++ * @caller_flags: any additional flags needed by the caller ++ */ ++int gfs2_freeze_lock(struct gfs2_sbd *sdp, struct gfs2_holder *freeze_gh, ++ int caller_flags) ++{ ++ int flags = LM_FLAG_NOEXP | GL_EXACT | caller_flags; ++ int error; ++ ++ error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, flags, ++ freeze_gh); ++ if (error && error != GLR_TRYFAILED) ++ fs_err(sdp, "can't lock the freeze lock: %d\n", error); ++ return error; ++} ++ ++void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh) ++{ ++ if (gfs2_holder_initialized(freeze_gh)) ++ gfs2_glock_dq_uninit(freeze_gh); ++} ++ + static void signal_our_withdraw(struct gfs2_sbd *sdp) + { + struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl; +- struct inode *inode = sdp->sd_jdesc->jd_inode; +- struct gfs2_inode *ip = GFS2_I(inode); +- struct gfs2_glock *i_gl = ip->i_gl; +- u64 no_formal_ino = ip->i_no_formal_ino; ++ struct inode *inode; ++ struct gfs2_inode *ip; ++ struct gfs2_glock *i_gl; ++ u64 no_formal_ino; ++ int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + int ret = 0; + int tries; + +- if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) ++ if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc) + return; + ++ inode = sdp->sd_jdesc->jd_inode; ++ ip = GFS2_I(inode); ++ i_gl = ip->i_gl; ++ no_formal_ino = ip->i_no_formal_ino; ++ + /* Prevent any glock dq until withdraw recovery is complete */ + set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); + /* +@@ -118,8 +149,21 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) + * therefore we need to clear SDF_JOURNAL_LIVE manually. + */ + clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); +- if (!sb_rdonly(sdp->sd_vfs)) +- ret = gfs2_make_fs_ro(sdp); ++ if (!sb_rdonly(sdp->sd_vfs)) { ++ struct gfs2_holder freeze_gh; ++ ++ gfs2_holder_mark_uninitialized(&freeze_gh); ++ if (sdp->sd_freeze_gl && ++ !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) { ++ ret = gfs2_freeze_lock(sdp, &freeze_gh, ++ log_write_allowed ? 0 : LM_FLAG_TRY); ++ if (ret == GLR_TRYFAILED) ++ ret = 0; ++ } ++ if (!ret) ++ ret = gfs2_make_fs_ro(sdp); ++ gfs2_freeze_unlock(&freeze_gh); ++ } + + if (sdp->sd_lockstruct.ls_ops->lm_lock == NULL) { /* lock_nolock */ + if (!ret) +diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h +index d7562981b3a09..aa3771281acac 100644 +--- a/fs/gfs2/util.h ++++ b/fs/gfs2/util.h +@@ -149,6 +149,9 @@ int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, + + extern int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + bool verbose); ++extern int gfs2_freeze_lock(struct gfs2_sbd *sdp, ++ struct gfs2_holder *freeze_gh, int caller_flags); ++extern void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh); + + #define gfs2_io_error(sdp) \ + gfs2_io_error_i((sdp), __func__, __FILE__, __LINE__); +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 691c998691439..06e9c21819957 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2085,6 +2085,7 @@ static void __io_req_task_submit(struct io_kiocb *req) + __io_req_task_cancel(req, -EFAULT); + mutex_unlock(&ctx->uring_lock); + ++ ctx->flags &= ~IORING_SETUP_R_DISABLED; + if (ctx->flags & IORING_SETUP_SQPOLL) + io_sq_thread_drop_mm(); + } +@@ -2616,6 +2617,13 @@ static bool io_rw_reissue(struct io_kiocb *req, long res) + return false; + if ((res != -EAGAIN && res != -EOPNOTSUPP) || io_wq_current_is_worker()) + return false; ++ /* ++ * If ref is dying, we might be running poll reap from the exit work. ++ * Don't attempt to reissue from that path, just let it fail with ++ * -EAGAIN. ++ */ ++ if (percpu_ref_is_dying(&req->ctx->refs)) ++ return false; + + ret = io_sq_thread_acquire_mm(req->ctx, req); + +@@ -3493,6 +3501,7 @@ retry: + goto out_free; + } else if (ret > 0 && ret < io_size) { + /* we got some bytes, but not all. retry. */ ++ kiocb->ki_flags &= ~IOCB_WAITQ; + goto retry; + } + done: +@@ -6233,9 +6242,10 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer) + if (prev) { + req_set_fail_links(prev); + io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); +- io_put_req(prev); ++ io_put_req_deferred(prev, 1); + } else { +- io_req_complete(req, -ETIME); ++ io_cqring_add_event(req, -ETIME, 0); ++ io_put_req_deferred(req, 1); + } + return HRTIMER_NORESTART; + } +@@ -8684,6 +8694,8 @@ static void io_disable_sqo_submit(struct io_ring_ctx *ctx) + { + mutex_lock(&ctx->uring_lock); + ctx->sqo_dead = 1; ++ if (ctx->flags & IORING_SETUP_R_DISABLED) ++ io_sq_offload_start(ctx); + mutex_unlock(&ctx->uring_lock); + + /* make sure callers enter the ring to get error */ +@@ -9662,10 +9674,7 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx) + if (ctx->restrictions.registered) + ctx->restricted = 1; + +- ctx->flags &= ~IORING_SETUP_R_DISABLED; +- + io_sq_offload_start(ctx); +- + return 0; + } + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index 5849c1bd88f17..e5aad1c10ea32 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -897,6 +897,8 @@ nfsd_file_find_locked(struct inode *inode, unsigned int may_flags, + continue; + if (!nfsd_match_cred(nf->nf_cred, current_cred())) + continue; ++ if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) ++ continue; + if (nfsd_file_get(nf) != NULL) + return nf; + } +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index e83b21778816d..2e68cea148e0d 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1299,7 +1299,7 @@ nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, + struct nfsd_file *dst) + { + nfs42_ssc_close(src->nf_file); +- /* 'src' is freed by nfsd4_do_async_copy */ ++ fput(src->nf_file); + nfsd_file_put(dst); + mntput(ss_mnt); + } +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index ee4e6e3b995d4..55cf60b71cde0 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -5372,7 +5372,7 @@ nfs4_laundromat(struct nfsd_net *nn) + idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) { + cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid); + if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID && +- cps->cpntf_time > cutoff) ++ cps->cpntf_time < cutoff) + _free_cpntf_state_locked(nn, cps); + } + spin_unlock(&nn->s2s_cp_lock); +diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c +index c331efe8de953..bbf241a431f27 100644 +--- a/fs/pstore/inode.c ++++ b/fs/pstore/inode.c +@@ -467,7 +467,7 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type, + static void pstore_kill_sb(struct super_block *sb) + { + mutex_lock(&pstore_sb_lock); +- WARN_ON(pstore_sb != sb); ++ WARN_ON(pstore_sb && pstore_sb != sb); + + kill_litter_super(sb); + pstore_sb = NULL; +diff --git a/fs/select.c b/fs/select.c +index 37aaa8317f3ae..945896d0ac9e7 100644 +--- a/fs/select.c ++++ b/fs/select.c +@@ -1055,10 +1055,9 @@ static long do_restart_poll(struct restart_block *restart_block) + + ret = do_sys_poll(ufds, nfds, to); + +- if (ret == -ERESTARTNOHAND) { +- restart_block->fn = do_restart_poll; +- ret = -ERESTART_RESTARTBLOCK; +- } ++ if (ret == -ERESTARTNOHAND) ++ ret = set_restart_fn(restart_block, do_restart_poll); ++ + return ret; + } + +@@ -1080,7 +1079,6 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, + struct restart_block *restart_block; + + restart_block = ¤t->restart_block; +- restart_block->fn = do_restart_poll; + restart_block->poll.ufds = ufds; + restart_block->poll.nfds = nfds; + +@@ -1091,7 +1089,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, + } else + restart_block->poll.has_timeout = 0; + +- ret = -ERESTART_RESTARTBLOCK; ++ ret = set_restart_fn(restart_block, do_restart_poll); + } + return ret; + } +diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c +index 3fe933b1010c3..2243dc1fb48fe 100644 +--- a/fs/zonefs/super.c ++++ b/fs/zonefs/super.c +@@ -159,6 +159,21 @@ static int zonefs_writepages(struct address_space *mapping, + return iomap_writepages(mapping, wbc, &wpc, &zonefs_writeback_ops); + } + ++static int zonefs_swap_activate(struct swap_info_struct *sis, ++ struct file *swap_file, sector_t *span) ++{ ++ struct inode *inode = file_inode(swap_file); ++ struct zonefs_inode_info *zi = ZONEFS_I(inode); ++ ++ if (zi->i_ztype != ZONEFS_ZTYPE_CNV) { ++ zonefs_err(inode->i_sb, ++ "swap file: not a conventional zone file\n"); ++ return -EINVAL; ++ } ++ ++ return iomap_swapfile_activate(sis, swap_file, span, &zonefs_iomap_ops); ++} ++ + static const struct address_space_operations zonefs_file_aops = { + .readpage = zonefs_readpage, + .readahead = zonefs_readahead, +@@ -171,6 +186,7 @@ static const struct address_space_operations zonefs_file_aops = { + .is_partially_uptodate = iomap_is_partially_uptodate, + .error_remove_page = generic_error_remove_page, + .direct_IO = noop_direct_IO, ++ .swap_activate = zonefs_swap_activate, + }; + + static void zonefs_update_stats(struct inode *inode, loff_t new_isize) +@@ -719,6 +735,68 @@ out_release: + return ret; + } + ++/* ++ * Do not exceed the LFS limits nor the file zone size. If pos is under the ++ * limit it becomes a short access. If it exceeds the limit, return -EFBIG. ++ */ ++static loff_t zonefs_write_check_limits(struct file *file, loff_t pos, ++ loff_t count) ++{ ++ struct inode *inode = file_inode(file); ++ struct zonefs_inode_info *zi = ZONEFS_I(inode); ++ loff_t limit = rlimit(RLIMIT_FSIZE); ++ loff_t max_size = zi->i_max_size; ++ ++ if (limit != RLIM_INFINITY) { ++ if (pos >= limit) { ++ send_sig(SIGXFSZ, current, 0); ++ return -EFBIG; ++ } ++ count = min(count, limit - pos); ++ } ++ ++ if (!(file->f_flags & O_LARGEFILE)) ++ max_size = min_t(loff_t, MAX_NON_LFS, max_size); ++ ++ if (unlikely(pos >= max_size)) ++ return -EFBIG; ++ ++ return min(count, max_size - pos); ++} ++ ++static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from) ++{ ++ struct file *file = iocb->ki_filp; ++ struct inode *inode = file_inode(file); ++ struct zonefs_inode_info *zi = ZONEFS_I(inode); ++ loff_t count; ++ ++ if (IS_SWAPFILE(inode)) ++ return -ETXTBSY; ++ ++ if (!iov_iter_count(from)) ++ return 0; ++ ++ if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) ++ return -EINVAL; ++ ++ if (iocb->ki_flags & IOCB_APPEND) { ++ if (zi->i_ztype != ZONEFS_ZTYPE_SEQ) ++ return -EINVAL; ++ mutex_lock(&zi->i_truncate_mutex); ++ iocb->ki_pos = zi->i_wpoffset; ++ mutex_unlock(&zi->i_truncate_mutex); ++ } ++ ++ count = zonefs_write_check_limits(file, iocb->ki_pos, ++ iov_iter_count(from)); ++ if (count < 0) ++ return count; ++ ++ iov_iter_truncate(from, count); ++ return iov_iter_count(from); ++} ++ + /* + * Handle direct writes. For sequential zone files, this is the only possible + * write path. For these files, check that the user is issuing writes +@@ -736,8 +814,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) + struct super_block *sb = inode->i_sb; + bool sync = is_sync_kiocb(iocb); + bool append = false; +- size_t count; +- ssize_t ret; ++ ssize_t ret, count; + + /* + * For async direct IOs to sequential zone files, refuse IOCB_NOWAIT +@@ -755,12 +832,11 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) + inode_lock(inode); + } + +- ret = generic_write_checks(iocb, from); +- if (ret <= 0) ++ count = zonefs_write_checks(iocb, from); ++ if (count <= 0) { ++ ret = count; + goto inode_unlock; +- +- iov_iter_truncate(from, zi->i_max_size - iocb->ki_pos); +- count = iov_iter_count(from); ++ } + + if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) { + ret = -EINVAL; +@@ -820,12 +896,10 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb, + inode_lock(inode); + } + +- ret = generic_write_checks(iocb, from); ++ ret = zonefs_write_checks(iocb, from); + if (ret <= 0) + goto inode_unlock; + +- iov_iter_truncate(from, zi->i_max_size - iocb->ki_pos); +- + ret = iomap_file_buffered_write(iocb, from, &zonefs_iomap_ops); + if (ret > 0) + iocb->ki_pos += ret; +@@ -958,9 +1032,7 @@ static int zonefs_open_zone(struct inode *inode) + + mutex_lock(&zi->i_truncate_mutex); + +- zi->i_wr_refcnt++; +- if (zi->i_wr_refcnt == 1) { +- ++ if (!zi->i_wr_refcnt) { + if (atomic_inc_return(&sbi->s_open_zones) > sbi->s_max_open_zones) { + atomic_dec(&sbi->s_open_zones); + ret = -EBUSY; +@@ -970,7 +1042,6 @@ static int zonefs_open_zone(struct inode *inode) + if (i_size_read(inode) < zi->i_max_size) { + ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN); + if (ret) { +- zi->i_wr_refcnt--; + atomic_dec(&sbi->s_open_zones); + goto unlock; + } +@@ -978,6 +1049,8 @@ static int zonefs_open_zone(struct inode *inode) + } + } + ++ zi->i_wr_refcnt++; ++ + unlock: + mutex_unlock(&zi->i_truncate_mutex); + +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 642ce03f19c4c..76322b6452c80 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -1201,8 +1201,6 @@ struct bpf_prog * __must_check bpf_prog_inc_not_zero(struct bpf_prog *prog); + void bpf_prog_put(struct bpf_prog *prog); + int __bpf_prog_charge(struct user_struct *user, u32 pages); + void __bpf_prog_uncharge(struct user_struct *user, u32 pages); +-void __bpf_free_used_maps(struct bpf_prog_aux *aux, +- struct bpf_map **used_maps, u32 len); + + void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock); + void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock); +@@ -1652,6 +1650,9 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, + return bpf_prog_get_type_dev(ufd, type, false); + } + ++void __bpf_free_used_maps(struct bpf_prog_aux *aux, ++ struct bpf_map **used_maps, u32 len); ++ + bool bpf_prog_get_ok(struct bpf_prog *, enum bpf_prog_type *, bool); + + int bpf_prog_offload_compile(struct bpf_prog *prog); +diff --git a/include/linux/efi.h b/include/linux/efi.h +index d7c0e73af2b97..e17cd4c44f93a 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -72,8 +72,10 @@ typedef void *efi_handle_t; + */ + typedef guid_t efi_guid_t __aligned(__alignof__(u32)); + +-#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ +- GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) ++#define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \ ++ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ ++ (b) & 0xff, ((b) >> 8) & 0xff, \ ++ (c) & 0xff, ((c) >> 8) & 0xff, d } } + + /* + * Generic EFI table header +diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h +index 1bbd3014f9067..71902f41c9199 100644 +--- a/include/linux/regulator/pca9450.h ++++ b/include/linux/regulator/pca9450.h +@@ -147,6 +147,9 @@ enum { + #define BUCK6_FPWM 0x04 + #define BUCK6_ENMODE_MASK 0x03 + ++/* PCA9450_REG_BUCK123_PRESET_EN bit */ ++#define BUCK123_PRESET_EN 0x80 ++ + /* PCA9450_BUCK1OUT_DVS0 bits */ + #define BUCK1OUT_DVS0_MASK 0x7F + #define BUCK1OUT_DVS0_DEFAULT 0x14 +@@ -216,4 +219,11 @@ enum { + #define IRQ_THERM_105 0x02 + #define IRQ_THERM_125 0x01 + ++/* PCA9450_REG_RESET_CTRL bits */ ++#define WDOG_B_CFG_MASK 0xC0 ++#define WDOG_B_CFG_NONE 0x00 ++#define WDOG_B_CFG_WARM 0x40 ++#define WDOG_B_CFG_COLD_LDO12 0x80 ++#define WDOG_B_CFG_COLD 0xC0 ++ + #endif /* __LINUX_REG_PCA9450_H__ */ +diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h +index e93e249a4e9bf..f3040b0b4b235 100644 +--- a/include/linux/thread_info.h ++++ b/include/linux/thread_info.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_THREAD_INFO_IN_TASK + /* +@@ -39,6 +40,18 @@ enum { + + #ifdef __KERNEL__ + ++#ifndef arch_set_restart_data ++#define arch_set_restart_data(restart) do { } while (0) ++#endif ++ ++static inline long set_restart_fn(struct restart_block *restart, ++ long (*fn)(struct restart_block *)) ++{ ++ restart->fn = fn; ++ arch_set_restart_data(restart); ++ return -ERESTART_RESTARTBLOCK; ++} ++ + #ifndef THREAD_ALIGN + #define THREAD_ALIGN THREAD_SIZE + #endif +diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h +index 6b03fdd69d274..712363c7a2e8e 100644 +--- a/include/linux/usb_usual.h ++++ b/include/linux/usb_usual.h +@@ -86,6 +86,8 @@ + /* lies about caching, so always sync */ \ + US_FLAG(NO_SAME, 0x40000000) \ + /* Cannot handle WRITE_SAME */ \ ++ US_FLAG(SENSE_AFTER_SYNC, 0x80000000) \ ++ /* Do REQUEST_SENSE after SYNCHRONIZE_CACHE */ \ + + #define US_FLAG(name, value) US_FL_##name = value , + enum { US_DO_ALL_FLAGS }; +diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h +index 4e2d61e8fb1ed..e6a43163ab5b7 100644 +--- a/include/scsi/libsas.h ++++ b/include/scsi/libsas.h +@@ -391,10 +391,6 @@ struct sas_ha_struct { + int strict_wide_ports; /* both sas_addr and attached_sas_addr must match + * their siblings when forming wide ports */ + +- /* LLDD calls these to notify the class of an event. */ +- int (*notify_port_event)(struct asd_sas_phy *, enum port_event); +- int (*notify_phy_event)(struct asd_sas_phy *, enum phy_event); +- + void *lldd_ha; /* not touched by sas class code */ + + struct list_head eh_done_q; /* complete via scsi_eh_flush_done_q */ +@@ -706,4 +702,11 @@ struct sas_phy *sas_get_local_phy(struct domain_device *dev); + + int sas_request_addr(struct Scsi_Host *shost, u8 *addr); + ++int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event); ++int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event); ++int sas_notify_port_event_gfp(struct asd_sas_phy *phy, enum port_event event, ++ gfp_t gfp_flags); ++int sas_notify_phy_event_gfp(struct asd_sas_phy *phy, enum phy_event event, ++ gfp_t gfp_flags); ++ + #endif /* _SASLIB_H_ */ +diff --git a/kernel/futex.c b/kernel/futex.c +index 0693b3ea0f9a4..7cf1987cfdb4f 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2730,14 +2730,13 @@ retry: + goto out; + + restart = ¤t->restart_block; +- restart->fn = futex_wait_restart; + restart->futex.uaddr = uaddr; + restart->futex.val = val; + restart->futex.time = *abs_time; + restart->futex.bitset = bitset; + restart->futex.flags = flags | FLAGS_HAS_TIMEOUT; + +- ret = -ERESTART_RESTARTBLOCK; ++ ret = set_restart_fn(restart, futex_wait_restart); + + out: + if (to) { +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index c460e0496006e..79dc02b956dc3 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -1072,11 +1072,15 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) + irqreturn_t ret; + + local_bh_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + ret = action->thread_fn(action->irq, action->dev_id); + if (ret == IRQ_HANDLED) + atomic_inc(&desc->threads_handled); + + irq_finalize_oneshot(desc, action); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_enable(); + local_bh_enable(); + return ret; + } +diff --git a/kernel/jump_label.c b/kernel/jump_label.c +index 015ef903ce8cc..a0c325664190b 100644 +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -407,6 +407,14 @@ static bool jump_label_can_update(struct jump_entry *entry, bool init) + return false; + + if (!kernel_text_address(jump_entry_code(entry))) { ++ /* ++ * This skips patching built-in __exit, which ++ * is part of init_section_contains() but is ++ * not part of kernel_text_address(). ++ * ++ * Skipping built-in __exit is fine since it ++ * will never be executed. ++ */ + WARN_ONCE(!jump_entry_is_init(entry), + "can't patch jump_label at %pS", + (void *)jump_entry_code(entry)); +diff --git a/kernel/module.c b/kernel/module.c +index 94f926473e350..908d46abe1656 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2922,20 +2922,14 @@ static int module_sig_check(struct load_info *info, int flags) + * enforcing, certain errors are non-fatal. + */ + case -ENODATA: +- reason = "Loading of unsigned module"; +- goto decide; ++ reason = "unsigned module"; ++ break; + case -ENOPKG: +- reason = "Loading of module with unsupported crypto"; +- goto decide; ++ reason = "module with unsupported crypto"; ++ break; + case -ENOKEY: +- reason = "Loading of module with unavailable key"; +- decide: +- if (is_module_sig_enforced()) { +- pr_notice("%s: %s is rejected\n", info->name, reason); +- return -EKEYREJECTED; +- } +- +- return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); ++ reason = "module with unavailable key"; ++ break; + + /* All other errors are fatal, including nomem, unparseable + * signatures and signature check failures - even if signatures +@@ -2944,6 +2938,13 @@ static int module_sig_check(struct load_info *info, int flags) + default: + return err; + } ++ ++ if (is_module_sig_enforced()) { ++ pr_notice("Loading of %s is rejected\n", reason); ++ return -EKEYREJECTED; ++ } ++ ++ return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); + } + #else /* !CONFIG_MODULE_SIG */ + static int module_sig_check(struct load_info *info, int flags) +@@ -2952,9 +2953,33 @@ static int module_sig_check(struct load_info *info, int flags) + } + #endif /* !CONFIG_MODULE_SIG */ + +-/* Sanity checks against invalid binaries, wrong arch, weird elf version. */ +-static int elf_header_check(struct load_info *info) ++static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) ++{ ++ unsigned long secend; ++ ++ /* ++ * Check for both overflow and offset/size being ++ * too large. ++ */ ++ secend = shdr->sh_offset + shdr->sh_size; ++ if (secend < shdr->sh_offset || secend > info->len) ++ return -ENOEXEC; ++ ++ return 0; ++} ++ ++/* ++ * Sanity checks against invalid binaries, wrong arch, weird elf version. ++ * ++ * Also do basic validity checks against section offsets and sizes, the ++ * section name string table, and the indices used for it (sh_name). ++ */ ++static int elf_validity_check(struct load_info *info) + { ++ unsigned int i; ++ Elf_Shdr *shdr, *strhdr; ++ int err; ++ + if (info->len < sizeof(*(info->hdr))) + return -ENOEXEC; + +@@ -2964,11 +2989,78 @@ static int elf_header_check(struct load_info *info) + || info->hdr->e_shentsize != sizeof(Elf_Shdr)) + return -ENOEXEC; + ++ /* ++ * e_shnum is 16 bits, and sizeof(Elf_Shdr) is ++ * known and small. So e_shnum * sizeof(Elf_Shdr) ++ * will not overflow unsigned long on any platform. ++ */ + if (info->hdr->e_shoff >= info->len + || (info->hdr->e_shnum * sizeof(Elf_Shdr) > + info->len - info->hdr->e_shoff)) + return -ENOEXEC; + ++ info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; ++ ++ /* ++ * Verify if the section name table index is valid. ++ */ ++ if (info->hdr->e_shstrndx == SHN_UNDEF ++ || info->hdr->e_shstrndx >= info->hdr->e_shnum) ++ return -ENOEXEC; ++ ++ strhdr = &info->sechdrs[info->hdr->e_shstrndx]; ++ err = validate_section_offset(info, strhdr); ++ if (err < 0) ++ return err; ++ ++ /* ++ * The section name table must be NUL-terminated, as required ++ * by the spec. This makes strcmp and pr_* calls that access ++ * strings in the section safe. ++ */ ++ info->secstrings = (void *)info->hdr + strhdr->sh_offset; ++ if (info->secstrings[strhdr->sh_size - 1] != '\0') ++ return -ENOEXEC; ++ ++ /* ++ * The code assumes that section 0 has a length of zero and ++ * an addr of zero, so check for it. ++ */ ++ if (info->sechdrs[0].sh_type != SHT_NULL ++ || info->sechdrs[0].sh_size != 0 ++ || info->sechdrs[0].sh_addr != 0) ++ return -ENOEXEC; ++ ++ for (i = 1; i < info->hdr->e_shnum; i++) { ++ shdr = &info->sechdrs[i]; ++ switch (shdr->sh_type) { ++ case SHT_NULL: ++ case SHT_NOBITS: ++ continue; ++ case SHT_SYMTAB: ++ if (shdr->sh_link == SHN_UNDEF ++ || shdr->sh_link >= info->hdr->e_shnum) ++ return -ENOEXEC; ++ fallthrough; ++ default: ++ err = validate_section_offset(info, shdr); ++ if (err < 0) { ++ pr_err("Invalid ELF section in module (section %u type %u)\n", ++ i, shdr->sh_type); ++ return err; ++ } ++ ++ if (shdr->sh_flags & SHF_ALLOC) { ++ if (shdr->sh_name >= strhdr->sh_size) { ++ pr_err("Invalid ELF section name in module (section %u type %u)\n", ++ i, shdr->sh_type); ++ return -ENOEXEC; ++ } ++ } ++ break; ++ } ++ } ++ + return 0; + } + +@@ -3070,11 +3162,6 @@ static int rewrite_section_headers(struct load_info *info, int flags) + + for (i = 1; i < info->hdr->e_shnum; i++) { + Elf_Shdr *shdr = &info->sechdrs[i]; +- if (shdr->sh_type != SHT_NOBITS +- && info->len < shdr->sh_offset + shdr->sh_size) { +- pr_err("Module len %lu truncated\n", info->len); +- return -ENOEXEC; +- } + + /* Mark all sections sh_addr with their address in the + temporary image. */ +@@ -3106,11 +3193,6 @@ static int setup_load_info(struct load_info *info, int flags) + { + unsigned int i; + +- /* Set up the convenience variables */ +- info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; +- info->secstrings = (void *)info->hdr +- + info->sechdrs[info->hdr->e_shstrndx].sh_offset; +- + /* Try to find a name early so we can log errors with a module name */ + info->index.info = find_sec(info, ".modinfo"); + if (info->index.info) +@@ -3854,26 +3936,50 @@ static int load_module(struct load_info *info, const char __user *uargs, + long err = 0; + char *after_dashes; + +- err = elf_header_check(info); ++ /* ++ * Do the signature check (if any) first. All that ++ * the signature check needs is info->len, it does ++ * not need any of the section info. That can be ++ * set up later. This will minimize the chances ++ * of a corrupt module causing problems before ++ * we even get to the signature check. ++ * ++ * The check will also adjust info->len by stripping ++ * off the sig length at the end of the module, making ++ * checks against info->len more correct. ++ */ ++ err = module_sig_check(info, flags); ++ if (err) ++ goto free_copy; ++ ++ /* ++ * Do basic sanity checks against the ELF header and ++ * sections. ++ */ ++ err = elf_validity_check(info); + if (err) { +- pr_err("Module has invalid ELF header\n"); ++ pr_err("Module has invalid ELF structures\n"); + goto free_copy; + } + ++ /* ++ * Everything checks out, so set up the section info ++ * in the info structure. ++ */ + err = setup_load_info(info, flags); + if (err) + goto free_copy; + ++ /* ++ * Now that we know we have the correct module name, check ++ * if it's blacklisted. ++ */ + if (blacklisted(info->name)) { + err = -EPERM; + pr_err("Module %s is blacklisted\n", info->name); + goto free_copy; + } + +- err = module_sig_check(info, flags); +- if (err) +- goto free_copy; +- + err = rewrite_section_headers(info, flags); + if (err) + goto free_copy; +diff --git a/kernel/module_signature.c b/kernel/module_signature.c +index 4224a1086b7d8..00132d12487cd 100644 +--- a/kernel/module_signature.c ++++ b/kernel/module_signature.c +@@ -25,7 +25,7 @@ int mod_check_sig(const struct module_signature *ms, size_t file_len, + return -EBADMSG; + + if (ms->id_type != PKEY_ID_PKCS7) { +- pr_err("%s: Module is not signed with expected PKCS#7 message\n", ++ pr_err("%s: not signed with expected PKCS#7 message\n", + name); + return -ENOPKG; + } +diff --git a/kernel/module_signing.c b/kernel/module_signing.c +index 9d9fc678c91d6..8723ae70ea1fe 100644 +--- a/kernel/module_signing.c ++++ b/kernel/module_signing.c +@@ -30,7 +30,7 @@ int mod_verify_sig(const void *mod, struct load_info *info) + + memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); + +- ret = mod_check_sig(&ms, modlen, info->name); ++ ret = mod_check_sig(&ms, modlen, "module"); + if (ret) + return ret; + +diff --git a/kernel/static_call.c b/kernel/static_call.c +index 84565c2a41b8f..db914da6e7854 100644 +--- a/kernel/static_call.c ++++ b/kernel/static_call.c +@@ -182,7 +182,16 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func) + } + + if (!kernel_text_address((unsigned long)site_addr)) { +- WARN_ONCE(1, "can't patch static call site at %pS", ++ /* ++ * This skips patching built-in __exit, which ++ * is part of init_section_contains() but is ++ * not part of kernel_text_address(). ++ * ++ * Skipping built-in __exit is fine since it ++ * will never be executed. ++ */ ++ WARN_ONCE(!static_call_is_init(site), ++ "can't patch static call site at %pS", + site_addr); + continue; + } +diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c +index f4ace1bf83828..daeaa7140d0aa 100644 +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -848,9 +848,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, + if (flags == TIMER_ABSTIME) + return -ERESTARTNOHAND; + +- restart->fn = alarm_timer_nsleep_restart; + restart->nanosleep.clockid = type; + restart->nanosleep.expires = exp; ++ set_restart_fn(restart, alarm_timer_nsleep_restart); + return ret; + } + +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 4416f5d72c11e..9505b1f21cdf8 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1957,9 +1957,9 @@ long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode, + } + + restart = ¤t->restart_block; +- restart->fn = hrtimer_nanosleep_restart; + restart->nanosleep.clockid = t.timer.base->clockid; + restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer); ++ set_restart_fn(restart, hrtimer_nanosleep_restart); + out: + destroy_hrtimer_on_stack(&t.timer); + return ret; +diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c +index a71758e34e456..9abe15255bc4e 100644 +--- a/kernel/time/posix-cpu-timers.c ++++ b/kernel/time/posix-cpu-timers.c +@@ -1480,8 +1480,8 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, + if (flags & TIMER_ABSTIME) + return -ERESTARTNOHAND; + +- restart_block->fn = posix_cpu_nsleep_restart; + restart_block->nanosleep.clockid = which_clock; ++ set_restart_fn(restart_block, posix_cpu_nsleep_restart); + } + return error; + } +diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c +index 38de24af24c44..54031ee079a2c 100644 +--- a/net/qrtr/qrtr.c ++++ b/net/qrtr/qrtr.c +@@ -433,7 +433,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) + if (len == 0 || len & 3) + return -EINVAL; + +- skb = netdev_alloc_skb(NULL, len); ++ skb = __netdev_alloc_skb(NULL, len, GFP_ATOMIC | __GFP_NOWARN); + if (!skb) + return -ENOMEM; + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index c211b607239ed..d38788cd9433a 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1408,7 +1408,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + + sendit: + if (svc_authorise(rqstp)) +- goto close; ++ goto close_xprt; + return 1; /* Caller can now send it */ + + release_dropit: +@@ -1420,6 +1420,8 @@ release_dropit: + return 0; + + close: ++ svc_authorise(rqstp); ++close_xprt: + if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) + svc_close_xprt(rqstp->rq_xprt); + dprintk("svc: svc_process close\n"); +@@ -1428,7 +1430,7 @@ release_dropit: + err_short_len: + svc_printk(rqstp, "short len %zd, dropping request\n", + argv->iov_len); +- goto close; ++ goto close_xprt; + + err_bad_rpc: + serv->sv_stats->rpcbadfmt++; +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index 43cf8dbde898b..06e503466c32c 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -1062,7 +1062,7 @@ static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, st + struct svc_xprt *xprt; + int ret = 0; + +- spin_lock(&serv->sv_lock); ++ spin_lock_bh(&serv->sv_lock); + list_for_each_entry(xprt, xprt_list, xpt_list) { + if (xprt->xpt_net != net) + continue; +@@ -1070,7 +1070,7 @@ static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, st + set_bit(XPT_CLOSE, &xprt->xpt_flags); + svc_xprt_enqueue(xprt); + } +- spin_unlock(&serv->sv_lock); ++ spin_unlock_bh(&serv->sv_lock); + return ret; + } + +diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +index 5e7c4ba9e1476..c5154bc38e129 100644 +--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c ++++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +@@ -246,9 +246,9 @@ xprt_setup_rdma_bc(struct xprt_create *args) + xprt->timeout = &xprt_rdma_bc_timeout; + xprt_set_bound(xprt); + xprt_set_connected(xprt); +- xprt->bind_timeout = RPCRDMA_BIND_TO; +- xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO; +- xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO; ++ xprt->bind_timeout = 0; ++ xprt->reestablish_timeout = 0; ++ xprt->idle_timeout = 0; + + xprt->prot = XPRT_TRANSPORT_BC_RDMA; + xprt->ops = &xprt_rdma_bc_procs; +diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c +index 8e0c0380b4c4b..1a14c083e8cea 100644 +--- a/sound/firewire/dice/dice-stream.c ++++ b/sound/firewire/dice/dice-stream.c +@@ -493,11 +493,10 @@ void snd_dice_stream_stop_duplex(struct snd_dice *dice) + struct reg_params tx_params, rx_params; + + if (dice->substreams_counter == 0) { +- if (get_register_params(dice, &tx_params, &rx_params) >= 0) { +- amdtp_domain_stop(&dice->domain); ++ if (get_register_params(dice, &tx_params, &rx_params) >= 0) + finish_session(dice, &tx_params, &rx_params); +- } + ++ amdtp_domain_stop(&dice->domain); + release_resources(dice); + } + } +diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c +index 8060cc86dfea3..96903295a9677 100644 +--- a/sound/pci/hda/hda_generic.c ++++ b/sound/pci/hda/hda_generic.c +@@ -4065,7 +4065,7 @@ static int add_micmute_led_hook(struct hda_codec *codec) + + spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE; + spec->micmute_led.capture = 0; +- spec->micmute_led.led_value = 0; ++ spec->micmute_led.led_value = -1; + spec->micmute_led.old_hook = spec->cap_sync_hook; + spec->cap_sync_hook = update_micmute_led; + if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl)) +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b47504fa8dfd0..316b9b4ccb32d 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4225,6 +4225,12 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec, + } + } + ++static void alc236_fixup_hp_gpio_led(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ alc_fixup_hp_gpio_led(codec, action, 0x02, 0x01); ++} ++ + static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) + { +@@ -6381,6 +6387,7 @@ enum { + ALC294_FIXUP_ASUS_GX502_VERBS, + ALC285_FIXUP_HP_GPIO_LED, + ALC285_FIXUP_HP_MUTE_LED, ++ ALC236_FIXUP_HP_GPIO_LED, + ALC236_FIXUP_HP_MUTE_LED, + ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, + ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, +@@ -7616,6 +7623,10 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_mute_led, + }, ++ [ALC236_FIXUP_HP_GPIO_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc236_fixup_hp_gpio_led, ++ }, + [ALC236_FIXUP_HP_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led, +@@ -8045,9 +8056,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8783, "HP ZBook Fury 15 G7 Mobile Workstation", + ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), ++ SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), + SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +@@ -8242,7 +8256,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), + SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ + SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), + SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), + SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), + SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), +diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c +index 472caad17012e..85a1d00894a9c 100644 +--- a/sound/soc/codecs/ak4458.c ++++ b/sound/soc/codecs/ak4458.c +@@ -812,6 +812,7 @@ static const struct of_device_id ak4458_of_match[] = { + { .compatible = "asahi-kasei,ak4497", .data = &ak4497_drvdata}, + { }, + }; ++MODULE_DEVICE_TABLE(of, ak4458_of_match); + + static struct i2c_driver ak4458_i2c_driver = { + .driver = { +diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c +index 2f076d5ee284d..65a248c92f669 100644 +--- a/sound/soc/codecs/ak5558.c ++++ b/sound/soc/codecs/ak5558.c +@@ -419,6 +419,7 @@ static const struct of_device_id ak5558_i2c_dt_ids[] = { + { .compatible = "asahi-kasei,ak5558"}, + { } + }; ++MODULE_DEVICE_TABLE(of, ak5558_i2c_dt_ids); + + static struct i2c_driver ak5558_i2c_driver = { + .driver = { +diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c +index 40f682f5dab8b..d18ae5e3ee809 100644 +--- a/sound/soc/codecs/wcd934x.c ++++ b/sound/soc/codecs/wcd934x.c +@@ -1873,6 +1873,12 @@ static int wcd934x_set_channel_map(struct snd_soc_dai *dai, + + wcd = snd_soc_component_get_drvdata(dai->component); + ++ if (tx_num > WCD934X_TX_MAX || rx_num > WCD934X_RX_MAX) { ++ dev_err(wcd->dev, "Invalid tx %d or rx %d channel count\n", ++ tx_num, rx_num); ++ return -EINVAL; ++ } ++ + if (!tx_slot || !rx_slot) { + dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n", + tx_slot, rx_slot); +diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c +index 404be27c15fed..1d774c876c52e 100644 +--- a/sound/soc/fsl/fsl_ssi.c ++++ b/sound/soc/fsl/fsl_ssi.c +@@ -878,6 +878,7 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, + static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) + { + u32 strcr = 0, scr = 0, stcr, srcr, mask; ++ unsigned int slots; + + ssi->dai_fmt = fmt; + +@@ -909,10 +910,11 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) + return -EINVAL; + } + ++ slots = ssi->slots ? : 2; + regmap_update_bits(ssi->regs, REG_SSI_STCCR, +- SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); ++ SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); + regmap_update_bits(ssi->regs, REG_SSI_SRCCR, +- SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); ++ SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); + + /* Data on rising edge of bclk, frame low, 1clk before data */ + strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP | SSI_STCR_TEFS; +diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c +index ab31045cfc952..6cada4c1e283b 100644 +--- a/sound/soc/generic/simple-card-utils.c ++++ b/sound/soc/generic/simple-card-utils.c +@@ -172,15 +172,16 @@ int asoc_simple_parse_clk(struct device *dev, + * or device's module clock. + */ + clk = devm_get_clk_from_child(dev, node, NULL); +- if (IS_ERR(clk)) +- clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); +- + if (!IS_ERR(clk)) { +- simple_dai->clk = clk; + simple_dai->sysclk = clk_get_rate(clk); +- } else if (!of_property_read_u32(node, "system-clock-frequency", +- &val)) { ++ ++ simple_dai->clk = clk; ++ } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { + simple_dai->sysclk = val; ++ } else { ++ clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); ++ if (!IS_ERR(clk)) ++ simple_dai->sysclk = clk_get_rate(clk); + } + + if (of_property_read_bool(node, "system-clock-direction-out")) +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index d56db9f34373e..d5812e73eb63f 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -577,7 +577,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_JD_SRC_JD1_IN4P | +- BYT_RT5640_OVCD_TH_1500UA | ++ BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MCLK_EN), + }, +diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c +index 3ddd32fd3a44b..4fb2ec7c8867b 100644 +--- a/sound/soc/qcom/lpass-cpu.c ++++ b/sound/soc/qcom/lpass-cpu.c +@@ -737,7 +737,7 @@ static void of_lpass_cpu_parse_dai_data(struct device *dev, + + for_each_child_of_node(dev->of_node, node) { + ret = of_property_read_u32(node, "reg", &id); +- if (ret || id < 0 || id >= data->variant->num_dai) { ++ if (ret || id < 0) { + dev_err(dev, "valid dai id not found: %d\n", ret); + continue; + } +diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c +index 6c2760e27ea6f..153e9b2de0b53 100644 +--- a/sound/soc/qcom/sdm845.c ++++ b/sound/soc/qcom/sdm845.c +@@ -27,18 +27,18 @@ + #define SPK_TDM_RX_MASK 0x03 + #define NUM_TDM_SLOTS 8 + #define SLIM_MAX_TX_PORTS 16 +-#define SLIM_MAX_RX_PORTS 16 ++#define SLIM_MAX_RX_PORTS 13 + #define WCD934X_DEFAULT_MCLK_RATE 9600000 + + struct sdm845_snd_data { + struct snd_soc_jack jack; + bool jack_setup; +- bool stream_prepared[SLIM_MAX_RX_PORTS]; ++ bool stream_prepared[AFE_PORT_MAX]; + struct snd_soc_card *card; + uint32_t pri_mi2s_clk_count; + uint32_t sec_mi2s_clk_count; + uint32_t quat_tdm_clk_count; +- struct sdw_stream_runtime *sruntime[SLIM_MAX_RX_PORTS]; ++ struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; + }; + + static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; +diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c +index cd324f3d11d17..c731b9bd60b4c 100644 +--- a/sound/soc/sof/intel/hda-dsp.c ++++ b/sound/soc/sof/intel/hda-dsp.c +@@ -207,7 +207,7 @@ int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask) + + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, + HDA_DSP_REG_ADSPCS, adspcs, +- !(adspcs & HDA_DSP_ADSPCS_SPA_MASK(core_mask)), ++ !(adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)), + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC); + if (ret < 0) +diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c +index bb4128a72a42f..b0faf050132d8 100644 +--- a/sound/soc/sof/intel/hda.c ++++ b/sound/soc/sof/intel/hda.c +@@ -898,6 +898,7 @@ free_streams: + /* dsp_unmap: not currently used */ + iounmap(sdev->bar[HDA_DSP_BAR]); + hdac_bus_unmap: ++ platform_device_unregister(hdev->dmic_dev); + iounmap(bus->remap_addr); + hda_codec_i915_exit(sdev); + err: +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 448de77f43fd8..5171b3dc1eb9e 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -2883,7 +2883,7 @@ static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_v + u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; + u16 value = elem->value.enumerated.item[0]; + +- kctl->private_value = ((device << SND_DJM_DEVICE_SHIFT) | ++ kctl->private_value = (((unsigned long)device << SND_DJM_DEVICE_SHIFT) | + (group << SND_DJM_GROUP_SHIFT) | + value); + +@@ -2921,7 +2921,7 @@ static int snd_djm_controls_create(struct usb_mixer_interface *mixer, + value = device->controls[i].default_value; + knew.name = device->controls[i].name; + knew.private_value = ( +- (device_idx << SND_DJM_DEVICE_SHIFT) | ++ ((unsigned long)device_idx << SND_DJM_DEVICE_SHIFT) | + (i << SND_DJM_GROUP_SHIFT) | + value); + err = snd_djm_controls_update(mixer, device_idx, i, value); diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.26-27.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.26-27.patch new file mode 100644 index 0000000000..f9d83adf1b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.26-27.patch @@ -0,0 +1,8926 @@ +diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst +index a5d27553d59c9..cd8a585568045 100644 +--- a/Documentation/virt/kvm/api.rst ++++ b/Documentation/virt/kvm/api.rst +@@ -4810,8 +4810,10 @@ If an MSR access is not permitted through the filtering, it generates a + allows user space to deflect and potentially handle various MSR accesses + into user space. + +-If a vCPU is in running state while this ioctl is invoked, the vCPU may +-experience inconsistent filtering behavior on MSR accesses. ++Note, invoking this ioctl with a vCPU is running is inherently racy. However, ++KVM does guarantee that vCPUs will see either the previous filter or the new ++filter, e.g. MSRs with identical settings in both the old and new filter will ++have deterministic behavior. + + + 5. The kvm_run structure +diff --git a/Makefile b/Makefile +index d4b87e604762a..4801cc25e3472 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 26 ++SUBLEVEL = 27 + EXTRAVERSION = + NAME = Dare mighty things + +@@ -265,7 +265,8 @@ no-dot-config-targets := $(clean-targets) \ + $(version_h) headers headers_% archheaders archscripts \ + %asm-generic kernelversion %src-pkg dt_binding_check \ + outputmakefile +-no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease ++no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \ ++ image_name + single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ + + config-build := +diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts +index 73b6b1f89de99..775ceb3acb6c0 100644 +--- a/arch/arm/boot/dts/at91-sam9x60ek.dts ++++ b/arch/arm/boot/dts/at91-sam9x60ek.dts +@@ -334,14 +334,6 @@ + }; + + &pinctrl { +- atmel,mux-mask = < +- /* A B C */ +- 0xFFFFFE7F 0xC0E0397F 0xEF00019D /* pioA */ +- 0x03FFFFFF 0x02FC7E68 0x00780000 /* pioB */ +- 0xffffffff 0xF83FFFFF 0xB800F3FC /* pioC */ +- 0x003FFFFF 0x003F8000 0x00000000 /* pioD */ +- >; +- + adc { + pinctrl_adc_default: adc_default { + atmel,pins = ; +diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi +index b1f994c0ae793..e4824abb385ac 100644 +--- a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi ++++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi +@@ -84,8 +84,8 @@ + pinctrl-0 = <&pinctrl_macb0_default>; + phy-mode = "rmii"; + +- ethernet-phy@0 { +- reg = <0x0>; ++ ethernet-phy@7 { ++ reg = <0x7>; + interrupt-parent = <&pioA>; + interrupts = ; + pinctrl-names = "default"; +diff --git a/arch/arm/boot/dts/imx6ull-myir-mys-6ulx-eval.dts b/arch/arm/boot/dts/imx6ull-myir-mys-6ulx-eval.dts +index ecbb2cc5b9ab4..79cc45728cd2d 100644 +--- a/arch/arm/boot/dts/imx6ull-myir-mys-6ulx-eval.dts ++++ b/arch/arm/boot/dts/imx6ull-myir-mys-6ulx-eval.dts +@@ -14,5 +14,6 @@ + }; + + &gpmi { ++ fsl,use-minimum-ecc; + status = "okay"; + }; +diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi +index 84066c1298df9..ec45ced3cde68 100644 +--- a/arch/arm/boot/dts/sam9x60.dtsi ++++ b/arch/arm/boot/dts/sam9x60.dtsi +@@ -606,6 +606,15 @@ + compatible = "microchip,sam9x60-pinctrl", "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff400 0xfffff400 0x800>; + ++ /* mux-mask corresponding to sam9x60 SoC in TFBGA228L package */ ++ atmel,mux-mask = < ++ /* A B C */ ++ 0xffffffff 0xffe03fff 0xef00019d /* pioA */ ++ 0x03ffffff 0x02fc7e7f 0x00780000 /* pioB */ ++ 0xffffffff 0xffffffff 0xf83fffff /* pioC */ ++ 0x003fffff 0x003f8000 0x00000000 /* pioD */ ++ >; ++ + pioA: gpio@fffff400 { + compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; +diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c +index 62df666c2bd0b..17b66f0d0deef 100644 +--- a/arch/arm/mach-omap2/sr_device.c ++++ b/arch/arm/mach-omap2/sr_device.c +@@ -88,34 +88,26 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, + + extern struct omap_sr_data omap_sr_pdata[]; + +-static int __init sr_dev_init(struct omap_hwmod *oh, void *user) ++static int __init sr_init_by_name(const char *name, const char *voltdm) + { + struct omap_sr_data *sr_data = NULL; + struct omap_volt_data *volt_data; +- struct omap_smartreflex_dev_attr *sr_dev_attr; + static int i; + +- if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) || +- !strncmp(oh->name, "smartreflex_mpu", 16)) ++ if (!strncmp(name, "smartreflex_mpu_iva", 20) || ++ !strncmp(name, "smartreflex_mpu", 16)) + sr_data = &omap_sr_pdata[OMAP_SR_MPU]; +- else if (!strncmp(oh->name, "smartreflex_core", 17)) ++ else if (!strncmp(name, "smartreflex_core", 17)) + sr_data = &omap_sr_pdata[OMAP_SR_CORE]; +- else if (!strncmp(oh->name, "smartreflex_iva", 16)) ++ else if (!strncmp(name, "smartreflex_iva", 16)) + sr_data = &omap_sr_pdata[OMAP_SR_IVA]; + + if (!sr_data) { +- pr_err("%s: Unknown instance %s\n", __func__, oh->name); ++ pr_err("%s: Unknown instance %s\n", __func__, name); + return -EINVAL; + } + +- sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; +- if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { +- pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", +- __func__, oh->name); +- goto exit; +- } +- +- sr_data->name = oh->name; ++ sr_data->name = name; + if (cpu_is_omap343x()) + sr_data->ip_type = 1; + else +@@ -136,10 +128,10 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) + } + } + +- sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); ++ sr_data->voltdm = voltdm_lookup(voltdm); + if (!sr_data->voltdm) { + pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", +- __func__, sr_dev_attr->sensor_voltdm_name); ++ __func__, voltdm); + goto exit; + } + +@@ -160,6 +152,20 @@ exit: + return 0; + } + ++static int __init sr_dev_init(struct omap_hwmod *oh, void *user) ++{ ++ struct omap_smartreflex_dev_attr *sr_dev_attr; ++ ++ sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; ++ if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { ++ pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", ++ __func__, oh->name); ++ return 0; ++ } ++ ++ return sr_init_by_name(oh->name, sr_dev_attr->sensor_voltdm_name); ++} ++ + /* + * API to be called from board files to enable smartreflex + * autocompensation at init. +@@ -169,7 +175,42 @@ void __init omap_enable_smartreflex_on_init(void) + sr_enable_on_init = true; + } + ++static const char * const omap4_sr_instances[] = { ++ "mpu", ++ "iva", ++ "core", ++}; ++ ++static const char * const dra7_sr_instances[] = { ++ "mpu", ++ "core", ++}; ++ + int __init omap_devinit_smartreflex(void) + { ++ const char * const *sr_inst; ++ int i, nr_sr = 0; ++ ++ if (soc_is_omap44xx()) { ++ sr_inst = omap4_sr_instances; ++ nr_sr = ARRAY_SIZE(omap4_sr_instances); ++ ++ } else if (soc_is_dra7xx()) { ++ sr_inst = dra7_sr_instances; ++ nr_sr = ARRAY_SIZE(dra7_sr_instances); ++ } ++ ++ if (nr_sr) { ++ const char *name, *voltdm; ++ ++ for (i = 0; i < nr_sr; i++) { ++ name = kasprintf(GFP_KERNEL, "smartreflex_%s", sr_inst[i]); ++ voltdm = sr_inst[i]; ++ sr_init_by_name(name, voltdm); ++ } ++ ++ return 0; ++ } ++ + return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); + } +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +index 6a2c091990479..5fd3ea2028c64 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +@@ -192,6 +192,7 @@ + ranges = <0x0 0x00 0x1700000 0x100000>; + reg = <0x00 0x1700000 0x0 0x100000>; + interrupts = ; ++ dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.4-job-ring", +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +index 0464b8aa4bc4d..b1b9544d8e7fd 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +@@ -322,6 +322,7 @@ + ranges = <0x0 0x00 0x1700000 0x100000>; + reg = <0x00 0x1700000 0x0 0x100000>; + interrupts = <0 75 0x4>; ++ dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.4-job-ring", +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +index 0b4545012d43e..acf2ae2e151a0 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +@@ -325,6 +325,7 @@ + ranges = <0x0 0x00 0x1700000 0x100000>; + reg = <0x00 0x1700000 0x0 0x100000>; + interrupts = ; ++ dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.4-job-ring", +diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c +index e6e284265f19d..58303a9ec32c4 100644 +--- a/arch/arm64/kernel/crash_dump.c ++++ b/arch/arm64/kernel/crash_dump.c +@@ -64,5 +64,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) + { + memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); ++ *ppos += count; ++ + return count; + } +diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c +index fa56af1a59c39..dbce0dcf4cc06 100644 +--- a/arch/arm64/kernel/stacktrace.c ++++ b/arch/arm64/kernel/stacktrace.c +@@ -199,8 +199,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) + + #ifdef CONFIG_STACKTRACE + +-void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, +- struct task_struct *task, struct pt_regs *regs) ++noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, ++ void *cookie, struct task_struct *task, ++ struct pt_regs *regs) + { + struct stackframe frame; + +@@ -208,8 +209,8 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, + start_backtrace(&frame, regs->regs[29], regs->pc); + else if (task == current) + start_backtrace(&frame, +- (unsigned long)__builtin_frame_address(0), +- (unsigned long)arch_stack_walk); ++ (unsigned long)__builtin_frame_address(1), ++ (unsigned long)__builtin_return_address(0)); + else + start_backtrace(&frame, thread_saved_fp(task), + thread_saved_pc(task)); +diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h +index 6c6f16e409a87..0d23c00493018 100644 +--- a/arch/ia64/include/asm/syscall.h ++++ b/arch/ia64/include/asm/syscall.h +@@ -32,7 +32,7 @@ static inline void syscall_rollback(struct task_struct *task, + static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) + { +- return regs->r10 == -1 ? regs->r8:0; ++ return regs->r10 == -1 ? -regs->r8:0; + } + + static inline long syscall_get_return_value(struct task_struct *task, +diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c +index 75c070aed81e0..dad3a605cb7e5 100644 +--- a/arch/ia64/kernel/ptrace.c ++++ b/arch/ia64/kernel/ptrace.c +@@ -2010,27 +2010,39 @@ static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data) + { + struct syscall_get_set_args *args = data; + struct pt_regs *pt = args->regs; +- unsigned long *krbs, cfm, ndirty; ++ unsigned long *krbs, cfm, ndirty, nlocals, nouts; + int i, count; + + if (unw_unwind_to_user(info) < 0) + return; + ++ /* ++ * We get here via a few paths: ++ * - break instruction: cfm is shared with caller. ++ * syscall args are in out= regs, locals are non-empty. ++ * - epsinstruction: cfm is set by br.call ++ * locals don't exist. ++ * ++ * For both cases argguments are reachable in cfm.sof - cfm.sol. ++ * CFM: [ ... | sor: 17..14 | sol : 13..7 | sof : 6..0 ] ++ */ + cfm = pt->cr_ifs; ++ nlocals = (cfm >> 7) & 0x7f; /* aka sol */ ++ nouts = (cfm & 0x7f) - nlocals; /* aka sof - sol */ + krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8; + ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); + + count = 0; + if (in_syscall(pt)) +- count = min_t(int, args->n, cfm & 0x7f); ++ count = min_t(int, args->n, nouts); + ++ /* Iterate over outs. */ + for (i = 0; i < count; i++) { ++ int j = ndirty + nlocals + i + args->i; + if (args->rw) +- *ia64_rse_skip_regs(krbs, ndirty + i + args->i) = +- args->args[i]; ++ *ia64_rse_skip_regs(krbs, j) = args->args[i]; + else +- args->args[i] = *ia64_rse_skip_regs(krbs, +- ndirty + i + args->i); ++ args->args[i] = *ia64_rse_skip_regs(krbs, j); + } + + if (!args->rw) { +diff --git a/arch/powerpc/include/asm/dcr-native.h b/arch/powerpc/include/asm/dcr-native.h +index 7141ccea8c94e..a92059964579b 100644 +--- a/arch/powerpc/include/asm/dcr-native.h ++++ b/arch/powerpc/include/asm/dcr-native.h +@@ -53,8 +53,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val) + #define mfdcr(rn) \ + ({unsigned int rval; \ + if (__builtin_constant_p(rn) && rn < 1024) \ +- asm volatile("mfdcr %0," __stringify(rn) \ +- : "=r" (rval)); \ ++ asm volatile("mfdcr %0, %1" : "=r" (rval) \ ++ : "n" (rn)); \ + else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \ + rval = mfdcrx(rn); \ + else \ +@@ -64,8 +64,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val) + #define mtdcr(rn, v) \ + do { \ + if (__builtin_constant_p(rn) && rn < 1024) \ +- asm volatile("mtdcr " __stringify(rn) ",%0" \ +- : : "r" (v)); \ ++ asm volatile("mtdcr %0, %1" \ ++ : : "n" (rn), "r" (v)); \ + else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \ + mtdcrx(rn, v); \ + else \ +diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c +index d92e5eaa4c1d7..a850dccd78ea1 100644 +--- a/arch/sparc/kernel/traps_64.c ++++ b/arch/sparc/kernel/traps_64.c +@@ -275,14 +275,13 @@ bool is_no_fault_exception(struct pt_regs *regs) + asi = (regs->tstate >> 24); /* saved %asi */ + else + asi = (insn >> 5); /* immediate asi */ +- if ((asi & 0xf2) == ASI_PNF) { +- if (insn & 0x1000000) { /* op3[5:4]=3 */ +- handle_ldf_stq(insn, regs); +- return true; +- } else if (insn & 0x200000) { /* op3[2], stores */ ++ if ((asi & 0xf6) == ASI_PNF) { ++ if (insn & 0x200000) /* op3[2], stores */ + return false; +- } +- handle_ld_nf(insn, regs); ++ if (insn & 0x1000000) /* op3[5:4]=3 (fp) */ ++ handle_ldf_stq(insn, regs); ++ else ++ handle_ld_nf(insn, regs); + return true; + } + } +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 7e5f33a0d0e2f..02d4c74d30e2b 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -890,6 +890,12 @@ enum kvm_irqchip_mode { + KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */ + }; + ++struct kvm_x86_msr_filter { ++ u8 count; ++ bool default_allow:1; ++ struct msr_bitmap_range ranges[16]; ++}; ++ + #define APICV_INHIBIT_REASON_DISABLE 0 + #define APICV_INHIBIT_REASON_HYPERV 1 + #define APICV_INHIBIT_REASON_NESTED 2 +@@ -985,14 +991,12 @@ struct kvm_arch { + bool guest_can_read_msr_platform_info; + bool exception_payload_enabled; + ++ bool bus_lock_detection_enabled; ++ + /* Deflect RDMSR and WRMSR to user space when they trigger a #GP */ + u32 user_space_msr_mask; + +- struct { +- u8 count; +- bool default_allow:1; +- struct msr_bitmap_range ranges[16]; +- } msr_filter; ++ struct kvm_x86_msr_filter __rcu *msr_filter; + + struct kvm_pmu_event_filter *pmu_event_filter; + struct task_struct *nx_lpage_recovery_thread; +diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h +index c37f11999d0c0..cbb67b6030f97 100644 +--- a/arch/x86/include/asm/static_call.h ++++ b/arch/x86/include/asm/static_call.h +@@ -37,4 +37,11 @@ + #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \ + __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; nop; nop; nop; nop") + ++ ++#define ARCH_ADD_TRAMP_KEY(name) \ ++ asm(".pushsection .static_call_tramp_key, \"a\" \n" \ ++ ".long " STATIC_CALL_TRAMP_STR(name) " - . \n" \ ++ ".long " STATIC_CALL_KEY_STR(name) " - . \n" \ ++ ".popsection \n") ++ + #endif /* _ASM_STATIC_CALL_H */ +diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h +index ab09af613788b..5941e18edd5a9 100644 +--- a/arch/x86/include/asm/xen/page.h ++++ b/arch/x86/include/asm/xen/page.h +@@ -86,18 +86,6 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, + } + #endif + +-/* +- * The maximum amount of extra memory compared to the base size. The +- * main scaling factor is the size of struct page. At extreme ratios +- * of base:extra, all the base memory can be filled with page +- * structures for the extra memory, leaving no space for anything +- * else. +- * +- * 10x seems like a reasonable balance between scaling flexibility and +- * leaving a practically usable system. +- */ +-#define XEN_EXTRA_MEM_RATIO (10) +- + /* + * Helper functions to write or read unsigned long values to/from + * memory, when the access may fault. +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index fa5f059c2b940..0d8383b82bca4 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1505,35 +1505,44 @@ EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); + + bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) + { ++ struct kvm_x86_msr_filter *msr_filter; ++ struct msr_bitmap_range *ranges; + struct kvm *kvm = vcpu->kvm; +- struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; +- u32 count = kvm->arch.msr_filter.count; +- u32 i; +- bool r = kvm->arch.msr_filter.default_allow; ++ bool allowed; + int idx; ++ u32 i; + +- /* MSR filtering not set up or x2APIC enabled, allow everything */ +- if (!count || (index >= 0x800 && index <= 0x8ff)) ++ /* x2APIC MSRs do not support filtering. */ ++ if (index >= 0x800 && index <= 0x8ff) + return true; + +- /* Prevent collision with set_msr_filter */ + idx = srcu_read_lock(&kvm->srcu); + +- for (i = 0; i < count; i++) { ++ msr_filter = srcu_dereference(kvm->arch.msr_filter, &kvm->srcu); ++ if (!msr_filter) { ++ allowed = true; ++ goto out; ++ } ++ ++ allowed = msr_filter->default_allow; ++ ranges = msr_filter->ranges; ++ ++ for (i = 0; i < msr_filter->count; i++) { + u32 start = ranges[i].base; + u32 end = start + ranges[i].nmsrs; + u32 flags = ranges[i].flags; + unsigned long *bitmap = ranges[i].bitmap; + + if ((index >= start) && (index < end) && (flags & type)) { +- r = !!test_bit(index - start, bitmap); ++ allowed = !!test_bit(index - start, bitmap); + break; + } + } + ++out: + srcu_read_unlock(&kvm->srcu, idx); + +- return r; ++ return allowed; + } + EXPORT_SYMBOL_GPL(kvm_msr_allowed); + +@@ -5291,25 +5300,34 @@ split_irqchip_unlock: + return r; + } + +-static void kvm_clear_msr_filter(struct kvm *kvm) ++static struct kvm_x86_msr_filter *kvm_alloc_msr_filter(bool default_allow) ++{ ++ struct kvm_x86_msr_filter *msr_filter; ++ ++ msr_filter = kzalloc(sizeof(*msr_filter), GFP_KERNEL_ACCOUNT); ++ if (!msr_filter) ++ return NULL; ++ ++ msr_filter->default_allow = default_allow; ++ return msr_filter; ++} ++ ++static void kvm_free_msr_filter(struct kvm_x86_msr_filter *msr_filter) + { + u32 i; +- u32 count = kvm->arch.msr_filter.count; +- struct msr_bitmap_range ranges[16]; + +- mutex_lock(&kvm->lock); +- kvm->arch.msr_filter.count = 0; +- memcpy(ranges, kvm->arch.msr_filter.ranges, count * sizeof(ranges[0])); +- mutex_unlock(&kvm->lock); +- synchronize_srcu(&kvm->srcu); ++ if (!msr_filter) ++ return; ++ ++ for (i = 0; i < msr_filter->count; i++) ++ kfree(msr_filter->ranges[i].bitmap); + +- for (i = 0; i < count; i++) +- kfree(ranges[i].bitmap); ++ kfree(msr_filter); + } + +-static int kvm_add_msr_filter(struct kvm *kvm, struct kvm_msr_filter_range *user_range) ++static int kvm_add_msr_filter(struct kvm_x86_msr_filter *msr_filter, ++ struct kvm_msr_filter_range *user_range) + { +- struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; + struct msr_bitmap_range range; + unsigned long *bitmap = NULL; + size_t bitmap_size; +@@ -5343,11 +5361,9 @@ static int kvm_add_msr_filter(struct kvm *kvm, struct kvm_msr_filter_range *user + goto err; + } + +- /* Everything ok, add this range identifier to our global pool */ +- ranges[kvm->arch.msr_filter.count] = range; +- /* Make sure we filled the array before we tell anyone to walk it */ +- smp_wmb(); +- kvm->arch.msr_filter.count++; ++ /* Everything ok, add this range identifier. */ ++ msr_filter->ranges[msr_filter->count] = range; ++ msr_filter->count++; + + return 0; + err: +@@ -5358,10 +5374,11 @@ err: + static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) + { + struct kvm_msr_filter __user *user_msr_filter = argp; ++ struct kvm_x86_msr_filter *new_filter, *old_filter; + struct kvm_msr_filter filter; + bool default_allow; +- int r = 0; + bool empty = true; ++ int r = 0; + u32 i; + + if (copy_from_user(&filter, user_msr_filter, sizeof(filter))) +@@ -5374,25 +5391,32 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) + if (empty && !default_allow) + return -EINVAL; + +- kvm_clear_msr_filter(kvm); +- +- kvm->arch.msr_filter.default_allow = default_allow; ++ new_filter = kvm_alloc_msr_filter(default_allow); ++ if (!new_filter) ++ return -ENOMEM; + +- /* +- * Protect from concurrent calls to this function that could trigger +- * a TOCTOU violation on kvm->arch.msr_filter.count. +- */ +- mutex_lock(&kvm->lock); + for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) { +- r = kvm_add_msr_filter(kvm, &filter.ranges[i]); +- if (r) +- break; ++ r = kvm_add_msr_filter(new_filter, &filter.ranges[i]); ++ if (r) { ++ kvm_free_msr_filter(new_filter); ++ return r; ++ } + } + ++ mutex_lock(&kvm->lock); ++ ++ /* The per-VM filter is protected by kvm->lock... */ ++ old_filter = srcu_dereference_check(kvm->arch.msr_filter, &kvm->srcu, 1); ++ ++ rcu_assign_pointer(kvm->arch.msr_filter, new_filter); ++ synchronize_srcu(&kvm->srcu); ++ ++ kvm_free_msr_filter(old_filter); ++ + kvm_make_all_cpus_request(kvm, KVM_REQ_MSR_FILTER_CHANGED); + mutex_unlock(&kvm->lock); + +- return r; ++ return 0; + } + + long kvm_arch_vm_ioctl(struct file *filp, +@@ -10423,8 +10447,6 @@ void kvm_arch_pre_destroy_vm(struct kvm *kvm) + + void kvm_arch_destroy_vm(struct kvm *kvm) + { +- u32 i; +- + if (current->mm == kvm->mm) { + /* + * Free memory regions allocated on behalf of userspace, +@@ -10441,8 +10463,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) + } + if (kvm_x86_ops.vm_destroy) + kvm_x86_ops.vm_destroy(kvm); +- for (i = 0; i < kvm->arch.msr_filter.count; i++) +- kfree(kvm->arch.msr_filter.ranges[i].bitmap); ++ kvm_free_msr_filter(srcu_dereference_check(kvm->arch.msr_filter, &kvm->srcu, 1)); + kvm_pic_destroy(kvm); + kvm_ioapic_destroy(kvm); + kvm_free_vcpus(kvm); +diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c +index f80d10d39cf6d..cc85e199108eb 100644 +--- a/arch/x86/mm/mem_encrypt.c ++++ b/arch/x86/mm/mem_encrypt.c +@@ -231,7 +231,7 @@ static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc) + if (pgprot_val(old_prot) == pgprot_val(new_prot)) + return; + +- pa = pfn << page_level_shift(level); ++ pa = pfn << PAGE_SHIFT; + size = page_level_size(level); + + /* +diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c +index 60da7e793385e..56e0f290fef65 100644 +--- a/arch/x86/xen/p2m.c ++++ b/arch/x86/xen/p2m.c +@@ -98,8 +98,8 @@ EXPORT_SYMBOL_GPL(xen_p2m_size); + unsigned long xen_max_p2m_pfn __read_mostly; + EXPORT_SYMBOL_GPL(xen_max_p2m_pfn); + +-#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT +-#define P2M_LIMIT CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT ++#ifdef CONFIG_XEN_MEMORY_HOTPLUG_LIMIT ++#define P2M_LIMIT CONFIG_XEN_MEMORY_HOTPLUG_LIMIT + #else + #define P2M_LIMIT 0 + #endif +@@ -416,9 +416,6 @@ void __init xen_vmalloc_p2m_tree(void) + xen_p2m_last_pfn = xen_max_p2m_pfn; + + p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE; +- if (!p2m_limit && IS_ENABLED(CONFIG_XEN_UNPOPULATED_ALLOC)) +- p2m_limit = xen_start_info->nr_pages * XEN_EXTRA_MEM_RATIO; +- + vm.flags = VM_ALLOC; + vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit), + PMD_SIZE * PMDS_PER_MID_PAGE); +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index 1a3b75652fa4f..8bfc103301077 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -59,6 +59,18 @@ static struct { + } xen_remap_buf __initdata __aligned(PAGE_SIZE); + static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY; + ++/* ++ * The maximum amount of extra memory compared to the base size. The ++ * main scaling factor is the size of struct page. At extreme ratios ++ * of base:extra, all the base memory can be filled with page ++ * structures for the extra memory, leaving no space for anything ++ * else. ++ * ++ * 10x seems like a reasonable balance between scaling flexibility and ++ * leaving a practically usable system. ++ */ ++#define EXTRA_MEM_RATIO (10) ++ + static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB); + + static void __init xen_parse_512gb(void) +@@ -778,13 +790,13 @@ char * __init xen_memory_setup(void) + extra_pages += max_pages - max_pfn; + + /* +- * Clamp the amount of extra memory to a XEN_EXTRA_MEM_RATIO ++ * Clamp the amount of extra memory to a EXTRA_MEM_RATIO + * factor the base size. + * + * Make sure we have no memory above max_pages, as this area + * isn't handled by the p2m management. + */ +- extra_pages = min3(XEN_EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), ++ extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), + extra_pages, max_pages - max_pfn); + i = 0; + addr = xen_e820_table.entries[0].addr; +diff --git a/block/blk-cgroup-rwstat.c b/block/blk-cgroup-rwstat.c +index 85d5790ac49b0..3304e841df7ce 100644 +--- a/block/blk-cgroup-rwstat.c ++++ b/block/blk-cgroup-rwstat.c +@@ -109,6 +109,7 @@ void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol, + + lockdep_assert_held(&blkg->q->queue_lock); + ++ memset(sum, 0, sizeof(*sum)); + rcu_read_lock(); + blkg_for_each_descendant_pre(pos_blkg, pos_css, blkg) { + struct blkg_rwstat *rwstat; +@@ -122,7 +123,7 @@ void blkg_rwstat_recursive_sum(struct blkcg_gq *blkg, struct blkcg_policy *pol, + rwstat = (void *)pos_blkg + off; + + for (i = 0; i < BLKG_RWSTAT_NR; i++) +- sum->cnt[i] = blkg_rwstat_read_counter(rwstat, i); ++ sum->cnt[i] += blkg_rwstat_read_counter(rwstat, i); + } + rcu_read_unlock(); + } +diff --git a/block/blk-merge.c b/block/blk-merge.c +index 97b7c28215652..7cdd566966473 100644 +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -375,6 +375,14 @@ unsigned int blk_recalc_rq_segments(struct request *rq) + switch (bio_op(rq->bio)) { + case REQ_OP_DISCARD: + case REQ_OP_SECURE_ERASE: ++ if (queue_max_discard_segments(rq->q) > 1) { ++ struct bio *bio = rq->bio; ++ ++ for_each_bio(bio) ++ nr_phys_segs++; ++ return nr_phys_segs; ++ } ++ return 1; + case REQ_OP_WRITE_ZEROES: + return 0; + case REQ_OP_WRITE_SAME: +diff --git a/block/blk-zoned.c b/block/blk-zoned.c +index 4676c6f00489c..ab7d7ebcf6ddc 100644 +--- a/block/blk-zoned.c ++++ b/block/blk-zoned.c +@@ -240,7 +240,7 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, + */ + if (op == REQ_OP_ZONE_RESET && + blkdev_allow_reset_all_zones(bdev, sector, nr_sectors)) { +- bio->bi_opf = REQ_OP_ZONE_RESET_ALL; ++ bio->bi_opf = REQ_OP_ZONE_RESET_ALL | REQ_SYNC; + break; + } + +diff --git a/block/genhd.c b/block/genhd.c +index ec6264e2ed671..796baf7612024 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -732,10 +732,8 @@ static void register_disk(struct device *parent, struct gendisk *disk, + disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); + disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); + +- if (disk->flags & GENHD_FL_HIDDEN) { +- dev_set_uevent_suppress(ddev, 0); ++ if (disk->flags & GENHD_FL_HIDDEN) + return; +- } + + disk_scan_partitions(disk); + +diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c +index 3f045b5953b2e..a0c1a665dfc12 100644 +--- a/drivers/acpi/acpica/nsaccess.c ++++ b/drivers/acpi/acpica/nsaccess.c +@@ -99,13 +99,12 @@ acpi_status acpi_ns_root_initialize(void) + * just create and link the new node(s) here. + */ + new_node = +- ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node)); ++ acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name)); + if (!new_node) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + +- ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name); + new_node->descriptor_type = ACPI_DESC_TYPE_NAMED; + new_node->type = init_val->type; + +diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h +index aee023ad02375..a958ad60a3394 100644 +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -9,6 +9,8 @@ + #ifndef _ACPI_INTERNAL_H_ + #define _ACPI_INTERNAL_H_ + ++#include ++ + #define PREFIX "ACPI: " + + int early_acpi_osi_init(void); +@@ -96,9 +98,11 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); + + extern struct list_head acpi_bus_id_list; + ++#define ACPI_MAX_DEVICE_INSTANCES 4096 ++ + struct acpi_device_bus_id { + const char *bus_id; +- unsigned int instance_no; ++ struct ida instance_ida; + struct list_head node; + }; + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index dca5cc423cd41..b47f14ac75ae0 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -482,9 +482,8 @@ static void acpi_device_del(struct acpi_device *device) + list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) + if (!strcmp(acpi_device_bus_id->bus_id, + acpi_device_hid(device))) { +- if (acpi_device_bus_id->instance_no > 0) +- acpi_device_bus_id->instance_no--; +- else { ++ ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no); ++ if (ida_is_empty(&acpi_device_bus_id->instance_ida)) { + list_del(&acpi_device_bus_id->node); + kfree_const(acpi_device_bus_id->bus_id); + kfree(acpi_device_bus_id); +@@ -623,12 +622,38 @@ void acpi_bus_put_acpi_device(struct acpi_device *adev) + put_device(&adev->dev); + } + ++static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) ++{ ++ struct acpi_device_bus_id *acpi_device_bus_id; ++ ++ /* Find suitable bus_id and instance number in acpi_bus_id_list. */ ++ list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { ++ if (!strcmp(acpi_device_bus_id->bus_id, dev_id)) ++ return acpi_device_bus_id; ++ } ++ return NULL; ++} ++ ++static int acpi_device_set_name(struct acpi_device *device, ++ struct acpi_device_bus_id *acpi_device_bus_id) ++{ ++ struct ida *instance_ida = &acpi_device_bus_id->instance_ida; ++ int result; ++ ++ result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL); ++ if (result < 0) ++ return result; ++ ++ device->pnp.instance_no = result; ++ dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, result); ++ return 0; ++} ++ + int acpi_device_add(struct acpi_device *device, + void (*release)(struct device *)) + { ++ struct acpi_device_bus_id *acpi_device_bus_id; + int result; +- struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; +- int found = 0; + + if (device->handle) { + acpi_status status; +@@ -654,41 +679,38 @@ int acpi_device_add(struct acpi_device *device, + INIT_LIST_HEAD(&device->del_list); + mutex_init(&device->physical_node_lock); + +- new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); +- if (!new_bus_id) { +- pr_err(PREFIX "Memory allocation error\n"); +- result = -ENOMEM; +- goto err_detach; +- } +- + mutex_lock(&acpi_device_lock); +- /* +- * Find suitable bus_id and instance number in acpi_bus_id_list +- * If failed, create one and link it into acpi_bus_id_list +- */ +- list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { +- if (!strcmp(acpi_device_bus_id->bus_id, +- acpi_device_hid(device))) { +- acpi_device_bus_id->instance_no++; +- found = 1; +- kfree(new_bus_id); +- break; ++ ++ acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device)); ++ if (acpi_device_bus_id) { ++ result = acpi_device_set_name(device, acpi_device_bus_id); ++ if (result) ++ goto err_unlock; ++ } else { ++ acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id), ++ GFP_KERNEL); ++ if (!acpi_device_bus_id) { ++ result = -ENOMEM; ++ goto err_unlock; + } +- } +- if (!found) { +- acpi_device_bus_id = new_bus_id; + acpi_device_bus_id->bus_id = + kstrdup_const(acpi_device_hid(device), GFP_KERNEL); + if (!acpi_device_bus_id->bus_id) { +- pr_err(PREFIX "Memory allocation error for bus id\n"); ++ kfree(acpi_device_bus_id); + result = -ENOMEM; +- goto err_free_new_bus_id; ++ goto err_unlock; ++ } ++ ++ ida_init(&acpi_device_bus_id->instance_ida); ++ ++ result = acpi_device_set_name(device, acpi_device_bus_id); ++ if (result) { ++ kfree(acpi_device_bus_id); ++ goto err_unlock; + } + +- acpi_device_bus_id->instance_no = 0; + list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); + } +- dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); + + if (device->parent) + list_add_tail(&device->node, &device->parent->children); +@@ -720,13 +742,9 @@ int acpi_device_add(struct acpi_device *device, + list_del(&device->node); + list_del(&device->wakeup_list); + +- err_free_new_bus_id: +- if (!found) +- kfree(new_bus_id); +- ++ err_unlock: + mutex_unlock(&acpi_device_lock); + +- err_detach: + acpi_detach_data(device->handle, acpi_scan_drop_device); + return result; + } +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index 811d298637cb2..83cd4c95faf0d 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -147,6 +147,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + }, + }, + { ++ .callback = video_detect_force_vendor, + .ident = "Sony VPCEH3U1E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c +index 316a9947541fe..b574cce98dc36 100644 +--- a/drivers/atm/eni.c ++++ b/drivers/atm/eni.c +@@ -2260,7 +2260,8 @@ out: + return rc; + + err_eni_release: +- eni_do_release(dev); ++ dev->phy = NULL; ++ iounmap(ENI_DEV(dev)->ioaddr); + err_unregister: + atm_dev_deregister(dev); + err_free_consistent: +diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c +index 3c081b6171a8f..bfca7b8a6f31e 100644 +--- a/drivers/atm/idt77105.c ++++ b/drivers/atm/idt77105.c +@@ -262,7 +262,7 @@ static int idt77105_start(struct atm_dev *dev) + { + unsigned long flags; + +- if (!(dev->dev_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) ++ if (!(dev->phy_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) + return -ENOMEM; + PRIV(dev)->dev = dev; + spin_lock_irqsave(&idt77105_priv_lock, flags); +@@ -337,7 +337,7 @@ static int idt77105_stop(struct atm_dev *dev) + else + idt77105_all = walk->next; + dev->phy = NULL; +- dev->dev_data = NULL; ++ dev->phy_data = NULL; + kfree(walk); + break; + } +diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c +index ac811cfa68431..92edd100a394f 100644 +--- a/drivers/atm/lanai.c ++++ b/drivers/atm/lanai.c +@@ -2234,6 +2234,7 @@ static int lanai_dev_open(struct atm_dev *atmdev) + conf1_write(lanai); + #endif + iounmap(lanai->base); ++ lanai->base = NULL; + error_pci: + pci_disable_device(lanai->pci); + error: +@@ -2246,6 +2247,8 @@ static int lanai_dev_open(struct atm_dev *atmdev) + static void lanai_dev_close(struct atm_dev *atmdev) + { + struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data; ++ if (lanai->base==NULL) ++ return; + printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n", + lanai->number); + lanai_timed_poll_stop(lanai); +@@ -2553,7 +2556,7 @@ static int lanai_init_one(struct pci_dev *pci, + struct atm_dev *atmdev; + int result; + +- lanai = kmalloc(sizeof(*lanai), GFP_KERNEL); ++ lanai = kzalloc(sizeof(*lanai), GFP_KERNEL); + if (lanai == NULL) { + printk(KERN_ERR DEV_LABEL + ": couldn't allocate dev_data structure!\n"); +diff --git a/drivers/atm/uPD98402.c b/drivers/atm/uPD98402.c +index 7850758b5bb82..239852d855589 100644 +--- a/drivers/atm/uPD98402.c ++++ b/drivers/atm/uPD98402.c +@@ -211,7 +211,7 @@ static void uPD98402_int(struct atm_dev *dev) + static int uPD98402_start(struct atm_dev *dev) + { + DPRINTK("phy_start\n"); +- if (!(dev->dev_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) ++ if (!(dev->phy_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) + return -ENOMEM; + spin_lock_init(&PRIV(dev)->lock); + memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats)); +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index bfda153b1a41d..5ef67bacb585e 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -305,7 +305,7 @@ static int rpm_get_suppliers(struct device *dev) + return 0; + } + +-static void rpm_put_suppliers(struct device *dev) ++static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) + { + struct device_link *link; + +@@ -313,10 +313,30 @@ static void rpm_put_suppliers(struct device *dev) + device_links_read_lock_held()) { + + while (refcount_dec_not_one(&link->rpm_active)) +- pm_runtime_put(link->supplier); ++ pm_runtime_put_noidle(link->supplier); ++ ++ if (try_to_suspend) ++ pm_request_idle(link->supplier); + } + } + ++static void rpm_put_suppliers(struct device *dev) ++{ ++ __rpm_put_suppliers(dev, true); ++} ++ ++static void rpm_suspend_suppliers(struct device *dev) ++{ ++ struct device_link *link; ++ int idx = device_links_read_lock(); ++ ++ list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, ++ device_links_read_lock_held()) ++ pm_request_idle(link->supplier); ++ ++ device_links_read_unlock(idx); ++} ++ + /** + * __rpm_callback - Run a given runtime PM callback for a given device. + * @cb: Runtime PM callback to run. +@@ -344,8 +364,10 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + idx = device_links_read_lock(); + + retval = rpm_get_suppliers(dev); +- if (retval) ++ if (retval) { ++ rpm_put_suppliers(dev); + goto fail; ++ } + + device_links_read_unlock(idx); + } +@@ -368,9 +390,9 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + || (dev->power.runtime_status == RPM_RESUMING && retval))) { + idx = device_links_read_lock(); + +- fail: +- rpm_put_suppliers(dev); ++ __rpm_put_suppliers(dev, false); + ++fail: + device_links_read_unlock(idx); + } + +@@ -642,8 +664,11 @@ static int rpm_suspend(struct device *dev, int rpmflags) + goto out; + } + ++ if (dev->power.irq_safe) ++ goto out; ++ + /* Maybe the parent is now able to suspend. */ +- if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { ++ if (parent && !parent->power.ignore_children) { + spin_unlock(&dev->power.lock); + + spin_lock(&parent->power.lock); +@@ -652,6 +677,14 @@ static int rpm_suspend(struct device *dev, int rpmflags) + + spin_lock(&dev->power.lock); + } ++ /* Maybe the suppliers are now able to suspend. */ ++ if (dev->power.links_count > 0) { ++ spin_unlock_irq(&dev->power.lock); ++ ++ rpm_suspend_suppliers(dev); ++ ++ spin_lock_irq(&dev->power.lock); ++ } + + out: + trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); +diff --git a/drivers/block/umem.c b/drivers/block/umem.c +index 2b95d7b33b918..5eb44e4a91eeb 100644 +--- a/drivers/block/umem.c ++++ b/drivers/block/umem.c +@@ -877,6 +877,7 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + if (card->mm_pages[0].desc == NULL || + card->mm_pages[1].desc == NULL) { + dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); ++ ret = -ENOMEM; + goto failed_alloc; + } + reset_page(&card->mm_pages[0]); +@@ -888,8 +889,10 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + spin_lock_init(&card->lock); + + card->queue = blk_alloc_queue(NUMA_NO_NODE); +- if (!card->queue) ++ if (!card->queue) { ++ ret = -ENOMEM; + goto failed_alloc; ++ } + + tasklet_init(&card->tasklet, process_page, (unsigned long)card); + +diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c +index da16121140cab..3874233f7194d 100644 +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -891,7 +891,7 @@ next: + out: + for (i = last_map; i < num; i++) { + /* Don't zap current batch's valid persistent grants. */ +- if(i >= last_map + segs_to_map) ++ if(i >= map_until) + pages[i]->persistent_gnt = NULL; + pages[i]->handle = BLKBACK_INVALID_HANDLE; + } +diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c +index b040447575adc..dcfb32ee5cb60 100644 +--- a/drivers/bus/omap_l3_noc.c ++++ b/drivers/bus/omap_l3_noc.c +@@ -285,7 +285,7 @@ static int omap_l3_probe(struct platform_device *pdev) + */ + l3->debug_irq = platform_get_irq(pdev, 0); + ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, +- 0x0, "l3-dbg-irq", l3); ++ IRQF_NO_THREAD, "l3-dbg-irq", l3); + if (ret) { + dev_err(l3->dev, "request_irq failed for %d\n", + l3->debug_irq); +@@ -294,7 +294,7 @@ static int omap_l3_probe(struct platform_device *pdev) + + l3->app_irq = platform_get_irq(pdev, 1); + ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, +- 0x0, "l3-app-irq", l3); ++ IRQF_NO_THREAD, "l3-app-irq", l3); + if (ret) + dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); + +diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c +index b080739ab0c33..7e80dbd4a3f9f 100644 +--- a/drivers/clk/qcom/gcc-sc7180.c ++++ b/drivers/clk/qcom/gcc-sc7180.c +@@ -620,7 +620,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 5, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_floor_ops, + }, + }; + +@@ -642,7 +642,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 3776d960f405e..1c192a42f11e0 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -103,6 +103,8 @@ static const struct of_device_id whitelist[] __initconst = { + static const struct of_device_id blacklist[] __initconst = { + { .compatible = "allwinner,sun50i-h6", }, + ++ { .compatible = "arm,vexpress", }, ++ + { .compatible = "calxeda,highbank", }, + { .compatible = "calxeda,ecx-2000", }, + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index 49a1f8ce4baa6..863f059bc498a 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -174,7 +174,7 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, + int ret, value; + + ret = request_threaded_irq(event->irq, NULL, event->handler, +- event->irqflags, "ACPI:Event", event); ++ event->irqflags | IRQF_ONESHOT, "ACPI:Event", event); + if (ret) { + dev_err(acpi_gpio->chip->parent, + "Failed to setup interrupt handler for %d\n", +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index 16f73c1023943..ca868271f4c43 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -239,6 +239,7 @@ source "drivers/gpu/drm/arm/Kconfig" + config DRM_RADEON + tristate "ATI Radeon" + depends on DRM && PCI && MMU ++ depends on AGP || !AGP + select FW_LOADER + select DRM_KMS_HELPER + select DRM_TTM +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 1a880cb48d19e..a2425f7ca7597 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -1093,6 +1093,7 @@ static const struct pci_device_id pciidlist[] = { + {0x1002, 0x73A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, + {0x1002, 0x73AB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, + {0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, ++ {0x1002, 0x73AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, + {0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, + + {0, 0, 0} +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +index e2c2eb45a7934..1ea8af48ae2f5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +@@ -146,7 +146,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, + size = mode_cmd->pitches[0] * height; + aligned_size = ALIGN(size, PAGE_SIZE); + ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags, +- ttm_bo_type_kernel, NULL, &gobj); ++ ttm_bo_type_device, NULL, &gobj); + if (ret) { + pr_err("failed to allocate framebuffer (%d)\n", aligned_size); + return -ENOMEM; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +index 15c2ff264ff60..1a347484cf2a1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +@@ -341,8 +341,7 @@ void enc2_hw_init(struct link_encoder *enc) + } else { + AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); + +- AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d); +- ++ AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); + } + + //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index b5fe2a008bd47..7ed4d7c8734f0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -295,7 +295,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { + .num_banks = 8, + .num_chans = 4, + .vmm_page_size_bytes = 4096, +- .dram_clock_change_latency_us = 11.72, ++ .dram_clock_change_latency_us = 23.84, + .return_bus_width_bytes = 64, + .dispclk_dppclk_vco_speed_mhz = 3600, + .xfc_bus_transport_time_us = 4, +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index c5223a9e0d891..b76425164e297 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -524,6 +524,48 @@ static int smu7_force_switch_to_arbf0(struct pp_hwmgr *hwmgr) + tmp, MC_CG_ARB_FREQ_F0); + } + ++static uint16_t smu7_override_pcie_speed(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ uint16_t pcie_gen = 0; ++ ++ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4 && ++ adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN4) ++ pcie_gen = 3; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 && ++ adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ pcie_gen = 2; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 && ++ adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2) ++ pcie_gen = 1; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 && ++ adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1) ++ pcie_gen = 0; ++ ++ return pcie_gen; ++} ++ ++static uint16_t smu7_override_pcie_width(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ uint16_t pcie_width = 0; ++ ++ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) ++ pcie_width = 16; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) ++ pcie_width = 12; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) ++ pcie_width = 8; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) ++ pcie_width = 4; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) ++ pcie_width = 2; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) ++ pcie_width = 1; ++ ++ return pcie_width; ++} ++ + static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr) + { + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); +@@ -620,6 +662,11 @@ static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr) + PP_Min_PCIEGen), + get_pcie_lane_support(data->pcie_lane_cap, + PP_Max_PCIELane)); ++ ++ if (data->pcie_dpm_key_disabled) ++ phm_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, ++ data->dpm_table.pcie_speed_table.count, ++ smu7_override_pcie_speed(hwmgr), smu7_override_pcie_width(hwmgr)); + } + return 0; + } +@@ -1180,6 +1227,13 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr) + NULL)), + "Failed to enable pcie DPM during DPM Start Function!", + return -EINVAL); ++ } else { ++ PP_ASSERT_WITH_CODE( ++ (0 == smum_send_msg_to_smc(hwmgr, ++ PPSMC_MSG_PCIeDPM_Disable, ++ NULL)), ++ "Failed to disble pcie DPM during DPM Start Function!", ++ return -EINVAL); + } + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index 18e4eb8884c26..ed4eafc744d3d 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -54,6 +54,9 @@ + #include "smuio/smuio_9_0_offset.h" + #include "smuio/smuio_9_0_sh_mask.h" + ++#define smnPCIE_LC_SPEED_CNTL 0x11140290 ++#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 ++ + #define HBM_MEMORY_CHANNEL_WIDTH 128 + + static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; +@@ -443,8 +446,7 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + if (PP_CAP(PHM_PlatformCaps_VCEDPM)) + data->smu_features[GNLD_DPM_VCE].supported = true; + +- if (!data->registry_data.pcie_dpm_key_disabled) +- data->smu_features[GNLD_DPM_LINK].supported = true; ++ data->smu_features[GNLD_DPM_LINK].supported = true; + + if (!data->registry_data.dcefclk_dpm_key_disabled) + data->smu_features[GNLD_DPM_DCEFCLK].supported = true; +@@ -1545,6 +1547,13 @@ static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) + pp_table->PcieLaneCount[i] = pcie_width; + } + ++ if (data->registry_data.pcie_dpm_key_disabled) { ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ pp_table->PcieGenSpeed[i] = pcie_gen; ++ pp_table->PcieLaneCount[i] = pcie_width; ++ } ++ } ++ + return 0; + } + +@@ -2967,6 +2976,14 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap) + } + } + ++ if (data->registry_data.pcie_dpm_key_disabled) { ++ PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, ++ false, data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap), ++ "Attempt to Disable Link DPM feature Failed!", return -EINVAL); ++ data->smu_features[GNLD_DPM_LINK].enabled = false; ++ data->smu_features[GNLD_DPM_LINK].supported = false; ++ } ++ + return 0; + } + +@@ -4583,6 +4600,24 @@ static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe + return 0; + } + ++static int vega10_get_current_pcie_link_width_level(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = hwmgr->adev; ++ ++ return (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & ++ PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) ++ >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; ++} ++ ++static int vega10_get_current_pcie_link_speed_level(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = hwmgr->adev; ++ ++ return (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & ++ PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) ++ >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; ++} ++ + static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, char *buf) + { +@@ -4591,8 +4626,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); + struct vega10_single_dpm_table *soc_table = &(data->dpm_table.soc_table); + struct vega10_single_dpm_table *dcef_table = &(data->dpm_table.dcef_table); +- struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table); + struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL; ++ uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width; ++ PPTable_t *pptable = &(data->smc_state_table.pp_table); + + int i, now, size = 0, count = 0; + +@@ -4649,15 +4685,31 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + "*" : ""); + break; + case PP_PCIE: +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex, &now); +- +- for (i = 0; i < pcie_table->count; i++) +- size += sprintf(buf + size, "%d: %s %s\n", i, +- (pcie_table->pcie_gen[i] == 0) ? "2.5GT/s, x1" : +- (pcie_table->pcie_gen[i] == 1) ? "5.0GT/s, x16" : +- (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "", +- (i == now) ? "*" : ""); ++ current_gen_speed = ++ vega10_get_current_pcie_link_speed_level(hwmgr); ++ current_lane_width = ++ vega10_get_current_pcie_link_width_level(hwmgr); ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ gen_speed = pptable->PcieGenSpeed[i]; ++ lane_width = pptable->PcieLaneCount[i]; ++ ++ size += sprintf(buf + size, "%d: %s %s %s\n", i, ++ (gen_speed == 0) ? "2.5GT/s," : ++ (gen_speed == 1) ? "5.0GT/s," : ++ (gen_speed == 2) ? "8.0GT/s," : ++ (gen_speed == 3) ? "16.0GT/s," : "", ++ (lane_width == 1) ? "x1" : ++ (lane_width == 2) ? "x2" : ++ (lane_width == 3) ? "x4" : ++ (lane_width == 4) ? "x8" : ++ (lane_width == 5) ? "x12" : ++ (lane_width == 6) ? "x16" : "", ++ (current_gen_speed == gen_speed) && ++ (current_lane_width == lane_width) ? ++ "*" : ""); ++ } + break; ++ + case OD_SCLK: + if (hwmgr->od_enabled) { + size = sprintf(buf, "%s:\n", "OD_SCLK"); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +index 62076035029ac..e68651fb7ca4c 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +@@ -133,6 +133,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) + data->registry_data.auto_wattman_debug = 0; + data->registry_data.auto_wattman_sample_period = 100; + data->registry_data.auto_wattman_threshold = 50; ++ data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); + } + + static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr) +@@ -539,6 +540,29 @@ static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) + pp_table->PcieLaneCount[i] = pcie_width_arg; + } + ++ /* override to the highest if it's disabled from ppfeaturmask */ ++ if (data->registry_data.pcie_dpm_key_disabled) { ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ ++ pp_table->PcieGenSpeed[i] = pcie_gen; ++ pp_table->PcieLaneCount[i] = pcie_width; ++ } ++ ret = vega12_enable_smc_features(hwmgr, ++ false, ++ data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap); ++ PP_ASSERT_WITH_CODE(!ret, ++ "Attempt to Disable DPM LINK Failed!", ++ return ret); ++ data->smu_features[GNLD_DPM_LINK].enabled = false; ++ data->smu_features[GNLD_DPM_LINK].supported = false; ++ } + return 0; + } + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +index 251979c059c8b..60cde0c528257 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -171,6 +171,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) + data->registry_data.gfxoff_controlled_by_driver = 1; + data->gfxoff_allowed = false; + data->counter_gfxoff = 0; ++ data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); + } + + static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) +@@ -885,6 +886,30 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) + pp_table->PcieLaneCount[i] = pcie_width_arg; + } + ++ /* override to the highest if it's disabled from ppfeaturmask */ ++ if (data->registry_data.pcie_dpm_key_disabled) { ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ ++ pp_table->PcieGenSpeed[i] = pcie_gen; ++ pp_table->PcieLaneCount[i] = pcie_width; ++ } ++ ret = vega20_enable_smc_features(hwmgr, ++ false, ++ data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap); ++ PP_ASSERT_WITH_CODE(!ret, ++ "Attempt to Disable DPM LINK Failed!", ++ return ret); ++ data->smu_features[GNLD_DPM_LINK].enabled = false; ++ data->smu_features[GNLD_DPM_LINK].supported = false; ++ } ++ + return 0; + } + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +index d1533bdc1335e..2b7e85318a76a 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +@@ -675,7 +675,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) + struct page **pages = pvec + pinned; + + ret = pin_user_pages_fast(ptr, num_pages, +- !userptr->ro ? FOLL_WRITE : 0, pages); ++ FOLL_WRITE | FOLL_FORCE, pages); + if (ret < 0) { + unpin_user_pages(pvec, pinned); + kvfree(pvec); +diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +index 7fb36b12fe7a2..6614f67364862 100644 +--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c ++++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +@@ -316,7 +316,18 @@ void i915_vma_revoke_fence(struct i915_vma *vma) + WRITE_ONCE(fence->vma, NULL); + vma->fence = NULL; + +- with_intel_runtime_pm_if_in_use(fence_to_uncore(fence)->rpm, wakeref) ++ /* ++ * Skip the write to HW if and only if the device is currently ++ * suspended. ++ * ++ * If the driver does not currently hold a wakeref (if_in_use == 0), ++ * the device may currently be runtime suspended, or it may be woken ++ * up before the suspend takes place. If the device is not suspended ++ * (powered down) and we skip clearing the fence register, the HW is ++ * left in an undefined state where we may end up with multiple ++ * registers overlapping. ++ */ ++ with_intel_runtime_pm_if_active(fence_to_uncore(fence)->rpm, wakeref) + fence_write(fence); + } + +diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c +index 153ca9e65382e..8b725efb2254c 100644 +--- a/drivers/gpu/drm/i915/intel_runtime_pm.c ++++ b/drivers/gpu/drm/i915/intel_runtime_pm.c +@@ -412,12 +412,20 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm) + } + + /** +- * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use ++ * __intel_runtime_pm_get_if_active - grab a runtime pm reference if device is active + * @rpm: the intel_runtime_pm structure ++ * @ignore_usecount: get a ref even if dev->power.usage_count is 0 + * + * This function grabs a device-level runtime pm reference if the device is +- * already in use and ensures that it is powered up. It is illegal to try +- * and access the HW should intel_runtime_pm_get_if_in_use() report failure. ++ * already active and ensures that it is powered up. It is illegal to try ++ * and access the HW should intel_runtime_pm_get_if_active() report failure. ++ * ++ * If @ignore_usecount=true, a reference will be acquired even if there is no ++ * user requiring the device to be powered up (dev->power.usage_count == 0). ++ * If the function returns false in this case then it's guaranteed that the ++ * device's runtime suspend hook has been called already or that it will be ++ * called (and hence it's also guaranteed that the device's runtime resume ++ * hook will be called eventually). + * + * Any runtime pm reference obtained by this function must have a symmetric + * call to intel_runtime_pm_put() to release the reference again. +@@ -425,7 +433,8 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm) + * Returns: the wakeref cookie to pass to intel_runtime_pm_put(), evaluates + * as True if the wakeref was acquired, or False otherwise. + */ +-intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) ++static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm, ++ bool ignore_usecount) + { + if (IS_ENABLED(CONFIG_PM)) { + /* +@@ -434,7 +443,7 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) + * function, since the power state is undefined. This applies + * atm to the late/early system suspend/resume handlers. + */ +- if (pm_runtime_get_if_in_use(rpm->kdev) <= 0) ++ if (pm_runtime_get_if_active(rpm->kdev, ignore_usecount) <= 0) + return 0; + } + +@@ -443,6 +452,16 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) + return track_intel_runtime_pm_wakeref(rpm); + } + ++intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm) ++{ ++ return __intel_runtime_pm_get_if_active(rpm, false); ++} ++ ++intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm) ++{ ++ return __intel_runtime_pm_get_if_active(rpm, true); ++} ++ + /** + * intel_runtime_pm_get_noresume - grab a runtime pm reference + * @rpm: the intel_runtime_pm structure +diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h +index ae64ff14c6425..1e4ddd11c12bb 100644 +--- a/drivers/gpu/drm/i915/intel_runtime_pm.h ++++ b/drivers/gpu/drm/i915/intel_runtime_pm.h +@@ -177,6 +177,7 @@ void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm); + + intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm); + intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm); ++intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm); + intel_wakeref_t intel_runtime_pm_get_noresume(struct intel_runtime_pm *rpm); + intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); + +@@ -188,6 +189,10 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); + for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \ + intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + ++#define with_intel_runtime_pm_if_active(rpm, wf) \ ++ for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \ ++ intel_runtime_pm_put((rpm), (wf)), (wf) = 0) ++ + void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm); + #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref); +diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c +index a45fe95aff494..3dc65877fa10d 100644 +--- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c ++++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c +@@ -163,7 +163,7 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, + break; + case MSM_DSI_PHY_7NM: + case MSM_DSI_PHY_7NM_V4_1: +- pll = msm_dsi_pll_7nm_init(pdev, id); ++ pll = msm_dsi_pll_7nm_init(pdev, type, id); + break; + default: + pll = ERR_PTR(-ENXIO); +diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h +index 3405982a092c4..bbecb1de5678e 100644 +--- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h ++++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h +@@ -117,10 +117,12 @@ msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) + } + #endif + #ifdef CONFIG_DRM_MSM_DSI_7NM_PHY +-struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id); ++struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, ++ enum msm_dsi_phy_type type, int id); + #else + static inline struct msm_dsi_pll * +-msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) ++msm_dsi_pll_7nm_init(struct platform_device *pdev, ++ enum msm_dsi_phy_type type, int id) + { + return ERR_PTR(-ENODEV); + } +diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +index 93bf142e4a4e6..c1f6708367ae9 100644 +--- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +@@ -852,7 +852,8 @@ err_base_clk_hw: + return ret; + } + +-struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) ++struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, ++ enum msm_dsi_phy_type type, int id) + { + struct dsi_pll_7nm *pll_7nm; + struct msm_dsi_pll *pll; +@@ -885,7 +886,7 @@ struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id) + pll = &pll_7nm->base; + pll->min_rate = 1000000000UL; + pll->max_rate = 3500000000UL; +- if (pll->type == MSM_DSI_PHY_7NM_V4_1) { ++ if (type == MSM_DSI_PHY_7NM_V4_1) { + pll->min_rate = 600000000UL; + pll->max_rate = (unsigned long)5000000000ULL; + /* workaround for max rate overflowing on 32-bit builds: */ +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index 3d0adfa6736a5..b38ebccad42ff 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -1079,6 +1079,10 @@ static int __maybe_unused msm_pm_resume(struct device *dev) + static int __maybe_unused msm_pm_prepare(struct device *dev) + { + struct drm_device *ddev = dev_get_drvdata(dev); ++ struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL; ++ ++ if (!priv || !priv->kms) ++ return 0; + + return drm_mode_config_helper_suspend(ddev); + } +@@ -1086,6 +1090,10 @@ static int __maybe_unused msm_pm_prepare(struct device *dev) + static void __maybe_unused msm_pm_complete(struct device *dev) + { + struct drm_device *ddev = dev_get_drvdata(dev); ++ struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL; ++ ++ if (!priv || !priv->kms) ++ return; + + drm_mode_config_helper_resume(ddev); + } +@@ -1318,6 +1326,10 @@ static int msm_pdev_remove(struct platform_device *pdev) + static void msm_pdev_shutdown(struct platform_device *pdev) + { + struct drm_device *drm = platform_get_drvdata(pdev); ++ struct msm_drm_private *priv = drm ? drm->dev_private : NULL; ++ ++ if (!priv || !priv->kms) ++ return; + + drm_atomic_helper_shutdown(drm); + } +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 8769e7aa097f4..81903749d2415 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -3610,13 +3610,13 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) + ep->com.local_addr.ss_family == AF_INET) { + err = cxgb4_remove_server_filter( + ep->com.dev->rdev.lldi.ports[0], ep->stid, +- ep->com.dev->rdev.lldi.rxq_ids[0], 0); ++ ep->com.dev->rdev.lldi.rxq_ids[0], false); + } else { + struct sockaddr_in6 *sin6; + c4iw_init_wr_wait(ep->com.wr_waitp); + err = cxgb4_remove_server( + ep->com.dev->rdev.lldi.ports[0], ep->stid, +- ep->com.dev->rdev.lldi.rxq_ids[0], 0); ++ ep->com.dev->rdev.lldi.rxq_ids[0], true); + if (err) + goto done; + err = c4iw_wait_for_reply(&ep->com.dev->rdev, ep->com.wr_waitp, +diff --git a/drivers/irqchip/irq-ingenic-tcu.c b/drivers/irqchip/irq-ingenic-tcu.c +index 7a7222d4c19c0..b938d1d04d96e 100644 +--- a/drivers/irqchip/irq-ingenic-tcu.c ++++ b/drivers/irqchip/irq-ingenic-tcu.c +@@ -179,5 +179,6 @@ err_free_tcu: + } + IRQCHIP_DECLARE(jz4740_tcu_irq, "ingenic,jz4740-tcu", ingenic_tcu_irq_init); + IRQCHIP_DECLARE(jz4725b_tcu_irq, "ingenic,jz4725b-tcu", ingenic_tcu_irq_init); ++IRQCHIP_DECLARE(jz4760_tcu_irq, "ingenic,jz4760-tcu", ingenic_tcu_irq_init); + IRQCHIP_DECLARE(jz4770_tcu_irq, "ingenic,jz4770-tcu", ingenic_tcu_irq_init); + IRQCHIP_DECLARE(x1000_tcu_irq, "ingenic,x1000-tcu", ingenic_tcu_irq_init); +diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c +index b61a8901ef722..ea36bb00be80b 100644 +--- a/drivers/irqchip/irq-ingenic.c ++++ b/drivers/irqchip/irq-ingenic.c +@@ -155,6 +155,7 @@ static int __init intc_2chip_of_init(struct device_node *node, + { + return ingenic_intc_of_init(node, 2); + } ++IRQCHIP_DECLARE(jz4760_intc, "ingenic,jz4760-intc", intc_2chip_of_init); + IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init); + IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init); + IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init); +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index 5e306bba43751..1ca65b434f1fa 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -529,7 +529,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ + * Grab our output buffer. + */ + nl = orig_nl = get_result_buffer(param, param_size, &len); +- if (len < needed) { ++ if (len < needed || len < sizeof(nl->dev)) { + param->flags |= DM_BUFFER_FULL_FLAG; + goto out; + } +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index 9b824c21580a4..5c590895c14c3 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -1387,6 +1387,13 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev, + return !q || blk_queue_zoned_model(q) != *zoned_model; + } + ++/* ++ * Check the device zoned model based on the target feature flag. If the target ++ * has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are ++ * also accepted but all devices must have the same zoned model. If the target ++ * has the DM_TARGET_MIXED_ZONED_MODEL feature set, the devices can have any ++ * zoned model with all zoned devices having the same zone size. ++ */ + static bool dm_table_supports_zoned_model(struct dm_table *t, + enum blk_zoned_model zoned_model) + { +@@ -1396,13 +1403,15 @@ static bool dm_table_supports_zoned_model(struct dm_table *t, + for (i = 0; i < dm_table_get_num_targets(t); i++) { + ti = dm_table_get_target(t, i); + +- if (zoned_model == BLK_ZONED_HM && +- !dm_target_supports_zoned_hm(ti->type)) +- return false; +- +- if (!ti->type->iterate_devices || +- ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model)) +- return false; ++ if (dm_target_supports_zoned_hm(ti->type)) { ++ if (!ti->type->iterate_devices || ++ ti->type->iterate_devices(ti, device_not_zoned_model, ++ &zoned_model)) ++ return false; ++ } else if (!dm_target_supports_mixed_zoned_model(ti->type)) { ++ if (zoned_model == BLK_ZONED_HM) ++ return false; ++ } + } + + return true; +@@ -1414,9 +1423,17 @@ static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev * + struct request_queue *q = bdev_get_queue(dev->bdev); + unsigned int *zone_sectors = data; + ++ if (!blk_queue_is_zoned(q)) ++ return 0; ++ + return !q || blk_queue_zone_sectors(q) != *zone_sectors; + } + ++/* ++ * Check consistency of zoned model and zone sectors across all targets. For ++ * zone sectors, if the destination device is a zoned block device, it shall ++ * have the specified zone_sectors. ++ */ + static int validate_hardware_zoned_model(struct dm_table *table, + enum blk_zoned_model zoned_model, + unsigned int zone_sectors) +@@ -1435,7 +1452,7 @@ static int validate_hardware_zoned_model(struct dm_table *table, + return -EINVAL; + + if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) { +- DMERR("%s: zone sectors is not consistent across all devices", ++ DMERR("%s: zone sectors is not consistent across all zoned devices", + dm_device_name(table->md)); + return -EINVAL; + } +diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c +index 6b8e5bdd8526d..808a98ef624c3 100644 +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -34,7 +34,7 @@ + #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" + #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" + +-#define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC + \ ++#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \ + DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) + + static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; +diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c +index 697f9de37355e..7e88df64d197b 100644 +--- a/drivers/md/dm-zoned-target.c ++++ b/drivers/md/dm-zoned-target.c +@@ -1143,7 +1143,7 @@ static int dmz_message(struct dm_target *ti, unsigned int argc, char **argv, + static struct target_type dmz_type = { + .name = "zoned", + .version = {2, 0, 0}, +- .features = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM, ++ .features = DM_TARGET_SINGLETON | DM_TARGET_MIXED_ZONED_MODEL, + .module = THIS_MODULE, + .ctr = dmz_ctr, + .dtr = dmz_dtr, +diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c +index 71b3a4d5adc65..7b0bf470795c4 100644 +--- a/drivers/misc/habanalabs/common/device.c ++++ b/drivers/misc/habanalabs/common/device.c +@@ -106,6 +106,8 @@ static int hl_device_release_ctrl(struct inode *inode, struct file *filp) + list_del(&hpriv->dev_node); + mutex_unlock(&hdev->fpriv_list_lock); + ++ put_pid(hpriv->taskpid); ++ + kfree(hpriv); + + return 0; +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 6d5a39af10978..47afc5938c26b 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3918,15 +3918,11 @@ static int bond_neigh_init(struct neighbour *n) + + rcu_read_lock(); + slave = bond_first_slave_rcu(bond); +- if (!slave) { +- ret = -EINVAL; ++ if (!slave) + goto out; +- } + slave_ops = slave->dev->netdev_ops; +- if (!slave_ops->ndo_neigh_setup) { +- ret = -EINVAL; ++ if (!slave_ops->ndo_neigh_setup) + goto out; +- } + + /* TODO: find another way [1] to implement this. + * Passing a zeroed structure is fragile, +diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c +index 1a9e9b9a4bf6c..6c75e5897620d 100644 +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -212,18 +212,6 @@ static const struct can_bittiming_const c_can_bittiming_const = { + .brp_inc = 1, + }; + +-static inline void c_can_pm_runtime_enable(const struct c_can_priv *priv) +-{ +- if (priv->device) +- pm_runtime_enable(priv->device); +-} +- +-static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv) +-{ +- if (priv->device) +- pm_runtime_disable(priv->device); +-} +- + static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv) + { + if (priv->device) +@@ -1335,7 +1323,6 @@ static const struct net_device_ops c_can_netdev_ops = { + + int register_c_can_dev(struct net_device *dev) + { +- struct c_can_priv *priv = netdev_priv(dev); + int err; + + /* Deactivate pins to prevent DRA7 DCAN IP from being +@@ -1345,28 +1332,19 @@ int register_c_can_dev(struct net_device *dev) + */ + pinctrl_pm_select_sleep_state(dev->dev.parent); + +- c_can_pm_runtime_enable(priv); +- + dev->flags |= IFF_ECHO; /* we support local echo */ + dev->netdev_ops = &c_can_netdev_ops; + + err = register_candev(dev); +- if (err) +- c_can_pm_runtime_disable(priv); +- else ++ if (!err) + devm_can_led_init(dev); +- + return err; + } + EXPORT_SYMBOL_GPL(register_c_can_dev); + + void unregister_c_can_dev(struct net_device *dev) + { +- struct c_can_priv *priv = netdev_priv(dev); +- + unregister_candev(dev); +- +- c_can_pm_runtime_disable(priv); + } + EXPORT_SYMBOL_GPL(unregister_c_can_dev); + +diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c +index 406b4847e5dc3..7efb60b508762 100644 +--- a/drivers/net/can/c_can/c_can_pci.c ++++ b/drivers/net/can/c_can/c_can_pci.c +@@ -239,12 +239,13 @@ static void c_can_pci_remove(struct pci_dev *pdev) + { + struct net_device *dev = pci_get_drvdata(pdev); + struct c_can_priv *priv = netdev_priv(dev); ++ void __iomem *addr = priv->base; + + unregister_c_can_dev(dev); + + free_c_can_dev(dev); + +- pci_iounmap(pdev, priv->base); ++ pci_iounmap(pdev, addr); + pci_disable_msi(pdev); + pci_clear_master(pdev); + pci_release_regions(pdev); +diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c +index 05f425ceb53a2..47b251b1607ce 100644 +--- a/drivers/net/can/c_can/c_can_platform.c ++++ b/drivers/net/can/c_can/c_can_platform.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -386,6 +387,7 @@ static int c_can_plat_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + ++ pm_runtime_enable(priv->device); + ret = register_c_can_dev(dev); + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", +@@ -398,6 +400,7 @@ static int c_can_plat_probe(struct platform_device *pdev) + return 0; + + exit_free_device: ++ pm_runtime_disable(priv->device); + free_c_can_dev(dev); + exit: + dev_err(&pdev->dev, "probe failed\n"); +@@ -408,9 +411,10 @@ exit: + static int c_can_plat_remove(struct platform_device *pdev) + { + struct net_device *dev = platform_get_drvdata(pdev); ++ struct c_can_priv *priv = netdev_priv(dev); + + unregister_c_can_dev(dev); +- ++ pm_runtime_disable(priv->device); + free_c_can_dev(dev); + + return 0; +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +index 24cd3c1027ecc..dc9b4aae3abb6 100644 +--- a/drivers/net/can/dev.c ++++ b/drivers/net/can/dev.c +@@ -1255,6 +1255,7 @@ static void can_dellink(struct net_device *dev, struct list_head *head) + + static struct rtnl_link_ops can_link_ops __read_mostly = { + .kind = "can", ++ .netns_refund = true, + .maxtype = IFLA_CAN_MAX, + .policy = can_policy, + .setup = can_setup, +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index d712c6fdbc87d..7cbaac238ff62 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -658,9 +658,15 @@ static int flexcan_chip_disable(struct flexcan_priv *priv) + static int flexcan_chip_freeze(struct flexcan_priv *priv) + { + struct flexcan_regs __iomem *regs = priv->regs; +- unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; ++ unsigned int timeout; ++ u32 bitrate = priv->can.bittiming.bitrate; + u32 reg; + ++ if (bitrate) ++ timeout = 1000 * 1000 * 10 / bitrate; ++ else ++ timeout = FLEXCAN_TIMEOUT_US / 10; ++ + reg = priv->read(®s->mcr); + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; + priv->write(reg, ®s->mcr); +diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c +index 43151dd6cb1c3..99323c273aa56 100644 +--- a/drivers/net/can/kvaser_pciefd.c ++++ b/drivers/net/can/kvaser_pciefd.c +@@ -57,6 +57,7 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices"); + #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 + #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c + #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 ++#define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424 + #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 + #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 + /* Loopback control register */ +@@ -949,6 +950,9 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) + timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, + 0); + ++ /* Disable Bus load reporting */ ++ iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); ++ + tx_npackets = ioread32(can->reg_base + + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG); + if (((tx_npackets >> KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT) & +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index 3c1e379751683..6f0bf5db885cd 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -502,9 +502,6 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota) + } + + while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { +- if (rxfs & RXFS_RFL) +- netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); +- + m_can_read_fifo(dev, rxfs); + + quota--; +@@ -885,7 +882,7 @@ static int m_can_rx_peripheral(struct net_device *dev) + { + struct m_can_classdev *cdev = netdev_priv(dev); + +- m_can_rx_handler(dev, 1); ++ m_can_rx_handler(dev, M_CAN_NAPI_WEIGHT); + + m_can_enable_all_interrupts(cdev); + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index f504b6858ed29..52100d4fe5a25 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1070,13 +1070,6 @@ static int b53_setup(struct dsa_switch *ds) + b53_disable_port(ds, port); + } + +- /* Let DSA handle the case were multiple bridges span the same switch +- * device and different VLAN awareness settings are requested, which +- * would be breaking filtering semantics for any of the other bridge +- * devices. (not hardware supported) +- */ +- ds->vlan_filtering_is_global = true; +- + return b53_setup_devlink_resources(ds); + } + +@@ -2627,6 +2620,13 @@ struct b53_device *b53_switch_alloc(struct device *base, + ds->configure_vlan_while_not_filtering = true; + ds->untag_bridge_pvid = true; + dev->vlan_enabled = ds->configure_vlan_while_not_filtering; ++ /* Let DSA handle the case were multiple bridges span the same switch ++ * device and different VLAN awareness settings are requested, which ++ * would be breaking filtering semantics for any of the other bridge ++ * devices. (not hardware supported) ++ */ ++ ds->vlan_filtering_is_global = true; ++ + mutex_init(&dev->reg_mutex); + mutex_init(&dev->stats_mutex); + +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index edb0a1027b38f..510324916e916 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -584,8 +584,10 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) + * in bits 15:8 and the patch level in bits 7:0 which is exactly what + * the REG_PHY_REVISION register layout is. + */ +- +- return priv->hw_params.gphy_rev; ++ if (priv->int_phy_mask & BIT(port)) ++ return priv->hw_params.gphy_rev; ++ else ++ return 0; + } + + static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, +diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +index 1b7e8c91b5417..423d6d78d15c7 100644 +--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +@@ -727,7 +727,7 @@ static int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input) + kvfree(tx_info); + return 0; + } +- tx_info->open_state = false; ++ tx_info->open_state = CH_KTLS_OPEN_SUCCESS; + spin_unlock(&tx_info->lock); + + complete(&tx_info->completion); +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index ba7f857d1710d..ae09cac876028 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -1510,7 +1510,7 @@ dm9000_probe(struct platform_device *pdev) + goto out; + } + +- db->irq_wake = platform_get_irq(pdev, 1); ++ db->irq_wake = platform_get_irq_optional(pdev, 1); + if (db->irq_wake >= 0) { + dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake); + +diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c +index 80fb1f537bb33..c9c380c508791 100644 +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -1308,6 +1308,7 @@ static int ftgmac100_poll(struct napi_struct *napi, int budget) + */ + if (unlikely(priv->need_mac_restart)) { + ftgmac100_start_hw(priv); ++ priv->need_mac_restart = false; + + /* Re-enable "bad" interrupts */ + iowrite32(FTGMAC100_INT_BAD, +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +index 21a6ce415cb22..2b90a345507b8 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h ++++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +@@ -234,6 +234,8 @@ enum enetc_bdr_type {TX, RX}; + #define ENETC_PM0_MAXFRM 0x8014 + #define ENETC_SET_TX_MTU(val) ((val) << 16) + #define ENETC_SET_MAXFRM(val) ((val) & 0xffff) ++#define ENETC_PM0_RX_FIFO 0x801c ++#define ENETC_PM0_RX_FIFO_VAL 1 + + #define ENETC_PM_IMDIO_BASE 0x8030 + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +index 83187cd59fddd..68133563a40c1 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +@@ -490,6 +490,12 @@ static void enetc_configure_port_mac(struct enetc_hw *hw) + + enetc_port_wr(hw, ENETC_PM1_CMD_CFG, ENETC_PM0_CMD_PHY_TX_EN | + ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC); ++ ++ /* On LS1028A, the MAC RX FIFO defaults to 2, which is too high ++ * and may lead to RX lock-up under traffic. Set it to 1 instead, ++ * as recommended by the hardware team. ++ */ ++ enetc_port_wr(hw, ENETC_PM0_RX_FIFO, ENETC_PM0_RX_FIFO_VAL); + } + + static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) +diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c +index 2e344aada4c60..1753807cbf97e 100644 +--- a/drivers/net/ethernet/freescale/fec_ptp.c ++++ b/drivers/net/ethernet/freescale/fec_ptp.c +@@ -377,9 +377,16 @@ static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) + u64 ns; + unsigned long flags; + ++ mutex_lock(&adapter->ptp_clk_mutex); ++ /* Check the ptp clock */ ++ if (!adapter->ptp_clk_on) { ++ mutex_unlock(&adapter->ptp_clk_mutex); ++ return -EINVAL; ++ } + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_read(&adapter->tc); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); ++ mutex_unlock(&adapter->ptp_clk_mutex); + + *ts = ns_to_timespec64(ns); + +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index d391a45cebb66..4fab2ee5bbf58 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -2391,6 +2391,10 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus, + if (lstatus & BD_LFLAG(RXBD_LAST)) + size -= skb->len; + ++ WARN(size < 0, "gianfar: rx fragment size underflow"); ++ if (size < 0) ++ return false; ++ + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + rxb->page_offset + RXBUF_ALIGNMENT, + size, GFAR_RXB_TRUESIZE); +@@ -2553,6 +2557,17 @@ static int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, + if (lstatus & BD_LFLAG(RXBD_EMPTY)) + break; + ++ /* lost RXBD_LAST descriptor due to overrun */ ++ if (skb && ++ (lstatus & BD_LFLAG(RXBD_FIRST))) { ++ /* discard faulty buffer */ ++ dev_kfree_skb(skb); ++ skb = NULL; ++ rx_queue->stats.rx_dropped++; ++ ++ /* can continue normally */ ++ } ++ + /* order rx buffer descriptor reads */ + rmb(); + +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +index 858cb293152a9..8bce5f1510bec 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -1663,8 +1663,10 @@ static int hns_nic_clear_all_rx_fetch(struct net_device *ndev) + for (j = 0; j < fetch_num; j++) { + /* alloc one skb and init */ + skb = hns_assemble_skb(ndev); +- if (!skb) ++ if (!skb) { ++ ret = -ENOMEM; + goto out; ++ } + rd = &tx_ring_data(priv, skb->queue_mapping); + hns_nic_net_xmit_hw(ndev, skb, rd); + +diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c +index 88faf05e23baf..0b1e890dd583b 100644 +--- a/drivers/net/ethernet/intel/e1000e/82571.c ++++ b/drivers/net/ethernet/intel/e1000e/82571.c +@@ -899,6 +899,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) + } else { + data &= ~IGP02E1000_PM_D0_LPLU; + ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); ++ if (ret_val) ++ return ret_val; + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + * during Dx states where the power conservation is most + * important. During driver activity we should enable +diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c +index e9b82c209c2df..a0948002ddf85 100644 +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -5974,15 +5974,19 @@ static void e1000_reset_task(struct work_struct *work) + struct e1000_adapter *adapter; + adapter = container_of(work, struct e1000_adapter, reset_task); + ++ rtnl_lock(); + /* don't run the task if already down */ +- if (test_bit(__E1000_DOWN, &adapter->state)) ++ if (test_bit(__E1000_DOWN, &adapter->state)) { ++ rtnl_unlock(); + return; ++ } + + if (!(adapter->flags & FLAG_RESTART_NOW)) { + e1000e_dump(adapter); + e_err("Reset adapter unexpectedly\n"); + } + e1000e_reinit_locked(adapter); ++ rtnl_unlock(); + } + + /** +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index 0a867d64d4675..dc5b3c06d1e01 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1776,7 +1776,8 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter) + goto err_alloc; + } + +- if (iavf_process_config(adapter)) ++ err = iavf_process_config(adapter); ++ if (err) + goto err_alloc; + adapter->current_op = VIRTCHNL_OP_UNKNOWN; + +diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h +index aaa954aae5744..7bda8c5edea5d 100644 +--- a/drivers/net/ethernet/intel/igb/igb.h ++++ b/drivers/net/ethernet/intel/igb/igb.h +@@ -748,8 +748,8 @@ void igb_ptp_suspend(struct igb_adapter *adapter); + void igb_ptp_rx_hang(struct igb_adapter *adapter); + void igb_ptp_tx_hang(struct igb_adapter *adapter); + void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); +-void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, +- struct sk_buff *skb); ++int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, ++ struct sk_buff *skb); + int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); + int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); + void igb_set_flag_queue_pairs(struct igb_adapter *, const u32); +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 0d343d0509739..fecfcfcf161ca 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -8232,7 +8232,8 @@ static inline bool igb_page_is_reserved(struct page *page) + return (page_to_nid(page) != numa_mem_id()) || page_is_pfmemalloc(page); + } + +-static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer) ++static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, ++ int rx_buf_pgcnt) + { + unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; + struct page *page = rx_buffer->page; +@@ -8243,7 +8244,7 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer) + + #if (PAGE_SIZE < 8192) + /* if we are only owner of page we can reuse it */ +- if (unlikely((page_ref_count(page) - pagecnt_bias) > 1)) ++ if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1)) + return false; + #else + #define IGB_LAST_OFFSET \ +@@ -8319,9 +8320,10 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring, + return NULL; + + if (unlikely(igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))) { +- igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb); +- xdp->data += IGB_TS_HDR_LEN; +- size -= IGB_TS_HDR_LEN; ++ if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb)) { ++ xdp->data += IGB_TS_HDR_LEN; ++ size -= IGB_TS_HDR_LEN; ++ } + } + + /* Determine available headroom for copy */ +@@ -8382,8 +8384,8 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring, + + /* pull timestamp out of packet data */ + if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { +- igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb); +- __skb_pull(skb, IGB_TS_HDR_LEN); ++ if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb)) ++ __skb_pull(skb, IGB_TS_HDR_LEN); + } + + /* update buffer offset */ +@@ -8632,11 +8634,17 @@ static unsigned int igb_rx_offset(struct igb_ring *rx_ring) + } + + static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring, +- const unsigned int size) ++ const unsigned int size, int *rx_buf_pgcnt) + { + struct igb_rx_buffer *rx_buffer; + + rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; ++ *rx_buf_pgcnt = ++#if (PAGE_SIZE < 8192) ++ page_count(rx_buffer->page); ++#else ++ 0; ++#endif + prefetchw(rx_buffer->page); + + /* we are reusing so sync this buffer for CPU use */ +@@ -8652,9 +8660,9 @@ static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring, + } + + static void igb_put_rx_buffer(struct igb_ring *rx_ring, +- struct igb_rx_buffer *rx_buffer) ++ struct igb_rx_buffer *rx_buffer, int rx_buf_pgcnt) + { +- if (igb_can_reuse_rx_page(rx_buffer)) { ++ if (igb_can_reuse_rx_page(rx_buffer, rx_buf_pgcnt)) { + /* hand second half of page back to the ring */ + igb_reuse_rx_page(rx_ring, rx_buffer); + } else { +@@ -8681,6 +8689,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + u16 cleaned_count = igb_desc_unused(rx_ring); + unsigned int xdp_xmit = 0; + struct xdp_buff xdp; ++ int rx_buf_pgcnt; + + xdp.rxq = &rx_ring->xdp_rxq; + +@@ -8711,7 +8720,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + */ + dma_rmb(); + +- rx_buffer = igb_get_rx_buffer(rx_ring, size); ++ rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); + + /* retrieve a buffer from the ring */ + if (!skb) { +@@ -8754,7 +8763,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + break; + } + +- igb_put_rx_buffer(rx_ring, rx_buffer); ++ igb_put_rx_buffer(rx_ring, rx_buffer, rx_buf_pgcnt); + cleaned_count++; + + /* fetch next buffer in frame if non-eop */ +diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c +index 7cc5428c3b3d2..86a576201f5ff 100644 +--- a/drivers/net/ethernet/intel/igb/igb_ptp.c ++++ b/drivers/net/ethernet/intel/igb/igb_ptp.c +@@ -856,6 +856,9 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) + dev_kfree_skb_any(skb); + } + ++#define IGB_RET_PTP_DISABLED 1 ++#define IGB_RET_PTP_INVALID 2 ++ + /** + * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp + * @q_vector: Pointer to interrupt specific structure +@@ -864,19 +867,29 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) + * + * This function is meant to retrieve a timestamp from the first buffer of an + * incoming frame. The value is stored in little endian format starting on +- * byte 8. ++ * byte 8 ++ * ++ * Returns: 0 if success, nonzero if failure + **/ +-void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, +- struct sk_buff *skb) ++int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, ++ struct sk_buff *skb) + { +- __le64 *regval = (__le64 *)va; + struct igb_adapter *adapter = q_vector->adapter; ++ __le64 *regval = (__le64 *)va; + int adjust = 0; + ++ if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) ++ return IGB_RET_PTP_DISABLED; ++ + /* The timestamp is recorded in little endian format. + * DWORD: 0 1 2 3 + * Field: Reserved Reserved SYSTIML SYSTIMH + */ ++ ++ /* check reserved dwords are zero, be/le doesn't matter for zero */ ++ if (regval[0]) ++ return IGB_RET_PTP_INVALID; ++ + igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), + le64_to_cpu(regval[1])); + +@@ -896,6 +909,8 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, + } + skb_hwtstamps(skb)->hwtstamp = + ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); ++ ++ return 0; + } + + /** +@@ -906,13 +921,15 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, + * This function is meant to retrieve a timestamp from the internal registers + * of the adapter and store it in the skb. + **/ +-void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, +- struct sk_buff *skb) ++void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) + { + struct igb_adapter *adapter = q_vector->adapter; + struct e1000_hw *hw = &adapter->hw; +- u64 regval; + int adjust = 0; ++ u64 regval; ++ ++ if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) ++ return; + + /* If this bit is set, then the RX registers contain the time stamp. No + * other packet will be time stamped until we read these registers, so +diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h +index 35baae900c1fd..6dca67d9c25d8 100644 +--- a/drivers/net/ethernet/intel/igc/igc.h ++++ b/drivers/net/ethernet/intel/igc/igc.h +@@ -545,7 +545,7 @@ void igc_ptp_init(struct igc_adapter *adapter); + void igc_ptp_reset(struct igc_adapter *adapter); + void igc_ptp_suspend(struct igc_adapter *adapter); + void igc_ptp_stop(struct igc_adapter *adapter); +-void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va, ++void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, __le32 *va, + struct sk_buff *skb); + int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); + int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); +diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c +index ec8cd69d49928..da259cd59adda 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -1695,6 +1695,9 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, + Autoneg); + } + ++ /* Set pause flow control settings */ ++ ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); ++ + switch (hw->fc.requested_mode) { + case igc_fc_full: + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); +@@ -1709,9 +1712,7 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, + Asym_Pause); + break; + default: +- ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); +- ethtool_link_ksettings_add_link_mode(cmd, advertising, +- Asym_Pause); ++ break; + } + + status = pm_runtime_suspended(&adapter->pdev->dev) ? +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index b673ac1199bbc..7b822cdcc6c58 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -3846,10 +3846,19 @@ static void igc_reset_task(struct work_struct *work) + + adapter = container_of(work, struct igc_adapter, reset_task); + ++ rtnl_lock(); ++ /* If we're already down or resetting, just bail */ ++ if (test_bit(__IGC_DOWN, &adapter->state) || ++ test_bit(__IGC_RESETTING, &adapter->state)) { ++ rtnl_unlock(); ++ return; ++ } ++ + igc_rings_dump(adapter); + igc_regs_dump(adapter); + netdev_err(adapter->netdev, "Reset adapter\n"); + igc_reinit_locked(adapter); ++ rtnl_unlock(); + } + + /** +diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c +index ac0b9c85da7ca..545f4d0e67cf4 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ptp.c ++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c +@@ -152,46 +152,54 @@ static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter, + } + + /** +- * igc_ptp_rx_pktstamp - retrieve Rx per packet timestamp ++ * igc_ptp_rx_pktstamp - Retrieve timestamp from Rx packet buffer + * @q_vector: Pointer to interrupt specific structure + * @va: Pointer to address containing Rx buffer + * @skb: Buffer containing timestamp and packet + * +- * This function is meant to retrieve the first timestamp from the +- * first buffer of an incoming frame. The value is stored in little +- * endian format starting on byte 0. There's a second timestamp +- * starting on byte 8. +- **/ +-void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va, ++ * This function retrieves the timestamp saved in the beginning of packet ++ * buffer. While two timestamps are available, one in timer0 reference and the ++ * other in timer1 reference, this function considers only the timestamp in ++ * timer0 reference. ++ */ ++void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, __le32 *va, + struct sk_buff *skb) + { + struct igc_adapter *adapter = q_vector->adapter; +- __le64 *regval = (__le64 *)va; +- int adjust = 0; +- +- /* The timestamp is recorded in little endian format. +- * DWORD: | 0 | 1 | 2 | 3 +- * Field: | Timer0 Low | Timer0 High | Timer1 Low | Timer1 High ++ u64 regval; ++ int adjust; ++ ++ /* Timestamps are saved in little endian at the beginning of the packet ++ * buffer following the layout: ++ * ++ * DWORD: | 0 | 1 | 2 | 3 | ++ * Field: | Timer1 SYSTIML | Timer1 SYSTIMH | Timer0 SYSTIML | Timer0 SYSTIMH | ++ * ++ * SYSTIML holds the nanoseconds part while SYSTIMH holds the seconds ++ * part of the timestamp. + */ +- igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), +- le64_to_cpu(regval[0])); +- +- /* adjust timestamp for the RX latency based on link speed */ +- if (adapter->hw.mac.type == igc_i225) { +- switch (adapter->link_speed) { +- case SPEED_10: +- adjust = IGC_I225_RX_LATENCY_10; +- break; +- case SPEED_100: +- adjust = IGC_I225_RX_LATENCY_100; +- break; +- case SPEED_1000: +- adjust = IGC_I225_RX_LATENCY_1000; +- break; +- case SPEED_2500: +- adjust = IGC_I225_RX_LATENCY_2500; +- break; +- } ++ regval = le32_to_cpu(va[2]); ++ regval |= (u64)le32_to_cpu(va[3]) << 32; ++ igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); ++ ++ /* Adjust timestamp for the RX latency based on link speed */ ++ switch (adapter->link_speed) { ++ case SPEED_10: ++ adjust = IGC_I225_RX_LATENCY_10; ++ break; ++ case SPEED_100: ++ adjust = IGC_I225_RX_LATENCY_100; ++ break; ++ case SPEED_1000: ++ adjust = IGC_I225_RX_LATENCY_1000; ++ break; ++ case SPEED_2500: ++ adjust = IGC_I225_RX_LATENCY_2500; ++ break; ++ default: ++ adjust = 0; ++ netdev_warn_once(adapter->netdev, "Imprecise timestamp\n"); ++ break; + } + skb_hwtstamps(skb)->hwtstamp = + ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index f3f449f53920f..278fc866fad49 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -9582,8 +9582,10 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, + ixgbe_atr_compute_perfect_hash_82599(&input->filter, mask); + err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter, + input->sw_idx, queue); +- if (!err) +- ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); ++ if (err) ++ goto err_out_w_lock; ++ ++ ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); + spin_unlock(&adapter->fdir_perfect_lock); + + if ((uhtid != 0x800) && (adapter->jump_tables[uhtid])) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h +index 91a9d00e4fb51..407b9477da248 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h +@@ -140,6 +140,15 @@ enum npc_kpu_lh_ltype { + NPC_LT_LH_CUSTOM1 = 0xF, + }; + ++/* NPC port kind defines how the incoming or outgoing packets ++ * are processed. NPC accepts packets from up to 64 pkinds. ++ * Software assigns pkind for each incoming port such as CGX ++ * Ethernet interfaces, LBK interfaces, etc. ++ */ ++enum npc_pkind_type { ++ NPC_TX_DEF_PKIND = 63ULL, /* NIX-TX PKIND */ ++}; ++ + struct npc_kpu_profile_cam { + u8 state; + u8 state_mask; +@@ -300,6 +309,28 @@ struct nix_rx_action { + /* NPC_AF_INTFX_KEX_CFG field masks */ + #define NPC_PARSE_NIBBLE GENMASK_ULL(30, 0) + ++/* NPC_PARSE_KEX_S nibble definitions for each field */ ++#define NPC_PARSE_NIBBLE_CHAN GENMASK_ULL(2, 0) ++#define NPC_PARSE_NIBBLE_ERRLEV BIT_ULL(3) ++#define NPC_PARSE_NIBBLE_ERRCODE GENMASK_ULL(5, 4) ++#define NPC_PARSE_NIBBLE_L2L3_BCAST BIT_ULL(6) ++#define NPC_PARSE_NIBBLE_LA_FLAGS GENMASK_ULL(8, 7) ++#define NPC_PARSE_NIBBLE_LA_LTYPE BIT_ULL(9) ++#define NPC_PARSE_NIBBLE_LB_FLAGS GENMASK_ULL(11, 10) ++#define NPC_PARSE_NIBBLE_LB_LTYPE BIT_ULL(12) ++#define NPC_PARSE_NIBBLE_LC_FLAGS GENMASK_ULL(14, 13) ++#define NPC_PARSE_NIBBLE_LC_LTYPE BIT_ULL(15) ++#define NPC_PARSE_NIBBLE_LD_FLAGS GENMASK_ULL(17, 16) ++#define NPC_PARSE_NIBBLE_LD_LTYPE BIT_ULL(18) ++#define NPC_PARSE_NIBBLE_LE_FLAGS GENMASK_ULL(20, 19) ++#define NPC_PARSE_NIBBLE_LE_LTYPE BIT_ULL(21) ++#define NPC_PARSE_NIBBLE_LF_FLAGS GENMASK_ULL(23, 22) ++#define NPC_PARSE_NIBBLE_LF_LTYPE BIT_ULL(24) ++#define NPC_PARSE_NIBBLE_LG_FLAGS GENMASK_ULL(26, 25) ++#define NPC_PARSE_NIBBLE_LG_LTYPE BIT_ULL(27) ++#define NPC_PARSE_NIBBLE_LH_FLAGS GENMASK_ULL(29, 28) ++#define NPC_PARSE_NIBBLE_LH_LTYPE BIT_ULL(30) ++ + /* NIX Receive Vtag Action Structure */ + #define VTAG0_VALID_BIT BIT_ULL(15) + #define VTAG0_TYPE_MASK GENMASK_ULL(14, 12) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h b/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h +index 77bb4ed326005..0e4af93be0fb4 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h +@@ -148,6 +148,20 @@ + (((bytesm1) << 16) | ((hdr_ofs) << 8) | ((ena) << 7) | \ + ((flags_ena) << 6) | ((key_ofs) & 0x3F)) + ++/* Rx parse key extract nibble enable */ ++#define NPC_PARSE_NIBBLE_INTF_RX (NPC_PARSE_NIBBLE_CHAN | \ ++ NPC_PARSE_NIBBLE_LA_LTYPE | \ ++ NPC_PARSE_NIBBLE_LB_LTYPE | \ ++ NPC_PARSE_NIBBLE_LC_LTYPE | \ ++ NPC_PARSE_NIBBLE_LD_LTYPE | \ ++ NPC_PARSE_NIBBLE_LE_LTYPE) ++/* Tx parse key extract nibble enable */ ++#define NPC_PARSE_NIBBLE_INTF_TX (NPC_PARSE_NIBBLE_LA_LTYPE | \ ++ NPC_PARSE_NIBBLE_LB_LTYPE | \ ++ NPC_PARSE_NIBBLE_LC_LTYPE | \ ++ NPC_PARSE_NIBBLE_LD_LTYPE | \ ++ NPC_PARSE_NIBBLE_LE_LTYPE) ++ + enum npc_kpu_parser_state { + NPC_S_NA = 0, + NPC_S_KPU1_ETHER, +@@ -13385,9 +13399,10 @@ static const struct npc_mcam_kex npc_mkex_default = { + .name = "default", + .kpu_version = NPC_KPU_PROFILE_VER, + .keyx_cfg = { +- /* nibble: LA..LE (ltype only) + Channel */ +- [NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | 0x49247, +- [NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) | ((1ULL << 19) - 1), ++ /* nibble: LA..LE (ltype only) + channel */ ++ [NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_RX, ++ /* nibble: LA..LE (ltype only) */ ++ [NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_TX, + }, + .intf_lid_lt_ld = { + /* Default RX MCAM KEX profile */ +@@ -13405,12 +13420,14 @@ static const struct npc_mcam_kex npc_mkex_default = { + /* Layer B: Single VLAN (CTAG) */ + /* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */ + [NPC_LT_LB_CTAG] = { +- KEX_LD_CFG(0x03, 0x0, 0x1, 0x0, 0x4), ++ KEX_LD_CFG(0x03, 0x2, 0x1, 0x0, 0x4), + }, + /* Layer B: Stacked VLAN (STAG|QinQ) */ + [NPC_LT_LB_STAG_QINQ] = { +- /* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */ +- KEX_LD_CFG(0x03, 0x4, 0x1, 0x0, 0x4), ++ /* Outer VLAN: 2 bytes, KW0[63:48] */ ++ KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6), ++ /* Ethertype: 2 bytes, KW0[47:32] */ ++ KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x4), + }, + [NPC_LT_LB_FDSA] = { + /* SWITCH PORT: 1 byte, KW0[63:48] */ +@@ -13436,17 +13453,69 @@ static const struct npc_mcam_kex npc_mkex_default = { + [NPC_LID_LD] = { + /* Layer D:UDP */ + [NPC_LT_LD_UDP] = { +- /* SPORT: 2 bytes, KW3[15:0] */ +- KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18), +- /* DPORT: 2 bytes, KW3[31:16] */ +- KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a), ++ /* SPORT+DPORT: 4 bytes, KW3[31:0] */ ++ KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18), ++ }, ++ /* Layer D:TCP */ ++ [NPC_LT_LD_TCP] = { ++ /* SPORT+DPORT: 4 bytes, KW3[31:0] */ ++ KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18), ++ }, ++ }, ++ }, ++ ++ /* Default TX MCAM KEX profile */ ++ [NIX_INTF_TX] = { ++ [NPC_LID_LA] = { ++ /* Layer A: NIX_INST_HDR_S + Ethernet */ ++ /* NIX appends 8 bytes of NIX_INST_HDR_S at the ++ * start of each TX packet supplied to NPC. ++ */ ++ [NPC_LT_LA_IH_NIX_ETHER] = { ++ /* PF_FUNC: 2B , KW0 [47:32] */ ++ KEX_LD_CFG(0x01, 0x0, 0x1, 0x0, 0x4), ++ /* DMAC: 6 bytes, KW1[63:16] */ ++ KEX_LD_CFG(0x05, 0x8, 0x1, 0x0, 0xa), ++ }, ++ }, ++ [NPC_LID_LB] = { ++ /* Layer B: Single VLAN (CTAG) */ ++ [NPC_LT_LB_CTAG] = { ++ /* CTAG VLAN[2..3] KW0[63:48] */ ++ KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6), ++ /* CTAG VLAN[2..3] KW1[15:0] */ ++ KEX_LD_CFG(0x01, 0x4, 0x1, 0x0, 0x8), ++ }, ++ /* Layer B: Stacked VLAN (STAG|QinQ) */ ++ [NPC_LT_LB_STAG_QINQ] = { ++ /* Outer VLAN: 2 bytes, KW0[63:48] */ ++ KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6), ++ /* Outer VLAN: 2 Bytes, KW1[15:0] */ ++ KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x8), ++ }, ++ }, ++ [NPC_LID_LC] = { ++ /* Layer C: IPv4 */ ++ [NPC_LT_LC_IP] = { ++ /* SIP+DIP: 8 bytes, KW2[63:0] */ ++ KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10), ++ }, ++ /* Layer C: IPv6 */ ++ [NPC_LT_LC_IP6] = { ++ /* Everything up to SADDR: 8 bytes, KW2[63:0] */ ++ KEX_LD_CFG(0x07, 0x0, 0x1, 0x0, 0x10), ++ }, ++ }, ++ [NPC_LID_LD] = { ++ /* Layer D:UDP */ ++ [NPC_LT_LD_UDP] = { ++ /* SPORT+DPORT: 4 bytes, KW3[31:0] */ ++ KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18), + }, + /* Layer D:TCP */ + [NPC_LT_LD_TCP] = { +- /* SPORT: 2 bytes, KW3[15:0] */ +- KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18), +- /* DPORT: 2 bytes, KW3[31:16] */ +- KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a), ++ /* SPORT+DPORT: 4 bytes, KW3[31:0] */ ++ KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18), + }, + }, + }, +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +index e1f9189607303..644d28b0692b3 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +@@ -2151,8 +2151,10 @@ static void rvu_unregister_interrupts(struct rvu *rvu) + INTR_MASK(rvu->hw->total_pfs) & ~1ULL); + + for (irq = 0; irq < rvu->num_vec; irq++) { +- if (rvu->irq_allocated[irq]) ++ if (rvu->irq_allocated[irq]) { + free_irq(pci_irq_vector(rvu->pdev, irq), rvu); ++ rvu->irq_allocated[irq] = false; ++ } + } + + pci_free_irq_vectors(rvu->pdev); +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +index 809f50ab0432e..bc870bff14df7 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +@@ -144,12 +144,14 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, + char __user *buffer, + size_t count, loff_t *ppos) + { +- int index, off = 0, flag = 0, go_back = 0, off_prev; ++ int index, off = 0, flag = 0, go_back = 0, len = 0; + struct rvu *rvu = filp->private_data; + int lf, pf, vf, pcifunc; + struct rvu_block block; + int bytes_not_copied; ++ int lf_str_size = 12; + int buf_size = 2048; ++ char *lfs; + char *buf; + + /* don't allow partial reads */ +@@ -159,12 +161,20 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) + return -ENOSPC; +- off += scnprintf(&buf[off], buf_size - 1 - off, "\npcifunc\t\t"); ++ ++ lfs = kzalloc(lf_str_size, GFP_KERNEL); ++ if (!lfs) { ++ kfree(buf); ++ return -ENOMEM; ++ } ++ off += scnprintf(&buf[off], buf_size - 1 - off, "%-*s", lf_str_size, ++ "pcifunc"); + for (index = 0; index < BLK_COUNT; index++) +- if (strlen(rvu->hw->block[index].name)) +- off += scnprintf(&buf[off], buf_size - 1 - off, +- "%*s\t", (index - 1) * 2, +- rvu->hw->block[index].name); ++ if (strlen(rvu->hw->block[index].name)) { ++ off += scnprintf(&buf[off], buf_size - 1 - off, ++ "%-*s", lf_str_size, ++ rvu->hw->block[index].name); ++ } + off += scnprintf(&buf[off], buf_size - 1 - off, "\n"); + for (pf = 0; pf < rvu->hw->total_pfs; pf++) { + for (vf = 0; vf <= rvu->hw->total_vfs; vf++) { +@@ -173,14 +183,15 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, + continue; + + if (vf) { ++ sprintf(lfs, "PF%d:VF%d", pf, vf - 1); + go_back = scnprintf(&buf[off], + buf_size - 1 - off, +- "PF%d:VF%d\t\t", pf, +- vf - 1); ++ "%-*s", lf_str_size, lfs); + } else { ++ sprintf(lfs, "PF%d", pf); + go_back = scnprintf(&buf[off], + buf_size - 1 - off, +- "PF%d\t\t", pf); ++ "%-*s", lf_str_size, lfs); + } + + off += go_back; +@@ -188,20 +199,22 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, + block = rvu->hw->block[index]; + if (!strlen(block.name)) + continue; +- off_prev = off; ++ len = 0; ++ lfs[len] = '\0'; + for (lf = 0; lf < block.lf.max; lf++) { + if (block.fn_map[lf] != pcifunc) + continue; + flag = 1; +- off += scnprintf(&buf[off], buf_size - 1 +- - off, "%3d,", lf); ++ len += sprintf(&lfs[len], "%d,", lf); + } +- if (flag && off_prev != off) +- off--; +- else +- go_back++; ++ ++ if (flag) ++ len--; ++ lfs[len] = '\0'; + off += scnprintf(&buf[off], buf_size - 1 - off, +- "\t"); ++ "%-*s", lf_str_size, lfs); ++ if (!strlen(lfs)) ++ go_back += lf_str_size; + } + if (!flag) + off -= go_back; +@@ -213,6 +226,7 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp, + } + + bytes_not_copied = copy_to_user(buffer, buf, off); ++ kfree(lfs); + kfree(buf); + + if (bytes_not_copied) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +index 21a89dd76d3c1..f6a3cf3e6f236 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +@@ -1129,6 +1129,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, + /* Config Rx pkt length, csum checks and apad enable / disable */ + rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), req->rx_cfg); + ++ /* Configure pkind for TX parse config */ ++ cfg = NPC_TX_DEF_PKIND; ++ rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg); ++ + intf = is_afvf(pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX; + err = nix_interface_init(rvu, pcifunc, intf, nixlf); + if (err) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 511b01dd03edc..169ae491f9786 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -2035,10 +2035,10 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu, + index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); + if (index >= mcam->bmap_entries) + break; ++ entry = index + 1; + if (mcam->entry2cntr_map[index] != req->cntr) + continue; + +- entry = index + 1; + npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, + index, req->cntr); + } +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index 66f1a212f1f4e..9fef9be015e5e 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1616,6 +1616,7 @@ int otx2_stop(struct net_device *netdev) + struct otx2_nic *pf = netdev_priv(netdev); + struct otx2_cq_poll *cq_poll = NULL; + struct otx2_qset *qset = &pf->qset; ++ struct otx2_rss_info *rss; + int qidx, vec, wrk; + + netif_carrier_off(netdev); +@@ -1628,6 +1629,10 @@ int otx2_stop(struct net_device *netdev) + /* First stop packet Rx/Tx */ + otx2_rxtx_enable(pf, false); + ++ /* Clear RSS enable flag */ ++ rss = &pf->hw.rss_info; ++ rss->enable = false; ++ + /* Cleanup Queue IRQ */ + vec = pci_irq_vector(pf->pdev, + pf->hw.nix_msixoff + NIX_LF_QINT_VEC_START); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index 2f05b0f9de019..9da34f82d4668 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -90,14 +90,15 @@ struct page_pool; + MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0) + #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) + +-#define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2) ++#define MLX5_ALIGN_MTTS(mtts) (ALIGN(mtts, 8)) ++#define MLX5_ALIGNED_MTTS_OCTW(mtts) ((mtts) / 2) ++#define MLX5_MTT_OCTW(mtts) (MLX5_ALIGNED_MTTS_OCTW(MLX5_ALIGN_MTTS(mtts))) + /* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between + * WQEs, This page will absorb write overflow by the hardware, when + * receiving packets larger than MTU. These oversize packets are + * dropped by the driver at a later stage. + */ +-#define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE + 1, 8)) +-#define MLX5E_LOG_ALIGNED_MPWQE_PPW (ilog2(MLX5E_REQUIRED_WQE_MTTS)) ++#define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1)) + #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) + #define MLX5E_MAX_RQ_NUM_MTTS \ + ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +index 24e2c0d955b99..b42396df3111d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +@@ -1182,7 +1182,8 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) + + mlx5e_tc_match_to_reg_get_match(spec, CTSTATE_TO_REG, + &ctstate, &ctstate_mask); +- if (ctstate_mask) ++ ++ if ((ctstate & ctstate_mask) == MLX5_CT_STATE_TRK_BIT) + return -EOPNOTSUPP; + + ctstate_mask |= MLX5_CT_STATE_TRK_BIT; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c +index e472ed0eacfbc..7ed3f9f79f11a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c +@@ -227,6 +227,10 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv, + option_key = (struct geneve_opt *)&enc_opts.key->data[0]; + option_mask = (struct geneve_opt *)&enc_opts.mask->data[0]; + ++ if (option_mask->opt_class == 0 && option_mask->type == 0 && ++ !memchr_inv(option_mask->opt_data, 0, option_mask->length * 4)) ++ return 0; ++ + if (option_key->length > max_tlv_option_data_len) { + NL_SET_ERR_MSG_MOD(extack, + "Matching on GENEVE options: unsupported option len"); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index b8622440243b4..bcd05457647e2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -1873,6 +1873,7 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, + { + struct mlx5e_priv *priv = netdev_priv(netdev); + struct mlx5_core_dev *mdev = priv->mdev; ++ int err; + + if (!MLX5_CAP_GEN(mdev, cqe_compression)) + return -EOPNOTSUPP; +@@ -1882,7 +1883,10 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev, + return -EINVAL; + } + +- mlx5e_modify_rx_cqe_compression_locked(priv, enable); ++ err = mlx5e_modify_rx_cqe_compression_locked(priv, enable); ++ if (err) ++ return err; ++ + priv->channels.params.rx_cqe_compress_def = enable; + + return 0; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 6394f9d8c6851..e2006c6053c9c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -303,9 +303,9 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq + rq->wqe_overflow.addr); + } + +-static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix) ++static u64 mlx5e_get_mpwqe_offset(u16 wqe_ix) + { +- return (wqe_ix << MLX5E_LOG_ALIGNED_MPWQE_PPW) << PAGE_SHIFT; ++ return MLX5E_REQUIRED_MTTS(wqe_ix) << PAGE_SHIFT; + } + + static void mlx5e_init_frags_partition(struct mlx5e_rq *rq) +@@ -544,7 +544,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, + mlx5_wq_ll_get_wqe(&rq->mpwqe.wq, i); + u32 byte_count = + rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz; +- u64 dma_offset = mlx5e_get_mpwqe_offset(rq, i); ++ u64 dma_offset = mlx5e_get_mpwqe_offset(i); + + wqe->data[0].addr = cpu_to_be64(dma_offset + rq->buff.headroom); + wqe->data[0].byte_count = cpu_to_be32(byte_count); +@@ -3666,10 +3666,17 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) + } + + if (mlx5e_is_uplink_rep(priv)) { ++ struct mlx5e_vport_stats *vstats = &priv->stats.vport; ++ + stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok); + stats->rx_bytes = PPORT_802_3_GET(pstats, a_octets_received_ok); + stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok); + stats->tx_bytes = PPORT_802_3_GET(pstats, a_octets_transmitted_ok); ++ ++ /* vport multicast also counts packets that are dropped due to steering ++ * or rx out of buffer ++ */ ++ stats->multicast = VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); + } else { + mlx5e_fold_sw_stats64(priv, stats); + } +@@ -4494,8 +4501,10 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) + struct mlx5e_channel *c = priv->channels.c[i]; + + mlx5e_rq_replace_xdp_prog(&c->rq, prog); +- if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) ++ if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) { ++ bpf_prog_inc(prog); + mlx5e_rq_replace_xdp_prog(&c->xskrq, prog); ++ } + } + + unlock: +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 6d2ba8b84187c..7e1f8660dfec0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -506,7 +506,6 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) + struct mlx5e_icosq *sq = &rq->channel->icosq; + struct mlx5_wq_cyc *wq = &sq->wq; + struct mlx5e_umr_wqe *umr_wqe; +- u16 xlt_offset = ix << (MLX5E_LOG_ALIGNED_MPWQE_PPW - 1); + u16 pi; + int err; + int i; +@@ -537,7 +536,8 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) + umr_wqe->ctrl.opmod_idx_opcode = + cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) | + MLX5_OPCODE_UMR); +- umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); ++ umr_wqe->uctrl.xlt_offset = ++ cpu_to_be16(MLX5_ALIGNED_MTTS_OCTW(MLX5E_REQUIRED_MTTS(ix))); + + sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { + .wqe_type = MLX5E_ICOSQ_WQE_UMR_RX, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 4b8a442f09cd6..930f19c598bb6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -2597,6 +2597,16 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, + *match_level = MLX5_MATCH_L4; + } + ++ /* Currenlty supported only for MPLS over UDP */ ++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS) && ++ !netif_is_bareudp(filter_dev)) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Matching on MPLS is supported only for MPLS over UDP"); ++ netdev_err(priv->netdev, ++ "Matching on MPLS is supported only for MPLS over UDP\n"); ++ return -EOPNOTSUPP; ++ } ++ + return 0; + } + +@@ -3200,6 +3210,37 @@ static int is_action_keys_supported(const struct flow_action_entry *act, + return 0; + } + ++static bool modify_tuple_supported(bool modify_tuple, bool ct_clear, ++ bool ct_flow, struct netlink_ext_ack *extack, ++ struct mlx5e_priv *priv, ++ struct mlx5_flow_spec *spec) ++{ ++ if (!modify_tuple || ct_clear) ++ return true; ++ ++ if (ct_flow) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "can't offload tuple modification with non-clear ct()"); ++ netdev_info(priv->netdev, ++ "can't offload tuple modification with non-clear ct()"); ++ return false; ++ } ++ ++ /* Add ct_state=-trk match so it will be offloaded for non ct flows ++ * (or after clear action), as otherwise, since the tuple is changed, ++ * we can't restore ct state ++ */ ++ if (mlx5_tc_ct_add_no_trk_match(spec)) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "can't offload tuple modification with ct matches and no ct(clear) action"); ++ netdev_info(priv->netdev, ++ "can't offload tuple modification with ct matches and no ct(clear) action"); ++ return false; ++ } ++ ++ return true; ++} ++ + static bool modify_header_match_supported(struct mlx5e_priv *priv, + struct mlx5_flow_spec *spec, + struct flow_action *flow_action, +@@ -3238,18 +3279,9 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv, + return err; + } + +- /* Add ct_state=-trk match so it will be offloaded for non ct flows +- * (or after clear action), as otherwise, since the tuple is changed, +- * we can't restore ct state +- */ +- if (!ct_clear && modify_tuple && +- mlx5_tc_ct_add_no_trk_match(spec)) { +- NL_SET_ERR_MSG_MOD(extack, +- "can't offload tuple modify header with ct matches"); +- netdev_info(priv->netdev, +- "can't offload tuple modify header with ct matches"); ++ if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack, ++ priv, spec)) + return false; +- } + + ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); + if (modify_ip_header && ip_proto != IPPROTO_TCP && +diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +index 5defd31d481c2..aa06fcb38f8b9 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +@@ -327,8 +327,14 @@ int nfp_compile_flow_metadata(struct nfp_app *app, + goto err_free_ctx_entry; + } + ++ /* Do net allocate a mask-id for pre_tun_rules. These flows are used to ++ * configure the pre_tun table and are never actually send to the ++ * firmware as an add-flow message. This causes the mask-id allocation ++ * on the firmware to get out of sync if allocated here. ++ */ + new_mask_id = 0; +- if (!nfp_check_mask_add(app, nfp_flow->mask_data, ++ if (!nfp_flow->pre_tun_rule.dev && ++ !nfp_check_mask_add(app, nfp_flow->mask_data, + nfp_flow->meta.mask_len, + &nfp_flow->meta.flags, &new_mask_id)) { + NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot allocate a new mask id"); +@@ -359,7 +365,8 @@ int nfp_compile_flow_metadata(struct nfp_app *app, + goto err_remove_mask; + } + +- if (!nfp_check_mask_remove(app, nfp_flow->mask_data, ++ if (!nfp_flow->pre_tun_rule.dev && ++ !nfp_check_mask_remove(app, nfp_flow->mask_data, + nfp_flow->meta.mask_len, + NULL, &new_mask_id)) { + NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot release mask id"); +@@ -374,8 +381,10 @@ int nfp_compile_flow_metadata(struct nfp_app *app, + return 0; + + err_remove_mask: +- nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, +- NULL, &new_mask_id); ++ if (!nfp_flow->pre_tun_rule.dev) ++ nfp_check_mask_remove(app, nfp_flow->mask_data, ++ nfp_flow->meta.mask_len, ++ NULL, &new_mask_id); + err_remove_rhash: + WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, + &ctx_entry->ht_node, +@@ -406,9 +415,10 @@ int nfp_modify_flow_metadata(struct nfp_app *app, + + __nfp_modify_flow_metadata(priv, nfp_flow); + +- nfp_check_mask_remove(app, nfp_flow->mask_data, +- nfp_flow->meta.mask_len, &nfp_flow->meta.flags, +- &new_mask_id); ++ if (!nfp_flow->pre_tun_rule.dev) ++ nfp_check_mask_remove(app, nfp_flow->mask_data, ++ nfp_flow->meta.mask_len, &nfp_flow->meta.flags, ++ &new_mask_id); + + /* Update flow payload with mask ids. */ + nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; +diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c +index 1c59aff2163c7..d72225d64a75d 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c +@@ -1142,6 +1142,12 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, + return -EOPNOTSUPP; + } + ++ if (!(key_layer & NFP_FLOWER_LAYER_IPV4) && ++ !(key_layer & NFP_FLOWER_LAYER_IPV6)) { ++ NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: match on ipv4/ipv6 eth_type must be present"); ++ return -EOPNOTSUPP; ++ } ++ + /* Skip fields known to exist. */ + mask += sizeof(struct nfp_flower_meta_tci); + ext += sizeof(struct nfp_flower_meta_tci); +@@ -1152,6 +1158,13 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, + mask += sizeof(struct nfp_flower_in_port); + ext += sizeof(struct nfp_flower_in_port); + ++ /* Ensure destination MAC address matches pre_tun_dev. */ ++ mac = (struct nfp_flower_mac_mpls *)ext; ++ if (memcmp(&mac->mac_dst[0], flow->pre_tun_rule.dev->dev_addr, 6)) { ++ NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: dest MAC must match output dev MAC"); ++ return -EOPNOTSUPP; ++ } ++ + /* Ensure destination MAC address is fully matched. */ + mac = (struct nfp_flower_mac_mpls *)mask; + if (!is_broadcast_ether_addr(&mac->mac_dst[0])) { +@@ -1159,6 +1172,11 @@ nfp_flower_validate_pre_tun_rule(struct nfp_app *app, + return -EOPNOTSUPP; + } + ++ if (mac->mpls_lse) { ++ NL_SET_ERR_MSG_MOD(extack, "unsupported pre-tunnel rule: MPLS not supported"); ++ return -EOPNOTSUPP; ++ } ++ + mask += sizeof(struct nfp_flower_mac_mpls); + ext += sizeof(struct nfp_flower_mac_mpls); + if (key_layer & NFP_FLOWER_LAYER_IPV4 || +diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +index 7248d248f6041..d19c02e991145 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +@@ -16,8 +16,9 @@ + #define NFP_FL_MAX_ROUTES 32 + + #define NFP_TUN_PRE_TUN_RULE_LIMIT 32 +-#define NFP_TUN_PRE_TUN_RULE_DEL 0x1 +-#define NFP_TUN_PRE_TUN_IDX_BIT 0x8 ++#define NFP_TUN_PRE_TUN_RULE_DEL BIT(0) ++#define NFP_TUN_PRE_TUN_IDX_BIT BIT(3) ++#define NFP_TUN_PRE_TUN_IPV6_BIT BIT(7) + + /** + * struct nfp_tun_pre_run_rule - rule matched before decap +@@ -1268,6 +1269,7 @@ int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, + { + struct nfp_flower_priv *app_priv = app->priv; + struct nfp_tun_offloaded_mac *mac_entry; ++ struct nfp_flower_meta_tci *key_meta; + struct nfp_tun_pre_tun_rule payload; + struct net_device *internal_dev; + int err; +@@ -1290,6 +1292,15 @@ int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app, + if (!mac_entry) + return -ENOENT; + ++ /* Set/clear IPV6 bit. cpu_to_be16() swap will lead to MSB being ++ * set/clear for port_idx. ++ */ ++ key_meta = (struct nfp_flower_meta_tci *)flow->unmasked_data; ++ if (key_meta->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV6) ++ mac_entry->index |= NFP_TUN_PRE_TUN_IPV6_BIT; ++ else ++ mac_entry->index &= ~NFP_TUN_PRE_TUN_IPV6_BIT; ++ + payload.port_idx = cpu_to_be16(mac_entry->index); + + /* Copy mac id and vlan to flow - dev may not exist at delete time. */ +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +index a81feffb09b8b..909eca14f647f 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +@@ -1077,15 +1077,17 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) + { + int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems; + struct ionic_tx_stats *stats = q_to_tx_stats(q); ++ int ndescs; + int err; + +- /* If TSO, need roundup(skb->len/mss) descs */ ++ /* Each desc is mss long max, so a descriptor for each gso_seg */ + if (skb_is_gso(skb)) +- return (skb->len / skb_shinfo(skb)->gso_size) + 1; ++ ndescs = skb_shinfo(skb)->gso_segs; ++ else ++ ndescs = 1; + +- /* If non-TSO, just need 1 desc and nr_frags sg elems */ + if (skb_shinfo(skb)->nr_frags <= sg_elems) +- return 1; ++ return ndescs; + + /* Too many frags, so linearize */ + err = skb_linearize(skb); +@@ -1094,8 +1096,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) + + stats->linearize++; + +- /* Need 1 desc and zero sg elems */ +- return 1; ++ return ndescs; + } + + static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs) +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +index 7760a3394e93c..7ecb3dfe30bd2 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +@@ -1425,6 +1425,7 @@ void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter) + + if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) { + vfree(fw_dump->tmpl_hdr); ++ fw_dump->tmpl_hdr = NULL; + + if (qlcnic_83xx_md_check_extended_dump_capability(adapter)) + extended = !qlcnic_83xx_extend_md_capab(adapter); +@@ -1443,6 +1444,8 @@ void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter) + struct qlcnic_83xx_dump_template_hdr *hdr; + + hdr = fw_dump->tmpl_hdr; ++ if (!hdr) ++ return; + hdr->drv_cap_mask = 0x1f; + fw_dump->cap_mask = 0x1f; + dev_info(&pdev->dev, +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index 1591715c97177..d634da20b4f94 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -4726,6 +4726,9 @@ static void rtl8169_down(struct rtl8169_private *tp) + + rtl8169_update_counters(tp); + ++ pci_clear_master(tp->pci_dev); ++ rtl_pci_commit(tp); ++ + rtl8169_cleanup(tp, true); + + rtl_pll_power_down(tp); +@@ -4733,6 +4736,7 @@ static void rtl8169_down(struct rtl8169_private *tp) + + static void rtl8169_up(struct rtl8169_private *tp) + { ++ pci_set_master(tp->pci_dev); + rtl_pll_power_up(tp); + rtl8169_init_phy(tp); + napi_enable(&tp->napi); +@@ -5394,8 +5398,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + + rtl_hw_reset(tp); + +- pci_set_master(pdev); +- + rc = rtl_alloc_irq(tp); + if (rc < 0) { + dev_err(&pdev->dev, "Can't allocate interrupt\n"); +diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c +index 1503cc9ec6e2d..ef3634d1b9f7f 100644 +--- a/drivers/net/ethernet/socionext/netsec.c ++++ b/drivers/net/ethernet/socionext/netsec.c +@@ -1708,14 +1708,17 @@ static int netsec_netdev_init(struct net_device *ndev) + goto err1; + + /* set phy power down */ +- data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) | +- BMCR_PDOWN; +- netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); ++ data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR); ++ netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, ++ data | BMCR_PDOWN); + + ret = netsec_reset_hardware(priv, true); + if (ret) + goto err2; + ++ /* Restore phy power state */ ++ netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); ++ + spin_lock_init(&priv->desc_ring[NETSEC_RING_TX].lock); + spin_lock_init(&priv->desc_ring[NETSEC_RING_RX].lock); + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index a5e0eff4a3874..9f5ccf1a0a540 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -1217,6 +1217,8 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) + plat_dat->init = sun8i_dwmac_init; + plat_dat->exit = sun8i_dwmac_exit; + plat_dat->setup = sun8i_dwmac_setup; ++ plat_dat->tx_fifo_size = 4096; ++ plat_dat->rx_fifo_size = 16384; + + ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); + if (ret) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index 2ecd3a8a690c2..cbf4429fb1d23 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -402,19 +402,53 @@ static void dwmac4_rd_set_tx_ic(struct dma_desc *p) + p->des2 |= cpu_to_le32(TDES2_INTERRUPT_ON_COMPLETION); + } + +-static void dwmac4_display_ring(void *head, unsigned int size, bool rx) ++static void dwmac4_display_ring(void *head, unsigned int size, bool rx, ++ dma_addr_t dma_rx_phy, unsigned int desc_size) + { +- struct dma_desc *p = (struct dma_desc *)head; ++ dma_addr_t dma_addr; + int i; + + pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); + +- for (i = 0; i < size; i++) { +- pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", +- i, (unsigned int)virt_to_phys(p), +- le32_to_cpu(p->des0), le32_to_cpu(p->des1), +- le32_to_cpu(p->des2), le32_to_cpu(p->des3)); +- p++; ++ if (desc_size == sizeof(struct dma_desc)) { ++ struct dma_desc *p = (struct dma_desc *)head; ++ ++ for (i = 0; i < size; i++) { ++ dma_addr = dma_rx_phy + i * sizeof(*p); ++ pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, ++ le32_to_cpu(p->des0), le32_to_cpu(p->des1), ++ le32_to_cpu(p->des2), le32_to_cpu(p->des3)); ++ p++; ++ } ++ } else if (desc_size == sizeof(struct dma_extended_desc)) { ++ struct dma_extended_desc *extp = (struct dma_extended_desc *)head; ++ ++ for (i = 0; i < size; i++) { ++ dma_addr = dma_rx_phy + i * sizeof(*extp); ++ pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, ++ le32_to_cpu(extp->basic.des0), le32_to_cpu(extp->basic.des1), ++ le32_to_cpu(extp->basic.des2), le32_to_cpu(extp->basic.des3), ++ le32_to_cpu(extp->des4), le32_to_cpu(extp->des5), ++ le32_to_cpu(extp->des6), le32_to_cpu(extp->des7)); ++ extp++; ++ } ++ } else if (desc_size == sizeof(struct dma_edesc)) { ++ struct dma_edesc *ep = (struct dma_edesc *)head; ++ ++ for (i = 0; i < size; i++) { ++ dma_addr = dma_rx_phy + i * sizeof(*ep); ++ pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, ++ le32_to_cpu(ep->des4), le32_to_cpu(ep->des5), ++ le32_to_cpu(ep->des6), le32_to_cpu(ep->des7), ++ le32_to_cpu(ep->basic.des0), le32_to_cpu(ep->basic.des1), ++ le32_to_cpu(ep->basic.des2), le32_to_cpu(ep->basic.des3)); ++ ep++; ++ } ++ } else { ++ pr_err("unsupported descriptor!"); + } + } + +diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +index d02cec296f51e..6650edfab5bc4 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +@@ -417,19 +417,22 @@ static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc, + } + } + +-static void enh_desc_display_ring(void *head, unsigned int size, bool rx) ++static void enh_desc_display_ring(void *head, unsigned int size, bool rx, ++ dma_addr_t dma_rx_phy, unsigned int desc_size) + { + struct dma_extended_desc *ep = (struct dma_extended_desc *)head; ++ dma_addr_t dma_addr; + int i; + + pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; ++ dma_addr = dma_rx_phy + i * sizeof(*ep); + + x = *(u64 *)ep; +- pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", +- i, (unsigned int)virt_to_phys(ep), ++ pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, + (unsigned int)x, (unsigned int)(x >> 32), + ep->basic.des2, ep->basic.des3); + ep++; +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h +index afe7ec496545a..b0b84244ef107 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -78,7 +78,8 @@ struct stmmac_desc_ops { + /* get rx timestamp status */ + int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats); + /* Display ring */ +- void (*display_ring)(void *head, unsigned int size, bool rx); ++ void (*display_ring)(void *head, unsigned int size, bool rx, ++ dma_addr_t dma_rx_phy, unsigned int desc_size); + /* set MSS via context descriptor */ + void (*set_mss)(struct dma_desc *p, unsigned int mss); + /* get descriptor skbuff address */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +index f083360e4ba67..98ef43f35802a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +@@ -269,19 +269,22 @@ static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats) + return 1; + } + +-static void ndesc_display_ring(void *head, unsigned int size, bool rx) ++static void ndesc_display_ring(void *head, unsigned int size, bool rx, ++ dma_addr_t dma_rx_phy, unsigned int desc_size) + { + struct dma_desc *p = (struct dma_desc *)head; ++ dma_addr_t dma_addr; + int i; + + pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; ++ dma_addr = dma_rx_phy + i * sizeof(*p); + + x = *(u64 *)p; +- pr_info("%03d [0x%x]: 0x%x 0x%x 0x%x 0x%x", +- i, (unsigned int)virt_to_phys(p), ++ pr_info("%03d [%pad]: 0x%x 0x%x 0x%x 0x%x", ++ i, &dma_addr, + (unsigned int)x, (unsigned int)(x >> 32), + p->des2, p->des3); + p++; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 7d01c5cf60c96..6012eadae4604 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1109,6 +1109,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv) + static void stmmac_display_rx_rings(struct stmmac_priv *priv) + { + u32 rx_cnt = priv->plat->rx_queues_to_use; ++ unsigned int desc_size; + void *head_rx; + u32 queue; + +@@ -1118,19 +1119,24 @@ static void stmmac_display_rx_rings(struct stmmac_priv *priv) + + pr_info("\tRX Queue %u rings\n", queue); + +- if (priv->extend_desc) ++ if (priv->extend_desc) { + head_rx = (void *)rx_q->dma_erx; +- else ++ desc_size = sizeof(struct dma_extended_desc); ++ } else { + head_rx = (void *)rx_q->dma_rx; ++ desc_size = sizeof(struct dma_desc); ++ } + + /* Display RX ring */ +- stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true); ++ stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true, ++ rx_q->dma_rx_phy, desc_size); + } + } + + static void stmmac_display_tx_rings(struct stmmac_priv *priv) + { + u32 tx_cnt = priv->plat->tx_queues_to_use; ++ unsigned int desc_size; + void *head_tx; + u32 queue; + +@@ -1140,14 +1146,19 @@ static void stmmac_display_tx_rings(struct stmmac_priv *priv) + + pr_info("\tTX Queue %d rings\n", queue); + +- if (priv->extend_desc) ++ if (priv->extend_desc) { + head_tx = (void *)tx_q->dma_etx; +- else if (tx_q->tbs & STMMAC_TBS_AVAIL) ++ desc_size = sizeof(struct dma_extended_desc); ++ } else if (tx_q->tbs & STMMAC_TBS_AVAIL) { + head_tx = (void *)tx_q->dma_entx; +- else ++ desc_size = sizeof(struct dma_edesc); ++ } else { + head_tx = (void *)tx_q->dma_tx; ++ desc_size = sizeof(struct dma_desc); ++ } + +- stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false); ++ stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false, ++ tx_q->dma_tx_phy, desc_size); + } + } + +@@ -3710,18 +3721,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) + unsigned int count = 0, error = 0, len = 0; + int status = 0, coe = priv->hw->rx_csum; + unsigned int next_entry = rx_q->cur_rx; ++ unsigned int desc_size; + struct sk_buff *skb = NULL; + + if (netif_msg_rx_status(priv)) { + void *rx_head; + + netdev_dbg(priv->dev, "%s: descriptor ring:\n", __func__); +- if (priv->extend_desc) ++ if (priv->extend_desc) { + rx_head = (void *)rx_q->dma_erx; +- else ++ desc_size = sizeof(struct dma_extended_desc); ++ } else { + rx_head = (void *)rx_q->dma_rx; ++ desc_size = sizeof(struct dma_desc); ++ } + +- stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true); ++ stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true, ++ rx_q->dma_rx_phy, desc_size); + } + while (count < limit) { + unsigned int buf1_len = 0, buf2_len = 0; +@@ -4289,24 +4305,27 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr) + static struct dentry *stmmac_fs_dir; + + static void sysfs_display_ring(void *head, int size, int extend_desc, +- struct seq_file *seq) ++ struct seq_file *seq, dma_addr_t dma_phy_addr) + { + int i; + struct dma_extended_desc *ep = (struct dma_extended_desc *)head; + struct dma_desc *p = (struct dma_desc *)head; ++ dma_addr_t dma_addr; + + for (i = 0; i < size; i++) { + if (extend_desc) { +- seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", +- i, (unsigned int)virt_to_phys(ep), ++ dma_addr = dma_phy_addr + i * sizeof(*ep); ++ seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, + le32_to_cpu(ep->basic.des0), + le32_to_cpu(ep->basic.des1), + le32_to_cpu(ep->basic.des2), + le32_to_cpu(ep->basic.des3)); + ep++; + } else { +- seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", +- i, (unsigned int)virt_to_phys(p), ++ dma_addr = dma_phy_addr + i * sizeof(*p); ++ seq_printf(seq, "%d [%pad]: 0x%x 0x%x 0x%x 0x%x\n", ++ i, &dma_addr, + le32_to_cpu(p->des0), le32_to_cpu(p->des1), + le32_to_cpu(p->des2), le32_to_cpu(p->des3)); + p++; +@@ -4334,11 +4353,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v) + if (priv->extend_desc) { + seq_printf(seq, "Extended descriptor ring:\n"); + sysfs_display_ring((void *)rx_q->dma_erx, +- priv->dma_rx_size, 1, seq); ++ priv->dma_rx_size, 1, seq, rx_q->dma_rx_phy); + } else { + seq_printf(seq, "Descriptor ring:\n"); + sysfs_display_ring((void *)rx_q->dma_rx, +- priv->dma_rx_size, 0, seq); ++ priv->dma_rx_size, 0, seq, rx_q->dma_rx_phy); + } + } + +@@ -4350,11 +4369,11 @@ static int stmmac_rings_status_show(struct seq_file *seq, void *v) + if (priv->extend_desc) { + seq_printf(seq, "Extended descriptor ring:\n"); + sysfs_display_ring((void *)tx_q->dma_etx, +- priv->dma_tx_size, 1, seq); ++ priv->dma_tx_size, 1, seq, tx_q->dma_tx_phy); + } else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) { + seq_printf(seq, "Descriptor ring:\n"); + sysfs_display_ring((void *)tx_q->dma_tx, +- priv->dma_tx_size, 0, seq); ++ priv->dma_tx_size, 0, seq, tx_q->dma_tx_phy); + } + } + +diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c +index 68695d4afacd5..707ccdd03b19e 100644 +--- a/drivers/net/ethernet/sun/niu.c ++++ b/drivers/net/ethernet/sun/niu.c +@@ -3931,8 +3931,6 @@ static void niu_xmac_interrupt(struct niu *np) + mp->rx_mcasts += RXMAC_MC_FRM_CNT_COUNT; + if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) + mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; +- if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) +- mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; + if (val & XRXMAC_STATUS_RXHIST1_CNT_EXP) + mp->rx_hist_cnt1 += RXMAC_HIST_CNT1_COUNT; + if (val & XRXMAC_STATUS_RXHIST2_CNT_EXP) +diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c +index b8f4f419173f9..d054c6e83b1c9 100644 +--- a/drivers/net/ethernet/tehuti/tehuti.c ++++ b/drivers/net/ethernet/tehuti/tehuti.c +@@ -2044,6 +2044,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + /*bdx_hw_reset(priv); */ + if (bdx_read_mac(priv)) { + pr_err("load MAC address failed\n"); ++ err = -EFAULT; + goto err_out_iomap; + } + SET_NETDEV_DEV(ndev, &pdev->dev); +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h +index f34c7903ff524..7326ad4d5e1c7 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h +@@ -419,6 +419,9 @@ struct axienet_local { + struct phylink *phylink; + struct phylink_config phylink_config; + ++ /* Reference to PCS/PMA PHY if used */ ++ struct mdio_device *pcs_phy; ++ + /* Clock for AXI bus */ + struct clk *clk; + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index eea0bb7c23ede..69c79cc24e6e4 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1517,10 +1517,27 @@ static void axienet_validate(struct phylink_config *config, + + phylink_set(mask, Asym_Pause); + phylink_set(mask, Pause); +- phylink_set(mask, 1000baseX_Full); +- phylink_set(mask, 10baseT_Full); +- phylink_set(mask, 100baseT_Full); +- phylink_set(mask, 1000baseT_Full); ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_NA: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_GMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ phylink_set(mask, 1000baseX_Full); ++ phylink_set(mask, 1000baseT_Full); ++ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) ++ break; ++ fallthrough; ++ case PHY_INTERFACE_MODE_MII: ++ phylink_set(mask, 100baseT_Full); ++ phylink_set(mask, 10baseT_Full); ++ default: ++ break; ++ } + + bitmap_and(supported, supported, mask, + __ETHTOOL_LINK_MODE_MASK_NBITS); +@@ -1533,38 +1550,46 @@ static void axienet_mac_pcs_get_state(struct phylink_config *config, + { + struct net_device *ndev = to_net_dev(config->dev); + struct axienet_local *lp = netdev_priv(ndev); +- u32 emmc_reg, fcc_reg; +- +- state->interface = lp->phy_mode; +- +- emmc_reg = axienet_ior(lp, XAE_EMMC_OFFSET); +- if (emmc_reg & XAE_EMMC_LINKSPD_1000) +- state->speed = SPEED_1000; +- else if (emmc_reg & XAE_EMMC_LINKSPD_100) +- state->speed = SPEED_100; +- else +- state->speed = SPEED_10; +- +- state->pause = 0; +- fcc_reg = axienet_ior(lp, XAE_FCC_OFFSET); +- if (fcc_reg & XAE_FCC_FCTX_MASK) +- state->pause |= MLO_PAUSE_TX; +- if (fcc_reg & XAE_FCC_FCRX_MASK) +- state->pause |= MLO_PAUSE_RX; + +- state->an_complete = 0; +- state->duplex = 1; ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ phylink_mii_c22_pcs_get_state(lp->pcs_phy, state); ++ break; ++ default: ++ break; ++ } + } + + static void axienet_mac_an_restart(struct phylink_config *config) + { +- /* Unsupported, do nothing */ ++ struct net_device *ndev = to_net_dev(config->dev); ++ struct axienet_local *lp = netdev_priv(ndev); ++ ++ phylink_mii_c22_pcs_an_restart(lp->pcs_phy); + } + + static void axienet_mac_config(struct phylink_config *config, unsigned int mode, + const struct phylink_link_state *state) + { +- /* nothing meaningful to do */ ++ struct net_device *ndev = to_net_dev(config->dev); ++ struct axienet_local *lp = netdev_priv(ndev); ++ int ret; ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ ret = phylink_mii_c22_pcs_config(lp->pcs_phy, mode, ++ state->interface, ++ state->advertising); ++ if (ret < 0) ++ netdev_warn(ndev, "Failed to configure PCS: %d\n", ++ ret); ++ break; ++ ++ default: ++ break; ++ } + } + + static void axienet_mac_link_down(struct phylink_config *config, +@@ -1823,7 +1848,7 @@ static int axienet_probe(struct platform_device *pdev) + if (IS_ERR(lp->regs)) { + dev_err(&pdev->dev, "could not map Axi Ethernet regs.\n"); + ret = PTR_ERR(lp->regs); +- goto free_netdev; ++ goto cleanup_clk; + } + lp->regs_start = ethres->start; + +@@ -1898,12 +1923,12 @@ static int axienet_probe(struct platform_device *pdev) + break; + default: + ret = -EINVAL; +- goto free_netdev; ++ goto cleanup_clk; + } + } else { + ret = of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); + if (ret) +- goto free_netdev; ++ goto cleanup_clk; + } + + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ +@@ -1916,7 +1941,7 @@ static int axienet_probe(struct platform_device *pdev) + dev_err(&pdev->dev, + "unable to get DMA resource\n"); + of_node_put(np); +- goto free_netdev; ++ goto cleanup_clk; + } + lp->dma_regs = devm_ioremap_resource(&pdev->dev, + &dmares); +@@ -1936,12 +1961,12 @@ static int axienet_probe(struct platform_device *pdev) + if (IS_ERR(lp->dma_regs)) { + dev_err(&pdev->dev, "could not map DMA regs\n"); + ret = PTR_ERR(lp->dma_regs); +- goto free_netdev; ++ goto cleanup_clk; + } + if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) { + dev_err(&pdev->dev, "could not determine irqs\n"); + ret = -ENOMEM; +- goto free_netdev; ++ goto cleanup_clk; + } + + /* Autodetect the need for 64-bit DMA pointers. +@@ -1971,7 +1996,7 @@ static int axienet_probe(struct platform_device *pdev) + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); + if (ret) { + dev_err(&pdev->dev, "No suitable DMA available\n"); +- goto free_netdev; ++ goto cleanup_clk; + } + + /* Check for Ethernet core IRQ (optional) */ +@@ -1997,6 +2022,20 @@ static int axienet_probe(struct platform_device *pdev) + dev_warn(&pdev->dev, + "error registering MDIO bus: %d\n", ret); + } ++ if (lp->phy_mode == PHY_INTERFACE_MODE_SGMII || ++ lp->phy_mode == PHY_INTERFACE_MODE_1000BASEX) { ++ if (!lp->phy_node) { ++ dev_err(&pdev->dev, "phy-handle required for 1000BaseX/SGMII\n"); ++ ret = -EINVAL; ++ goto cleanup_mdio; ++ } ++ lp->pcs_phy = of_mdio_find_device(lp->phy_node); ++ if (!lp->pcs_phy) { ++ ret = -EPROBE_DEFER; ++ goto cleanup_mdio; ++ } ++ lp->phylink_config.pcs_poll = true; ++ } + + lp->phylink_config.dev = &ndev->dev; + lp->phylink_config.type = PHYLINK_NETDEV; +@@ -2007,17 +2046,30 @@ static int axienet_probe(struct platform_device *pdev) + if (IS_ERR(lp->phylink)) { + ret = PTR_ERR(lp->phylink); + dev_err(&pdev->dev, "phylink_create error (%i)\n", ret); +- goto free_netdev; ++ goto cleanup_mdio; + } + + ret = register_netdev(lp->ndev); + if (ret) { + dev_err(lp->dev, "register_netdev() error (%i)\n", ret); +- goto free_netdev; ++ goto cleanup_phylink; + } + + return 0; + ++cleanup_phylink: ++ phylink_destroy(lp->phylink); ++ ++cleanup_mdio: ++ if (lp->pcs_phy) ++ put_device(&lp->pcs_phy->dev); ++ if (lp->mii_bus) ++ axienet_mdio_teardown(lp); ++ of_node_put(lp->phy_node); ++ ++cleanup_clk: ++ clk_disable_unprepare(lp->clk); ++ + free_netdev: + free_netdev(ndev); + +@@ -2034,6 +2086,9 @@ static int axienet_remove(struct platform_device *pdev) + if (lp->phylink) + phylink_destroy(lp->phylink); + ++ if (lp->pcs_phy) ++ put_device(&lp->pcs_phy->dev); ++ + axienet_mdio_teardown(lp); + + clk_disable_unprepare(lp->clk); +diff --git a/drivers/net/ipa/ipa_qmi.c b/drivers/net/ipa/ipa_qmi.c +index 5090f0f923ad5..1a87a49538c50 100644 +--- a/drivers/net/ipa/ipa_qmi.c ++++ b/drivers/net/ipa/ipa_qmi.c +@@ -249,6 +249,7 @@ static struct qmi_msg_handler ipa_server_msg_handlers[] = { + .decoded_size = IPA_QMI_DRIVER_INIT_COMPLETE_REQ_SZ, + .fn = ipa_server_driver_init_complete, + }, ++ { }, + }; + + /* Handle an INIT_DRIVER response message from the modem. */ +@@ -269,6 +270,7 @@ static struct qmi_msg_handler ipa_client_msg_handlers[] = { + .decoded_size = IPA_QMI_INIT_DRIVER_RSP_SZ, + .fn = ipa_client_init_driver, + }, ++ { }, + }; + + /* Return a pointer to an init modem driver request structure, which contains +diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c +index cd271de9609be..dbed15dc0fe77 100644 +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -26,7 +26,46 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); + MODULE_AUTHOR("Maciej W. Rozycki"); + MODULE_LICENSE("GPL"); + +-static int bcm54xx_config_clock_delay(struct phy_device *phydev); ++static int bcm54xx_config_clock_delay(struct phy_device *phydev) ++{ ++ int rc, val; ++ ++ /* handling PHY's internal RX clock delay */ ++ val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); ++ val |= MII_BCM54XX_AUXCTL_MISC_WREN; ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { ++ /* Disable RGMII RXC-RXD skew */ ++ val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; ++ } ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { ++ /* Enable RGMII RXC-RXD skew */ ++ val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; ++ } ++ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, ++ val); ++ if (rc < 0) ++ return rc; ++ ++ /* handling PHY's internal TX clock delay */ ++ val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { ++ /* Disable internal TX clock delay */ ++ val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; ++ } ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || ++ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { ++ /* Enable internal TX clock delay */ ++ val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN; ++ } ++ rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); ++ if (rc < 0) ++ return rc; ++ ++ return 0; ++} + + static int bcm54210e_config_init(struct phy_device *phydev) + { +@@ -64,45 +103,62 @@ static int bcm54612e_config_init(struct phy_device *phydev) + return 0; + } + +-static int bcm54xx_config_clock_delay(struct phy_device *phydev) ++static int bcm54616s_config_init(struct phy_device *phydev) + { + int rc, val; + +- /* handling PHY's internal RX clock delay */ ++ if (phydev->interface != PHY_INTERFACE_MODE_SGMII && ++ phydev->interface != PHY_INTERFACE_MODE_1000BASEX) ++ return 0; ++ ++ /* Ensure proper interface mode is selected. */ ++ /* Disable RGMII mode */ + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); ++ if (val < 0) ++ return val; ++ val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; +- if (phydev->interface == PHY_INTERFACE_MODE_RGMII || +- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { +- /* Disable RGMII RXC-RXD skew */ +- val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; +- } +- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || +- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { +- /* Enable RGMII RXC-RXD skew */ +- val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; +- } + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + +- /* handling PHY's internal TX clock delay */ +- val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); +- if (phydev->interface == PHY_INTERFACE_MODE_RGMII || +- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { +- /* Disable internal TX clock delay */ +- val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; +- } +- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || +- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { +- /* Enable internal TX clock delay */ +- val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN; +- } +- rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); ++ /* Select 1000BASE-X register set (primary SerDes) */ ++ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE); ++ if (val < 0) ++ return val; ++ val |= BCM54XX_SHD_MODE_1000BX; ++ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); + if (rc < 0) + return rc; + +- return 0; ++ /* Power down SerDes interface */ ++ rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); ++ if (rc < 0) ++ return rc; ++ ++ /* Select proper interface mode */ ++ val &= ~BCM54XX_SHD_INTF_SEL_MASK; ++ val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ? ++ BCM54XX_SHD_INTF_SEL_SGMII : ++ BCM54XX_SHD_INTF_SEL_GBIC; ++ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); ++ if (rc < 0) ++ return rc; ++ ++ /* Power up SerDes interface */ ++ rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); ++ if (rc < 0) ++ return rc; ++ ++ /* Select copper register set */ ++ val &= ~BCM54XX_SHD_MODE_1000BX; ++ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val); ++ if (rc < 0) ++ return rc; ++ ++ /* Power up copper interface */ ++ return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); + } + + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ +@@ -283,15 +339,21 @@ static int bcm54xx_config_init(struct phy_device *phydev) + + bcm54xx_adjust_rxrefclk(phydev); + +- if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) { ++ switch (BRCM_PHY_MODEL(phydev)) { ++ case PHY_ID_BCM50610: ++ case PHY_ID_BCM50610M: ++ err = bcm54xx_config_clock_delay(phydev); ++ break; ++ case PHY_ID_BCM54210E: + err = bcm54210e_config_init(phydev); +- if (err) +- return err; +- } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) { ++ break; ++ case PHY_ID_BCM54612E: + err = bcm54612e_config_init(phydev); +- if (err) +- return err; +- } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { ++ break; ++ case PHY_ID_BCM54616S: ++ err = bcm54616s_config_init(phydev); ++ break; ++ case PHY_ID_BCM54810: + /* For BCM54810, we need to disable BroadR-Reach function */ + val = bcm_phy_read_exp(phydev, + BCM54810_EXP_BROADREACH_LRE_MISC_CTL); +@@ -299,9 +361,10 @@ static int bcm54xx_config_init(struct phy_device *phydev) + err = bcm_phy_write_exp(phydev, + BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); +- if (err < 0) +- return err; ++ break; + } ++ if (err) ++ return err; + + bcm54xx_phydsp_config(phydev); + +@@ -332,6 +395,11 @@ static int bcm54xx_resume(struct phy_device *phydev) + if (ret < 0) + return ret; + ++ /* Upon exiting power down, the PHY remains in an internal reset state ++ * for 40us ++ */ ++ fsleep(40); ++ + return bcm54xx_config_init(phydev); + } + +@@ -475,7 +543,7 @@ static int bcm5481_config_aneg(struct phy_device *phydev) + + static int bcm54616s_probe(struct phy_device *phydev) + { +- int val, intf_sel; ++ int val; + + val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE); + if (val < 0) +@@ -487,8 +555,7 @@ static int bcm54616s_probe(struct phy_device *phydev) + * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX + * support is still missing as of now. + */ +- intf_sel = (val & BCM54XX_SHD_INTF_SEL_MASK) >> 1; +- if (intf_sel == 1) { ++ if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) { + val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL); + if (val < 0) + return val; +@@ -500,6 +567,8 @@ static int bcm54616s_probe(struct phy_device *phydev) + */ + if (!(val & BCM54616S_100FX_MODE)) + phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX; ++ ++ phydev->port = PORT_FIBRE; + } + + return 0; +diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c +index c162c9551bd11..a9b058bb1be87 100644 +--- a/drivers/net/phy/dp83822.c ++++ b/drivers/net/phy/dp83822.c +@@ -534,6 +534,9 @@ static int dp83822_probe(struct phy_device *phydev) + + dp83822_of_init(phydev); + ++ if (dp83822->fx_enabled) ++ phydev->port = PORT_FIBRE; ++ + return 0; + } + +diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c +index cf6dec7b7d8e7..a9daff88006b3 100644 +--- a/drivers/net/phy/dp83869.c ++++ b/drivers/net/phy/dp83869.c +@@ -821,6 +821,10 @@ static int dp83869_probe(struct phy_device *phydev) + if (ret) + return ret; + ++ if (dp83869->mode == DP83869_RGMII_100_BASE || ++ dp83869->mode == DP83869_RGMII_1000_BASE) ++ phydev->port = PORT_FIBRE; ++ + return dp83869_config_init(phydev); + } + +diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c +index fec58ad69e02c..cb8e4f0215fe8 100644 +--- a/drivers/net/phy/lxt.c ++++ b/drivers/net/phy/lxt.c +@@ -218,6 +218,7 @@ static int lxt973_probe(struct phy_device *phydev) + phy_write(phydev, MII_BMCR, val); + /* Remember that the port is in fiber mode. */ + phydev->priv = lxt973_probe; ++ phydev->port = PORT_FIBRE; + } else { + phydev->priv = NULL; + } +diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c +index 5aec673a0120b..5dbdaf0f5f09c 100644 +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -1449,6 +1449,7 @@ static int marvell_read_status_page(struct phy_device *phydev, int page) + phydev->asym_pause = 0; + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; ++ phydev->port = fiber ? PORT_FIBRE : PORT_TP; + + if (phydev->autoneg == AUTONEG_ENABLE) + err = marvell_read_status_page_an(phydev, fiber, status); +diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c +index 1901ba277413d..b1bb9b8e1e4ed 100644 +--- a/drivers/net/phy/marvell10g.c ++++ b/drivers/net/phy/marvell10g.c +@@ -631,6 +631,7 @@ static int mv3310_read_status_10gbaser(struct phy_device *phydev) + phydev->link = 1; + phydev->speed = SPEED_10000; + phydev->duplex = DUPLEX_FULL; ++ phydev->port = PORT_FIBRE; + + return 0; + } +@@ -690,6 +691,7 @@ static int mv3310_read_status_copper(struct phy_device *phydev) + + phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ? + DUPLEX_FULL : DUPLEX_HALF; ++ phydev->port = PORT_TP; + phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ? + ETH_TP_MDI_X : ETH_TP_MDI; + +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 47ae1d1723c54..9b0bc8b74bc01 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -308,14 +308,19 @@ static int kszphy_config_init(struct phy_device *phydev) + return kszphy_config_reset(phydev); + } + ++static int ksz8041_fiber_mode(struct phy_device *phydev) ++{ ++ struct device_node *of_node = phydev->mdio.dev.of_node; ++ ++ return of_property_read_bool(of_node, "micrel,fiber-mode"); ++} ++ + static int ksz8041_config_init(struct phy_device *phydev) + { + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + +- struct device_node *of_node = phydev->mdio.dev.of_node; +- + /* Limit supported and advertised modes in fiber mode */ +- if (of_property_read_bool(of_node, "micrel,fiber-mode")) { ++ if (ksz8041_fiber_mode(phydev)) { + phydev->dev_flags |= MICREL_PHY_FXEN; + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); +@@ -1143,6 +1148,9 @@ static int kszphy_probe(struct phy_device *phydev) + } + } + ++ if (ksz8041_fiber_mode(phydev)) ++ phydev->port = PORT_FIBRE; ++ + /* Support legacy board-file configuration */ + if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { + priv->rmii_ref_clk_sel = true; +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 49e96ca585fff..28ddaad721ed1 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -327,7 +327,7 @@ void phy_ethtool_ksettings_get(struct phy_device *phydev, + if (phydev->interface == PHY_INTERFACE_MODE_MOCA) + cmd->base.port = PORT_BNC; + else +- cmd->base.port = PORT_MII; ++ cmd->base.port = phydev->port; + cmd->base.transceiver = phy_is_internal(phydev) ? + XCVR_INTERNAL : XCVR_EXTERNAL; + cmd->base.phy_address = phydev->mdio.addr; +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index 2d4eed2d61ce9..85f3cde5ffd09 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -576,6 +576,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id, + dev->pause = 0; + dev->asym_pause = 0; + dev->link = 0; ++ dev->port = PORT_TP; + dev->interface = PHY_INTERFACE_MODE_GMII; + + dev->autoneg = AUTONEG_ENABLE; +@@ -1384,6 +1385,14 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + + phydev->state = PHY_READY; + ++ /* Port is set to PORT_TP by default and the actual PHY driver will set ++ * it to different value depending on the PHY configuration. If we have ++ * the generic PHY driver we can't figure it out, thus set the old ++ * legacy PORT_MII value. ++ */ ++ if (using_genphy) ++ phydev->port = PORT_MII; ++ + /* Initial carrier state is off as the phy is about to be + * (re)initialized. + */ +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index fe2296fdda19d..6072e87ed6c3c 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -472,7 +472,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, + err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, + state->interface); + if (err < 0) +- phylink_err(pl, "mac_prepare failed: %pe\n", ++ phylink_err(pl, "mac_finish failed: %pe\n", + ERR_PTR(err)); + } + } +diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c +index dba847f280962..2520421946a6a 100644 +--- a/drivers/net/usb/cdc-phonet.c ++++ b/drivers/net/usb/cdc-phonet.c +@@ -387,6 +387,8 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i + + err = register_netdev(dev); + if (err) { ++ /* Set disconnected flag so that disconnect() returns early. */ ++ pnd->disconnected = 1; + usb_driver_release_interface(&usbpn_driver, data_intf); + goto out; + } +diff --git a/drivers/net/veth.c b/drivers/net/veth.c +index 8c737668008a0..be18b243642f0 100644 +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -301,8 +301,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) + if (rxq < rcv->real_num_rx_queues) { + rq = &rcv_priv->rq[rxq]; + rcv_xdp = rcu_access_pointer(rq->xdp_prog); +- if (rcv_xdp) +- skb_record_rx_queue(skb, rxq); ++ skb_record_rx_queue(skb, rxq); + } + + skb_tx_timestamp(skb); +diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c +index dca97cd7c4e75..7eac6a3e1cdee 100644 +--- a/drivers/net/wan/fsl_ucc_hdlc.c ++++ b/drivers/net/wan/fsl_ucc_hdlc.c +@@ -204,14 +204,18 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) + priv->rx_skbuff = kcalloc(priv->rx_ring_size, + sizeof(*priv->rx_skbuff), + GFP_KERNEL); +- if (!priv->rx_skbuff) ++ if (!priv->rx_skbuff) { ++ ret = -ENOMEM; + goto free_ucc_pram; ++ } + + priv->tx_skbuff = kcalloc(priv->tx_ring_size, + sizeof(*priv->tx_skbuff), + GFP_KERNEL); +- if (!priv->tx_skbuff) ++ if (!priv->tx_skbuff) { ++ ret = -ENOMEM; + goto free_rx_skbuff; ++ } + + priv->skb_curtx = 0; + priv->skb_dirtytx = 0; +diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c +index 34bc53facd11c..6938cb3bdf4e9 100644 +--- a/drivers/net/wan/hdlc_x25.c ++++ b/drivers/net/wan/hdlc_x25.c +@@ -23,6 +23,8 @@ + + struct x25_state { + x25_hdlc_proto settings; ++ bool up; ++ spinlock_t up_lock; /* Protects "up" */ + }; + + static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); +@@ -105,6 +107,8 @@ static void x25_data_transmit(struct net_device *dev, struct sk_buff *skb) + + static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) + { ++ hdlc_device *hdlc = dev_to_hdlc(dev); ++ struct x25_state *x25st = state(hdlc); + int result; + + /* There should be a pseudo header of 1 byte added by upper layers. +@@ -115,12 +119,20 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + } + ++ spin_lock_bh(&x25st->up_lock); ++ if (!x25st->up) { ++ spin_unlock_bh(&x25st->up_lock); ++ kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } ++ + switch (skb->data[0]) { + case X25_IFACE_DATA: /* Data to be transmitted */ + skb_pull(skb, 1); + skb_reset_network_header(skb); + if ((result = lapb_data_request(dev, skb)) != LAPB_OK) + dev_kfree_skb(skb); ++ spin_unlock_bh(&x25st->up_lock); + return NETDEV_TX_OK; + + case X25_IFACE_CONNECT: +@@ -149,6 +161,7 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) + break; + } + ++ spin_unlock_bh(&x25st->up_lock); + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } +@@ -166,6 +179,7 @@ static int x25_open(struct net_device *dev) + .data_transmit = x25_data_transmit, + }; + hdlc_device *hdlc = dev_to_hdlc(dev); ++ struct x25_state *x25st = state(hdlc); + struct lapb_parms_struct params; + int result; + +@@ -192,6 +206,10 @@ static int x25_open(struct net_device *dev) + if (result != LAPB_OK) + return -EINVAL; + ++ spin_lock_bh(&x25st->up_lock); ++ x25st->up = true; ++ spin_unlock_bh(&x25st->up_lock); ++ + return 0; + } + +@@ -199,6 +217,13 @@ static int x25_open(struct net_device *dev) + + static void x25_close(struct net_device *dev) + { ++ hdlc_device *hdlc = dev_to_hdlc(dev); ++ struct x25_state *x25st = state(hdlc); ++ ++ spin_lock_bh(&x25st->up_lock); ++ x25st->up = false; ++ spin_unlock_bh(&x25st->up_lock); ++ + lapb_unregister(dev); + } + +@@ -207,15 +232,28 @@ static void x25_close(struct net_device *dev) + static int x25_rx(struct sk_buff *skb) + { + struct net_device *dev = skb->dev; ++ hdlc_device *hdlc = dev_to_hdlc(dev); ++ struct x25_state *x25st = state(hdlc); + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { + dev->stats.rx_dropped++; + return NET_RX_DROP; + } + +- if (lapb_data_received(dev, skb) == LAPB_OK) ++ spin_lock_bh(&x25st->up_lock); ++ if (!x25st->up) { ++ spin_unlock_bh(&x25st->up_lock); ++ kfree_skb(skb); ++ dev->stats.rx_dropped++; ++ return NET_RX_DROP; ++ } ++ ++ if (lapb_data_received(dev, skb) == LAPB_OK) { ++ spin_unlock_bh(&x25st->up_lock); + return NET_RX_SUCCESS; ++ } + ++ spin_unlock_bh(&x25st->up_lock); + dev->stats.rx_errors++; + dev_kfree_skb_any(skb); + return NET_RX_DROP; +@@ -300,6 +338,8 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) + return result; + + memcpy(&state(hdlc)->settings, &new_settings, size); ++ state(hdlc)->up = false; ++ spin_lock_init(&state(hdlc)->up_lock); + + /* There's no header_ops so hard_header_len should be 0. */ + dev->hard_header_len = 0; +diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c +index 262c40dc14a63..665a03ebf9efd 100644 +--- a/drivers/net/wireless/mediatek/mt76/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/dma.c +@@ -355,7 +355,6 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, + }; + struct ieee80211_hw *hw; + int len, n = 0, ret = -ENOMEM; +- struct mt76_queue_entry e; + struct mt76_txwi_cache *t; + struct sk_buff *iter; + dma_addr_t addr; +@@ -397,6 +396,11 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, + } + tx_info.nbuf = n; + ++ if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) { ++ ret = -ENOMEM; ++ goto unmap; ++ } ++ + dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size, + DMA_TO_DEVICE); + ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta, &tx_info); +@@ -405,11 +409,6 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, + if (ret < 0) + goto unmap; + +- if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) { +- ret = -ENOMEM; +- goto unmap; +- } +- + return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf, + tx_info.info, tx_info.skb, t); + +@@ -425,9 +424,7 @@ free: + dev->test.tx_done--; + #endif + +- e.skb = tx_info.skb; +- e.txwi = t; +- dev->drv->tx_complete_skb(dev, &e); ++ dev_kfree_skb(tx_info.skb); + mt76_put_txwi(dev, t); + return ret; + } +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index de846aaa8728b..610d2bc43ea2d 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -346,6 +346,7 @@ bool nvme_cancel_request(struct request *req, void *data, bool reserved) + return true; + + nvme_req(req)->status = NVME_SC_HOST_ABORTED_CMD; ++ nvme_req(req)->flags |= NVME_REQ_CANCELLED; + blk_mq_complete_request(req); + return true; + } +@@ -1371,7 +1372,7 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, + goto out_free_id; + } + +- error = -ENODEV; ++ error = NVME_SC_INVALID_NS | NVME_SC_DNR; + if ((*id)->ncap == 0) /* namespace not allocated or attached */ + goto out_free_id; + +@@ -3959,7 +3960,7 @@ static void nvme_ns_remove_by_nsid(struct nvme_ctrl *ctrl, u32 nsid) + static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids) + { + struct nvme_id_ns *id; +- int ret = -ENODEV; ++ int ret = NVME_SC_INVALID_NS | NVME_SC_DNR; + + if (test_bit(NVME_NS_DEAD, &ns->flags)) + goto out; +@@ -3968,7 +3969,7 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids) + if (ret) + goto out; + +- ret = -ENODEV; ++ ret = NVME_SC_INVALID_NS | NVME_SC_DNR; + if (!nvme_ns_ids_equal(&ns->head->ids, ids)) { + dev_err(ns->ctrl->device, + "identifiers changed for nsid %d\n", ns->head->ns_id); +@@ -3986,7 +3987,7 @@ out: + * + * TODO: we should probably schedule a delayed retry here. + */ +- if (ret && ret != -ENOMEM && !(ret > 0 && !(ret & NVME_SC_DNR))) ++ if (ret > 0 && (ret & NVME_SC_DNR)) + nvme_ns_remove(ns); + else + revalidate_disk_size(ns->disk, true); +@@ -4018,6 +4019,12 @@ static void nvme_validate_or_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) + nsid); + break; + } ++ if (!nvme_multi_css(ctrl)) { ++ dev_warn(ctrl->device, ++ "command set not reported for nsid: %d\n", ++ nsid); ++ break; ++ } + nvme_alloc_ns(ctrl, nsid, &ids); + break; + default: +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index fab068c8ba026..41257daf7464d 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -1956,7 +1956,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) + sizeof(op->rsp_iu), DMA_FROM_DEVICE); + + if (opstate == FCPOP_STATE_ABORTED) +- status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); ++ status = cpu_to_le16(NVME_SC_HOST_ABORTED_CMD << 1); + else if (freq->status) { + status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); + dev_info(ctrl->ctrl.device, +@@ -2443,6 +2443,7 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved) + struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); + struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req); + ++ op->nreq.flags |= NVME_REQ_CANCELLED; + __nvme_fc_abort_op(ctrl, op); + return true; + } +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 99c59f93a0641..4dca58f4afdf7 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3247,6 +3247,7 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | ++ NVME_QUIRK_DISABLE_WRITE_ZEROES| + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 06b6b742bb213..6c1f3ab7649c7 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -802,9 +802,8 @@ static void nvmet_rdma_write_data_done(struct ib_cq *cq, struct ib_wc *wc) + nvmet_req_uninit(&rsp->req); + nvmet_rdma_release_rsp(rsp); + if (wc->status != IB_WC_WR_FLUSH_ERR) { +- pr_info("RDMA WRITE for CQE 0x%p failed with status %s (%d).\n", +- wc->wr_cqe, ib_wc_status_msg(wc->status), +- wc->status); ++ pr_info("RDMA WRITE for CQE failed with status %s (%d).\n", ++ ib_wc_status_msg(wc->status), wc->status); + nvmet_rdma_error_comp(queue); + } + return; +diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c +index 30a9062d2b4b8..a90c32d072da3 100644 +--- a/drivers/platform/x86/intel-vbtn.c ++++ b/drivers/platform/x86/intel-vbtn.c +@@ -47,8 +47,16 @@ static const struct key_entry intel_vbtn_keymap[] = { + }; + + static const struct key_entry intel_vbtn_switchmap[] = { +- { KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ +- { KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ ++ /* ++ * SW_DOCK should only be reported for docking stations, but DSDTs using the ++ * intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set ++ * SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0). ++ * This causes userspace to think the laptop is docked to a port-replicator ++ * and to disable suspend-on-lid-close, which is undesirable. ++ * Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting. ++ */ ++ { KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ ++ { KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ + { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ + { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ + }; +diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c +index 52e4396d40717..c3036591b259a 100644 +--- a/drivers/regulator/qcom-rpmh-regulator.c ++++ b/drivers/regulator/qcom-rpmh-regulator.c +@@ -726,8 +726,8 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = { + static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_ops, +- .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000), +- .n_voltages = 5, ++ .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000), ++ .n_voltages = 236, + .pmic_mode_map = pmic_mode_map_pmic5_smps, + .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, + }; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index bb940cbcbb5dd..ac25ec5f97388 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -7358,14 +7358,18 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + ioc->pend_os_device_add_sz++; + ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, + GFP_KERNEL); +- if (!ioc->pend_os_device_add) ++ if (!ioc->pend_os_device_add) { ++ r = -ENOMEM; + goto out_free_resources; ++ } + + ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz; + ioc->device_remove_in_progress = + kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL); +- if (!ioc->device_remove_in_progress) ++ if (!ioc->device_remove_in_progress) { ++ r = -ENOMEM; + goto out_free_resources; ++ } + + ioc->fwfault_debug = mpt3sas_fwfault_debug; + +diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c +index 47ad64b066236..69c5b5ee2169b 100644 +--- a/drivers/scsi/qedi/qedi_main.c ++++ b/drivers/scsi/qedi/qedi_main.c +@@ -1675,6 +1675,7 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) + if (!qedi->global_queues[i]) { + QEDI_ERR(&qedi->dbg_ctx, + "Unable to allocation global queue %d.\n", i); ++ status = -ENOMEM; + goto mem_alloc_failure; + } + +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index a27a625839e68..dcae8f071c355 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -3222,8 +3222,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, + if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || + (cmd->sess && cmd->sess->deleted)) { + cmd->state = QLA_TGT_STATE_PROCESSED; +- res = 0; +- goto free; ++ return 0; + } + + ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, +@@ -3234,8 +3233,9 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, + + res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, + &full_req_cnt); +- if (unlikely(res != 0)) +- goto free; ++ if (unlikely(res != 0)) { ++ return res; ++ } + + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + +@@ -3255,8 +3255,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, + vha->flags.online, qla2x00_reset_active(vha), + cmd->reset_count, qpair->chip_reset); + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); +- res = 0; +- goto free; ++ return 0; + } + + /* Does F/W have an IOCBs for this request */ +@@ -3359,8 +3358,6 @@ out_unmap_unlock: + qlt_unmap_sg(vha, cmd); + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + +-free: +- vha->hw->tgt.tgt_ops->free_cmd(cmd); + return res; + } + EXPORT_SYMBOL(qlt_xmit_response); +diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c +index 61017acd3458b..7405fab324c82 100644 +--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c ++++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c +@@ -646,7 +646,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) + { + struct qla_tgt_cmd *cmd = container_of(se_cmd, + struct qla_tgt_cmd, se_cmd); +- struct scsi_qla_host *vha = cmd->vha; + + if (cmd->aborted) { + /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task +@@ -659,7 +658,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) + cmd->se_cmd.transport_state, + cmd->se_cmd.t_state, + cmd->se_cmd.se_cmd_flags); +- vha->hw->tgt.tgt_ops->free_cmd(cmd); + return 0; + } + +@@ -687,7 +685,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) + { + struct qla_tgt_cmd *cmd = container_of(se_cmd, + struct qla_tgt_cmd, se_cmd); +- struct scsi_qla_host *vha = cmd->vha; + int xmit_type = QLA_TGT_XMIT_STATUS; + + if (cmd->aborted) { +@@ -701,7 +698,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) + cmd, kref_read(&cmd->se_cmd.cmd_kref), + cmd->se_cmd.transport_state, cmd->se_cmd.t_state, + cmd->se_cmd.se_cmd_flags); +- vha->hw->tgt.tgt_ops->free_cmd(cmd); + return 0; + } + cmd->bufflen = se_cmd->data_length; +diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c +index a244c8ae1b4eb..20182e39cb282 100644 +--- a/drivers/scsi/ufs/ufs-qcom.c ++++ b/drivers/scsi/ufs/ufs-qcom.c +@@ -253,12 +253,17 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba) + { + int ret = 0; + struct ufs_qcom_host *host = ufshcd_get_variant(hba); ++ bool reenable_intr = false; + + if (!host->core_reset) { + dev_warn(hba->dev, "%s: reset control not set\n", __func__); + goto out; + } + ++ reenable_intr = hba->is_irq_enabled; ++ disable_irq(hba->irq); ++ hba->is_irq_enabled = false; ++ + ret = reset_control_assert(host->core_reset); + if (ret) { + dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n", +@@ -280,6 +285,11 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba) + + usleep_range(1000, 1100); + ++ if (reenable_intr) { ++ enable_irq(hba->irq); ++ hba->is_irq_enabled = true; ++ } ++ + out: + return ret; + } +diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c +index c8b14b3a171f7..fb067b5e4a977 100644 +--- a/drivers/soc/ti/omap_prm.c ++++ b/drivers/soc/ti/omap_prm.c +@@ -522,8 +522,12 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev, + reset->prm->data->name, id); + + exit: +- if (reset->clkdm) ++ if (reset->clkdm) { ++ /* At least dra7 iva needs a delay before clkdm idle */ ++ if (has_rstst) ++ udelay(1); + pdata->clkdm_allow_idle(reset->clkdm); ++ } + + return ret; + } +diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig +index 03fcc23516fd3..6e7d84ac06f50 100644 +--- a/drivers/staging/rtl8192e/Kconfig ++++ b/drivers/staging/rtl8192e/Kconfig +@@ -26,6 +26,7 @@ config RTLLIB_CRYPTO_CCMP + config RTLLIB_CRYPTO_TKIP + tristate "Support for rtllib TKIP crypto" + depends on RTLLIB ++ select CRYPTO + select CRYPTO_LIB_ARC4 + select CRYPTO_MICHAEL_MIC + default y +diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig +index 41645fe6ad48a..ea0efd290c372 100644 +--- a/drivers/xen/Kconfig ++++ b/drivers/xen/Kconfig +@@ -50,11 +50,11 @@ config XEN_BALLOON_MEMORY_HOTPLUG + + SUBSYSTEM=="memory", ACTION=="add", RUN+="/bin/sh -c '[ -f /sys$devpath/state ] && echo online > /sys$devpath/state'" + +-config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT ++config XEN_MEMORY_HOTPLUG_LIMIT + int "Hotplugged memory limit (in GiB) for a PV guest" + default 512 + depends on XEN_HAVE_PVMMU +- depends on XEN_BALLOON_MEMORY_HOTPLUG ++ depends on MEMORY_HOTPLUG + help + Maxmium amount of memory (in GiB) that a PV guest can be + expanded to when using memory hotplug. +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index cd9b1a16489b4..4bac32a274ceb 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -226,7 +226,6 @@ static void __del_qgroup_rb(struct btrfs_fs_info *fs_info, + { + struct btrfs_qgroup_list *list; + +- btrfs_sysfs_del_one_qgroup(fs_info, qgroup); + list_del(&qgroup->dirty); + while (!list_empty(&qgroup->groups)) { + list = list_first_entry(&qgroup->groups, +@@ -243,7 +242,6 @@ static void __del_qgroup_rb(struct btrfs_fs_info *fs_info, + list_del(&list->next_member); + kfree(list); + } +- kfree(qgroup); + } + + /* must be called with qgroup_lock held */ +@@ -569,6 +567,8 @@ void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info) + qgroup = rb_entry(n, struct btrfs_qgroup, node); + rb_erase(n, &fs_info->qgroup_tree); + __del_qgroup_rb(fs_info, qgroup); ++ btrfs_sysfs_del_one_qgroup(fs_info, qgroup); ++ kfree(qgroup); + } + /* + * We call btrfs_free_qgroup_config() when unmounting +@@ -1580,6 +1580,14 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) + spin_lock(&fs_info->qgroup_lock); + del_qgroup_rb(fs_info, qgroupid); + spin_unlock(&fs_info->qgroup_lock); ++ ++ /* ++ * Remove the qgroup from sysfs now without holding the qgroup_lock ++ * spinlock, since the sysfs_remove_group() function needs to take ++ * the mutex kernfs_mutex through kernfs_remove_by_name_ns(). ++ */ ++ btrfs_sysfs_del_one_qgroup(fs_info, qgroup); ++ kfree(qgroup); + out: + mutex_unlock(&fs_info->qgroup_ioctl_lock); + return ret; +diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c +index e027c718ca01a..8ffc40e84a594 100644 +--- a/fs/cachefiles/rdwr.c ++++ b/fs/cachefiles/rdwr.c +@@ -24,17 +24,16 @@ static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode, + container_of(wait, struct cachefiles_one_read, monitor); + struct cachefiles_object *object; + struct fscache_retrieval *op = monitor->op; +- struct wait_bit_key *key = _key; ++ struct wait_page_key *key = _key; + struct page *page = wait->private; + + ASSERT(key); + + _enter("{%lu},%u,%d,{%p,%u}", + monitor->netfs_page->index, mode, sync, +- key->flags, key->bit_nr); ++ key->page, key->bit_nr); + +- if (key->flags != &page->flags || +- key->bit_nr != PG_locked) ++ if (key->page != page || key->bit_nr != PG_locked) + return 0; + + _debug("--- monitor %p %lx ---", page, page->flags); +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 3295516af2aec..248ee81e01516 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1002,8 +1002,8 @@ struct cifs_ses { + bool binding:1; /* are we binding the session? */ + __u16 session_flags; + __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; +- __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; +- __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; ++ __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; ++ __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; + __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; + + __u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; +diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h +index 593d826820c34..a843422942b1d 100644 +--- a/fs/cifs/cifspdu.h ++++ b/fs/cifs/cifspdu.h +@@ -147,6 +147,11 @@ + */ + #define SMB3_SIGN_KEY_SIZE (16) + ++/* ++ * Size of the smb3 encryption/decryption keys ++ */ ++#define SMB3_ENC_DEC_KEY_SIZE (32) ++ + #define CIFS_CLIENT_CHALLENGE_SIZE (8) + #define CIFS_SERVER_CHALLENGE_SIZE (8) + #define CIFS_HMAC_MD5_HASH_SIZE (16) +diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h +index 99a1951a01ec2..d9a990c991213 100644 +--- a/fs/cifs/smb2glob.h ++++ b/fs/cifs/smb2glob.h +@@ -58,6 +58,7 @@ + #define SMB2_HMACSHA256_SIZE (32) + #define SMB2_CMACAES_SIZE (16) + #define SMB3_SIGNKEY_SIZE (16) ++#define SMB3_GCM128_CRYPTKEY_SIZE (16) + #define SMB3_GCM256_CRYPTKEY_SIZE (32) + + /* Maximum buffer size value we can send with 1 credit */ +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 02998c79bb907..46d247c722eec 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1980,6 +1980,7 @@ smb2_duplicate_extents(const unsigned int xid, + { + int rc; + unsigned int ret_data_len; ++ struct inode *inode; + struct duplicate_extents_to_file dup_ext_buf; + struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink); + +@@ -1996,10 +1997,21 @@ smb2_duplicate_extents(const unsigned int xid, + cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n", + src_off, dest_off, len); + +- rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); +- if (rc) +- goto duplicate_extents_out; ++ inode = d_inode(trgtfile->dentry); ++ if (inode->i_size < dest_off + len) { ++ rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); ++ if (rc) ++ goto duplicate_extents_out; + ++ /* ++ * Although also could set plausible allocation size (i_blocks) ++ * here in addition to setting the file size, in reflink ++ * it is likely that the target file is sparse. Its allocation ++ * size will be queried on next revalidate, but it is important ++ * to make sure that file's cached size is updated immediately ++ */ ++ cifs_setsize(inode, dest_off + len); ++ } + rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, + trgtfile->fid.volatile_fid, + FSCTL_DUPLICATE_EXTENTS_TO_FILE, +@@ -4056,7 +4068,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key) + if (ses->Suid == ses_id) { + ses_enc_key = enc ? ses->smb3encryptionkey : + ses->smb3decryptionkey; +- memcpy(key, ses_enc_key, SMB3_SIGN_KEY_SIZE); ++ memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE); + spin_unlock(&cifs_tcp_ses_lock); + return 0; + } +@@ -4083,7 +4095,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + int rc = 0; + struct scatterlist *sg; + u8 sign[SMB2_SIGNATURE_SIZE] = {}; +- u8 key[SMB3_SIGN_KEY_SIZE]; ++ u8 key[SMB3_ENC_DEC_KEY_SIZE]; + struct aead_request *req; + char *iv; + unsigned int iv_len; +@@ -4107,10 +4119,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + tfm = enc ? server->secmech.ccmaesencrypt : + server->secmech.ccmaesdecrypt; + +- if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM) ++ if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || ++ (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) + rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE); + else +- rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE); ++ rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE); + + if (rc) { + cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index c6f8bc6729aa1..d1d550647cd64 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -4032,8 +4032,7 @@ smb2_async_readv(struct cifs_readdata *rdata) + if (rdata->credits.value > 0) { + shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, + SMB2_MAX_BUFFER_SIZE)); +- shdr->CreditRequest = +- cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); ++ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); + + rc = adjust_credits(server, &rdata->credits, rdata->bytes); + if (rc) +@@ -4339,8 +4338,7 @@ smb2_async_writev(struct cifs_writedata *wdata, + if (wdata->credits.value > 0) { + shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, + SMB2_MAX_BUFFER_SIZE)); +- shdr->CreditRequest = +- cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); ++ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); + + rc = adjust_credits(server, &wdata->credits, wdata->bytes); + if (rc) +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index ebccd71cc60a3..e6fa76ab70be7 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -298,7 +298,8 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, + { + unsigned char zero = 0x0; + __u8 i[4] = {0, 0, 0, 1}; +- __u8 L[4] = {0, 0, 0, 128}; ++ __u8 L128[4] = {0, 0, 0, 128}; ++ __u8 L256[4] = {0, 0, 1, 0}; + int rc = 0; + unsigned char prfhash[SMB2_HMACSHA256_SIZE]; + unsigned char *hashptr = prfhash; +@@ -354,8 +355,14 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, + goto smb3signkey_ret; + } + +- rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, +- L, 4); ++ if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || ++ (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) { ++ rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, ++ L256, 4); ++ } else { ++ rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, ++ L128, 4); ++ } + if (rc) { + cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__); + goto smb3signkey_ret; +@@ -390,6 +397,9 @@ generate_smb3signingkey(struct cifs_ses *ses, + const struct derivation_triplet *ptriplet) + { + int rc; ++#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS ++ struct TCP_Server_Info *server = ses->server; ++#endif + + /* + * All channels use the same encryption/decryption keys but +@@ -422,11 +432,11 @@ generate_smb3signingkey(struct cifs_ses *ses, + rc = generate_key(ses, ptriplet->encryption.label, + ptriplet->encryption.context, + ses->smb3encryptionkey, +- SMB3_SIGN_KEY_SIZE); ++ SMB3_ENC_DEC_KEY_SIZE); + rc = generate_key(ses, ptriplet->decryption.label, + ptriplet->decryption.context, + ses->smb3decryptionkey, +- SMB3_SIGN_KEY_SIZE); ++ SMB3_ENC_DEC_KEY_SIZE); + if (rc) + return rc; + } +@@ -442,14 +452,23 @@ generate_smb3signingkey(struct cifs_ses *ses, + */ + cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid), + &ses->Suid); ++ cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type); + cifs_dbg(VFS, "Session Key %*ph\n", + SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response); + cifs_dbg(VFS, "Signing Key %*ph\n", + SMB3_SIGN_KEY_SIZE, ses->smb3signingkey); +- cifs_dbg(VFS, "ServerIn Key %*ph\n", +- SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey); +- cifs_dbg(VFS, "ServerOut Key %*ph\n", +- SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey); ++ if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || ++ (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) { ++ cifs_dbg(VFS, "ServerIn Key %*ph\n", ++ SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey); ++ cifs_dbg(VFS, "ServerOut Key %*ph\n", ++ SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey); ++ } else { ++ cifs_dbg(VFS, "ServerIn Key %*ph\n", ++ SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey); ++ cifs_dbg(VFS, "ServerOut Key %*ph\n", ++ SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey); ++ } + #endif + return rc; + } +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 7b45b3b79df56..503a0056b60f2 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -1170,7 +1170,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, + } + if (rc != 0) { + for (; i < num_rqst; i++) { +- cifs_server_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", ++ cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n", + midQ[i]->mid, le16_to_cpu(midQ[i]->command)); + send_cancel(server, &rqst[i], midQ[i]); + spin_lock(&GlobalMid_Lock); +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index e67d5de6f28ca..b6229fe1aa233 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2732,8 +2732,15 @@ static int ext4_mb_init_backend(struct super_block *sb) + } + + if (ext4_has_feature_flex_bg(sb)) { +- /* a single flex group is supposed to be read by a single IO */ +- sbi->s_mb_prefetch = min(1 << sbi->s_es->s_log_groups_per_flex, ++ /* a single flex group is supposed to be read by a single IO. ++ * 2 ^ s_log_groups_per_flex != UINT_MAX as s_mb_prefetch is ++ * unsigned integer, so the maximum shift is 32. ++ */ ++ if (sbi->s_es->s_log_groups_per_flex >= 32) { ++ ext4_msg(sb, KERN_ERR, "too many log groups per flexible block group"); ++ goto err_freesgi; ++ } ++ sbi->s_mb_prefetch = min_t(uint, 1 << sbi->s_es->s_log_groups_per_flex, + BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9)); + sbi->s_mb_prefetch *= 8; /* 8 prefetch IOs in flight at most */ + } else { +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 4698471795732..5462f26907c19 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1459,6 +1459,9 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, + if (!ce) + return NULL; + ++ WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) && ++ !(current->flags & PF_MEMALLOC_NOFS)); ++ + ea_data = kvmalloc(value_len, GFP_KERNEL); + if (!ea_data) { + mb_cache_entry_put(ea_inode_cache, ce); +@@ -2325,6 +2328,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, + error = -ENOSPC; + goto cleanup; + } ++ WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS)); + } + + error = ext4_reserve_inode_write(handle, inode, &is.iloc); +diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c +index 2e9314091c81d..1955dea999f79 100644 +--- a/fs/gfs2/log.c ++++ b/fs/gfs2/log.c +@@ -935,12 +935,16 @@ static void trans_drain(struct gfs2_trans *tr) + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); ++ if (!list_empty(&bd->bd_ail_st_list)) ++ gfs2_remove_from_ail(bd); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } + head = &tr->tr_databuf; + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); ++ if (!list_empty(&bd->bd_ail_st_list)) ++ gfs2_remove_from_ail(bd); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } + } +diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c +index 6d4bf7ea7b3be..7f850ff6a05de 100644 +--- a/fs/gfs2/trans.c ++++ b/fs/gfs2/trans.c +@@ -134,6 +134,8 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl, + bd->bd_bh = bh; + bd->bd_gl = gl; + INIT_LIST_HEAD(&bd->bd_list); ++ INIT_LIST_HEAD(&bd->bd_ail_st_list); ++ INIT_LIST_HEAD(&bd->bd_ail_gl_list); + bh->b_private = bd; + return bd; + } +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 06e9c21819957..dde290eb7dd0c 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -3996,6 +3996,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock, + static int io_provide_buffers_prep(struct io_kiocb *req, + const struct io_uring_sqe *sqe) + { ++ unsigned long size; + struct io_provide_buf *p = &req->pbuf; + u64 tmp; + +@@ -4009,7 +4010,8 @@ static int io_provide_buffers_prep(struct io_kiocb *req, + p->addr = READ_ONCE(sqe->addr); + p->len = READ_ONCE(sqe->len); + +- if (!access_ok(u64_to_user_ptr(p->addr), (p->len * p->nbufs))) ++ size = (unsigned long)p->len * p->nbufs; ++ if (!access_ok(u64_to_user_ptr(p->addr), size)) + return -EFAULT; + + p->bgid = READ_ONCE(sqe->buf_group); +diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig +index e2a488d403a61..14a72224b6571 100644 +--- a/fs/nfs/Kconfig ++++ b/fs/nfs/Kconfig +@@ -127,7 +127,7 @@ config PNFS_BLOCK + config PNFS_FLEXFILE_LAYOUT + tristate + depends on NFS_V4_1 && NFS_V3 +- default m ++ default NFS_V4 + + config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN + string "NFSv4.1 Implementation ID Domain" +diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c +index 69971f6c840d2..dff6b52d26a85 100644 +--- a/fs/nfs/nfs3xdr.c ++++ b/fs/nfs/nfs3xdr.c +@@ -35,6 +35,7 @@ + */ + #define NFS3_fhandle_sz (1+16) + #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */ ++#define NFS3_post_op_fh_sz (1+NFS3_fh_sz) + #define NFS3_sattr_sz (15) + #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) + #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) +@@ -72,7 +73,7 @@ + #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1+1) + #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3+1) + #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4) +-#define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) ++#define NFS3_createres_sz (1+NFS3_post_op_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) + #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz)) + #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) + #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2+1) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index ba2dfba4854bf..15ac6b6893e76 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5891,6 +5891,9 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl + unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); + int ret, i; + ++ /* You can't remove system.nfs4_acl: */ ++ if (buflen == 0) ++ return -EINVAL; + if (!nfs4_server_supports_acls(server)) + return -EOPNOTSUPP; + if (npages > ARRAY_SIZE(pages)) +diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c +index eb02072d28dd6..723763746238d 100644 +--- a/fs/squashfs/export.c ++++ b/fs/squashfs/export.c +@@ -152,14 +152,18 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, + start = le64_to_cpu(table[n]); + end = le64_to_cpu(table[n + 1]); + +- if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= end ++ || (end - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } + } + + start = le64_to_cpu(table[indexes - 1]); +- if (start >= lookup_table_start || (lookup_table_start - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= lookup_table_start || ++ (lookup_table_start - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } +diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c +index 11581bf31af41..ea5387679723f 100644 +--- a/fs/squashfs/id.c ++++ b/fs/squashfs/id.c +@@ -97,14 +97,16 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, + start = le64_to_cpu(table[n]); + end = le64_to_cpu(table[n + 1]); + +- if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= end || (end - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } + } + + start = le64_to_cpu(table[indexes - 1]); +- if (start >= id_table_start || (id_table_start - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= id_table_start || (id_table_start - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } +diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h +index 8d64edb80ebf0..b3fdc8212c5f5 100644 +--- a/fs/squashfs/squashfs_fs.h ++++ b/fs/squashfs/squashfs_fs.h +@@ -17,6 +17,7 @@ + + /* size of metadata (inode and directory) blocks */ + #define SQUASHFS_METADATA_SIZE 8192 ++#define SQUASHFS_BLOCK_OFFSET 2 + + /* default size of block device I/O */ + #ifdef CONFIG_SQUASHFS_4K_DEVBLK_SIZE +diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c +index ead66670b41a5..087cab8c78f4e 100644 +--- a/fs/squashfs/xattr_id.c ++++ b/fs/squashfs/xattr_id.c +@@ -109,14 +109,16 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, + start = le64_to_cpu(table[n]); + end = le64_to_cpu(table[n + 1]); + +- if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= end || (end - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } + } + + start = le64_to_cpu(table[indexes - 1]); +- if (start >= table_start || (table_start - start) > SQUASHFS_METADATA_SIZE) { ++ if (start >= table_start || (table_start - start) > ++ (SQUASHFS_METADATA_SIZE + SQUASHFS_BLOCK_OFFSET)) { + kfree(table); + return ERR_PTR(-EINVAL); + } +diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h +index 6d1879bf94403..37dac195adbb4 100644 +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -233,6 +233,7 @@ struct acpi_pnp_type { + + struct acpi_device_pnp { + acpi_bus_id bus_id; /* Object name */ ++ int instance_no; /* Instance number of this object */ + struct acpi_pnp_type type; /* ID type */ + acpi_bus_address bus_address; /* _ADR */ + char *unique_id; /* _UID */ +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 34d8287cd7749..d7efbc5490e8c 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -393,7 +393,10 @@ + . = ALIGN(8); \ + __start_static_call_sites = .; \ + KEEP(*(.static_call_sites)) \ +- __stop_static_call_sites = .; ++ __stop_static_call_sites = .; \ ++ __start_static_call_tramp_key = .; \ ++ KEEP(*(.static_call_tramp_key)) \ ++ __stop_static_call_tramp_key = .; + + /* + * Allow architectures to handle ro_after_init data on their +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 76322b6452c80..dd236ef59db3e 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -1059,7 +1059,7 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array, + struct bpf_prog *include_prog, + struct bpf_prog_array **new_array); + +-#define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null) \ ++#define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null, set_cg_storage) \ + ({ \ + struct bpf_prog_array_item *_item; \ + struct bpf_prog *_prog; \ +@@ -1072,7 +1072,8 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array, + goto _out; \ + _item = &_array->items[0]; \ + while ((_prog = READ_ONCE(_item->prog))) { \ +- bpf_cgroup_storage_set(_item->cgroup_storage); \ ++ if (set_cg_storage) \ ++ bpf_cgroup_storage_set(_item->cgroup_storage); \ + _ret &= func(_prog, ctx); \ + _item++; \ + } \ +@@ -1133,10 +1134,10 @@ _out: \ + }) + + #define BPF_PROG_RUN_ARRAY(array, ctx, func) \ +- __BPF_PROG_RUN_ARRAY(array, ctx, func, false) ++ __BPF_PROG_RUN_ARRAY(array, ctx, func, false, true) + + #define BPF_PROG_RUN_ARRAY_CHECK(array, ctx, func) \ +- __BPF_PROG_RUN_ARRAY(array, ctx, func, true) ++ __BPF_PROG_RUN_ARRAY(array, ctx, func, true, false) + + #ifdef CONFIG_BPF_SYSCALL + DECLARE_PER_CPU(int, bpf_prog_active); +diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h +index d0bd226d6bd96..54665952d6ade 100644 +--- a/include/linux/brcmphy.h ++++ b/include/linux/brcmphy.h +@@ -136,6 +136,7 @@ + + #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x07 + #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN 0x0010 ++#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN 0x0080 + #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN 0x0100 + #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200 + #define MII_BCM54XX_AUXCTL_MISC_WREN 0x8000 +@@ -222,6 +223,9 @@ + /* 11111: Mode Control Register */ + #define BCM54XX_SHD_MODE 0x1f + #define BCM54XX_SHD_INTF_SEL_MASK GENMASK(2, 1) /* INTERF_SEL[1:0] */ ++#define BCM54XX_SHD_INTF_SEL_RGMII 0x02 ++#define BCM54XX_SHD_INTF_SEL_SGMII 0x04 ++#define BCM54XX_SHD_INTF_SEL_GBIC 0x06 + #define BCM54XX_SHD_MODE_1000BX BIT(0) /* Enable 1000-X registers */ + + /* +diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h +index d2d7f9b6a2761..50cc070cb1f7c 100644 +--- a/include/linux/device-mapper.h ++++ b/include/linux/device-mapper.h +@@ -246,7 +246,11 @@ struct target_type { + #define dm_target_passes_integrity(type) ((type)->features & DM_TARGET_PASSES_INTEGRITY) + + /* +- * Indicates that a target supports host-managed zoned block devices. ++ * Indicates support for zoned block devices: ++ * - DM_TARGET_ZONED_HM: the target also supports host-managed zoned ++ * block devices but does not support combining different zoned models. ++ * - DM_TARGET_MIXED_ZONED_MODEL: the target supports combining multiple ++ * devices with different zoned models. + */ + #define DM_TARGET_ZONED_HM 0x00000040 + #define dm_target_supports_zoned_hm(type) ((type)->features & DM_TARGET_ZONED_HM) +@@ -257,6 +261,15 @@ struct target_type { + #define DM_TARGET_NOWAIT 0x00000080 + #define dm_target_supports_nowait(type) ((type)->features & DM_TARGET_NOWAIT) + ++#ifdef CONFIG_BLK_DEV_ZONED ++#define DM_TARGET_MIXED_ZONED_MODEL 0x00000200 ++#define dm_target_supports_mixed_zoned_model(type) \ ++ ((type)->features & DM_TARGET_MIXED_ZONED_MODEL) ++#else ++#define DM_TARGET_MIXED_ZONED_MODEL 0x00000000 ++#define dm_target_supports_mixed_zoned_model(type) (false) ++#endif ++ + struct dm_target { + struct dm_table *table; + struct target_type *type; +diff --git a/include/linux/hugetlb_cgroup.h b/include/linux/hugetlb_cgroup.h +index 2ad6e92f124ad..0bff345c4bc68 100644 +--- a/include/linux/hugetlb_cgroup.h ++++ b/include/linux/hugetlb_cgroup.h +@@ -113,6 +113,11 @@ static inline bool hugetlb_cgroup_disabled(void) + return !cgroup_subsys_enabled(hugetlb_cgrp_subsys); + } + ++static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) ++{ ++ css_put(&h_cg->css); ++} ++ + extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, + struct hugetlb_cgroup **ptr); + extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages, +@@ -138,7 +143,8 @@ extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, + + extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, + struct file_region *rg, +- unsigned long nr_pages); ++ unsigned long nr_pages, ++ bool region_del); + + extern void hugetlb_cgroup_file_init(void) __init; + extern void hugetlb_cgroup_migrate(struct page *oldhpage, +@@ -147,7 +153,8 @@ extern void hugetlb_cgroup_migrate(struct page *oldhpage, + #else + static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, + struct file_region *rg, +- unsigned long nr_pages) ++ unsigned long nr_pages, ++ bool region_del) + { + } + +@@ -185,6 +192,10 @@ static inline bool hugetlb_cgroup_disabled(void) + return true; + } + ++static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) ++{ ++} ++ + static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, + struct hugetlb_cgroup **ptr) + { +diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h +index a367ead4bf4bb..e11555989090c 100644 +--- a/include/linux/if_macvlan.h ++++ b/include/linux/if_macvlan.h +@@ -42,13 +42,14 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, + if (likely(success)) { + struct vlan_pcpu_stats *pcpu_stats; + +- pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); ++ pcpu_stats = get_cpu_ptr(vlan->pcpu_stats); + u64_stats_update_begin(&pcpu_stats->syncp); + pcpu_stats->rx_packets++; + pcpu_stats->rx_bytes += len; + if (multicast) + pcpu_stats->rx_multicast++; + u64_stats_update_end(&pcpu_stats->syncp); ++ put_cpu_ptr(vlan->pcpu_stats); + } else { + this_cpu_inc(vlan->pcpu_stats->rx_errors); + } +diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h +index 922a7f6004658..c691b1ac95f88 100644 +--- a/include/linux/memcontrol.h ++++ b/include/linux/memcontrol.h +@@ -937,9 +937,7 @@ static inline void memcg_memory_event_mm(struct mm_struct *mm, + rcu_read_unlock(); + } + +-#ifdef CONFIG_TRANSPARENT_HUGEPAGE +-void mem_cgroup_split_huge_fixup(struct page *head); +-#endif ++void split_page_memcg(struct page *head, unsigned int nr); + + #else /* CONFIG_MEMCG */ + +@@ -1267,7 +1265,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, + return 0; + } + +-static inline void mem_cgroup_split_huge_fixup(struct page *head) ++static inline void split_page_memcg(struct page *head, unsigned int nr) + { + } + +diff --git a/include/linux/mm.h b/include/linux/mm.h +index b8eadd9f96802..08a48d3eaeaae 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1414,13 +1414,26 @@ static inline bool cpupid_match_pid(struct task_struct *task, int cpupid) + #endif /* CONFIG_NUMA_BALANCING */ + + #ifdef CONFIG_KASAN_SW_TAGS ++ ++/* ++ * KASAN per-page tags are stored xor'ed with 0xff. This allows to avoid ++ * setting tags for all pages to native kernel tag value 0xff, as the default ++ * value 0x00 maps to 0xff. ++ */ ++ + static inline u8 page_kasan_tag(const struct page *page) + { +- return (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; ++ u8 tag; ++ ++ tag = (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; ++ tag ^= 0xff; ++ ++ return tag; + } + + static inline void page_kasan_tag_set(struct page *page, u8 tag) + { ++ tag ^= 0xff; + page->flags &= ~(KASAN_TAG_MASK << KASAN_TAG_PGSHIFT); + page->flags |= (tag & KASAN_TAG_MASK) << KASAN_TAG_PGSHIFT; + } +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 915f4f100383b..3433ecc9c1f74 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -23,6 +23,7 @@ + #endif + #define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1)) + ++#define INIT_PASID 0 + + struct address_space; + struct mem_cgroup; +diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h +index b8200782dedeb..1a6a9eb6d3fac 100644 +--- a/include/linux/mmu_notifier.h ++++ b/include/linux/mmu_notifier.h +@@ -169,11 +169,11 @@ struct mmu_notifier_ops { + * the last refcount is dropped. + * + * If blockable argument is set to false then the callback cannot +- * sleep and has to return with -EAGAIN. 0 should be returned +- * otherwise. Please note that if invalidate_range_start approves +- * a non-blocking behavior then the same applies to +- * invalidate_range_end. +- * ++ * sleep and has to return with -EAGAIN if sleeping would be required. ++ * 0 should be returned otherwise. Please note that notifiers that can ++ * fail invalidate_range_start are not allowed to implement ++ * invalidate_range_end, as there is no mechanism for informing the ++ * notifier that its start failed. + */ + int (*invalidate_range_start)(struct mmu_notifier *subscription, + const struct mmu_notifier_range *range); +diff --git a/include/linux/mutex.h b/include/linux/mutex.h +index dcd185cbfe793..4d671fba3cab4 100644 +--- a/include/linux/mutex.h ++++ b/include/linux/mutex.h +@@ -185,7 +185,7 @@ extern void mutex_lock_io(struct mutex *lock); + # define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock) + # define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock) + # define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) +-# define mutex_lock_io_nested(lock, subclass) mutex_lock(lock) ++# define mutex_lock_io_nested(lock, subclass) mutex_lock_io(lock) + #endif + + /* +diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h +index 8ebb641937571..8ec48466410a6 100644 +--- a/include/linux/netfilter/x_tables.h ++++ b/include/linux/netfilter/x_tables.h +@@ -227,7 +227,7 @@ struct xt_table { + unsigned int valid_hooks; + + /* Man behind the curtain... */ +- struct xt_table_info __rcu *private; ++ struct xt_table_info *private; + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +@@ -376,7 +376,7 @@ static inline unsigned int xt_write_recseq_begin(void) + * since addend is most likely 1 + */ + __this_cpu_add(xt_recseq.sequence, addend); +- smp_wmb(); ++ smp_mb(); + + return addend; + } +@@ -448,9 +448,6 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu) + + struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *); + +-struct xt_table_info +-*xt_table_get_private_protected(const struct xt_table *table); +- + #ifdef CONFIG_COMPAT + #include + +diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h +index d5570deff4003..b032f094a7827 100644 +--- a/include/linux/pagemap.h ++++ b/include/linux/pagemap.h +@@ -559,7 +559,6 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, + return pgoff; + } + +-/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */ + struct wait_page_key { + struct page *page; + int bit_nr; +diff --git a/include/linux/phy.h b/include/linux/phy.h +index 56563e5e0dc75..08725a262f320 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -499,6 +499,7 @@ struct macsec_ops; + * + * @speed: Current link speed + * @duplex: Current duplex ++ * @port: Current port + * @pause: Current pause + * @asym_pause: Current asymmetric pause + * @supported: Combined MAC/PHY supported linkmodes +@@ -577,6 +578,7 @@ struct phy_device { + */ + int speed; + int duplex; ++ int port; + int pause; + int asym_pause; + u8 master_slave_get; +diff --git a/include/linux/static_call.h b/include/linux/static_call.h +index 695da4c9b3381..04e6042d252d3 100644 +--- a/include/linux/static_call.h ++++ b/include/linux/static_call.h +@@ -107,26 +107,10 @@ extern void arch_static_call_transform(void *site, void *tramp, void *func, bool + + #define STATIC_CALL_TRAMP_ADDR(name) &STATIC_CALL_TRAMP(name) + +-/* +- * __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from +- * the symbol table so that objtool can reference it when it generates the +- * .static_call_sites section. +- */ +-#define __static_call(name) \ +-({ \ +- __ADDRESSABLE(STATIC_CALL_KEY(name)); \ +- &STATIC_CALL_TRAMP(name); \ +-}) +- + #else + #define STATIC_CALL_TRAMP_ADDR(name) NULL + #endif + +- +-#define DECLARE_STATIC_CALL(name, func) \ +- extern struct static_call_key STATIC_CALL_KEY(name); \ +- extern typeof(func) STATIC_CALL_TRAMP(name); +- + #define static_call_update(name, func) \ + ({ \ + BUILD_BUG_ON(!__same_type(*(func), STATIC_CALL_TRAMP(name))); \ +@@ -154,6 +138,12 @@ struct static_call_key { + }; + }; + ++/* For finding the key associated with a trampoline */ ++struct static_call_tramp_key { ++ s32 tramp; ++ s32 key; ++}; ++ + extern void __static_call_update(struct static_call_key *key, void *tramp, void *func); + extern int static_call_mod_init(struct module *mod); + extern int static_call_text_reserved(void *start, void *end); +@@ -174,17 +164,23 @@ extern int static_call_text_reserved(void *start, void *end); + }; \ + ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) + +-#define static_call(name) __static_call(name) + #define static_call_cond(name) (void)__static_call(name) + + #define EXPORT_STATIC_CALL(name) \ + EXPORT_SYMBOL(STATIC_CALL_KEY(name)); \ + EXPORT_SYMBOL(STATIC_CALL_TRAMP(name)) +- + #define EXPORT_STATIC_CALL_GPL(name) \ + EXPORT_SYMBOL_GPL(STATIC_CALL_KEY(name)); \ + EXPORT_SYMBOL_GPL(STATIC_CALL_TRAMP(name)) + ++/* Leave the key unexported, so modules can't change static call targets: */ ++#define EXPORT_STATIC_CALL_TRAMP(name) \ ++ EXPORT_SYMBOL(STATIC_CALL_TRAMP(name)); \ ++ ARCH_ADD_TRAMP_KEY(name) ++#define EXPORT_STATIC_CALL_TRAMP_GPL(name) \ ++ EXPORT_SYMBOL_GPL(STATIC_CALL_TRAMP(name)); \ ++ ARCH_ADD_TRAMP_KEY(name) ++ + #elif defined(CONFIG_HAVE_STATIC_CALL) + + static inline int static_call_init(void) { return 0; } +@@ -207,7 +203,6 @@ struct static_call_key { + }; \ + ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) + +-#define static_call(name) __static_call(name) + #define static_call_cond(name) (void)__static_call(name) + + static inline +@@ -227,11 +222,16 @@ static inline int static_call_text_reserved(void *start, void *end) + #define EXPORT_STATIC_CALL(name) \ + EXPORT_SYMBOL(STATIC_CALL_KEY(name)); \ + EXPORT_SYMBOL(STATIC_CALL_TRAMP(name)) +- + #define EXPORT_STATIC_CALL_GPL(name) \ + EXPORT_SYMBOL_GPL(STATIC_CALL_KEY(name)); \ + EXPORT_SYMBOL_GPL(STATIC_CALL_TRAMP(name)) + ++/* Leave the key unexported, so modules can't change static call targets: */ ++#define EXPORT_STATIC_CALL_TRAMP(name) \ ++ EXPORT_SYMBOL(STATIC_CALL_TRAMP(name)) ++#define EXPORT_STATIC_CALL_TRAMP_GPL(name) \ ++ EXPORT_SYMBOL_GPL(STATIC_CALL_TRAMP(name)) ++ + #else /* Generic implementation */ + + static inline int static_call_init(void) { return 0; } +@@ -252,9 +252,6 @@ struct static_call_key { + .func = NULL, \ + } + +-#define static_call(name) \ +- ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) +- + static inline void __static_call_nop(void) { } + + /* +diff --git a/include/linux/static_call_types.h b/include/linux/static_call_types.h +index 89135bb35bf76..ae5662d368b98 100644 +--- a/include/linux/static_call_types.h ++++ b/include/linux/static_call_types.h +@@ -4,11 +4,13 @@ + + #include + #include ++#include + + #define STATIC_CALL_KEY_PREFIX __SCK__ + #define STATIC_CALL_KEY_PREFIX_STR __stringify(STATIC_CALL_KEY_PREFIX) + #define STATIC_CALL_KEY_PREFIX_LEN (sizeof(STATIC_CALL_KEY_PREFIX_STR) - 1) + #define STATIC_CALL_KEY(name) __PASTE(STATIC_CALL_KEY_PREFIX, name) ++#define STATIC_CALL_KEY_STR(name) __stringify(STATIC_CALL_KEY(name)) + + #define STATIC_CALL_TRAMP_PREFIX __SCT__ + #define STATIC_CALL_TRAMP_PREFIX_STR __stringify(STATIC_CALL_TRAMP_PREFIX) +@@ -32,4 +34,52 @@ struct static_call_site { + s32 key; + }; + ++#define DECLARE_STATIC_CALL(name, func) \ ++ extern struct static_call_key STATIC_CALL_KEY(name); \ ++ extern typeof(func) STATIC_CALL_TRAMP(name); ++ ++#ifdef CONFIG_HAVE_STATIC_CALL ++ ++#define __raw_static_call(name) (&STATIC_CALL_TRAMP(name)) ++ ++#ifdef CONFIG_HAVE_STATIC_CALL_INLINE ++ ++/* ++ * __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from ++ * the symbol table so that objtool can reference it when it generates the ++ * .static_call_sites section. ++ */ ++#define __STATIC_CALL_ADDRESSABLE(name) \ ++ __ADDRESSABLE(STATIC_CALL_KEY(name)) ++ ++#define __static_call(name) \ ++({ \ ++ __STATIC_CALL_ADDRESSABLE(name); \ ++ __raw_static_call(name); \ ++}) ++ ++#else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ ++ ++#define __STATIC_CALL_ADDRESSABLE(name) ++#define __static_call(name) __raw_static_call(name) ++ ++#endif /* CONFIG_HAVE_STATIC_CALL_INLINE */ ++ ++#ifdef MODULE ++#define __STATIC_CALL_MOD_ADDRESSABLE(name) ++#define static_call_mod(name) __raw_static_call(name) ++#else ++#define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name) ++#define static_call_mod(name) __static_call(name) ++#endif ++ ++#define static_call(name) __static_call(name) ++ ++#else ++ ++#define static_call(name) \ ++ ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) ++ ++#endif /* CONFIG_HAVE_STATIC_CALL */ ++ + #endif /* _STATIC_CALL_TYPES_H */ +diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h +index c6abb79501b33..e81856c0ba134 100644 +--- a/include/linux/u64_stats_sync.h ++++ b/include/linux/u64_stats_sync.h +@@ -115,12 +115,13 @@ static inline void u64_stats_inc(u64_stats_t *p) + } + #endif + ++#if BITS_PER_LONG == 32 && defined(CONFIG_SMP) ++#define u64_stats_init(syncp) seqcount_init(&(syncp)->seq) ++#else + static inline void u64_stats_init(struct u64_stats_sync *syncp) + { +-#if BITS_PER_LONG == 32 && defined(CONFIG_SMP) +- seqcount_init(&syncp->seq); +-#endif + } ++#endif + + static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) + { +diff --git a/include/linux/usermode_driver.h b/include/linux/usermode_driver.h +index 073a9e0ec07d0..ad970416260dd 100644 +--- a/include/linux/usermode_driver.h ++++ b/include/linux/usermode_driver.h +@@ -14,5 +14,6 @@ struct umd_info { + int umd_load_blob(struct umd_info *info, const void *data, size_t len); + int umd_unload_blob(struct umd_info *info); + int fork_usermode_driver(struct umd_info *info); ++void umd_cleanup_helper(struct umd_info *info); + + #endif /* __LINUX_USERMODE_DRIVER_H__ */ +diff --git a/include/net/dst.h b/include/net/dst.h +index 8ea8812b0b418..acd15c544cf37 100644 +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -535,4 +535,15 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) + dst->ops->update_pmtu(dst, NULL, skb, mtu, false); + } + ++struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); ++void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, ++ struct sk_buff *skb, u32 mtu, bool confirm_neigh); ++void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk, ++ struct sk_buff *skb); ++u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old); ++struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst, ++ struct sk_buff *skb, ++ const void *daddr); ++unsigned int dst_blackhole_mtu(const struct dst_entry *dst); ++ + #endif /* _NET_DST_H */ +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index 111d7771b2081..aa92af3dd444d 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -284,7 +284,7 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) + return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; + } + +-void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); ++bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); + void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req); + + static inline void inet_csk_prepare_for_destroy_sock(struct sock *sk) +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index c1c0a4ff92ae9..ed4a9d098164f 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1508,6 +1508,7 @@ struct nft_trans_flowtable { + struct nft_flowtable *flowtable; + bool update; + struct list_head hook_list; ++ u32 flags; + }; + + #define nft_trans_flowtable(trans) \ +@@ -1516,6 +1517,8 @@ struct nft_trans_flowtable { + (((struct nft_trans_flowtable *)trans->data)->update) + #define nft_trans_flowtable_hooks(trans) \ + (((struct nft_trans_flowtable *)trans->data)->hook_list) ++#define nft_trans_flowtable_flags(trans) \ ++ (((struct nft_trans_flowtable *)trans->data)->flags) + + int __init nft_chain_filter_init(void); + void nft_chain_filter_fini(void); +diff --git a/include/net/nexthop.h b/include/net/nexthop.h +index 2fd76a9b6dc8b..4c8c9fe9a3f0e 100644 +--- a/include/net/nexthop.h ++++ b/include/net/nexthop.h +@@ -362,6 +362,7 @@ static inline struct fib_nh *fib_info_nh(struct fib_info *fi, int nhsel) + int fib6_check_nexthop(struct nexthop *nh, struct fib6_config *cfg, + struct netlink_ext_ack *extack); + ++/* Caller should either hold rcu_read_lock(), or RTNL. */ + static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) + { + struct nh_info *nhi; +@@ -382,6 +383,29 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) + return NULL; + } + ++/* Variant of nexthop_fib6_nh(). ++ * Caller should either hold rcu_read_lock_bh(), or RTNL. ++ */ ++static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) ++{ ++ struct nh_info *nhi; ++ ++ if (nh->is_group) { ++ struct nh_group *nh_grp; ++ ++ nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp); ++ nh = nexthop_mpath_select(nh_grp, 0); ++ if (!nh) ++ return NULL; ++ } ++ ++ nhi = rcu_dereference_bh_rtnl(nh->nh_info); ++ if (nhi->family == AF_INET6) ++ return &nhi->fib6_nh; ++ ++ return NULL; ++} ++ + static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) + { + struct fib6_nh *fib6_nh; +diff --git a/include/net/red.h b/include/net/red.h +index 932f0d79d60cb..9e6647c4ccd1f 100644 +--- a/include/net/red.h ++++ b/include/net/red.h +@@ -168,7 +168,8 @@ static inline void red_set_vars(struct red_vars *v) + v->qcount = -1; + } + +-static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_log) ++static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, ++ u8 Scell_log, u8 *stab) + { + if (fls(qth_min) + Wlog > 32) + return false; +@@ -178,6 +179,13 @@ static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_ + return false; + if (qth_max < qth_min) + return false; ++ if (stab) { ++ int i; ++ ++ for (i = 0; i < RED_STAB_SIZE; i++) ++ if (stab[i] >= 32) ++ return false; ++ } + return true; + } + +diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h +index e2091bb2b3a8e..4da61c950e931 100644 +--- a/include/net/rtnetlink.h ++++ b/include/net/rtnetlink.h +@@ -33,6 +33,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh) + * + * @list: Used internally + * @kind: Identifier ++ * @netns_refund: Physical device, move to init_net on netns exit + * @maxtype: Highest device specific netlink attribute number + * @policy: Netlink policy for device specific attribute validation + * @validate: Optional validation function for netlink/changelink parameters +@@ -64,6 +65,7 @@ struct rtnl_link_ops { + size_t priv_size; + void (*setup)(struct net_device *dev); + ++ bool netns_refund; + unsigned int maxtype; + const struct nla_policy *policy; + int (*validate)(struct nlattr *tb[], +diff --git a/include/uapi/linux/psample.h b/include/uapi/linux/psample.h +index aea26ab1431c1..bff5032c98df4 100644 +--- a/include/uapi/linux/psample.h ++++ b/include/uapi/linux/psample.h +@@ -3,7 +3,6 @@ + #define __UAPI_PSAMPLE_H + + enum { +- /* sampled packet metadata */ + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, +@@ -11,10 +10,8 @@ enum { + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, +- PSAMPLE_ATTR_TUNNEL, +- +- /* commands attributes */ + PSAMPLE_ATTR_GROUP_REFCOUNT, ++ PSAMPLE_ATTR_TUNNEL, + + __PSAMPLE_ATTR_MAX + }; +diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c +index c2a501cd90eba..a4ac48c7dada1 100644 +--- a/kernel/bpf/bpf_inode_storage.c ++++ b/kernel/bpf/bpf_inode_storage.c +@@ -109,7 +109,7 @@ static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key) + fd = *(int *)key; + f = fget_raw(fd); + if (!f) +- return NULL; ++ return ERR_PTR(-EBADF); + + sdata = inode_storage_lookup(f->f_inode, map, true); + fput(f); +diff --git a/kernel/bpf/preload/bpf_preload_kern.c b/kernel/bpf/preload/bpf_preload_kern.c +index 79c5772465f14..53736e52c1dfa 100644 +--- a/kernel/bpf/preload/bpf_preload_kern.c ++++ b/kernel/bpf/preload/bpf_preload_kern.c +@@ -60,9 +60,12 @@ static int finish(void) + &magic, sizeof(magic), &pos); + if (n != sizeof(magic)) + return -EPIPE; ++ + tgid = umd_ops.info.tgid; +- wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); +- umd_ops.info.tgid = NULL; ++ if (tgid) { ++ wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); ++ umd_cleanup_helper(&umd_ops.info); ++ } + return 0; + } + +@@ -80,10 +83,18 @@ static int __init load_umd(void) + + static void __exit fini_umd(void) + { ++ struct pid *tgid; ++ + bpf_preload_ops = NULL; ++ + /* kill UMD in case it's still there due to earlier error */ +- kill_pid(umd_ops.info.tgid, SIGKILL, 1); +- umd_ops.info.tgid = NULL; ++ tgid = umd_ops.info.tgid; ++ if (tgid) { ++ kill_pid(tgid, SIGKILL, 1); ++ ++ wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); ++ umd_cleanup_helper(&umd_ops.info); ++ } + umd_unload_blob(&umd_ops.info); + } + late_initcall(load_umd); +diff --git a/kernel/fork.c b/kernel/fork.c +index c675fdbd3dce1..7c044d377926c 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -992,6 +992,13 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p) + #endif + } + ++static void mm_init_pasid(struct mm_struct *mm) ++{ ++#ifdef CONFIG_IOMMU_SUPPORT ++ mm->pasid = INIT_PASID; ++#endif ++} ++ + static void mm_init_uprobes_state(struct mm_struct *mm) + { + #ifdef CONFIG_UPROBES +@@ -1022,6 +1029,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, + mm_init_cpumask(mm); + mm_init_aio(mm); + mm_init_owner(mm, p); ++ mm_init_pasid(mm); + RCU_INIT_POINTER(mm->exe_file, NULL); + mmu_notifier_subscriptions_init(mm); + init_tlb_flush_pending(mm); +diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c +index c94b820a1b62c..8743150db2acc 100644 +--- a/kernel/gcov/clang.c ++++ b/kernel/gcov/clang.c +@@ -75,7 +75,9 @@ struct gcov_fn_info { + + u32 num_counters; + u64 *counters; ++#if CONFIG_CLANG_VERSION < 110000 + const char *function_name; ++#endif + }; + + static struct gcov_info *current_info; +@@ -105,6 +107,7 @@ void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush) + } + EXPORT_SYMBOL(llvm_gcov_init); + ++#if CONFIG_CLANG_VERSION < 110000 + void llvm_gcda_start_file(const char *orig_filename, const char version[4], + u32 checksum) + { +@@ -113,7 +116,17 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4], + current_info->checksum = checksum; + } + EXPORT_SYMBOL(llvm_gcda_start_file); ++#else ++void llvm_gcda_start_file(const char *orig_filename, u32 version, u32 checksum) ++{ ++ current_info->filename = orig_filename; ++ current_info->version = version; ++ current_info->checksum = checksum; ++} ++EXPORT_SYMBOL(llvm_gcda_start_file); ++#endif + ++#if CONFIG_CLANG_VERSION < 110000 + void llvm_gcda_emit_function(u32 ident, const char *function_name, + u32 func_checksum, u8 use_extra_checksum, u32 cfg_checksum) + { +@@ -133,6 +146,24 @@ void llvm_gcda_emit_function(u32 ident, const char *function_name, + list_add_tail(&info->head, ¤t_info->functions); + } + EXPORT_SYMBOL(llvm_gcda_emit_function); ++#else ++void llvm_gcda_emit_function(u32 ident, u32 func_checksum, ++ u8 use_extra_checksum, u32 cfg_checksum) ++{ ++ struct gcov_fn_info *info = kzalloc(sizeof(*info), GFP_KERNEL); ++ ++ if (!info) ++ return; ++ ++ INIT_LIST_HEAD(&info->head); ++ info->ident = ident; ++ info->checksum = func_checksum; ++ info->use_extra_checksum = use_extra_checksum; ++ info->cfg_checksum = cfg_checksum; ++ list_add_tail(&info->head, ¤t_info->functions); ++} ++EXPORT_SYMBOL(llvm_gcda_emit_function); ++#endif + + void llvm_gcda_emit_arcs(u32 num_counters, u64 *counters) + { +@@ -295,6 +326,7 @@ void gcov_info_add(struct gcov_info *dst, struct gcov_info *src) + } + } + ++#if CONFIG_CLANG_VERSION < 110000 + static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn) + { + size_t cv_size; /* counter values size */ +@@ -322,6 +354,28 @@ err_name: + kfree(fn_dup); + return NULL; + } ++#else ++static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn) ++{ ++ size_t cv_size; /* counter values size */ ++ struct gcov_fn_info *fn_dup = kmemdup(fn, sizeof(*fn), ++ GFP_KERNEL); ++ if (!fn_dup) ++ return NULL; ++ INIT_LIST_HEAD(&fn_dup->head); ++ ++ cv_size = fn->num_counters * sizeof(fn->counters[0]); ++ fn_dup->counters = vmalloc(cv_size); ++ if (!fn_dup->counters) { ++ kfree(fn_dup); ++ return NULL; ++ } ++ ++ memcpy(fn_dup->counters, fn->counters, cv_size); ++ ++ return fn_dup; ++} ++#endif + + /** + * gcov_info_dup - duplicate profiling data set +@@ -362,6 +416,7 @@ err: + * gcov_info_free - release memory for profiling data set duplicate + * @info: profiling data set duplicate to free + */ ++#if CONFIG_CLANG_VERSION < 110000 + void gcov_info_free(struct gcov_info *info) + { + struct gcov_fn_info *fn, *tmp; +@@ -375,6 +430,20 @@ void gcov_info_free(struct gcov_info *info) + kfree(info->filename); + kfree(info); + } ++#else ++void gcov_info_free(struct gcov_info *info) ++{ ++ struct gcov_fn_info *fn, *tmp; ++ ++ list_for_each_entry_safe(fn, tmp, &info->functions, head) { ++ vfree(fn->counters); ++ list_del(&fn->head); ++ kfree(fn); ++ } ++ kfree(info->filename); ++ kfree(info); ++} ++#endif + + #define ITER_STRIDE PAGE_SIZE + +diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c +index c1ff7fa030abe..994ca8353543a 100644 +--- a/kernel/power/energy_model.c ++++ b/kernel/power/energy_model.c +@@ -85,7 +85,7 @@ static int __init em_debug_init(void) + + return 0; + } +-core_initcall(em_debug_init); ++fs_initcall(em_debug_init); + #else /* CONFIG_DEBUG_FS */ + static void em_debug_create_pd(struct device *dev) {} + static void em_debug_remove_pd(struct device *dev) {} +diff --git a/kernel/static_call.c b/kernel/static_call.c +index db914da6e7854..49efbdc5b4800 100644 +--- a/kernel/static_call.c ++++ b/kernel/static_call.c +@@ -12,6 +12,8 @@ + + extern struct static_call_site __start_static_call_sites[], + __stop_static_call_sites[]; ++extern struct static_call_tramp_key __start_static_call_tramp_key[], ++ __stop_static_call_tramp_key[]; + + static bool static_call_initialized; + +@@ -33,27 +35,30 @@ static inline void *static_call_addr(struct static_call_site *site) + return (void *)((long)site->addr + (long)&site->addr); + } + ++static inline unsigned long __static_call_key(const struct static_call_site *site) ++{ ++ return (long)site->key + (long)&site->key; ++} + + static inline struct static_call_key *static_call_key(const struct static_call_site *site) + { +- return (struct static_call_key *) +- (((long)site->key + (long)&site->key) & ~STATIC_CALL_SITE_FLAGS); ++ return (void *)(__static_call_key(site) & ~STATIC_CALL_SITE_FLAGS); + } + + /* These assume the key is word-aligned. */ + static inline bool static_call_is_init(struct static_call_site *site) + { +- return ((long)site->key + (long)&site->key) & STATIC_CALL_SITE_INIT; ++ return __static_call_key(site) & STATIC_CALL_SITE_INIT; + } + + static inline bool static_call_is_tail(struct static_call_site *site) + { +- return ((long)site->key + (long)&site->key) & STATIC_CALL_SITE_TAIL; ++ return __static_call_key(site) & STATIC_CALL_SITE_TAIL; + } + + static inline void static_call_set_init(struct static_call_site *site) + { +- site->key = ((long)static_call_key(site) | STATIC_CALL_SITE_INIT) - ++ site->key = (__static_call_key(site) | STATIC_CALL_SITE_INIT) - + (long)&site->key; + } + +@@ -197,7 +202,7 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func) + } + + arch_static_call_transform(site_addr, NULL, func, +- static_call_is_tail(site)); ++ static_call_is_tail(site)); + } + } + +@@ -332,10 +337,60 @@ static int __static_call_mod_text_reserved(void *start, void *end) + return ret; + } + ++static unsigned long tramp_key_lookup(unsigned long addr) ++{ ++ struct static_call_tramp_key *start = __start_static_call_tramp_key; ++ struct static_call_tramp_key *stop = __stop_static_call_tramp_key; ++ struct static_call_tramp_key *tramp_key; ++ ++ for (tramp_key = start; tramp_key != stop; tramp_key++) { ++ unsigned long tramp; ++ ++ tramp = (long)tramp_key->tramp + (long)&tramp_key->tramp; ++ if (tramp == addr) ++ return (long)tramp_key->key + (long)&tramp_key->key; ++ } ++ ++ return 0; ++} ++ + static int static_call_add_module(struct module *mod) + { +- return __static_call_init(mod, mod->static_call_sites, +- mod->static_call_sites + mod->num_static_call_sites); ++ struct static_call_site *start = mod->static_call_sites; ++ struct static_call_site *stop = start + mod->num_static_call_sites; ++ struct static_call_site *site; ++ ++ for (site = start; site != stop; site++) { ++ unsigned long s_key = __static_call_key(site); ++ unsigned long addr = s_key & ~STATIC_CALL_SITE_FLAGS; ++ unsigned long key; ++ ++ /* ++ * Is the key is exported, 'addr' points to the key, which ++ * means modules are allowed to call static_call_update() on ++ * it. ++ * ++ * Otherwise, the key isn't exported, and 'addr' points to the ++ * trampoline so we need to lookup the key. ++ * ++ * We go through this dance to prevent crazy modules from ++ * abusing sensitive static calls. ++ */ ++ if (!kernel_text_address(addr)) ++ continue; ++ ++ key = tramp_key_lookup(addr); ++ if (!key) { ++ pr_warn("Failed to fixup __raw_static_call() usage at: %ps\n", ++ static_call_addr(site)); ++ return -EINVAL; ++ } ++ ++ key |= s_key & STATIC_CALL_SITE_FLAGS; ++ site->key = key - (long)&site->key; ++ } ++ ++ return __static_call_init(mod, start, stop); + } + + static void static_call_del_module(struct module *mod) +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 9c1bba8cc51b0..82041bbf8fc2d 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -5045,6 +5045,20 @@ struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr) + return NULL; + } + ++static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long addr) ++{ ++ struct ftrace_direct_func *direct; ++ ++ direct = kmalloc(sizeof(*direct), GFP_KERNEL); ++ if (!direct) ++ return NULL; ++ direct->addr = addr; ++ direct->count = 0; ++ list_add_rcu(&direct->next, &ftrace_direct_funcs); ++ ftrace_direct_func_count++; ++ return direct; ++} ++ + /** + * register_ftrace_direct - Call a custom trampoline directly + * @ip: The address of the nop at the beginning of a function +@@ -5120,15 +5134,11 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr) + + direct = ftrace_find_direct_func(addr); + if (!direct) { +- direct = kmalloc(sizeof(*direct), GFP_KERNEL); ++ direct = ftrace_alloc_direct_func(addr); + if (!direct) { + kfree(entry); + goto out_unlock; + } +- direct->addr = addr; +- direct->count = 0; +- list_add_rcu(&direct->next, &ftrace_direct_funcs); +- ftrace_direct_func_count++; + } + + entry->ip = ip; +@@ -5329,6 +5339,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry, + int modify_ftrace_direct(unsigned long ip, + unsigned long old_addr, unsigned long new_addr) + { ++ struct ftrace_direct_func *direct, *new_direct = NULL; + struct ftrace_func_entry *entry; + struct dyn_ftrace *rec; + int ret = -ENODEV; +@@ -5344,6 +5355,20 @@ int modify_ftrace_direct(unsigned long ip, + if (entry->direct != old_addr) + goto out_unlock; + ++ direct = ftrace_find_direct_func(old_addr); ++ if (WARN_ON(!direct)) ++ goto out_unlock; ++ if (direct->count > 1) { ++ ret = -ENOMEM; ++ new_direct = ftrace_alloc_direct_func(new_addr); ++ if (!new_direct) ++ goto out_unlock; ++ direct->count--; ++ new_direct->count++; ++ } else { ++ direct->addr = new_addr; ++ } ++ + /* + * If there's no other ftrace callback on the rec->ip location, + * then it can be changed directly by the architecture. +@@ -5357,6 +5382,14 @@ int modify_ftrace_direct(unsigned long ip, + ret = 0; + } + ++ if (unlikely(ret && new_direct)) { ++ direct->count++; ++ list_del_rcu(&new_direct->next); ++ synchronize_rcu_tasks(); ++ kfree(new_direct); ++ ftrace_direct_func_count--; ++ } ++ + out_unlock: + mutex_unlock(&ftrace_lock); + mutex_unlock(&direct_mutex); +diff --git a/kernel/usermode_driver.c b/kernel/usermode_driver.c +index 0b35212ffc3d0..bb7bb3b478abf 100644 +--- a/kernel/usermode_driver.c ++++ b/kernel/usermode_driver.c +@@ -139,13 +139,22 @@ static void umd_cleanup(struct subprocess_info *info) + struct umd_info *umd_info = info->data; + + /* cleanup if umh_setup() was successful but exec failed */ +- if (info->retval) { +- fput(umd_info->pipe_to_umh); +- fput(umd_info->pipe_from_umh); +- put_pid(umd_info->tgid); +- umd_info->tgid = NULL; +- } ++ if (info->retval) ++ umd_cleanup_helper(umd_info); ++} ++ ++/** ++ * umd_cleanup_helper - release the resources which were allocated in umd_setup ++ * @info: information about usermode driver ++ */ ++void umd_cleanup_helper(struct umd_info *info) ++{ ++ fput(info->pipe_to_umh); ++ fput(info->pipe_from_umh); ++ put_pid(info->tgid); ++ info->tgid = NULL; + } ++EXPORT_SYMBOL_GPL(umd_cleanup_helper); + + /** + * fork_usermode_driver - fork a usermode driver +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 4a78514830d5a..d9ade23ac2b22 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -2433,7 +2433,7 @@ static void __split_huge_page(struct page *page, struct list_head *list, + lruvec = mem_cgroup_page_lruvec(head, pgdat); + + /* complete memcg works before add pages to LRU */ +- mem_cgroup_split_huge_fixup(head); ++ split_page_memcg(head, nr); + + if (PageAnon(head) && PageSwapCache(head)) { + swp_entry_t entry = { .val = page_private(head) }; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 94c6b3d4df96a..573f1a0183be6 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -285,6 +285,17 @@ static void record_hugetlb_cgroup_uncharge_info(struct hugetlb_cgroup *h_cg, + nrg->reservation_counter = + &h_cg->rsvd_hugepage[hstate_index(h)]; + nrg->css = &h_cg->css; ++ /* ++ * The caller will hold exactly one h_cg->css reference for the ++ * whole contiguous reservation region. But this area might be ++ * scattered when there are already some file_regions reside in ++ * it. As a result, many file_regions may share only one css ++ * reference. In order to ensure that one file_region must hold ++ * exactly one h_cg->css reference, we should do css_get for ++ * each file_region and leave the reference held by caller ++ * untouched. ++ */ ++ css_get(&h_cg->css); + if (!resv->pages_per_hpage) + resv->pages_per_hpage = pages_per_huge_page(h); + /* pages_per_hpage should be the same for all entries in +@@ -298,6 +309,14 @@ static void record_hugetlb_cgroup_uncharge_info(struct hugetlb_cgroup *h_cg, + #endif + } + ++static void put_uncharge_info(struct file_region *rg) ++{ ++#ifdef CONFIG_CGROUP_HUGETLB ++ if (rg->css) ++ css_put(rg->css); ++#endif ++} ++ + static bool has_same_uncharge_info(struct file_region *rg, + struct file_region *org) + { +@@ -321,6 +340,7 @@ static void coalesce_file_region(struct resv_map *resv, struct file_region *rg) + prg->to = rg->to; + + list_del(&rg->link); ++ put_uncharge_info(rg); + kfree(rg); + + rg = prg; +@@ -332,6 +352,7 @@ static void coalesce_file_region(struct resv_map *resv, struct file_region *rg) + nrg->from = rg->from; + + list_del(&rg->link); ++ put_uncharge_info(rg); + kfree(rg); + } + } +@@ -664,7 +685,7 @@ retry: + + del += t - f; + hugetlb_cgroup_uncharge_file_region( +- resv, rg, t - f); ++ resv, rg, t - f, false); + + /* New entry for end of split region */ + nrg->from = t; +@@ -685,7 +706,7 @@ retry: + if (f <= rg->from && t >= rg->to) { /* Remove entire region */ + del += rg->to - rg->from; + hugetlb_cgroup_uncharge_file_region(resv, rg, +- rg->to - rg->from); ++ rg->to - rg->from, true); + list_del(&rg->link); + kfree(rg); + continue; +@@ -693,13 +714,13 @@ retry: + + if (f <= rg->from) { /* Trim beginning of region */ + hugetlb_cgroup_uncharge_file_region(resv, rg, +- t - rg->from); ++ t - rg->from, false); + + del += t - rg->from; + rg->from = t; + } else { /* Trim end of region */ + hugetlb_cgroup_uncharge_file_region(resv, rg, +- rg->to - f); ++ rg->to - f, false); + + del += rg->to - f; + rg->to = f; +@@ -5189,6 +5210,10 @@ int hugetlb_reserve_pages(struct inode *inode, + */ + long rsv_adjust; + ++ /* ++ * hugetlb_cgroup_uncharge_cgroup_rsvd() will put the ++ * reference to h_cg->css. See comment below for detail. ++ */ + hugetlb_cgroup_uncharge_cgroup_rsvd( + hstate_index(h), + (chg - add) * pages_per_huge_page(h), h_cg); +@@ -5196,6 +5221,14 @@ int hugetlb_reserve_pages(struct inode *inode, + rsv_adjust = hugepage_subpool_put_pages(spool, + chg - add); + hugetlb_acct_memory(h, -rsv_adjust); ++ } else if (h_cg) { ++ /* ++ * The file_regions will hold their own reference to ++ * h_cg->css. So we should release the reference held ++ * via hugetlb_cgroup_charge_cgroup_rsvd() when we are ++ * done. ++ */ ++ hugetlb_cgroup_put_rsvd_cgroup(h_cg); + } + } + return 0; +diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c +index 9182848dda3e0..1348819f546cb 100644 +--- a/mm/hugetlb_cgroup.c ++++ b/mm/hugetlb_cgroup.c +@@ -391,7 +391,8 @@ void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, unsigned long start, + + void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, + struct file_region *rg, +- unsigned long nr_pages) ++ unsigned long nr_pages, ++ bool region_del) + { + if (hugetlb_cgroup_disabled() || !resv || !rg || !nr_pages) + return; +@@ -400,7 +401,12 @@ void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, + !resv->reservation_counter) { + page_counter_uncharge(rg->reservation_counter, + nr_pages * resv->pages_per_hpage); +- css_put(rg->css); ++ /* ++ * Only do css_put(rg->css) when we delete the entire region ++ * because one file_region must hold exactly one css reference. ++ */ ++ if (region_del) ++ css_put(rg->css); + } + } + +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index d6966f1ebc7af..d72d2b90474a4 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -3268,26 +3268,25 @@ void obj_cgroup_uncharge(struct obj_cgroup *objcg, size_t size) + + #endif /* CONFIG_MEMCG_KMEM */ + +-#ifdef CONFIG_TRANSPARENT_HUGEPAGE +- + /* +- * Because tail pages are not marked as "used", set it. We're under +- * pgdat->lru_lock and migration entries setup in all page mappings. ++ * Because head->mem_cgroup is not set on tails, set it now. + */ +-void mem_cgroup_split_huge_fixup(struct page *head) ++void split_page_memcg(struct page *head, unsigned int nr) + { + struct mem_cgroup *memcg = head->mem_cgroup; ++ int kmemcg = PageKmemcg(head); + int i; + +- if (mem_cgroup_disabled()) ++ if (mem_cgroup_disabled() || !memcg) + return; + +- for (i = 1; i < HPAGE_PMD_NR; i++) { +- css_get(&memcg->css); ++ for (i = 1; i < nr; i++) { + head[i].mem_cgroup = memcg; ++ if (kmemcg) ++ __SetPageKmemcg(head + i); + } ++ css_get_many(&memcg->css, nr - 1); + } +-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + + #ifdef CONFIG_MEMCG_SWAP + /** +diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c +index 5654dd19addc0..07f42a7a60657 100644 +--- a/mm/mmu_notifier.c ++++ b/mm/mmu_notifier.c +@@ -501,10 +501,33 @@ static int mn_hlist_invalidate_range_start( + ""); + WARN_ON(mmu_notifier_range_blockable(range) || + _ret != -EAGAIN); ++ /* ++ * We call all the notifiers on any EAGAIN, ++ * there is no way for a notifier to know if ++ * its start method failed, thus a start that ++ * does EAGAIN can't also do end. ++ */ ++ WARN_ON(ops->invalidate_range_end); + ret = _ret; + } + } + } ++ ++ if (ret) { ++ /* ++ * Must be non-blocking to get here. If there are multiple ++ * notifiers and one or more failed start, any that succeeded ++ * start are expecting their end to be called. Do so now. ++ */ ++ hlist_for_each_entry_rcu(subscription, &subscriptions->list, ++ hlist, srcu_read_lock_held(&srcu)) { ++ if (!subscription->ops->invalidate_range_end) ++ continue; ++ ++ subscription->ops->invalidate_range_end(subscription, ++ range); ++ } ++ } + srcu_read_unlock(&srcu, id); + + return ret; +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 690f79c781cf7..7ffa706e5c305 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3272,6 +3272,7 @@ void split_page(struct page *page, unsigned int order) + for (i = 1; i < (1 << order); i++) + set_page_refcounted(page + i); + split_page_owner(page, 1 << order); ++ split_page_memcg(page, 1 << order); + } + EXPORT_SYMBOL_GPL(split_page); + +diff --git a/mm/z3fold.c b/mm/z3fold.c +index 0152ad9931a87..8ae944eeb8e20 100644 +--- a/mm/z3fold.c ++++ b/mm/z3fold.c +@@ -1350,8 +1350,22 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) + page = list_entry(pos, struct page, lru); + + zhdr = page_address(page); +- if (test_bit(PAGE_HEADLESS, &page->private)) ++ if (test_bit(PAGE_HEADLESS, &page->private)) { ++ /* ++ * For non-headless pages, we wait to do this ++ * until we have the page lock to avoid racing ++ * with __z3fold_alloc(). Headless pages don't ++ * have a lock (and __z3fold_alloc() will never ++ * see them), but we still need to test and set ++ * PAGE_CLAIMED to avoid racing with ++ * z3fold_free(), so just do it now before ++ * leaving the loop. ++ */ ++ if (test_and_set_bit(PAGE_CLAIMED, &page->private)) ++ continue; ++ + break; ++ } + + if (kref_get_unless_zero(&zhdr->refcount) == 0) { + zhdr = NULL; +diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c +index 015209bf44aa4..3c42095fa75fd 100644 +--- a/net/bridge/br_switchdev.c ++++ b/net/bridge/br_switchdev.c +@@ -123,6 +123,8 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) + { + if (!fdb->dst) + return; ++ if (test_bit(BR_FDB_LOCAL, &fdb->flags)) ++ return; + + switch (type) { + case RTM_DELNEIGH: +diff --git a/net/can/isotp.c b/net/can/isotp.c +index 8bd565f2073e7..ea1e227b8e544 100644 +--- a/net/can/isotp.c ++++ b/net/can/isotp.c +@@ -196,7 +196,7 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) + nskb->dev = dev; + can_skb_set_owner(nskb, sk); + ncf = (struct canfd_frame *)nskb->data; +- skb_put(nskb, so->ll.mtu); ++ skb_put_zero(nskb, so->ll.mtu); + + /* create & send flow control reply */ + ncf->can_id = so->txid; +@@ -215,8 +215,7 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) + if (ae) + ncf->data[0] = so->opt.ext_address; + +- if (so->ll.mtu == CANFD_MTU) +- ncf->flags = so->ll.tx_flags; ++ ncf->flags = so->ll.tx_flags; + + can_send_ret = can_send(nskb, 1); + if (can_send_ret) +@@ -780,7 +779,7 @@ isotp_tx_burst: + can_skb_prv(skb)->skbcnt = 0; + + cf = (struct canfd_frame *)skb->data; +- skb_put(skb, so->ll.mtu); ++ skb_put_zero(skb, so->ll.mtu); + + /* create consecutive frame */ + isotp_fill_dataframe(cf, so, ae, 0); +@@ -790,8 +789,7 @@ isotp_tx_burst: + so->tx.sn %= 16; + so->tx.bs++; + +- if (so->ll.mtu == CANFD_MTU) +- cf->flags = so->ll.tx_flags; ++ cf->flags = so->ll.tx_flags; + + skb->dev = dev; + can_skb_set_owner(skb, sk); +@@ -889,7 +887,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) + so->tx.idx = 0; + + cf = (struct canfd_frame *)skb->data; +- skb_put(skb, so->ll.mtu); ++ skb_put_zero(skb, so->ll.mtu); + + /* take care of a potential SF_DL ESC offset for TX_DL > 8 */ + off = (so->tx.ll_dl > CAN_MAX_DLEN) ? 1 : 0; +@@ -934,8 +932,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) + } + + /* send the first or only CAN frame */ +- if (so->ll.mtu == CANFD_MTU) +- cf->flags = so->ll.tx_flags; ++ cf->flags = so->ll.tx_flags; + + skb->dev = dev; + skb->sk = sk; +@@ -1212,7 +1209,8 @@ static int isotp_setsockopt(struct socket *sock, int level, int optname, + if (ll.mtu != CAN_MTU && ll.mtu != CANFD_MTU) + return -EINVAL; + +- if (ll.mtu == CAN_MTU && ll.tx_dl > CAN_MAX_DLEN) ++ if (ll.mtu == CAN_MTU && ++ (ll.tx_dl > CAN_MAX_DLEN || ll.tx_flags != 0)) + return -EINVAL; + + memcpy(&so->ll, &ll, sizeof(ll)); +diff --git a/net/core/dev.c b/net/core/dev.c +index 75ca6c6d01d6e..62ff7121b22d3 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1195,6 +1195,18 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + return -ENOMEM; + + for_each_netdev(net, d) { ++ struct netdev_name_node *name_node; ++ list_for_each_entry(name_node, &d->name_node->list, list) { ++ if (!sscanf(name_node->name, name, &i)) ++ continue; ++ if (i < 0 || i >= max_netdevices) ++ continue; ++ ++ /* avoid cases where sscanf is not exact inverse of printf */ ++ snprintf(buf, IFNAMSIZ, name, i); ++ if (!strncmp(buf, name_node->name, IFNAMSIZ)) ++ set_bit(i, inuse); ++ } + if (!sscanf(d->name, name, &i)) + continue; + if (i < 0 || i >= max_netdevices) +@@ -11094,7 +11106,7 @@ static void __net_exit default_device_exit(struct net *net) + continue; + + /* Leave virtual devices for the generic cleanup */ +- if (dev->rtnl_link_ops) ++ if (dev->rtnl_link_ops && !dev->rtnl_link_ops->netns_refund) + continue; + + /* Push remaining network devices to init_net */ +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 571f191c06d94..db65ce62b625a 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -1053,6 +1053,20 @@ static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack) + return 0; + + err_module_put: ++ for_each_possible_cpu(cpu) { ++ struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu); ++ struct sk_buff *skb; ++ ++ del_timer_sync(&hw_data->send_timer); ++ cancel_work_sync(&hw_data->dm_alert_work); ++ while ((skb = __skb_dequeue(&hw_data->drop_queue))) { ++ struct devlink_trap_metadata *hw_metadata; ++ ++ hw_metadata = NET_DM_SKB_CB(skb)->hw_metadata; ++ net_dm_hw_metadata_free(hw_metadata); ++ consume_skb(skb); ++ } ++ } + module_put(THIS_MODULE); + return rc; + } +@@ -1134,6 +1148,15 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) + err_unregister_trace: + unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL); + err_module_put: ++ for_each_possible_cpu(cpu) { ++ struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu); ++ struct sk_buff *skb; ++ ++ del_timer_sync(&data->send_timer); ++ cancel_work_sync(&data->dm_alert_work); ++ while ((skb = __skb_dequeue(&data->drop_queue))) ++ consume_skb(skb); ++ } + module_put(THIS_MODULE); + return rc; + } +diff --git a/net/core/dst.c b/net/core/dst.c +index 0c01bd8d9d81e..fb3bcba87744d 100644 +--- a/net/core/dst.c ++++ b/net/core/dst.c +@@ -237,37 +237,62 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) + } + EXPORT_SYMBOL(__dst_destroy_metrics_generic); + +-static struct dst_ops md_dst_ops = { +- .family = AF_UNSPEC, +-}; ++struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie) ++{ ++ return NULL; ++} + +-static int dst_md_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb) ++u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old) + { +- WARN_ONCE(1, "Attempting to call output on metadata dst\n"); +- kfree_skb(skb); +- return 0; ++ return NULL; + } + +-static int dst_md_discard(struct sk_buff *skb) ++struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst, ++ struct sk_buff *skb, ++ const void *daddr) + { +- WARN_ONCE(1, "Attempting to call input on metadata dst\n"); +- kfree_skb(skb); +- return 0; ++ return NULL; ++} ++ ++void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, ++ struct sk_buff *skb, u32 mtu, ++ bool confirm_neigh) ++{ ++} ++EXPORT_SYMBOL_GPL(dst_blackhole_update_pmtu); ++ ++void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk, ++ struct sk_buff *skb) ++{ ++} ++EXPORT_SYMBOL_GPL(dst_blackhole_redirect); ++ ++unsigned int dst_blackhole_mtu(const struct dst_entry *dst) ++{ ++ unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); ++ ++ return mtu ? : dst->dev->mtu; + } ++EXPORT_SYMBOL_GPL(dst_blackhole_mtu); ++ ++static struct dst_ops dst_blackhole_ops = { ++ .family = AF_UNSPEC, ++ .neigh_lookup = dst_blackhole_neigh_lookup, ++ .check = dst_blackhole_check, ++ .cow_metrics = dst_blackhole_cow_metrics, ++ .update_pmtu = dst_blackhole_update_pmtu, ++ .redirect = dst_blackhole_redirect, ++ .mtu = dst_blackhole_mtu, ++}; + + static void __metadata_dst_init(struct metadata_dst *md_dst, + enum metadata_type type, u8 optslen) +- + { + struct dst_entry *dst; + + dst = &md_dst->dst; +- dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE, ++ dst_init(dst, &dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, + DST_METADATA | DST_NOCOUNT); +- +- dst->input = dst_md_discard; +- dst->output = dst_md_discard_out; +- + memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst)); + md_dst->type = type; + } +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index e21950a2c8970..c79be25b2e0c2 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -175,7 +175,7 @@ void skb_flow_get_icmp_tci(const struct sk_buff *skb, + * avoid confusion with packets without such field + */ + if (icmp_has_id(ih->type)) +- key_icmp->id = ih->un.echo.id ? : 1; ++ key_icmp->id = ih->un.echo.id ? ntohs(ih->un.echo.id) : 1; + else + key_icmp->id = 0; + } +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 78ee1b5acf1f1..49f4034bf1263 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -319,6 +319,11 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (!ipv6_unicast_destination(skb)) + return 0; /* discard, don't send a reset here */ + ++ if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { ++ __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); ++ return 0; ++ } ++ + if (dccp_bad_service_code(sk, service)) { + dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; + goto drop; +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index 48d2b615edc26..1dfa561e8f981 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -705,12 +705,15 @@ static bool reqsk_queue_unlink(struct request_sock *req) + return found; + } + +-void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) ++bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) + { +- if (reqsk_queue_unlink(req)) { ++ bool unlinked = reqsk_queue_unlink(req); ++ ++ if (unlinked) { + reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); + reqsk_put(req); + } ++ return unlinked; + } + EXPORT_SYMBOL(inet_csk_reqsk_queue_drop); + +diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c +index c576a63d09db1..d1e04d2b5170e 100644 +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -203,7 +203,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, + + local_bh_disable(); + addend = xt_write_recseq_begin(); +- private = rcu_access_pointer(table->private); ++ private = READ_ONCE(table->private); /* Address dependency. */ + cpu = smp_processor_id(); + table_base = private->entries; + jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; +@@ -649,7 +649,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) + { + unsigned int countersize; + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + + /* We need atomic snapshot of counters: rest doesn't change + * (other than comefrom, which userspace doesn't care +@@ -673,7 +673,7 @@ static int copy_entries_to_user(unsigned int total_size, + unsigned int off, num; + const struct arpt_entry *e; + struct xt_counters *counters; +- struct xt_table_info *private = xt_table_get_private_protected(table); ++ struct xt_table_info *private = table->private; + int ret = 0; + void *loc_cpu_entry; + +@@ -807,7 +807,7 @@ static int get_info(struct net *net, void __user *user, const int *len) + t = xt_request_find_table_lock(net, NFPROTO_ARP, name); + if (!IS_ERR(t)) { + struct arpt_getinfo info; +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + #ifdef CONFIG_COMPAT + struct xt_table_info tmp; + +@@ -860,7 +860,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, + + t = xt_find_table_lock(net, NFPROTO_ARP, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + + if (get.size == private->size) + ret = copy_entries_to_user(private->size, +@@ -1017,7 +1017,7 @@ static int do_add_counters(struct net *net, sockptr_t arg, unsigned int len) + } + + local_bh_disable(); +- private = xt_table_get_private_protected(t); ++ private = t->private; + if (private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; +@@ -1330,7 +1330,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, + void __user *userptr) + { + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + void __user *pos; + unsigned int size; + int ret = 0; +@@ -1379,7 +1379,7 @@ static int compat_get_entries(struct net *net, + xt_compat_lock(NFPROTO_ARP); + t = xt_find_table_lock(net, NFPROTO_ARP, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + struct xt_table_info info; + + ret = compat_table_info(private, &info); +diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c +index e8f6f9d862376..f15bc21d73016 100644 +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -258,7 +258,7 @@ ipt_do_table(struct sk_buff *skb, + WARN_ON(!(table->valid_hooks & (1 << hook))); + local_bh_disable(); + addend = xt_write_recseq_begin(); +- private = rcu_access_pointer(table->private); ++ private = READ_ONCE(table->private); /* Address dependency. */ + cpu = smp_processor_id(); + table_base = private->entries; + jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; +@@ -791,7 +791,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) + { + unsigned int countersize; + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + + /* We need atomic snapshot of counters: rest doesn't change + (other than comefrom, which userspace doesn't care +@@ -815,7 +815,7 @@ copy_entries_to_user(unsigned int total_size, + unsigned int off, num; + const struct ipt_entry *e; + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + int ret = 0; + const void *loc_cpu_entry; + +@@ -964,7 +964,7 @@ static int get_info(struct net *net, void __user *user, const int *len) + t = xt_request_find_table_lock(net, AF_INET, name); + if (!IS_ERR(t)) { + struct ipt_getinfo info; +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + #ifdef CONFIG_COMPAT + struct xt_table_info tmp; + +@@ -1018,7 +1018,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, + + t = xt_find_table_lock(net, AF_INET, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + if (get.size == private->size) + ret = copy_entries_to_user(private->size, + t, uptr->entrytable); +@@ -1173,7 +1173,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len) + } + + local_bh_disable(); +- private = xt_table_get_private_protected(t); ++ private = t->private; + if (private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; +@@ -1543,7 +1543,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, + void __user *userptr) + { + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + void __user *pos; + unsigned int size; + int ret = 0; +@@ -1589,7 +1589,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, + xt_compat_lock(AF_INET); + t = xt_find_table_lock(net, AF_INET, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + struct xt_table_info info; + ret = compat_table_info(private, &info); + if (!ret && get.size == info.size) +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 9f43abeac3a8e..50a6d935376f5 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2682,44 +2682,15 @@ out: + return rth; + } + +-static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie) +-{ +- return NULL; +-} +- +-static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst) +-{ +- unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); +- +- return mtu ? : dst->dev->mtu; +-} +- +-static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, +- struct sk_buff *skb, u32 mtu, +- bool confirm_neigh) +-{ +-} +- +-static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk, +- struct sk_buff *skb) +-{ +-} +- +-static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst, +- unsigned long old) +-{ +- return NULL; +-} +- + static struct dst_ops ipv4_dst_blackhole_ops = { +- .family = AF_INET, +- .check = ipv4_blackhole_dst_check, +- .mtu = ipv4_blackhole_mtu, +- .default_advmss = ipv4_default_advmss, +- .update_pmtu = ipv4_rt_blackhole_update_pmtu, +- .redirect = ipv4_rt_blackhole_redirect, +- .cow_metrics = ipv4_rt_blackhole_cow_metrics, +- .neigh_lookup = ipv4_neigh_lookup, ++ .family = AF_INET, ++ .default_advmss = ipv4_default_advmss, ++ .neigh_lookup = ipv4_neigh_lookup, ++ .check = dst_blackhole_check, ++ .cow_metrics = dst_blackhole_cow_metrics, ++ .update_pmtu = dst_blackhole_update_pmtu, ++ .redirect = dst_blackhole_redirect, ++ .mtu = dst_blackhole_mtu, + }; + + struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 495dda2449fe5..f0f67b25c97ab 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -804,8 +804,11 @@ embryonic_reset: + tcp_reset(sk); + } + if (!fastopen) { +- inet_csk_reqsk_queue_drop(sk, req); +- __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); ++ bool unlinked = inet_csk_reqsk_queue_drop(sk, req); ++ ++ if (unlinked) ++ __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); ++ *req_stolen = !unlinked; + } + return NULL; + } +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index f43e275557251..1fb79dbde0cb3 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -2485,7 +2485,7 @@ static int ipv6_route_native_seq_show(struct seq_file *seq, void *v) + const struct net_device *dev; + + if (rt->nh) +- fib6_nh = nexthop_fib6_nh(rt->nh); ++ fib6_nh = nexthop_fib6_nh_bh(rt->nh); + + seq_printf(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen); + +diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c +index e96304d8a4a7f..06d60662717d1 100644 +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -245,16 +245,6 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev, + if (ipv6_addr_is_multicast(&hdr->saddr)) + goto err; + +- /* While RFC4291 is not explicit about v4mapped addresses +- * in IPv6 headers, it seems clear linux dual-stack +- * model can not deal properly with these. +- * Security models could be fooled by ::ffff:127.0.0.1 for example. +- * +- * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 +- */ +- if (ipv6_addr_v4mapped(&hdr->saddr)) +- goto err; +- + skb->transport_header = skb->network_header + sizeof(*hdr); + IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); + +diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c +index 0d453fa9e327b..2e2119bfcf137 100644 +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -280,7 +280,7 @@ ip6t_do_table(struct sk_buff *skb, + + local_bh_disable(); + addend = xt_write_recseq_begin(); +- private = rcu_access_pointer(table->private); ++ private = READ_ONCE(table->private); /* Address dependency. */ + cpu = smp_processor_id(); + table_base = private->entries; + jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; +@@ -807,7 +807,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) + { + unsigned int countersize; + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + + /* We need atomic snapshot of counters: rest doesn't change + (other than comefrom, which userspace doesn't care +@@ -831,7 +831,7 @@ copy_entries_to_user(unsigned int total_size, + unsigned int off, num; + const struct ip6t_entry *e; + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + int ret = 0; + const void *loc_cpu_entry; + +@@ -980,7 +980,7 @@ static int get_info(struct net *net, void __user *user, const int *len) + t = xt_request_find_table_lock(net, AF_INET6, name); + if (!IS_ERR(t)) { + struct ip6t_getinfo info; +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + #ifdef CONFIG_COMPAT + struct xt_table_info tmp; + +@@ -1035,7 +1035,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, + + t = xt_find_table_lock(net, AF_INET6, get.name); + if (!IS_ERR(t)) { +- struct xt_table_info *private = xt_table_get_private_protected(t); ++ struct xt_table_info *private = t->private; + if (get.size == private->size) + ret = copy_entries_to_user(private->size, + t, uptr->entrytable); +@@ -1189,7 +1189,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len) + } + + local_bh_disable(); +- private = xt_table_get_private_protected(t); ++ private = t->private; + if (private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; +@@ -1552,7 +1552,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, + void __user *userptr) + { + struct xt_counters *counters; +- const struct xt_table_info *private = xt_table_get_private_protected(table); ++ const struct xt_table_info *private = table->private; + void __user *pos; + unsigned int size; + int ret = 0; +@@ -1598,7 +1598,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, + xt_compat_lock(AF_INET6); + t = xt_find_table_lock(net, AF_INET6, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = xt_table_get_private_protected(t); ++ const struct xt_table_info *private = t->private; + struct xt_table_info info; + ret = compat_table_info(private, &info); + if (!ret && get.size == info.size) +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 7e0ce7af82346..fa276448d5a2a 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -258,34 +258,16 @@ static struct dst_ops ip6_dst_ops_template = { + .confirm_neigh = ip6_confirm_neigh, + }; + +-static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) +-{ +- unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); +- +- return mtu ? : dst->dev->mtu; +-} +- +-static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, +- struct sk_buff *skb, u32 mtu, +- bool confirm_neigh) +-{ +-} +- +-static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk, +- struct sk_buff *skb) +-{ +-} +- + static struct dst_ops ip6_dst_blackhole_ops = { +- .family = AF_INET6, +- .destroy = ip6_dst_destroy, +- .check = ip6_dst_check, +- .mtu = ip6_blackhole_mtu, +- .default_advmss = ip6_default_advmss, +- .update_pmtu = ip6_rt_blackhole_update_pmtu, +- .redirect = ip6_rt_blackhole_redirect, +- .cow_metrics = dst_cow_metrics_generic, +- .neigh_lookup = ip6_dst_neigh_lookup, ++ .family = AF_INET6, ++ .default_advmss = ip6_default_advmss, ++ .neigh_lookup = ip6_dst_neigh_lookup, ++ .check = ip6_dst_check, ++ .destroy = ip6_dst_destroy, ++ .cow_metrics = dst_cow_metrics_generic, ++ .update_pmtu = dst_blackhole_update_pmtu, ++ .redirect = dst_blackhole_redirect, ++ .mtu = dst_blackhole_mtu, + }; + + static const u32 ip6_template_metrics[RTAX_MAX] = { +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 991dc36f95ff0..3f9bb6dd1f986 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1170,6 +1170,11 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (!ipv6_unicast_destination(skb)) + goto drop; + ++ if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { ++ __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); ++ return 0; ++ } ++ + return tcp_conn_request(&tcp6_request_sock_ops, + &tcp_request_sock_ipv6_ops, sk, skb); + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 7276e66ae435e..2bf6271d9e3f6 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2961,14 +2961,14 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, + continue; + + for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++) { +- if (~sdata->rc_rateidx_mcs_mask[i][j]) { ++ if (sdata->rc_rateidx_mcs_mask[i][j] != 0xff) { + sdata->rc_has_mcs_mask[i] = true; + break; + } + } + + for (j = 0; j < NL80211_VHT_NSS_MAX; j++) { +- if (~sdata->rc_rateidx_vht_mcs_mask[i][j]) { ++ if (sdata->rc_rateidx_vht_mcs_mask[i][j] != 0xffff) { + sdata->rc_has_vht_mcs_mask[i] = true; + break; + } +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 1f552f374e97d..a7ac53a2f00d8 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1874,6 +1874,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) + + /* remove beacon */ + kfree(sdata->u.ibss.ie); ++ sdata->u.ibss.ie = NULL; ++ sdata->u.ibss.ie_len = 0; + + /* on the next join, re-program HT parameters */ + memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa)); +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 6adfcb9c06dcc..3f483e84d5df3 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -5023,7 +5023,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, + he_oper_ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, + ies->data, ies->len); + if (he_oper_ie && +- he_oper_ie[1] == ieee80211_he_oper_size(&he_oper_ie[3])) ++ he_oper_ie[1] >= ieee80211_he_oper_size(&he_oper_ie[3])) + he_oper = (void *)(he_oper_ie + 3); + else + he_oper = NULL; +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 94e624e9439b7..d8f9fb0646a4d 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -967,7 +967,7 @@ static void ieee80211_parse_extension_element(u32 *crc, + break; + case WLAN_EID_EXT_HE_OPERATION: + if (len >= sizeof(*elems->he_operation) && +- len == ieee80211_he_oper_size(data) - 1) { ++ len >= ieee80211_he_oper_size(data) - 1) { + if (crc) + *crc = crc32_be(*crc, (void *)elem, + elem->datalen + 2); +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 16adba172fb94..6317b9bc86815 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -398,6 +398,11 @@ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (!ipv6_unicast_destination(skb)) + goto drop; + ++ if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { ++ __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); ++ return 0; ++ } ++ + return tcp_conn_request(&mptcp_subflow_request_sock_ops, + &subflow_request_sock_ipv6_ops, sk, skb); + +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 3d0fd33be0186..c1bfd8181341a 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -2960,6 +2960,7 @@ static int ctnetlink_exp_dump_mask(struct sk_buff *skb, + memset(&m, 0xFF, sizeof(m)); + memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3)); + m.src.u.all = mask->src.u.all; ++ m.src.l3num = tuple->src.l3num; + m.dst.protonum = tuple->dst.protonum; + + nest_parms = nla_nest_start(skb, CTA_EXPECT_MASK); +diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c +index 4a4acbba78ff7..b03feb6e1226a 100644 +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -506,7 +506,7 @@ int nf_flow_table_init(struct nf_flowtable *flowtable) + { + int err; + +- INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); ++ INIT_DELAYED_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); + flow_block_init(&flowtable->flow_block); + init_rwsem(&flowtable->flow_block_lock); + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 8739ef135156b..978a968d7aeda 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -6632,6 +6632,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, + struct nft_hook *hook, *next; + struct nft_trans *trans; + bool unregister = false; ++ u32 flags; + int err; + + err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK], +@@ -6646,6 +6647,17 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, + } + } + ++ if (nla[NFTA_FLOWTABLE_FLAGS]) { ++ flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); ++ if (flags & ~NFT_FLOWTABLE_MASK) ++ return -EOPNOTSUPP; ++ if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^ ++ (flags & NFT_FLOWTABLE_HW_OFFLOAD)) ++ return -EOPNOTSUPP; ++ } else { ++ flags = flowtable->data.flags; ++ } ++ + err = nft_register_flowtable_net_hooks(ctx->net, ctx->table, + &flowtable_hook.list, flowtable); + if (err < 0) +@@ -6659,6 +6671,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, + goto err_flowtable_update_hook; + } + ++ nft_trans_flowtable_flags(trans) = flags; + nft_trans_flowtable(trans) = flowtable; + nft_trans_flowtable_update(trans) = true; + INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans)); +@@ -6753,8 +6766,10 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, + if (nla[NFTA_FLOWTABLE_FLAGS]) { + flowtable->data.flags = + ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); +- if (flowtable->data.flags & ~NFT_FLOWTABLE_MASK) ++ if (flowtable->data.flags & ~NFT_FLOWTABLE_MASK) { ++ err = -EOPNOTSUPP; + goto err3; ++ } + } + + write_pnet(&flowtable->data.net, net); +@@ -7966,6 +7981,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + break; + case NFT_MSG_NEWFLOWTABLE: + if (nft_trans_flowtable_update(trans)) { ++ nft_trans_flowtable(trans)->data.flags = ++ nft_trans_flowtable_flags(trans); + nf_tables_flowtable_notify(&trans->ctx, + nft_trans_flowtable(trans), + &nft_trans_flowtable_hooks(trans), +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index bce6ca203d462..6bd31a7a27fc5 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -1351,14 +1351,6 @@ struct xt_counters *xt_counters_alloc(unsigned int counters) + } + EXPORT_SYMBOL(xt_counters_alloc); + +-struct xt_table_info +-*xt_table_get_private_protected(const struct xt_table *table) +-{ +- return rcu_dereference_protected(table->private, +- mutex_is_locked(&xt[table->af].mutex)); +-} +-EXPORT_SYMBOL(xt_table_get_private_protected); +- + struct xt_table_info * + xt_replace_table(struct xt_table *table, + unsigned int num_counters, +@@ -1366,6 +1358,7 @@ xt_replace_table(struct xt_table *table, + int *error) + { + struct xt_table_info *private; ++ unsigned int cpu; + int ret; + + ret = xt_jumpstack_alloc(newinfo); +@@ -1375,20 +1368,47 @@ xt_replace_table(struct xt_table *table, + } + + /* Do the substitution. */ +- private = xt_table_get_private_protected(table); ++ local_bh_disable(); ++ private = table->private; + + /* Check inside lock: is the old number correct? */ + if (num_counters != private->number) { + pr_debug("num_counters != table->private->number (%u/%u)\n", + num_counters, private->number); ++ local_bh_enable(); + *error = -EAGAIN; + return NULL; + } + + newinfo->initial_entries = private->initial_entries; ++ /* ++ * Ensure contents of newinfo are visible before assigning to ++ * private. ++ */ ++ smp_wmb(); ++ table->private = newinfo; ++ ++ /* make sure all cpus see new ->private value */ ++ smp_mb(); + +- rcu_assign_pointer(table->private, newinfo); +- synchronize_rcu(); ++ /* ++ * Even though table entries have now been swapped, other CPU's ++ * may still be using the old entries... ++ */ ++ local_bh_enable(); ++ ++ /* ... so wait for even xt_recseq on all cpus */ ++ for_each_possible_cpu(cpu) { ++ seqcount_t *s = &per_cpu(xt_recseq, cpu); ++ u32 seq = raw_read_seqcount(s); ++ ++ if (seq & 1) { ++ do { ++ cond_resched(); ++ cpu_relax(); ++ } while (seq == raw_read_seqcount(s)); ++ } ++ } + + audit_log_nfcfg(table->name, table->af, private->number, + !private->number ? AUDIT_XT_OP_REGISTER : +@@ -1424,12 +1444,12 @@ struct xt_table *xt_register_table(struct net *net, + } + + /* Simplifies replace_table code. */ +- rcu_assign_pointer(table->private, bootstrap); ++ table->private = bootstrap; + + if (!xt_replace_table(table, 0, newinfo, &ret)) + goto unlock; + +- private = xt_table_get_private_protected(table); ++ private = table->private; + pr_debug("table->private->number = %u\n", private->number); + + /* save number of initial entries */ +@@ -1452,8 +1472,7 @@ void *xt_unregister_table(struct xt_table *table) + struct xt_table_info *private; + + mutex_lock(&xt[table->af].mutex); +- private = xt_table_get_private_protected(table); +- RCU_INIT_POINTER(table->private, NULL); ++ private = table->private; + list_del(&table->list); + mutex_unlock(&xt[table->af].mutex); + audit_log_nfcfg(table->name, table->af, private->number, +diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c +index 54031ee079a2c..45fbf5f4dcd25 100644 +--- a/net/qrtr/qrtr.c ++++ b/net/qrtr/qrtr.c +@@ -1035,6 +1035,11 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, + rc = copied; + + if (addr) { ++ /* There is an anonymous 2-byte hole after sq_family, ++ * make sure to clear it. ++ */ ++ memset(addr, 0, sizeof(*addr)); ++ + addr->sq_family = AF_QIPCRTR; + addr->sq_node = cb->src_node; + addr->sq_port = cb->src_port; +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 46c1b3e9f66a5..14316ba9b3b32 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -1432,7 +1432,7 @@ static int fl_set_key_ct(struct nlattr **tb, + &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK, + sizeof(key->ct_state)); + +- err = fl_validate_ct_state(mask->ct_state, ++ err = fl_validate_ct_state(key->ct_state & mask->ct_state, + tb[TCA_FLOWER_KEY_CT_STATE_MASK], + extack); + if (err) +diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c +index 50f680f03a547..2adbd945bf15a 100644 +--- a/net/sched/sch_choke.c ++++ b/net/sched/sch_choke.c +@@ -345,6 +345,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, + struct sk_buff **old = NULL; + unsigned int mask; + u32 max_P; ++ u8 *stab; + + if (opt == NULL) + return -EINVAL; +@@ -361,8 +362,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, + max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0; + + ctl = nla_data(tb[TCA_CHOKE_PARMS]); +- +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) ++ stab = nla_data(tb[TCA_CHOKE_STAB]); ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) + return -EINVAL; + + if (ctl->limit > CHOKE_MAX_QUEUE) +@@ -412,7 +413,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, + + red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, + ctl->Plog, ctl->Scell_log, +- nla_data(tb[TCA_CHOKE_STAB]), ++ stab, + max_P); + red_set_vars(&q->vars); + +diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c +index e0bc77533acc3..f4132dc25ac05 100644 +--- a/net/sched/sch_gred.c ++++ b/net/sched/sch_gred.c +@@ -480,7 +480,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, + struct gred_sched *table = qdisc_priv(sch); + struct gred_sched_data *q = table->tab[dp]; + +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) { ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) { + NL_SET_ERR_MSG_MOD(extack, "invalid RED parameters"); + return -EINVAL; + } +diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c +index b4ae34d7aa965..40adf1f07a82d 100644 +--- a/net/sched/sch_red.c ++++ b/net/sched/sch_red.c +@@ -242,6 +242,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, + unsigned char flags; + int err; + u32 max_P; ++ u8 *stab; + + if (tb[TCA_RED_PARMS] == NULL || + tb[TCA_RED_STAB] == NULL) +@@ -250,7 +251,9 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, + max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; + + ctl = nla_data(tb[TCA_RED_PARMS]); +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) ++ stab = nla_data(tb[TCA_RED_STAB]); ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ++ ctl->Scell_log, stab)) + return -EINVAL; + + err = red_get_flags(ctl->flags, TC_RED_HISTORIC_FLAGS, +@@ -288,7 +291,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb, + red_set_parms(&q->parms, + ctl->qth_min, ctl->qth_max, ctl->Wlog, + ctl->Plog, ctl->Scell_log, +- nla_data(tb[TCA_RED_STAB]), ++ stab, + max_P); + red_set_vars(&q->vars); + +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index b25e51440623b..066754a18569b 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -647,7 +647,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) + } + + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, +- ctl_v1->Wlog, ctl_v1->Scell_log)) ++ ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) + return -EINVAL; + if (ctl_v1 && ctl_v1->qth_min) { + p = kmalloc(sizeof(*p), GFP_KERNEL); +diff --git a/net/tipc/node.c b/net/tipc/node.c +index 83978d5dae594..e4452d55851f9 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -2855,17 +2855,22 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, + + #ifdef CONFIG_TIPC_CRYPTO + static int tipc_nl_retrieve_key(struct nlattr **attrs, +- struct tipc_aead_key **key) ++ struct tipc_aead_key **pkey) + { + struct nlattr *attr = attrs[TIPC_NLA_NODE_KEY]; ++ struct tipc_aead_key *key; + + if (!attr) + return -ENODATA; + +- *key = (struct tipc_aead_key *)nla_data(attr); +- if (nla_len(attr) < tipc_aead_key_size(*key)) ++ if (nla_len(attr) < sizeof(*key)) ++ return -EINVAL; ++ key = (struct tipc_aead_key *)nla_data(attr); ++ if (key->keylen > TIPC_AEAD_KEYLEN_MAX || ++ nla_len(attr) < tipc_aead_key_size(key)) + return -EINVAL; + ++ *pkey = key; + return 0; + } + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 791955f5e7ec0..cf86c1376b1a4 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -738,6 +738,7 @@ static struct sock *__vsock_create(struct net *net, + vsk->buffer_size = psk->buffer_size; + vsk->buffer_min_size = psk->buffer_min_size; + vsk->buffer_max_size = psk->buffer_max_size; ++ security_sk_clone(parent, sk); + } else { + vsk->trusted = ns_capable_noaudit(&init_user_ns, CAP_NET_ADMIN); + vsk->owner = get_current_cred(); +diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc +index 33487e99d83e5..11c9f045ee4b9 100755 +--- a/scripts/dummy-tools/gcc ++++ b/scripts/dummy-tools/gcc +@@ -89,3 +89,8 @@ if arg_contain -print-file-name=plugin "$@"; then + echo $plugin_dir + exit 0 + fi ++ ++# inverted return value ++if arg_contain -D__SIZEOF_INT128__=0 "$@"; then ++ exit 1 ++fi +diff --git a/security/integrity/iint.c b/security/integrity/iint.c +index 1d20003243c3f..0ba01847e836c 100644 +--- a/security/integrity/iint.c ++++ b/security/integrity/iint.c +@@ -98,6 +98,14 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode) + struct rb_node *node, *parent = NULL; + struct integrity_iint_cache *iint, *test_iint; + ++ /* ++ * The integrity's "iint_cache" is initialized at security_init(), ++ * unless it is not included in the ordered list of LSMs enabled ++ * on the boot command line. ++ */ ++ if (!iint_cache) ++ panic("%s: lsm=integrity required.\n", __func__); ++ + iint = integrity_iint_find(inode); + if (iint) + return iint; +diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h +index 3cc8bab31ea85..63ca6e79daeb9 100644 +--- a/security/selinux/include/security.h ++++ b/security/selinux/include/security.h +@@ -219,14 +219,21 @@ static inline bool selinux_policycap_genfs_seclabel_symlinks(void) + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]); + } + ++struct selinux_policy_convert_data; ++ ++struct selinux_load_state { ++ struct selinux_policy *policy; ++ struct selinux_policy_convert_data *convert_data; ++}; ++ + int security_mls_enabled(struct selinux_state *state); + int security_load_policy(struct selinux_state *state, +- void *data, size_t len, +- struct selinux_policy **newpolicyp); ++ void *data, size_t len, ++ struct selinux_load_state *load_state); + void selinux_policy_commit(struct selinux_state *state, +- struct selinux_policy *newpolicy); ++ struct selinux_load_state *load_state); + void selinux_policy_cancel(struct selinux_state *state, +- struct selinux_policy *policy); ++ struct selinux_load_state *load_state); + int security_read_policy(struct selinux_state *state, + void **data, size_t *len); + +diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c +index 4bde570d56a2c..2b745ae8cb981 100644 +--- a/security/selinux/selinuxfs.c ++++ b/security/selinux/selinuxfs.c +@@ -616,7 +616,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, + + { + struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info; +- struct selinux_policy *newpolicy; ++ struct selinux_load_state load_state; + ssize_t length; + void *data = NULL; + +@@ -642,23 +642,22 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, + if (copy_from_user(data, buf, count) != 0) + goto out; + +- length = security_load_policy(fsi->state, data, count, &newpolicy); ++ length = security_load_policy(fsi->state, data, count, &load_state); + if (length) { + pr_warn_ratelimited("SELinux: failed to load policy\n"); + goto out; + } + +- length = sel_make_policy_nodes(fsi, newpolicy); ++ length = sel_make_policy_nodes(fsi, load_state.policy); + if (length) { +- selinux_policy_cancel(fsi->state, newpolicy); +- goto out1; ++ selinux_policy_cancel(fsi->state, &load_state); ++ goto out; + } + +- selinux_policy_commit(fsi->state, newpolicy); ++ selinux_policy_commit(fsi->state, &load_state); + + length = count; + +-out1: + audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, + "auid=%u ses=%u lsm=selinux res=1", + from_kuid(&init_user_ns, audit_get_loginuid(current)), +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index 9704c8a32303f..495fc865faf55 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -66,6 +66,17 @@ + #include "audit.h" + #include "policycap_names.h" + ++struct convert_context_args { ++ struct selinux_state *state; ++ struct policydb *oldp; ++ struct policydb *newp; ++}; ++ ++struct selinux_policy_convert_data { ++ struct convert_context_args args; ++ struct sidtab_convert_params sidtab_params; ++}; ++ + /* Forward declaration. */ + static int context_struct_to_string(struct policydb *policydb, + struct context *context, +@@ -1975,12 +1986,6 @@ static inline int convert_context_handle_invalid_context( + return 0; + } + +-struct convert_context_args { +- struct selinux_state *state; +- struct policydb *oldp; +- struct policydb *newp; +-}; +- + /* + * Convert the values in the security context + * structure `oldc' from the values specified +@@ -2160,7 +2165,7 @@ static void selinux_policy_cond_free(struct selinux_policy *policy) + } + + void selinux_policy_cancel(struct selinux_state *state, +- struct selinux_policy *policy) ++ struct selinux_load_state *load_state) + { + struct selinux_policy *oldpolicy; + +@@ -2168,7 +2173,8 @@ void selinux_policy_cancel(struct selinux_state *state, + lockdep_is_held(&state->policy_mutex)); + + sidtab_cancel_convert(oldpolicy->sidtab); +- selinux_policy_free(policy); ++ selinux_policy_free(load_state->policy); ++ kfree(load_state->convert_data); + } + + static void selinux_notify_policy_change(struct selinux_state *state, +@@ -2183,9 +2189,9 @@ static void selinux_notify_policy_change(struct selinux_state *state, + } + + void selinux_policy_commit(struct selinux_state *state, +- struct selinux_policy *newpolicy) ++ struct selinux_load_state *load_state) + { +- struct selinux_policy *oldpolicy; ++ struct selinux_policy *oldpolicy, *newpolicy = load_state->policy; + u32 seqno; + + oldpolicy = rcu_dereference_protected(state->policy, +@@ -2225,6 +2231,7 @@ void selinux_policy_commit(struct selinux_state *state, + /* Free the old policy */ + synchronize_rcu(); + selinux_policy_free(oldpolicy); ++ kfree(load_state->convert_data); + + /* Notify others of the policy change */ + selinux_notify_policy_change(state, seqno); +@@ -2241,11 +2248,10 @@ void selinux_policy_commit(struct selinux_state *state, + * loading the new policy. + */ + int security_load_policy(struct selinux_state *state, void *data, size_t len, +- struct selinux_policy **newpolicyp) ++ struct selinux_load_state *load_state) + { + struct selinux_policy *newpolicy, *oldpolicy; +- struct sidtab_convert_params convert_params; +- struct convert_context_args args; ++ struct selinux_policy_convert_data *convert_data; + int rc = 0; + struct policy_file file = { data, len }, *fp = &file; + +@@ -2275,10 +2281,10 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len, + goto err_mapping; + } + +- + if (!selinux_initialized(state)) { + /* First policy load, so no need to preserve state from old policy */ +- *newpolicyp = newpolicy; ++ load_state->policy = newpolicy; ++ load_state->convert_data = NULL; + return 0; + } + +@@ -2292,29 +2298,38 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len, + goto err_free_isids; + } + ++ convert_data = kmalloc(sizeof(*convert_data), GFP_KERNEL); ++ if (!convert_data) { ++ rc = -ENOMEM; ++ goto err_free_isids; ++ } ++ + /* + * Convert the internal representations of contexts + * in the new SID table. + */ +- args.state = state; +- args.oldp = &oldpolicy->policydb; +- args.newp = &newpolicy->policydb; ++ convert_data->args.state = state; ++ convert_data->args.oldp = &oldpolicy->policydb; ++ convert_data->args.newp = &newpolicy->policydb; + +- convert_params.func = convert_context; +- convert_params.args = &args; +- convert_params.target = newpolicy->sidtab; ++ convert_data->sidtab_params.func = convert_context; ++ convert_data->sidtab_params.args = &convert_data->args; ++ convert_data->sidtab_params.target = newpolicy->sidtab; + +- rc = sidtab_convert(oldpolicy->sidtab, &convert_params); ++ rc = sidtab_convert(oldpolicy->sidtab, &convert_data->sidtab_params); + if (rc) { + pr_err("SELinux: unable to convert the internal" + " representation of contexts in the new SID" + " table\n"); +- goto err_free_isids; ++ goto err_free_convert_data; + } + +- *newpolicyp = newpolicy; ++ load_state->policy = newpolicy; ++ load_state->convert_data = convert_data; + return 0; + ++err_free_convert_data: ++ kfree(convert_data); + err_free_isids: + sidtab_destroy(newpolicy->sidtab); + err_mapping: +diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c +index d053beccfaec3..e2237239d922a 100644 +--- a/sound/hda/intel-nhlt.c ++++ b/sound/hda/intel-nhlt.c +@@ -39,6 +39,11 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt) + if (!nhlt) + return 0; + ++ if (nhlt->header.length <= sizeof(struct acpi_table_header)) { ++ dev_warn(dev, "Invalid DMIC description table\n"); ++ return 0; ++ } ++ + for (j = 0, epnt = nhlt->desc; j < nhlt->endpoint_count; j++, + epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length)) { + +diff --git a/tools/include/linux/static_call_types.h b/tools/include/linux/static_call_types.h +index 89135bb35bf76..ae5662d368b98 100644 +--- a/tools/include/linux/static_call_types.h ++++ b/tools/include/linux/static_call_types.h +@@ -4,11 +4,13 @@ + + #include + #include ++#include + + #define STATIC_CALL_KEY_PREFIX __SCK__ + #define STATIC_CALL_KEY_PREFIX_STR __stringify(STATIC_CALL_KEY_PREFIX) + #define STATIC_CALL_KEY_PREFIX_LEN (sizeof(STATIC_CALL_KEY_PREFIX_STR) - 1) + #define STATIC_CALL_KEY(name) __PASTE(STATIC_CALL_KEY_PREFIX, name) ++#define STATIC_CALL_KEY_STR(name) __stringify(STATIC_CALL_KEY(name)) + + #define STATIC_CALL_TRAMP_PREFIX __SCT__ + #define STATIC_CALL_TRAMP_PREFIX_STR __stringify(STATIC_CALL_TRAMP_PREFIX) +@@ -32,4 +34,52 @@ struct static_call_site { + s32 key; + }; + ++#define DECLARE_STATIC_CALL(name, func) \ ++ extern struct static_call_key STATIC_CALL_KEY(name); \ ++ extern typeof(func) STATIC_CALL_TRAMP(name); ++ ++#ifdef CONFIG_HAVE_STATIC_CALL ++ ++#define __raw_static_call(name) (&STATIC_CALL_TRAMP(name)) ++ ++#ifdef CONFIG_HAVE_STATIC_CALL_INLINE ++ ++/* ++ * __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from ++ * the symbol table so that objtool can reference it when it generates the ++ * .static_call_sites section. ++ */ ++#define __STATIC_CALL_ADDRESSABLE(name) \ ++ __ADDRESSABLE(STATIC_CALL_KEY(name)) ++ ++#define __static_call(name) \ ++({ \ ++ __STATIC_CALL_ADDRESSABLE(name); \ ++ __raw_static_call(name); \ ++}) ++ ++#else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ ++ ++#define __STATIC_CALL_ADDRESSABLE(name) ++#define __static_call(name) __raw_static_call(name) ++ ++#endif /* CONFIG_HAVE_STATIC_CALL_INLINE */ ++ ++#ifdef MODULE ++#define __STATIC_CALL_MOD_ADDRESSABLE(name) ++#define static_call_mod(name) __raw_static_call(name) ++#else ++#define __STATIC_CALL_MOD_ADDRESSABLE(name) __STATIC_CALL_ADDRESSABLE(name) ++#define static_call_mod(name) __static_call(name) ++#endif ++ ++#define static_call(name) __static_call(name) ++ ++#else ++ ++#define static_call(name) \ ++ ((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func)) ++ ++#endif /* CONFIG_HAVE_STATIC_CALL */ ++ + #endif /* _STATIC_CALL_TYPES_H */ +diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile +index 55bd78b3496fb..310f647c2d5b6 100644 +--- a/tools/lib/bpf/Makefile ++++ b/tools/lib/bpf/Makefile +@@ -236,7 +236,7 @@ define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ +- $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' ++ $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2' + endef + + install_lib: all_cmd +diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c +index 2f9d685bd522c..0911aea4cdbe5 100644 +--- a/tools/lib/bpf/btf_dump.c ++++ b/tools/lib/bpf/btf_dump.c +@@ -462,7 +462,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) + return err; + + case BTF_KIND_ARRAY: +- return btf_dump_order_type(d, btf_array(t)->type, through_ptr); ++ return btf_dump_order_type(d, btf_array(t)->type, false); + + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index b954db52bb807..95eef7ebdac5c 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -1162,7 +1162,8 @@ static int bpf_object__elf_init(struct bpf_object *obj) + if (!elf_rawdata(elf_getscn(obj->efile.elf, obj->efile.shstrndx), NULL)) { + pr_warn("elf: failed to get section names strings from %s: %s\n", + obj->path, elf_errmsg(-1)); +- return -LIBBPF_ERRNO__FORMAT; ++ err = -LIBBPF_ERRNO__FORMAT; ++ goto errout; + } + + /* Old LLVM set e_machine to EM_NONE */ +diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c +index 4dd73de00b6f1..d2cb28e9ef52e 100644 +--- a/tools/lib/bpf/netlink.c ++++ b/tools/lib/bpf/netlink.c +@@ -40,7 +40,7 @@ static int libbpf_netlink_open(__u32 *nl_pid) + memset(&sa, 0, sizeof(sa)); + sa.nl_family = AF_NETLINK; + +- sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); + if (sock < 0) + return -errno; + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index dc24aac08edd6..5c83f73ad6687 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -502,8 +502,21 @@ static int create_static_call_sections(struct objtool_file *file) + + key_sym = find_symbol_by_name(file->elf, tmp); + if (!key_sym) { +- WARN("static_call: can't find static_call_key symbol: %s", tmp); +- return -1; ++ if (!module) { ++ WARN("static_call: can't find static_call_key symbol: %s", tmp); ++ return -1; ++ } ++ ++ /* ++ * For modules(), the key might not be exported, which ++ * means the module can make static calls but isn't ++ * allowed to change them. ++ * ++ * In that case we temporarily set the key to be the ++ * trampoline address. This is fixed up in ++ * static_call_add_module(). ++ */ ++ key_sym = insn->call_dest; + } + free(key_name); + +diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c +index 42a85c86421d7..d8ada6a3c555a 100644 +--- a/tools/perf/util/auxtrace.c ++++ b/tools/perf/util/auxtrace.c +@@ -300,10 +300,6 @@ static int auxtrace_queues__queue_buffer(struct auxtrace_queues *queues, + queue->set = true; + queue->tid = buffer->tid; + queue->cpu = buffer->cpu; +- } else if (buffer->cpu != queue->cpu || buffer->tid != queue->tid) { +- pr_err("auxtrace queue conflict: cpu %d, tid %d vs cpu %d, tid %d\n", +- queue->cpu, queue->tid, buffer->cpu, buffer->tid); +- return -EINVAL; + } + + buffer->buffer_nr = queues->next_buffer_nr++; +diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c +index d9c624377da73..b4cf6dd57dd6e 100644 +--- a/tools/perf/util/synthetic-events.c ++++ b/tools/perf/util/synthetic-events.c +@@ -384,7 +384,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, + + while (!io.eof) { + static const char anonstr[] = "//anon"; +- size_t size; ++ size_t size, aligned_size; + + /* ensure null termination since stack will be reused. */ + event->mmap2.filename[0] = '\0'; +@@ -444,11 +444,12 @@ out: + } + + size = strlen(event->mmap2.filename) + 1; +- size = PERF_ALIGN(size, sizeof(u64)); ++ aligned_size = PERF_ALIGN(size, sizeof(u64)); + event->mmap2.len -= event->mmap.start; + event->mmap2.header.size = (sizeof(event->mmap2) - +- (sizeof(event->mmap2.filename) - size)); +- memset(event->mmap2.filename + size, 0, machine->id_hdr_size); ++ (sizeof(event->mmap2.filename) - aligned_size)); ++ memset(event->mmap2.filename + size, 0, machine->id_hdr_size + ++ (aligned_size - size)); + event->mmap2.header.size += machine->id_hdr_size; + event->mmap2.pid = tgid; + event->mmap2.tid = pid; +diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c +index b2282be6f9384..612d3899614ac 100644 +--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c ++++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c +@@ -332,5 +332,5 @@ int main(void) + + ksft_print_cnts(); + +- return 0; ++ return ret; + } +diff --git a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +index 9afe947cfae95..ba6eadfec5653 100644 +--- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c ++++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +@@ -508,10 +508,8 @@ int _ip6geneve_get_tunnel(struct __sk_buff *skb) + } + + ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt)); +- if (ret < 0) { +- ERROR(ret); +- return TC_ACT_SHOT; +- } ++ if (ret < 0) ++ gopt.opt_class = 0; + + bpf_trace_printk(fmt, sizeof(fmt), + key.tunnel_id, key.remote_ipv4, gopt.opt_class); +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index ce6bea9675c07..0ccb1dda099ae 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -658,7 +658,7 @@ test_ecn_decap() + # In accordance with INET_ECN_decapsulate() + __test_ecn_decap 00 00 0x00 + __test_ecn_decap 01 01 0x01 +- __test_ecn_decap 02 01 0x02 ++ __test_ecn_decap 02 01 0x01 + __test_ecn_decap 01 03 0x03 + __test_ecn_decap 02 03 0x03 + test_ecn_decap_error +diff --git a/tools/testing/selftests/net/reuseaddr_ports_exhausted.c b/tools/testing/selftests/net/reuseaddr_ports_exhausted.c +index 7b01b7c2ec104..066efd30e2946 100644 +--- a/tools/testing/selftests/net/reuseaddr_ports_exhausted.c ++++ b/tools/testing/selftests/net/reuseaddr_ports_exhausted.c +@@ -30,25 +30,25 @@ struct reuse_opts { + }; + + struct reuse_opts unreusable_opts[12] = { +- {0, 0, 0, 0}, +- {0, 0, 0, 1}, +- {0, 0, 1, 0}, +- {0, 0, 1, 1}, +- {0, 1, 0, 0}, +- {0, 1, 0, 1}, +- {0, 1, 1, 0}, +- {0, 1, 1, 1}, +- {1, 0, 0, 0}, +- {1, 0, 0, 1}, +- {1, 0, 1, 0}, +- {1, 0, 1, 1}, ++ {{0, 0}, {0, 0}}, ++ {{0, 0}, {0, 1}}, ++ {{0, 0}, {1, 0}}, ++ {{0, 0}, {1, 1}}, ++ {{0, 1}, {0, 0}}, ++ {{0, 1}, {0, 1}}, ++ {{0, 1}, {1, 0}}, ++ {{0, 1}, {1, 1}}, ++ {{1, 0}, {0, 0}}, ++ {{1, 0}, {0, 1}}, ++ {{1, 0}, {1, 0}}, ++ {{1, 0}, {1, 1}}, + }; + + struct reuse_opts reusable_opts[4] = { +- {1, 1, 0, 0}, +- {1, 1, 0, 1}, +- {1, 1, 1, 0}, +- {1, 1, 1, 1}, ++ {{1, 1}, {0, 0}}, ++ {{1, 1}, {0, 1}}, ++ {{1, 1}, {1, 0}}, ++ {{1, 1}, {1, 1}}, + }; + + int bind_port(struct __test_metadata *_metadata, int reuseaddr, int reuseport) diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.27-28.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.27-28.patch new file mode 100644 index 0000000000..cbb3f32e5d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.27-28.patch @@ -0,0 +1,7730 @@ +diff --git a/Makefile b/Makefile +index 4801cc25e3472..cb76f64abb6da 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 27 ++SUBLEVEL = 28 + EXTRAVERSION = + NAME = Dare mighty things + +diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c +index 6aabf1eced31e..afdad76078506 100644 +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -1447,14 +1447,30 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) + + static bool inside_linear_region(u64 start, u64 size) + { ++ u64 start_linear_pa = __pa(_PAGE_OFFSET(vabits_actual)); ++ u64 end_linear_pa = __pa(PAGE_END - 1); ++ ++ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { ++ /* ++ * Check for a wrap, it is possible because of randomized linear ++ * mapping the start physical address is actually bigger than ++ * the end physical address. In this case set start to zero ++ * because [0, end_linear_pa] range must still be able to cover ++ * all addressable physical addresses. ++ */ ++ if (start_linear_pa > end_linear_pa) ++ start_linear_pa = 0; ++ } ++ ++ WARN_ON(start_linear_pa > end_linear_pa); ++ + /* + * Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] + * accommodating both its ends but excluding PAGE_END. Max physical + * range which can be mapped inside this linear mapping range, must + * also be derived from its end points. + */ +- return start >= __pa(_PAGE_OFFSET(vabits_actual)) && +- (start + size - 1) <= __pa(PAGE_END - 1); ++ return start >= start_linear_pa && (start + size - 1) <= end_linear_pa; + } + + int arch_add_memory(int nid, u64 start, u64 size, +diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h +index 824b2c9da75bd..f944062c9d990 100644 +--- a/arch/riscv/include/asm/uaccess.h ++++ b/arch/riscv/include/asm/uaccess.h +@@ -306,7 +306,9 @@ do { \ + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable +- * to the result of dereferencing @ptr. ++ * to the result of dereferencing @ptr. The value of @x is copied to avoid ++ * re-ordering where @x is evaluated inside the block that enables user-space ++ * access (thus bypassing user space protection if @x is a function). + * + * Caller must check the pointer with access_ok() before calling this + * function. +@@ -316,12 +318,13 @@ do { \ + #define __put_user(x, ptr) \ + ({ \ + __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ ++ __typeof__(*__gu_ptr) __val = (x); \ + long __pu_err = 0; \ + \ + __chk_user_ptr(__gu_ptr); \ + \ + __enable_user_access(); \ +- __put_user_nocheck(x, __gu_ptr, __pu_err); \ ++ __put_user_nocheck(__val, __gu_ptr, __pu_err); \ + __disable_user_access(); \ + \ + __pu_err; \ +diff --git a/arch/s390/include/asm/vdso/data.h b/arch/s390/include/asm/vdso/data.h +index 7b3cdb4a5f481..73ee891426662 100644 +--- a/arch/s390/include/asm/vdso/data.h ++++ b/arch/s390/include/asm/vdso/data.h +@@ -6,7 +6,7 @@ + #include + + struct arch_vdso_data { +- __u64 tod_steering_delta; ++ __s64 tod_steering_delta; + __u64 tod_steering_end; + }; + +diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c +index 0ac30ee2c6330..b6517453fa234 100644 +--- a/arch/s390/kernel/time.c ++++ b/arch/s390/kernel/time.c +@@ -398,6 +398,7 @@ static void clock_sync_global(unsigned long long delta) + tod_steering_delta); + tod_steering_end = now + (abs(tod_steering_delta) << 15); + vdso_data->arch_data.tod_steering_end = tod_steering_end; ++ vdso_data->arch_data.tod_steering_delta = tod_steering_delta; + + /* Update LPAR offset. */ + if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0) +diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h +index c0538f82c9a22..57ef2094af93e 100644 +--- a/arch/x86/include/asm/smp.h ++++ b/arch/x86/include/asm/smp.h +@@ -132,6 +132,7 @@ void native_play_dead(void); + void play_dead_common(void); + void wbinvd_on_cpu(int cpu); + int wbinvd_on_all_cpus(void); ++bool wakeup_cpu0(void); + + void native_smp_send_reschedule(int cpu); + void native_send_call_func_ipi(const struct cpumask *mask); +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 7bdc0239a9435..14cd3186dc77d 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1554,10 +1554,18 @@ void __init acpi_boot_table_init(void) + /* + * Initialize the ACPI boot-time table parser. + */ +- if (acpi_table_init()) { ++ if (acpi_locate_initial_tables()) + disable_acpi(); +- return; +- } ++ else ++ acpi_reserve_initial_tables(); ++} ++ ++int __init early_acpi_boot_init(void) ++{ ++ if (acpi_disabled) ++ return 1; ++ ++ acpi_table_init_complete(); + + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + +@@ -1570,18 +1578,9 @@ void __init acpi_boot_table_init(void) + } else { + printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); + disable_acpi(); +- return; ++ return 1; + } + } +-} +- +-int __init early_acpi_boot_init(void) +-{ +- /* +- * If acpi_disabled, bail out +- */ +- if (acpi_disabled) +- return 1; + + /* + * Process the Multiple APIC Description Table (MADT), if present +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 84f581c91db45..d23795057c4f1 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1051,6 +1051,9 @@ void __init setup_arch(char **cmdline_p) + + cleanup_highmap(); + ++ /* Look for ACPI tables and reserve memory occupied by them. */ ++ acpi_boot_table_init(); ++ + memblock_set_current_limit(ISA_END_ADDRESS); + e820__memblock_setup(); + +@@ -1136,11 +1139,6 @@ void __init setup_arch(char **cmdline_p) + + early_platform_quirks(); + +- /* +- * Parse the ACPI tables for possible boot-time SMP configuration. +- */ +- acpi_boot_table_init(); +- + early_acpi_boot_init(); + + initmem_init(); +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index c65642c10aaea..5ea5f964f0a97 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -1655,7 +1655,7 @@ void play_dead_common(void) + local_irq_disable(); + } + +-static bool wakeup_cpu0(void) ++bool wakeup_cpu0(void) + { + if (smp_processor_id() == 0 && enable_start_cpu0) + return true; +diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c +index 1008cc6cb66c5..da6ce73c10bb7 100644 +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -246,11 +246,18 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) + return true; + } + +-static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) ++static bool nested_vmcb_check_save(struct vcpu_svm *svm, struct vmcb *vmcb12) + { + struct kvm_vcpu *vcpu = &svm->vcpu; + bool vmcb12_lma; + ++ /* ++ * FIXME: these should be done after copying the fields, ++ * to avoid TOC/TOU races. For these save area checks ++ * the possible damage is limited since kvm_set_cr0 and ++ * kvm_set_cr4 handle failure; EFER_SVME is an exception ++ * so it is force-set later in nested_prepare_vmcb_save. ++ */ + if ((vmcb12->save.efer & EFER_SVME) == 0) + return false; + +@@ -271,7 +278,7 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) + if (kvm_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) + return false; + +- return nested_vmcb_check_controls(&vmcb12->control); ++ return true; + } + + static void load_nested_vmcb_control(struct vcpu_svm *svm, +@@ -396,7 +403,14 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) + svm->vmcb->save.gdtr = vmcb12->save.gdtr; + svm->vmcb->save.idtr = vmcb12->save.idtr; + kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags); +- svm_set_efer(&svm->vcpu, vmcb12->save.efer); ++ ++ /* ++ * Force-set EFER_SVME even though it is checked earlier on the ++ * VMCB12, because the guest can flip the bit between the check ++ * and now. Clearing EFER_SVME would call svm_free_nested. ++ */ ++ svm_set_efer(&svm->vcpu, vmcb12->save.efer | EFER_SVME); ++ + svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); + svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); + svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = vmcb12->save.cr2; +@@ -454,7 +468,6 @@ int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb12_gpa, + int ret; + + svm->nested.vmcb12_gpa = vmcb12_gpa; +- load_nested_vmcb_control(svm, &vmcb12->control); + nested_prepare_vmcb_save(svm, vmcb12); + nested_prepare_vmcb_control(svm); + +@@ -501,7 +514,10 @@ int nested_svm_vmrun(struct vcpu_svm *svm) + if (WARN_ON_ONCE(!svm->nested.initialized)) + return -EINVAL; + +- if (!nested_vmcb_checks(svm, vmcb12)) { ++ load_nested_vmcb_control(svm, &vmcb12->control); ++ ++ if (!nested_vmcb_check_save(svm, vmcb12) || ++ !nested_vmcb_check_controls(&svm->nested.ctl)) { + vmcb12->control.exit_code = SVM_EXIT_ERR; + vmcb12->control.exit_code_hi = 0; + vmcb12->control.exit_info_1 = 0; +@@ -1205,6 +1221,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, + */ + if (!(save->cr0 & X86_CR0_PG)) + goto out_free; ++ if (!(save->efer & EFER_SVME)) ++ goto out_free; + + /* + * All checks done, we can enter guest mode. L1 control fields +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index 796506dcfc42e..023ac12f54a29 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1735,7 +1735,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog, + * add rsp, 8 // skip eth_type_trans's frame + * ret // return to its caller + */ +-int arch_prepare_bpf_trampoline(void *image, void *image_end, ++int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end, + const struct btf_func_model *m, u32 flags, + struct bpf_tramp_progs *tprogs, + void *orig_call) +@@ -1774,6 +1774,15 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, + + save_regs(m, &prog, nr_args, stack_size); + ++ if (flags & BPF_TRAMP_F_CALL_ORIG) { ++ /* arg1: mov rdi, im */ ++ emit_mov_imm64(&prog, BPF_REG_1, (long) im >> 32, (u32) (long) im); ++ if (emit_call(&prog, __bpf_tramp_enter, prog)) { ++ ret = -EINVAL; ++ goto cleanup; ++ } ++ } ++ + if (fentry->nr_progs) + if (invoke_bpf(m, &prog, fentry, stack_size)) + return -EINVAL; +@@ -1792,8 +1801,7 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, + } + + if (flags & BPF_TRAMP_F_CALL_ORIG) { +- if (fentry->nr_progs || fmod_ret->nr_progs) +- restore_regs(m, &prog, nr_args, stack_size); ++ restore_regs(m, &prog, nr_args, stack_size); + + /* call original function */ + if (emit_call(&prog, orig_call, prog)) { +@@ -1802,6 +1810,9 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, + } + /* remember return value in a stack for bpf prog to access */ + emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8); ++ im->ip_after_call = prog; ++ memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE); ++ prog += X86_PATCH_SIZE; + } + + if (fmod_ret->nr_progs) { +@@ -1832,9 +1843,17 @@ int arch_prepare_bpf_trampoline(void *image, void *image_end, + * the return value is only updated on the stack and still needs to be + * restored to R0. + */ +- if (flags & BPF_TRAMP_F_CALL_ORIG) ++ if (flags & BPF_TRAMP_F_CALL_ORIG) { ++ im->ip_epilogue = prog; ++ /* arg1: mov rdi, im */ ++ emit_mov_imm64(&prog, BPF_REG_1, (long) im >> 32, (u32) (long) im); ++ if (emit_call(&prog, __bpf_tramp_exit, prog)) { ++ ret = -EINVAL; ++ goto cleanup; ++ } + /* restore original return value back into RAX */ + emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); ++ } + + EMIT1(0x5B); /* pop rbx */ + EMIT1(0xC9); /* leave */ +diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S +index c426b846beefb..45cc0ae0af6f9 100644 +--- a/arch/xtensa/kernel/coprocessor.S ++++ b/arch/xtensa/kernel/coprocessor.S +@@ -99,37 +99,6 @@ + LOAD_CP_REGS_TAB(6) + LOAD_CP_REGS_TAB(7) + +-/* +- * coprocessor_flush(struct thread_info*, index) +- * a2 a3 +- * +- * Save coprocessor registers for coprocessor 'index'. +- * The register values are saved to or loaded from the coprocessor area +- * inside the task_info structure. +- * +- * Note that this function doesn't update the coprocessor_owner information! +- * +- */ +- +-ENTRY(coprocessor_flush) +- +- /* reserve 4 bytes on stack to save a0 */ +- abi_entry(4) +- +- s32i a0, a1, 0 +- movi a0, .Lsave_cp_regs_jump_table +- addx8 a3, a3, a0 +- l32i a4, a3, 4 +- l32i a3, a3, 0 +- add a2, a2, a4 +- beqz a3, 1f +- callx0 a3 +-1: l32i a0, a1, 0 +- +- abi_ret(4) +- +-ENDPROC(coprocessor_flush) +- + /* + * Entry condition: + * +@@ -245,6 +214,39 @@ ENTRY(fast_coprocessor) + + ENDPROC(fast_coprocessor) + ++ .text ++ ++/* ++ * coprocessor_flush(struct thread_info*, index) ++ * a2 a3 ++ * ++ * Save coprocessor registers for coprocessor 'index'. ++ * The register values are saved to or loaded from the coprocessor area ++ * inside the task_info structure. ++ * ++ * Note that this function doesn't update the coprocessor_owner information! ++ * ++ */ ++ ++ENTRY(coprocessor_flush) ++ ++ /* reserve 4 bytes on stack to save a0 */ ++ abi_entry(4) ++ ++ s32i a0, a1, 0 ++ movi a0, .Lsave_cp_regs_jump_table ++ addx8 a3, a3, a0 ++ l32i a4, a3, 4 ++ l32i a3, a3, 0 ++ add a2, a2, a4 ++ beqz a3, 1f ++ callx0 a3 ++1: l32i a0, a1, 0 ++ ++ abi_ret(4) ++ ++ENDPROC(coprocessor_flush) ++ + .data + + ENTRY(coprocessor_owner) +diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c +index 7666408ce12a4..95a74890c7e99 100644 +--- a/arch/xtensa/mm/fault.c ++++ b/arch/xtensa/mm/fault.c +@@ -112,8 +112,11 @@ good_area: + */ + fault = handle_mm_fault(vma, address, flags, regs); + +- if (fault_signal_pending(fault, regs)) ++ if (fault_signal_pending(fault, regs)) { ++ if (!user_mode(regs)) ++ goto bad_page_fault; + return; ++ } + + if (unlikely(fault & VM_FAULT_ERROR)) { + if (fault & VM_FAULT_OOM) +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index f66236cff69b0..4e303964f7e7f 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -29,6 +29,7 @@ + */ + #ifdef CONFIG_X86 + #include ++#include + #endif + + #define ACPI_PROCESSOR_CLASS "processor" +@@ -542,6 +543,12 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) + wait_for_freeze(); + } else + return -ENODEV; ++ ++#if defined(CONFIG_X86) && defined(CONFIG_HOTPLUG_CPU) ++ /* If NMI wants to wake up CPU0, start CPU0. */ ++ if (wakeup_cpu0()) ++ start_cpu0(); ++#endif + } + + /* Never reached */ +diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c +index e48690a006a4e..9d581045acff0 100644 +--- a/drivers/acpi/tables.c ++++ b/drivers/acpi/tables.c +@@ -780,7 +780,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, + } + + /* +- * acpi_table_init() ++ * acpi_locate_initial_tables() + * + * find RSDP, find and checksum SDT/XSDT. + * checksum all tables, print SDT/XSDT +@@ -788,7 +788,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, + * result: sdt_entry[] is initialized + */ + +-int __init acpi_table_init(void) ++int __init acpi_locate_initial_tables(void) + { + acpi_status status; + +@@ -803,9 +803,45 @@ int __init acpi_table_init(void) + status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + if (ACPI_FAILURE(status)) + return -EINVAL; +- acpi_table_initrd_scan(); + ++ return 0; ++} ++ ++void __init acpi_reserve_initial_tables(void) ++{ ++ int i; ++ ++ for (i = 0; i < ACPI_MAX_TABLES; i++) { ++ struct acpi_table_desc *table_desc = &initial_tables[i]; ++ u64 start = table_desc->address; ++ u64 size = table_desc->length; ++ ++ if (!start || !size) ++ break; ++ ++ pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n", ++ table_desc->signature.ascii, start, start + size - 1); ++ ++ memblock_reserve(start, size); ++ } ++} ++ ++void __init acpi_table_init_complete(void) ++{ ++ acpi_table_initrd_scan(); + check_multiple_madt(); ++} ++ ++int __init acpi_table_init(void) ++{ ++ int ret; ++ ++ ret = acpi_locate_initial_tables(); ++ if (ret) ++ return ret; ++ ++ acpi_table_init_complete(); ++ + return 0; + } + +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index 3c94ebc8d4bb0..43130d64e213d 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -97,6 +97,9 @@ static void deferred_probe_work_func(struct work_struct *work) + + get_device(dev); + ++ kfree(dev->p->deferred_probe_reason); ++ dev->p->deferred_probe_reason = NULL; ++ + /* + * Drop the mutex while probing each device; the probe path may + * manipulate the deferred list +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 5ef67bacb585e..d6d73ff94e88f 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -1690,8 +1690,8 @@ void pm_runtime_get_suppliers(struct device *dev) + device_links_read_lock_held()) + if (link->flags & DL_FLAG_PM_RUNTIME) { + link->supplier_preactivated = true; +- refcount_inc(&link->rpm_active); + pm_runtime_get_sync(link->supplier); ++ refcount_inc(&link->rpm_active); + } + + device_links_read_unlock(idx); +@@ -1704,6 +1704,8 @@ void pm_runtime_get_suppliers(struct device *dev) + void pm_runtime_put_suppliers(struct device *dev) + { + struct device_link *link; ++ unsigned long flags; ++ bool put; + int idx; + + idx = device_links_read_lock(); +@@ -1712,7 +1714,11 @@ void pm_runtime_put_suppliers(struct device *dev) + device_links_read_lock_held()) + if (link->supplier_preactivated) { + link->supplier_preactivated = false; +- if (refcount_dec_not_one(&link->rpm_active)) ++ spin_lock_irqsave(&dev->power.lock, flags); ++ put = pm_runtime_status_suspended(dev) && ++ refcount_dec_not_one(&link->rpm_active); ++ spin_unlock_irqrestore(&dev->power.lock, flags); ++ if (put) + pm_runtime_put(link->supplier); + } + +diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c +index 0a6438cbb3f30..e7a9561a826d3 100644 +--- a/drivers/extcon/extcon.c ++++ b/drivers/extcon/extcon.c +@@ -1241,6 +1241,7 @@ int extcon_dev_register(struct extcon_dev *edev) + sizeof(*edev->nh), GFP_KERNEL); + if (!edev->nh) { + ret = -ENOMEM; ++ device_unregister(&edev->dev); + goto err_dev; + } + +diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c +index 5fd6a60b67410..88ed971e32c0d 100644 +--- a/drivers/firewire/nosy.c ++++ b/drivers/firewire/nosy.c +@@ -346,6 +346,7 @@ nosy_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + struct client *client = file->private_data; + spinlock_t *client_list_lock = &client->lynx->client_list_lock; + struct nosy_stats stats; ++ int ret; + + switch (cmd) { + case NOSY_IOC_GET_STATS: +@@ -360,11 +361,15 @@ nosy_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + return 0; + + case NOSY_IOC_START: ++ ret = -EBUSY; + spin_lock_irq(client_list_lock); +- list_add_tail(&client->link, &client->lynx->client_list); ++ if (list_empty(&client->link)) { ++ list_add_tail(&client->link, &client->lynx->client_list); ++ ret = 0; ++ } + spin_unlock_irq(client_list_lock); + +- return 0; ++ return ret; + + case NOSY_IOC_STOP: + spin_lock_irq(client_list_lock); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index df110afa97bf4..605d1545274c2 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -2223,8 +2223,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, + uint64_t eaddr; + + /* validate the parameters */ +- if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || +- size == 0 || size & AMDGPU_GPU_PAGE_MASK) ++ if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || ++ size == 0 || size & ~PAGE_MASK) + return -EINVAL; + + /* make sure object fit at this offset */ +@@ -2289,8 +2289,8 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, + int r; + + /* validate the parameters */ +- if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || +- size == 0 || size & AMDGPU_GPU_PAGE_MASK) ++ if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || ++ size == 0 || size & ~PAGE_MASK) + return -EINVAL; + + /* make sure object fit at this offset */ +@@ -2435,7 +2435,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, + after->start = eaddr + 1; + after->last = tmp->last; + after->offset = tmp->offset; +- after->offset += after->start - tmp->start; ++ after->offset += (after->start - tmp->start) << PAGE_SHIFT; + after->flags = tmp->flags; + after->bo_va = tmp->bo_va; + list_add(&after->list, &tmp->bo_va->invalids); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +index b258a3dae767f..159add0f5aaae 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +@@ -155,7 +155,7 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev, + + /* Wait till CP writes sync code: */ + status = amdkfd_fence_wait_timeout( +- (unsigned int *) rm_state, ++ rm_state, + QUEUESTATE__ACTIVE, 1500); + + kfd_gtt_sa_free(dbgdev->dev, mem_obj); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +index c0ae04a08625c..8e5cfb1f8a512 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -1167,7 +1167,7 @@ static int start_cpsch(struct device_queue_manager *dqm) + if (retval) + goto fail_allocate_vidmem; + +- dqm->fence_addr = dqm->fence_mem->cpu_ptr; ++ dqm->fence_addr = (uint64_t *)dqm->fence_mem->cpu_ptr; + dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr; + + init_interrupts(dqm); +@@ -1340,8 +1340,8 @@ out: + return retval; + } + +-int amdkfd_fence_wait_timeout(unsigned int *fence_addr, +- unsigned int fence_value, ++int amdkfd_fence_wait_timeout(uint64_t *fence_addr, ++ uint64_t fence_value, + unsigned int timeout_ms) + { + unsigned long end_jiffies = msecs_to_jiffies(timeout_ms) + jiffies; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +index 7351dd195274e..45f8159465544 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +@@ -192,7 +192,7 @@ struct device_queue_manager { + uint16_t vmid_pasid[VMID_NUM]; + uint64_t pipelines_addr; + uint64_t fence_gpu_addr; +- unsigned int *fence_addr; ++ uint64_t *fence_addr; + struct kfd_mem_obj *fence_mem; + bool active_runlist; + int sched_policy; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +index 47ee40fbbd86c..c85e4f9d92cf2 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +@@ -345,7 +345,7 @@ fail_create_runlist_ib: + } + + int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, +- uint32_t fence_value) ++ uint64_t fence_value) + { + uint32_t *buffer, size; + int retval = 0; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +index dfaf771a42e66..e3ba0cd3b6fa7 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +@@ -283,7 +283,7 @@ static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer, + } + + static int pm_query_status_v9(struct packet_manager *pm, uint32_t *buffer, +- uint64_t fence_address, uint32_t fence_value) ++ uint64_t fence_address, uint64_t fence_value) + { + struct pm4_mes_query_status *packet; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c +index a852e0d7d804f..08442e7d99440 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c +@@ -263,7 +263,7 @@ static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer, + } + + static int pm_query_status_vi(struct packet_manager *pm, uint32_t *buffer, +- uint64_t fence_address, uint32_t fence_value) ++ uint64_t fence_address, uint64_t fence_value) + { + struct pm4_mes_query_status *packet; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index c77cf23032ac5..057c48a9b53a7 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -1006,8 +1006,8 @@ int pqm_get_wave_state(struct process_queue_manager *pqm, + u32 *ctl_stack_used_size, + u32 *save_area_used_size); + +-int amdkfd_fence_wait_timeout(unsigned int *fence_addr, +- unsigned int fence_value, ++int amdkfd_fence_wait_timeout(uint64_t *fence_addr, ++ uint64_t fence_value, + unsigned int timeout_ms); + + /* Packet Manager */ +@@ -1043,7 +1043,7 @@ struct packet_manager_funcs { + uint32_t filter_param, bool reset, + unsigned int sdma_engine); + int (*query_status)(struct packet_manager *pm, uint32_t *buffer, +- uint64_t fence_address, uint32_t fence_value); ++ uint64_t fence_address, uint64_t fence_value); + int (*release_mem)(uint64_t gpu_addr, uint32_t *buffer); + + /* Packet sizes */ +@@ -1065,7 +1065,7 @@ int pm_send_set_resources(struct packet_manager *pm, + struct scheduling_resources *res); + int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues); + int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, +- uint32_t fence_value); ++ uint64_t fence_value); + + int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, + enum kfd_unmap_queues_filter mode, +diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c +index 9bf5ad6d18a22..a1423be70721a 100644 +--- a/drivers/gpu/drm/imx/imx-drm-core.c ++++ b/drivers/gpu/drm/imx/imx-drm-core.c +@@ -215,7 +215,7 @@ static int imx_drm_bind(struct device *dev) + + ret = drmm_mode_config_init(drm); + if (ret) +- return ret; ++ goto err_kms; + + ret = drm_vblank_init(drm, MAX_CRTC); + if (ret) +diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c +index b2c8c68b7e261..3a244ef7f30f3 100644 +--- a/drivers/gpu/drm/tegra/dc.c ++++ b/drivers/gpu/drm/tegra/dc.c +@@ -2499,22 +2499,18 @@ static int tegra_dc_couple(struct tegra_dc *dc) + * POWER_CONTROL registers during CRTC enabling. + */ + if (dc->soc->coupled_pm && dc->pipe == 1) { +- u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER; +- struct device_link *link; +- struct device *partner; ++ struct device *companion; ++ struct tegra_dc *parent; + +- partner = driver_find_device(dc->dev->driver, NULL, NULL, +- tegra_dc_match_by_pipe); +- if (!partner) ++ companion = driver_find_device(dc->dev->driver, NULL, (const void *)0, ++ tegra_dc_match_by_pipe); ++ if (!companion) + return -EPROBE_DEFER; + +- link = device_link_add(dc->dev, partner, flags); +- if (!link) { +- dev_err(dc->dev, "failed to link controllers\n"); +- return -EINVAL; +- } ++ parent = dev_get_drvdata(companion); ++ dc->client.parent = &parent->client; + +- dev_dbg(dc->dev, "coupled to %s\n", dev_name(partner)); ++ dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion)); + } + + return 0; +diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c +index f02a035dda453..7b88261f57bb6 100644 +--- a/drivers/gpu/drm/tegra/sor.c ++++ b/drivers/gpu/drm/tegra/sor.c +@@ -3115,6 +3115,12 @@ static int tegra_sor_init(struct host1x_client *client) + * kernel is possible. + */ + if (sor->rst) { ++ err = pm_runtime_resume_and_get(sor->dev); ++ if (err < 0) { ++ dev_err(sor->dev, "failed to get runtime PM: %d\n", err); ++ return err; ++ } ++ + err = reset_control_acquire(sor->rst); + if (err < 0) { + dev_err(sor->dev, "failed to acquire SOR reset: %d\n", +@@ -3148,6 +3154,7 @@ static int tegra_sor_init(struct host1x_client *client) + } + + reset_control_release(sor->rst); ++ pm_runtime_put(sor->dev); + } + + err = clk_prepare_enable(sor->clk_safe); +diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile +index 22164300122d5..a2b4463d84802 100644 +--- a/drivers/net/can/Makefile ++++ b/drivers/net/can/Makefile +@@ -7,12 +7,7 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o + obj-$(CONFIG_CAN_VXCAN) += vxcan.o + obj-$(CONFIG_CAN_SLCAN) += slcan.o + +-obj-$(CONFIG_CAN_DEV) += can-dev.o +-can-dev-y += dev.o +-can-dev-y += rx-offload.o +- +-can-dev-$(CONFIG_CAN_LEDS) += led.o +- ++obj-y += dev/ + obj-y += rcar/ + obj-y += spi/ + obj-y += usb/ +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +deleted file mode 100644 +index dc9b4aae3abb6..0000000000000 +--- a/drivers/net/can/dev.c ++++ /dev/null +@@ -1,1339 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix +- * Copyright (C) 2006 Andrey Volkov, Varma Electronics +- * Copyright (C) 2008-2009 Wolfgang Grandegger +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define MOD_DESC "CAN device driver interface" +- +-MODULE_DESCRIPTION(MOD_DESC); +-MODULE_LICENSE("GPL v2"); +-MODULE_AUTHOR("Wolfgang Grandegger "); +- +-/* CAN DLC to real data length conversion helpers */ +- +-static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, +- 8, 12, 16, 20, 24, 32, 48, 64}; +- +-/* get data length from can_dlc with sanitized can_dlc */ +-u8 can_dlc2len(u8 can_dlc) +-{ +- return dlc2len[can_dlc & 0x0F]; +-} +-EXPORT_SYMBOL_GPL(can_dlc2len); +- +-static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */ +- 9, 9, 9, 9, /* 9 - 12 */ +- 10, 10, 10, 10, /* 13 - 16 */ +- 11, 11, 11, 11, /* 17 - 20 */ +- 12, 12, 12, 12, /* 21 - 24 */ +- 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */ +- 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */ +- 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */ +- 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */ +- 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */ +- +-/* map the sanitized data length to an appropriate data length code */ +-u8 can_len2dlc(u8 len) +-{ +- if (unlikely(len > 64)) +- return 0xF; +- +- return len2dlc[len]; +-} +-EXPORT_SYMBOL_GPL(can_len2dlc); +- +-#ifdef CONFIG_CAN_CALC_BITTIMING +-#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ +- +-/* Bit-timing calculation derived from: +- * +- * Code based on LinCAN sources and H8S2638 project +- * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz +- * Copyright 2005 Stanislav Marek +- * email: pisa@cmp.felk.cvut.cz +- * +- * Calculates proper bit-timing parameters for a specified bit-rate +- * and sample-point, which can then be used to set the bit-timing +- * registers of the CAN controller. You can find more information +- * in the header file linux/can/netlink.h. +- */ +-static int +-can_update_sample_point(const struct can_bittiming_const *btc, +- unsigned int sample_point_nominal, unsigned int tseg, +- unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, +- unsigned int *sample_point_error_ptr) +-{ +- unsigned int sample_point_error, best_sample_point_error = UINT_MAX; +- unsigned int sample_point, best_sample_point = 0; +- unsigned int tseg1, tseg2; +- int i; +- +- for (i = 0; i <= 1; i++) { +- tseg2 = tseg + CAN_SYNC_SEG - +- (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / +- 1000 - i; +- tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); +- tseg1 = tseg - tseg2; +- if (tseg1 > btc->tseg1_max) { +- tseg1 = btc->tseg1_max; +- tseg2 = tseg - tseg1; +- } +- +- sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / +- (tseg + CAN_SYNC_SEG); +- sample_point_error = abs(sample_point_nominal - sample_point); +- +- if (sample_point <= sample_point_nominal && +- sample_point_error < best_sample_point_error) { +- best_sample_point = sample_point; +- best_sample_point_error = sample_point_error; +- *tseg1_ptr = tseg1; +- *tseg2_ptr = tseg2; +- } +- } +- +- if (sample_point_error_ptr) +- *sample_point_error_ptr = best_sample_point_error; +- +- return best_sample_point; +-} +- +-static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, +- const struct can_bittiming_const *btc) +-{ +- struct can_priv *priv = netdev_priv(dev); +- unsigned int bitrate; /* current bitrate */ +- unsigned int bitrate_error; /* difference between current and nominal value */ +- unsigned int best_bitrate_error = UINT_MAX; +- unsigned int sample_point_error; /* difference between current and nominal value */ +- unsigned int best_sample_point_error = UINT_MAX; +- unsigned int sample_point_nominal; /* nominal sample point */ +- unsigned int best_tseg = 0; /* current best value for tseg */ +- unsigned int best_brp = 0; /* current best value for brp */ +- unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; +- u64 v64; +- +- /* Use CiA recommended sample points */ +- if (bt->sample_point) { +- sample_point_nominal = bt->sample_point; +- } else { +- if (bt->bitrate > 800000) +- sample_point_nominal = 750; +- else if (bt->bitrate > 500000) +- sample_point_nominal = 800; +- else +- sample_point_nominal = 875; +- } +- +- /* tseg even = round down, odd = round up */ +- for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; +- tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { +- tsegall = CAN_SYNC_SEG + tseg / 2; +- +- /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ +- brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; +- +- /* choose brp step which is possible in system */ +- brp = (brp / btc->brp_inc) * btc->brp_inc; +- if (brp < btc->brp_min || brp > btc->brp_max) +- continue; +- +- bitrate = priv->clock.freq / (brp * tsegall); +- bitrate_error = abs(bt->bitrate - bitrate); +- +- /* tseg brp biterror */ +- if (bitrate_error > best_bitrate_error) +- continue; +- +- /* reset sample point error if we have a better bitrate */ +- if (bitrate_error < best_bitrate_error) +- best_sample_point_error = UINT_MAX; +- +- can_update_sample_point(btc, sample_point_nominal, tseg / 2, +- &tseg1, &tseg2, &sample_point_error); +- if (sample_point_error > best_sample_point_error) +- continue; +- +- best_sample_point_error = sample_point_error; +- best_bitrate_error = bitrate_error; +- best_tseg = tseg / 2; +- best_brp = brp; +- +- if (bitrate_error == 0 && sample_point_error == 0) +- break; +- } +- +- if (best_bitrate_error) { +- /* Error in one-tenth of a percent */ +- v64 = (u64)best_bitrate_error * 1000; +- do_div(v64, bt->bitrate); +- bitrate_error = (u32)v64; +- if (bitrate_error > CAN_CALC_MAX_ERROR) { +- netdev_err(dev, +- "bitrate error %d.%d%% too high\n", +- bitrate_error / 10, bitrate_error % 10); +- return -EDOM; +- } +- netdev_warn(dev, "bitrate error %d.%d%%\n", +- bitrate_error / 10, bitrate_error % 10); +- } +- +- /* real sample point */ +- bt->sample_point = can_update_sample_point(btc, sample_point_nominal, +- best_tseg, &tseg1, &tseg2, +- NULL); +- +- v64 = (u64)best_brp * 1000 * 1000 * 1000; +- do_div(v64, priv->clock.freq); +- bt->tq = (u32)v64; +- bt->prop_seg = tseg1 / 2; +- bt->phase_seg1 = tseg1 - bt->prop_seg; +- bt->phase_seg2 = tseg2; +- +- /* check for sjw user settings */ +- if (!bt->sjw || !btc->sjw_max) { +- bt->sjw = 1; +- } else { +- /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ +- if (bt->sjw > btc->sjw_max) +- bt->sjw = btc->sjw_max; +- /* bt->sjw must not be higher than tseg2 */ +- if (tseg2 < bt->sjw) +- bt->sjw = tseg2; +- } +- +- bt->brp = best_brp; +- +- /* real bitrate */ +- bt->bitrate = priv->clock.freq / +- (bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); +- +- return 0; +-} +-#else /* !CONFIG_CAN_CALC_BITTIMING */ +-static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, +- const struct can_bittiming_const *btc) +-{ +- netdev_err(dev, "bit-timing calculation not available\n"); +- return -EINVAL; +-} +-#endif /* CONFIG_CAN_CALC_BITTIMING */ +- +-/* Checks the validity of the specified bit-timing parameters prop_seg, +- * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate +- * prescaler value brp. You can find more information in the header +- * file linux/can/netlink.h. +- */ +-static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, +- const struct can_bittiming_const *btc) +-{ +- struct can_priv *priv = netdev_priv(dev); +- int tseg1, alltseg; +- u64 brp64; +- +- tseg1 = bt->prop_seg + bt->phase_seg1; +- if (!bt->sjw) +- bt->sjw = 1; +- if (bt->sjw > btc->sjw_max || +- tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max || +- bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max) +- return -ERANGE; +- +- brp64 = (u64)priv->clock.freq * (u64)bt->tq; +- if (btc->brp_inc > 1) +- do_div(brp64, btc->brp_inc); +- brp64 += 500000000UL - 1; +- do_div(brp64, 1000000000UL); /* the practicable BRP */ +- if (btc->brp_inc > 1) +- brp64 *= btc->brp_inc; +- bt->brp = (u32)brp64; +- +- if (bt->brp < btc->brp_min || bt->brp > btc->brp_max) +- return -EINVAL; +- +- alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1; +- bt->bitrate = priv->clock.freq / (bt->brp * alltseg); +- bt->sample_point = ((tseg1 + 1) * 1000) / alltseg; +- +- return 0; +-} +- +-/* Checks the validity of predefined bitrate settings */ +-static int +-can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt, +- const u32 *bitrate_const, +- const unsigned int bitrate_const_cnt) +-{ +- struct can_priv *priv = netdev_priv(dev); +- unsigned int i; +- +- for (i = 0; i < bitrate_const_cnt; i++) { +- if (bt->bitrate == bitrate_const[i]) +- break; +- } +- +- if (i >= priv->bitrate_const_cnt) +- return -EINVAL; +- +- return 0; +-} +- +-static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, +- const struct can_bittiming_const *btc, +- const u32 *bitrate_const, +- const unsigned int bitrate_const_cnt) +-{ +- int err; +- +- /* Depending on the given can_bittiming parameter structure the CAN +- * timing parameters are calculated based on the provided bitrate OR +- * alternatively the CAN timing parameters (tq, prop_seg, etc.) are +- * provided directly which are then checked and fixed up. +- */ +- if (!bt->tq && bt->bitrate && btc) +- err = can_calc_bittiming(dev, bt, btc); +- else if (bt->tq && !bt->bitrate && btc) +- err = can_fixup_bittiming(dev, bt, btc); +- else if (!bt->tq && bt->bitrate && bitrate_const) +- err = can_validate_bitrate(dev, bt, bitrate_const, +- bitrate_const_cnt); +- else +- err = -EINVAL; +- +- return err; +-} +- +-static void can_update_state_error_stats(struct net_device *dev, +- enum can_state new_state) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- if (new_state <= priv->state) +- return; +- +- switch (new_state) { +- case CAN_STATE_ERROR_WARNING: +- priv->can_stats.error_warning++; +- break; +- case CAN_STATE_ERROR_PASSIVE: +- priv->can_stats.error_passive++; +- break; +- case CAN_STATE_BUS_OFF: +- priv->can_stats.bus_off++; +- break; +- default: +- break; +- } +-} +- +-static int can_tx_state_to_frame(struct net_device *dev, enum can_state state) +-{ +- switch (state) { +- case CAN_STATE_ERROR_ACTIVE: +- return CAN_ERR_CRTL_ACTIVE; +- case CAN_STATE_ERROR_WARNING: +- return CAN_ERR_CRTL_TX_WARNING; +- case CAN_STATE_ERROR_PASSIVE: +- return CAN_ERR_CRTL_TX_PASSIVE; +- default: +- return 0; +- } +-} +- +-static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) +-{ +- switch (state) { +- case CAN_STATE_ERROR_ACTIVE: +- return CAN_ERR_CRTL_ACTIVE; +- case CAN_STATE_ERROR_WARNING: +- return CAN_ERR_CRTL_RX_WARNING; +- case CAN_STATE_ERROR_PASSIVE: +- return CAN_ERR_CRTL_RX_PASSIVE; +- default: +- return 0; +- } +-} +- +-static const char *can_get_state_str(const enum can_state state) +-{ +- switch (state) { +- case CAN_STATE_ERROR_ACTIVE: +- return "Error Active"; +- case CAN_STATE_ERROR_WARNING: +- return "Error Warning"; +- case CAN_STATE_ERROR_PASSIVE: +- return "Error Passive"; +- case CAN_STATE_BUS_OFF: +- return "Bus Off"; +- case CAN_STATE_STOPPED: +- return "Stopped"; +- case CAN_STATE_SLEEPING: +- return "Sleeping"; +- default: +- return ""; +- } +- +- return ""; +-} +- +-void can_change_state(struct net_device *dev, struct can_frame *cf, +- enum can_state tx_state, enum can_state rx_state) +-{ +- struct can_priv *priv = netdev_priv(dev); +- enum can_state new_state = max(tx_state, rx_state); +- +- if (unlikely(new_state == priv->state)) { +- netdev_warn(dev, "%s: oops, state did not change", __func__); +- return; +- } +- +- netdev_dbg(dev, "Controller changed from %s State (%d) into %s State (%d).\n", +- can_get_state_str(priv->state), priv->state, +- can_get_state_str(new_state), new_state); +- +- can_update_state_error_stats(dev, new_state); +- priv->state = new_state; +- +- if (!cf) +- return; +- +- if (unlikely(new_state == CAN_STATE_BUS_OFF)) { +- cf->can_id |= CAN_ERR_BUSOFF; +- return; +- } +- +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] |= tx_state >= rx_state ? +- can_tx_state_to_frame(dev, tx_state) : 0; +- cf->data[1] |= tx_state <= rx_state ? +- can_rx_state_to_frame(dev, rx_state) : 0; +-} +-EXPORT_SYMBOL_GPL(can_change_state); +- +-/* Local echo of CAN messages +- * +- * CAN network devices *should* support a local echo functionality +- * (see Documentation/networking/can.rst). To test the handling of CAN +- * interfaces that do not support the local echo both driver types are +- * implemented. In the case that the driver does not support the echo +- * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core +- * to perform the echo as a fallback solution. +- */ +-static void can_flush_echo_skb(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- struct net_device_stats *stats = &dev->stats; +- int i; +- +- for (i = 0; i < priv->echo_skb_max; i++) { +- if (priv->echo_skb[i]) { +- kfree_skb(priv->echo_skb[i]); +- priv->echo_skb[i] = NULL; +- stats->tx_dropped++; +- stats->tx_aborted_errors++; +- } +- } +-} +- +-/* Put the skb on the stack to be looped backed locally lateron +- * +- * The function is typically called in the start_xmit function +- * of the device driver. The driver must protect access to +- * priv->echo_skb, if necessary. +- */ +-int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, +- unsigned int idx) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- BUG_ON(idx >= priv->echo_skb_max); +- +- /* check flag whether this packet has to be looped back */ +- if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || +- (skb->protocol != htons(ETH_P_CAN) && +- skb->protocol != htons(ETH_P_CANFD))) { +- kfree_skb(skb); +- return 0; +- } +- +- if (!priv->echo_skb[idx]) { +- skb = can_create_echo_skb(skb); +- if (!skb) +- return -ENOMEM; +- +- /* make settings for echo to reduce code in irq context */ +- skb->pkt_type = PACKET_BROADCAST; +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- skb->dev = dev; +- +- /* save this skb for tx interrupt echo handling */ +- priv->echo_skb[idx] = skb; +- } else { +- /* locking problem with netif_stop_queue() ?? */ +- netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx); +- kfree_skb(skb); +- return -EBUSY; +- } +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(can_put_echo_skb); +- +-struct sk_buff * +-__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- if (idx >= priv->echo_skb_max) { +- netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", +- __func__, idx, priv->echo_skb_max); +- return NULL; +- } +- +- if (priv->echo_skb[idx]) { +- /* Using "struct canfd_frame::len" for the frame +- * length is supported on both CAN and CANFD frames. +- */ +- struct sk_buff *skb = priv->echo_skb[idx]; +- struct canfd_frame *cf = (struct canfd_frame *)skb->data; +- +- /* get the real payload length for netdev statistics */ +- if (cf->can_id & CAN_RTR_FLAG) +- *len_ptr = 0; +- else +- *len_ptr = cf->len; +- +- priv->echo_skb[idx] = NULL; +- +- return skb; +- } +- +- return NULL; +-} +- +-/* Get the skb from the stack and loop it back locally +- * +- * The function is typically called when the TX done interrupt +- * is handled in the device driver. The driver must protect +- * access to priv->echo_skb, if necessary. +- */ +-unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) +-{ +- struct sk_buff *skb; +- u8 len; +- +- skb = __can_get_echo_skb(dev, idx, &len); +- if (!skb) +- return 0; +- +- skb_get(skb); +- if (netif_rx(skb) == NET_RX_SUCCESS) +- dev_consume_skb_any(skb); +- else +- dev_kfree_skb_any(skb); +- +- return len; +-} +-EXPORT_SYMBOL_GPL(can_get_echo_skb); +- +-/* Remove the skb from the stack and free it. +- * +- * The function is typically called when TX failed. +- */ +-void can_free_echo_skb(struct net_device *dev, unsigned int idx) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- BUG_ON(idx >= priv->echo_skb_max); +- +- if (priv->echo_skb[idx]) { +- dev_kfree_skb_any(priv->echo_skb[idx]); +- priv->echo_skb[idx] = NULL; +- } +-} +-EXPORT_SYMBOL_GPL(can_free_echo_skb); +- +-/* CAN device restart for bus-off recovery */ +-static void can_restart(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- struct net_device_stats *stats = &dev->stats; +- struct sk_buff *skb; +- struct can_frame *cf; +- int err; +- +- BUG_ON(netif_carrier_ok(dev)); +- +- /* No synchronization needed because the device is bus-off and +- * no messages can come in or go out. +- */ +- can_flush_echo_skb(dev); +- +- /* send restart message upstream */ +- skb = alloc_can_err_skb(dev, &cf); +- if (!skb) +- goto restart; +- +- cf->can_id |= CAN_ERR_RESTARTED; +- +- stats->rx_packets++; +- stats->rx_bytes += cf->can_dlc; +- +- netif_rx_ni(skb); +- +-restart: +- netdev_dbg(dev, "restarted\n"); +- priv->can_stats.restarts++; +- +- /* Now restart the device */ +- err = priv->do_set_mode(dev, CAN_MODE_START); +- +- netif_carrier_on(dev); +- if (err) +- netdev_err(dev, "Error %d during restart", err); +-} +- +-static void can_restart_work(struct work_struct *work) +-{ +- struct delayed_work *dwork = to_delayed_work(work); +- struct can_priv *priv = container_of(dwork, struct can_priv, +- restart_work); +- +- can_restart(priv->dev); +-} +- +-int can_restart_now(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- /* A manual restart is only permitted if automatic restart is +- * disabled and the device is in the bus-off state +- */ +- if (priv->restart_ms) +- return -EINVAL; +- if (priv->state != CAN_STATE_BUS_OFF) +- return -EBUSY; +- +- cancel_delayed_work_sync(&priv->restart_work); +- can_restart(dev); +- +- return 0; +-} +- +-/* CAN bus-off +- * +- * This functions should be called when the device goes bus-off to +- * tell the netif layer that no more packets can be sent or received. +- * If enabled, a timer is started to trigger bus-off recovery. +- */ +-void can_bus_off(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- if (priv->restart_ms) +- netdev_info(dev, "bus-off, scheduling restart in %d ms\n", +- priv->restart_ms); +- else +- netdev_info(dev, "bus-off\n"); +- +- netif_carrier_off(dev); +- +- if (priv->restart_ms) +- schedule_delayed_work(&priv->restart_work, +- msecs_to_jiffies(priv->restart_ms)); +-} +-EXPORT_SYMBOL_GPL(can_bus_off); +- +-static void can_setup(struct net_device *dev) +-{ +- dev->type = ARPHRD_CAN; +- dev->mtu = CAN_MTU; +- dev->hard_header_len = 0; +- dev->addr_len = 0; +- dev->tx_queue_len = 10; +- +- /* New-style flags. */ +- dev->flags = IFF_NOARP; +- dev->features = NETIF_F_HW_CSUM; +-} +- +-struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) +-{ +- struct sk_buff *skb; +- +- skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + +- sizeof(struct can_frame)); +- if (unlikely(!skb)) +- return NULL; +- +- skb->protocol = htons(ETH_P_CAN); +- skb->pkt_type = PACKET_BROADCAST; +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- +- skb_reset_mac_header(skb); +- skb_reset_network_header(skb); +- skb_reset_transport_header(skb); +- +- can_skb_reserve(skb); +- can_skb_prv(skb)->ifindex = dev->ifindex; +- can_skb_prv(skb)->skbcnt = 0; +- +- *cf = skb_put_zero(skb, sizeof(struct can_frame)); +- +- return skb; +-} +-EXPORT_SYMBOL_GPL(alloc_can_skb); +- +-struct sk_buff *alloc_canfd_skb(struct net_device *dev, +- struct canfd_frame **cfd) +-{ +- struct sk_buff *skb; +- +- skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + +- sizeof(struct canfd_frame)); +- if (unlikely(!skb)) +- return NULL; +- +- skb->protocol = htons(ETH_P_CANFD); +- skb->pkt_type = PACKET_BROADCAST; +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- +- skb_reset_mac_header(skb); +- skb_reset_network_header(skb); +- skb_reset_transport_header(skb); +- +- can_skb_reserve(skb); +- can_skb_prv(skb)->ifindex = dev->ifindex; +- can_skb_prv(skb)->skbcnt = 0; +- +- *cfd = skb_put_zero(skb, sizeof(struct canfd_frame)); +- +- return skb; +-} +-EXPORT_SYMBOL_GPL(alloc_canfd_skb); +- +-struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) +-{ +- struct sk_buff *skb; +- +- skb = alloc_can_skb(dev, cf); +- if (unlikely(!skb)) +- return NULL; +- +- (*cf)->can_id = CAN_ERR_FLAG; +- (*cf)->can_dlc = CAN_ERR_DLC; +- +- return skb; +-} +-EXPORT_SYMBOL_GPL(alloc_can_err_skb); +- +-/* Allocate and setup space for the CAN network device */ +-struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, +- unsigned int txqs, unsigned int rxqs) +-{ +- struct net_device *dev; +- struct can_priv *priv; +- int size; +- +- /* We put the driver's priv, the CAN mid layer priv and the +- * echo skb into the netdevice's priv. The memory layout for +- * the netdev_priv is like this: +- * +- * +-------------------------+ +- * | driver's priv | +- * +-------------------------+ +- * | struct can_ml_priv | +- * +-------------------------+ +- * | array of struct sk_buff | +- * +-------------------------+ +- */ +- +- size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv); +- +- if (echo_skb_max) +- size = ALIGN(size, sizeof(struct sk_buff *)) + +- echo_skb_max * sizeof(struct sk_buff *); +- +- dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup, +- txqs, rxqs); +- if (!dev) +- return NULL; +- +- priv = netdev_priv(dev); +- priv->dev = dev; +- +- dev->ml_priv = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN); +- +- if (echo_skb_max) { +- priv->echo_skb_max = echo_skb_max; +- priv->echo_skb = (void *)priv + +- (size - echo_skb_max * sizeof(struct sk_buff *)); +- } +- +- priv->state = CAN_STATE_STOPPED; +- +- INIT_DELAYED_WORK(&priv->restart_work, can_restart_work); +- +- return dev; +-} +-EXPORT_SYMBOL_GPL(alloc_candev_mqs); +- +-/* Free space of the CAN network device */ +-void free_candev(struct net_device *dev) +-{ +- free_netdev(dev); +-} +-EXPORT_SYMBOL_GPL(free_candev); +- +-/* changing MTU and control mode for CAN/CANFD devices */ +-int can_change_mtu(struct net_device *dev, int new_mtu) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- /* Do not allow changing the MTU while running */ +- if (dev->flags & IFF_UP) +- return -EBUSY; +- +- /* allow change of MTU according to the CANFD ability of the device */ +- switch (new_mtu) { +- case CAN_MTU: +- /* 'CANFD-only' controllers can not switch to CAN_MTU */ +- if (priv->ctrlmode_static & CAN_CTRLMODE_FD) +- return -EINVAL; +- +- priv->ctrlmode &= ~CAN_CTRLMODE_FD; +- break; +- +- case CANFD_MTU: +- /* check for potential CANFD ability */ +- if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) && +- !(priv->ctrlmode_static & CAN_CTRLMODE_FD)) +- return -EINVAL; +- +- priv->ctrlmode |= CAN_CTRLMODE_FD; +- break; +- +- default: +- return -EINVAL; +- } +- +- dev->mtu = new_mtu; +- return 0; +-} +-EXPORT_SYMBOL_GPL(can_change_mtu); +- +-/* Common open function when the device gets opened. +- * +- * This function should be called in the open function of the device +- * driver. +- */ +-int open_candev(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- if (!priv->bittiming.bitrate) { +- netdev_err(dev, "bit-timing not yet defined\n"); +- return -EINVAL; +- } +- +- /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ +- if ((priv->ctrlmode & CAN_CTRLMODE_FD) && +- (!priv->data_bittiming.bitrate || +- priv->data_bittiming.bitrate < priv->bittiming.bitrate)) { +- netdev_err(dev, "incorrect/missing data bit-timing\n"); +- return -EINVAL; +- } +- +- /* Switch carrier on if device was stopped while in bus-off state */ +- if (!netif_carrier_ok(dev)) +- netif_carrier_on(dev); +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(open_candev); +- +-#ifdef CONFIG_OF +-/* Common function that can be used to understand the limitation of +- * a transceiver when it provides no means to determine these limitations +- * at runtime. +- */ +-void of_can_transceiver(struct net_device *dev) +-{ +- struct device_node *dn; +- struct can_priv *priv = netdev_priv(dev); +- struct device_node *np = dev->dev.parent->of_node; +- int ret; +- +- dn = of_get_child_by_name(np, "can-transceiver"); +- if (!dn) +- return; +- +- ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max); +- of_node_put(dn); +- if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max)) +- netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n"); +-} +-EXPORT_SYMBOL_GPL(of_can_transceiver); +-#endif +- +-/* Common close function for cleanup before the device gets closed. +- * +- * This function should be called in the close function of the device +- * driver. +- */ +-void close_candev(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- cancel_delayed_work_sync(&priv->restart_work); +- can_flush_echo_skb(dev); +-} +-EXPORT_SYMBOL_GPL(close_candev); +- +-/* CAN netlink interface */ +-static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { +- [IFLA_CAN_STATE] = { .type = NLA_U32 }, +- [IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) }, +- [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 }, +- [IFLA_CAN_RESTART] = { .type = NLA_U32 }, +- [IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) }, +- [IFLA_CAN_BITTIMING_CONST] +- = { .len = sizeof(struct can_bittiming_const) }, +- [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, +- [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, +- [IFLA_CAN_DATA_BITTIMING] +- = { .len = sizeof(struct can_bittiming) }, +- [IFLA_CAN_DATA_BITTIMING_CONST] +- = { .len = sizeof(struct can_bittiming_const) }, +- [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, +-}; +- +-static int can_validate(struct nlattr *tb[], struct nlattr *data[], +- struct netlink_ext_ack *extack) +-{ +- bool is_can_fd = false; +- +- /* Make sure that valid CAN FD configurations always consist of +- * - nominal/arbitration bittiming +- * - data bittiming +- * - control mode with CAN_CTRLMODE_FD set +- */ +- +- if (!data) +- return 0; +- +- if (data[IFLA_CAN_CTRLMODE]) { +- struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); +- +- is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD; +- } +- +- if (is_can_fd) { +- if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING]) +- return -EOPNOTSUPP; +- } +- +- if (data[IFLA_CAN_DATA_BITTIMING]) { +- if (!is_can_fd || !data[IFLA_CAN_BITTIMING]) +- return -EOPNOTSUPP; +- } +- +- return 0; +-} +- +-static int can_changelink(struct net_device *dev, struct nlattr *tb[], +- struct nlattr *data[], +- struct netlink_ext_ack *extack) +-{ +- struct can_priv *priv = netdev_priv(dev); +- int err; +- +- /* We need synchronization with dev->stop() */ +- ASSERT_RTNL(); +- +- if (data[IFLA_CAN_BITTIMING]) { +- struct can_bittiming bt; +- +- /* Do not allow changing bittiming while running */ +- if (dev->flags & IFF_UP) +- return -EBUSY; +- +- /* Calculate bittiming parameters based on +- * bittiming_const if set, otherwise pass bitrate +- * directly via do_set_bitrate(). Bail out if neither +- * is given. +- */ +- if (!priv->bittiming_const && !priv->do_set_bittiming) +- return -EOPNOTSUPP; +- +- memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); +- err = can_get_bittiming(dev, &bt, +- priv->bittiming_const, +- priv->bitrate_const, +- priv->bitrate_const_cnt); +- if (err) +- return err; +- +- if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) { +- netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n", +- priv->bitrate_max); +- return -EINVAL; +- } +- +- memcpy(&priv->bittiming, &bt, sizeof(bt)); +- +- if (priv->do_set_bittiming) { +- /* Finally, set the bit-timing registers */ +- err = priv->do_set_bittiming(dev); +- if (err) +- return err; +- } +- } +- +- if (data[IFLA_CAN_CTRLMODE]) { +- struct can_ctrlmode *cm; +- u32 ctrlstatic; +- u32 maskedflags; +- +- /* Do not allow changing controller mode while running */ +- if (dev->flags & IFF_UP) +- return -EBUSY; +- cm = nla_data(data[IFLA_CAN_CTRLMODE]); +- ctrlstatic = priv->ctrlmode_static; +- maskedflags = cm->flags & cm->mask; +- +- /* check whether provided bits are allowed to be passed */ +- if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic)) +- return -EOPNOTSUPP; +- +- /* do not check for static fd-non-iso if 'fd' is disabled */ +- if (!(maskedflags & CAN_CTRLMODE_FD)) +- ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO; +- +- /* make sure static options are provided by configuration */ +- if ((maskedflags & ctrlstatic) != ctrlstatic) +- return -EOPNOTSUPP; +- +- /* clear bits to be modified and copy the flag values */ +- priv->ctrlmode &= ~cm->mask; +- priv->ctrlmode |= maskedflags; +- +- /* CAN_CTRLMODE_FD can only be set when driver supports FD */ +- if (priv->ctrlmode & CAN_CTRLMODE_FD) +- dev->mtu = CANFD_MTU; +- else +- dev->mtu = CAN_MTU; +- } +- +- if (data[IFLA_CAN_RESTART_MS]) { +- /* Do not allow changing restart delay while running */ +- if (dev->flags & IFF_UP) +- return -EBUSY; +- priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); +- } +- +- if (data[IFLA_CAN_RESTART]) { +- /* Do not allow a restart while not running */ +- if (!(dev->flags & IFF_UP)) +- return -EINVAL; +- err = can_restart_now(dev); +- if (err) +- return err; +- } +- +- if (data[IFLA_CAN_DATA_BITTIMING]) { +- struct can_bittiming dbt; +- +- /* Do not allow changing bittiming while running */ +- if (dev->flags & IFF_UP) +- return -EBUSY; +- +- /* Calculate bittiming parameters based on +- * data_bittiming_const if set, otherwise pass bitrate +- * directly via do_set_bitrate(). Bail out if neither +- * is given. +- */ +- if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) +- return -EOPNOTSUPP; +- +- memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), +- sizeof(dbt)); +- err = can_get_bittiming(dev, &dbt, +- priv->data_bittiming_const, +- priv->data_bitrate_const, +- priv->data_bitrate_const_cnt); +- if (err) +- return err; +- +- if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { +- netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n", +- priv->bitrate_max); +- return -EINVAL; +- } +- +- memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); +- +- if (priv->do_set_data_bittiming) { +- /* Finally, set the bit-timing registers */ +- err = priv->do_set_data_bittiming(dev); +- if (err) +- return err; +- } +- } +- +- if (data[IFLA_CAN_TERMINATION]) { +- const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]); +- const unsigned int num_term = priv->termination_const_cnt; +- unsigned int i; +- +- if (!priv->do_set_termination) +- return -EOPNOTSUPP; +- +- /* check whether given value is supported by the interface */ +- for (i = 0; i < num_term; i++) { +- if (termval == priv->termination_const[i]) +- break; +- } +- if (i >= num_term) +- return -EINVAL; +- +- /* Finally, set the termination value */ +- err = priv->do_set_termination(dev, termval); +- if (err) +- return err; +- +- priv->termination = termval; +- } +- +- return 0; +-} +- +-static size_t can_get_size(const struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- size_t size = 0; +- +- if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ +- size += nla_total_size(sizeof(struct can_bittiming)); +- if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ +- size += nla_total_size(sizeof(struct can_bittiming_const)); +- size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ +- size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ +- size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ +- size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ +- if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ +- size += nla_total_size(sizeof(struct can_berr_counter)); +- if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ +- size += nla_total_size(sizeof(struct can_bittiming)); +- if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ +- size += nla_total_size(sizeof(struct can_bittiming_const)); +- if (priv->termination_const) { +- size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */ +- size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */ +- priv->termination_const_cnt); +- } +- if (priv->bitrate_const) /* IFLA_CAN_BITRATE_CONST */ +- size += nla_total_size(sizeof(*priv->bitrate_const) * +- priv->bitrate_const_cnt); +- if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ +- size += nla_total_size(sizeof(*priv->data_bitrate_const) * +- priv->data_bitrate_const_cnt); +- size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */ +- +- return size; +-} +- +-static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- struct can_ctrlmode cm = {.flags = priv->ctrlmode}; +- struct can_berr_counter bec = { }; +- enum can_state state = priv->state; +- +- if (priv->do_get_state) +- priv->do_get_state(dev, &state); +- +- if ((priv->bittiming.bitrate && +- nla_put(skb, IFLA_CAN_BITTIMING, +- sizeof(priv->bittiming), &priv->bittiming)) || +- +- (priv->bittiming_const && +- nla_put(skb, IFLA_CAN_BITTIMING_CONST, +- sizeof(*priv->bittiming_const), priv->bittiming_const)) || +- +- nla_put(skb, IFLA_CAN_CLOCK, sizeof(priv->clock), &priv->clock) || +- nla_put_u32(skb, IFLA_CAN_STATE, state) || +- nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || +- nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || +- +- (priv->do_get_berr_counter && +- !priv->do_get_berr_counter(dev, &bec) && +- nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || +- +- (priv->data_bittiming.bitrate && +- nla_put(skb, IFLA_CAN_DATA_BITTIMING, +- sizeof(priv->data_bittiming), &priv->data_bittiming)) || +- +- (priv->data_bittiming_const && +- nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, +- sizeof(*priv->data_bittiming_const), +- priv->data_bittiming_const)) || +- +- (priv->termination_const && +- (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) || +- nla_put(skb, IFLA_CAN_TERMINATION_CONST, +- sizeof(*priv->termination_const) * +- priv->termination_const_cnt, +- priv->termination_const))) || +- +- (priv->bitrate_const && +- nla_put(skb, IFLA_CAN_BITRATE_CONST, +- sizeof(*priv->bitrate_const) * +- priv->bitrate_const_cnt, +- priv->bitrate_const)) || +- +- (priv->data_bitrate_const && +- nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST, +- sizeof(*priv->data_bitrate_const) * +- priv->data_bitrate_const_cnt, +- priv->data_bitrate_const)) || +- +- (nla_put(skb, IFLA_CAN_BITRATE_MAX, +- sizeof(priv->bitrate_max), +- &priv->bitrate_max)) +- ) +- +- return -EMSGSIZE; +- +- return 0; +-} +- +-static size_t can_get_xstats_size(const struct net_device *dev) +-{ +- return sizeof(struct can_device_stats); +-} +- +-static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- if (nla_put(skb, IFLA_INFO_XSTATS, +- sizeof(priv->can_stats), &priv->can_stats)) +- goto nla_put_failure; +- return 0; +- +-nla_put_failure: +- return -EMSGSIZE; +-} +- +-static int can_newlink(struct net *src_net, struct net_device *dev, +- struct nlattr *tb[], struct nlattr *data[], +- struct netlink_ext_ack *extack) +-{ +- return -EOPNOTSUPP; +-} +- +-static void can_dellink(struct net_device *dev, struct list_head *head) +-{ +-} +- +-static struct rtnl_link_ops can_link_ops __read_mostly = { +- .kind = "can", +- .netns_refund = true, +- .maxtype = IFLA_CAN_MAX, +- .policy = can_policy, +- .setup = can_setup, +- .validate = can_validate, +- .newlink = can_newlink, +- .changelink = can_changelink, +- .dellink = can_dellink, +- .get_size = can_get_size, +- .fill_info = can_fill_info, +- .get_xstats_size = can_get_xstats_size, +- .fill_xstats = can_fill_xstats, +-}; +- +-/* Register the CAN network device */ +-int register_candev(struct net_device *dev) +-{ +- struct can_priv *priv = netdev_priv(dev); +- +- /* Ensure termination_const, termination_const_cnt and +- * do_set_termination consistency. All must be either set or +- * unset. +- */ +- if ((!priv->termination_const != !priv->termination_const_cnt) || +- (!priv->termination_const != !priv->do_set_termination)) +- return -EINVAL; +- +- if (!priv->bitrate_const != !priv->bitrate_const_cnt) +- return -EINVAL; +- +- if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt) +- return -EINVAL; +- +- dev->rtnl_link_ops = &can_link_ops; +- netif_carrier_off(dev); +- +- return register_netdev(dev); +-} +-EXPORT_SYMBOL_GPL(register_candev); +- +-/* Unregister the CAN network device */ +-void unregister_candev(struct net_device *dev) +-{ +- unregister_netdev(dev); +-} +-EXPORT_SYMBOL_GPL(unregister_candev); +- +-/* Test if a network device is a candev based device +- * and return the can_priv* if so. +- */ +-struct can_priv *safe_candev_priv(struct net_device *dev) +-{ +- if (dev->type != ARPHRD_CAN || dev->rtnl_link_ops != &can_link_ops) +- return NULL; +- +- return netdev_priv(dev); +-} +-EXPORT_SYMBOL_GPL(safe_candev_priv); +- +-static __init int can_dev_init(void) +-{ +- int err; +- +- can_led_notifier_init(); +- +- err = rtnl_link_register(&can_link_ops); +- if (!err) +- pr_info(MOD_DESC "\n"); +- +- return err; +-} +-module_init(can_dev_init); +- +-static __exit void can_dev_exit(void) +-{ +- rtnl_link_unregister(&can_link_ops); +- +- can_led_notifier_exit(); +-} +-module_exit(can_dev_exit); +- +-MODULE_ALIAS_RTNL_LINK("can"); +diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile +new file mode 100644 +index 0000000000000..cba92e6bcf6f5 +--- /dev/null ++++ b/drivers/net/can/dev/Makefile +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-$(CONFIG_CAN_DEV) += can-dev.o ++can-dev-y += dev.o ++can-dev-y += rx-offload.o ++ ++can-dev-$(CONFIG_CAN_LEDS) += led.o +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +new file mode 100644 +index 0000000000000..2b38a99884f2f +--- /dev/null ++++ b/drivers/net/can/dev/dev.c +@@ -0,0 +1,1341 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix ++ * Copyright (C) 2006 Andrey Volkov, Varma Electronics ++ * Copyright (C) 2008-2009 Wolfgang Grandegger ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MOD_DESC "CAN device driver interface" ++ ++MODULE_DESCRIPTION(MOD_DESC); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Wolfgang Grandegger "); ++ ++/* CAN DLC to real data length conversion helpers */ ++ ++static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 12, 16, 20, 24, 32, 48, 64}; ++ ++/* get data length from can_dlc with sanitized can_dlc */ ++u8 can_dlc2len(u8 can_dlc) ++{ ++ return dlc2len[can_dlc & 0x0F]; ++} ++EXPORT_SYMBOL_GPL(can_dlc2len); ++ ++static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */ ++ 9, 9, 9, 9, /* 9 - 12 */ ++ 10, 10, 10, 10, /* 13 - 16 */ ++ 11, 11, 11, 11, /* 17 - 20 */ ++ 12, 12, 12, 12, /* 21 - 24 */ ++ 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */ ++ 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */ ++ 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */ ++ 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */ ++ 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */ ++ ++/* map the sanitized data length to an appropriate data length code */ ++u8 can_len2dlc(u8 len) ++{ ++ if (unlikely(len > 64)) ++ return 0xF; ++ ++ return len2dlc[len]; ++} ++EXPORT_SYMBOL_GPL(can_len2dlc); ++ ++#ifdef CONFIG_CAN_CALC_BITTIMING ++#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ ++ ++/* Bit-timing calculation derived from: ++ * ++ * Code based on LinCAN sources and H8S2638 project ++ * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz ++ * Copyright 2005 Stanislav Marek ++ * email: pisa@cmp.felk.cvut.cz ++ * ++ * Calculates proper bit-timing parameters for a specified bit-rate ++ * and sample-point, which can then be used to set the bit-timing ++ * registers of the CAN controller. You can find more information ++ * in the header file linux/can/netlink.h. ++ */ ++static int ++can_update_sample_point(const struct can_bittiming_const *btc, ++ unsigned int sample_point_nominal, unsigned int tseg, ++ unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, ++ unsigned int *sample_point_error_ptr) ++{ ++ unsigned int sample_point_error, best_sample_point_error = UINT_MAX; ++ unsigned int sample_point, best_sample_point = 0; ++ unsigned int tseg1, tseg2; ++ int i; ++ ++ for (i = 0; i <= 1; i++) { ++ tseg2 = tseg + CAN_SYNC_SEG - ++ (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / ++ 1000 - i; ++ tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); ++ tseg1 = tseg - tseg2; ++ if (tseg1 > btc->tseg1_max) { ++ tseg1 = btc->tseg1_max; ++ tseg2 = tseg - tseg1; ++ } ++ ++ sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / ++ (tseg + CAN_SYNC_SEG); ++ sample_point_error = abs(sample_point_nominal - sample_point); ++ ++ if (sample_point <= sample_point_nominal && ++ sample_point_error < best_sample_point_error) { ++ best_sample_point = sample_point; ++ best_sample_point_error = sample_point_error; ++ *tseg1_ptr = tseg1; ++ *tseg2_ptr = tseg2; ++ } ++ } ++ ++ if (sample_point_error_ptr) ++ *sample_point_error_ptr = best_sample_point_error; ++ ++ return best_sample_point; ++} ++ ++static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, ++ const struct can_bittiming_const *btc) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ unsigned int bitrate; /* current bitrate */ ++ unsigned int bitrate_error; /* difference between current and nominal value */ ++ unsigned int best_bitrate_error = UINT_MAX; ++ unsigned int sample_point_error; /* difference between current and nominal value */ ++ unsigned int best_sample_point_error = UINT_MAX; ++ unsigned int sample_point_nominal; /* nominal sample point */ ++ unsigned int best_tseg = 0; /* current best value for tseg */ ++ unsigned int best_brp = 0; /* current best value for brp */ ++ unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; ++ u64 v64; ++ ++ /* Use CiA recommended sample points */ ++ if (bt->sample_point) { ++ sample_point_nominal = bt->sample_point; ++ } else { ++ if (bt->bitrate > 800000) ++ sample_point_nominal = 750; ++ else if (bt->bitrate > 500000) ++ sample_point_nominal = 800; ++ else ++ sample_point_nominal = 875; ++ } ++ ++ /* tseg even = round down, odd = round up */ ++ for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; ++ tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { ++ tsegall = CAN_SYNC_SEG + tseg / 2; ++ ++ /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ ++ brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; ++ ++ /* choose brp step which is possible in system */ ++ brp = (brp / btc->brp_inc) * btc->brp_inc; ++ if (brp < btc->brp_min || brp > btc->brp_max) ++ continue; ++ ++ bitrate = priv->clock.freq / (brp * tsegall); ++ bitrate_error = abs(bt->bitrate - bitrate); ++ ++ /* tseg brp biterror */ ++ if (bitrate_error > best_bitrate_error) ++ continue; ++ ++ /* reset sample point error if we have a better bitrate */ ++ if (bitrate_error < best_bitrate_error) ++ best_sample_point_error = UINT_MAX; ++ ++ can_update_sample_point(btc, sample_point_nominal, tseg / 2, ++ &tseg1, &tseg2, &sample_point_error); ++ if (sample_point_error > best_sample_point_error) ++ continue; ++ ++ best_sample_point_error = sample_point_error; ++ best_bitrate_error = bitrate_error; ++ best_tseg = tseg / 2; ++ best_brp = brp; ++ ++ if (bitrate_error == 0 && sample_point_error == 0) ++ break; ++ } ++ ++ if (best_bitrate_error) { ++ /* Error in one-tenth of a percent */ ++ v64 = (u64)best_bitrate_error * 1000; ++ do_div(v64, bt->bitrate); ++ bitrate_error = (u32)v64; ++ if (bitrate_error > CAN_CALC_MAX_ERROR) { ++ netdev_err(dev, ++ "bitrate error %d.%d%% too high\n", ++ bitrate_error / 10, bitrate_error % 10); ++ return -EDOM; ++ } ++ netdev_warn(dev, "bitrate error %d.%d%%\n", ++ bitrate_error / 10, bitrate_error % 10); ++ } ++ ++ /* real sample point */ ++ bt->sample_point = can_update_sample_point(btc, sample_point_nominal, ++ best_tseg, &tseg1, &tseg2, ++ NULL); ++ ++ v64 = (u64)best_brp * 1000 * 1000 * 1000; ++ do_div(v64, priv->clock.freq); ++ bt->tq = (u32)v64; ++ bt->prop_seg = tseg1 / 2; ++ bt->phase_seg1 = tseg1 - bt->prop_seg; ++ bt->phase_seg2 = tseg2; ++ ++ /* check for sjw user settings */ ++ if (!bt->sjw || !btc->sjw_max) { ++ bt->sjw = 1; ++ } else { ++ /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ ++ if (bt->sjw > btc->sjw_max) ++ bt->sjw = btc->sjw_max; ++ /* bt->sjw must not be higher than tseg2 */ ++ if (tseg2 < bt->sjw) ++ bt->sjw = tseg2; ++ } ++ ++ bt->brp = best_brp; ++ ++ /* real bitrate */ ++ bt->bitrate = priv->clock.freq / ++ (bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); ++ ++ return 0; ++} ++#else /* !CONFIG_CAN_CALC_BITTIMING */ ++static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, ++ const struct can_bittiming_const *btc) ++{ ++ netdev_err(dev, "bit-timing calculation not available\n"); ++ return -EINVAL; ++} ++#endif /* CONFIG_CAN_CALC_BITTIMING */ ++ ++/* Checks the validity of the specified bit-timing parameters prop_seg, ++ * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate ++ * prescaler value brp. You can find more information in the header ++ * file linux/can/netlink.h. ++ */ ++static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, ++ const struct can_bittiming_const *btc) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ int tseg1, alltseg; ++ u64 brp64; ++ ++ tseg1 = bt->prop_seg + bt->phase_seg1; ++ if (!bt->sjw) ++ bt->sjw = 1; ++ if (bt->sjw > btc->sjw_max || ++ tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max || ++ bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max) ++ return -ERANGE; ++ ++ brp64 = (u64)priv->clock.freq * (u64)bt->tq; ++ if (btc->brp_inc > 1) ++ do_div(brp64, btc->brp_inc); ++ brp64 += 500000000UL - 1; ++ do_div(brp64, 1000000000UL); /* the practicable BRP */ ++ if (btc->brp_inc > 1) ++ brp64 *= btc->brp_inc; ++ bt->brp = (u32)brp64; ++ ++ if (bt->brp < btc->brp_min || bt->brp > btc->brp_max) ++ return -EINVAL; ++ ++ alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1; ++ bt->bitrate = priv->clock.freq / (bt->brp * alltseg); ++ bt->sample_point = ((tseg1 + 1) * 1000) / alltseg; ++ ++ return 0; ++} ++ ++/* Checks the validity of predefined bitrate settings */ ++static int ++can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt, ++ const u32 *bitrate_const, ++ const unsigned int bitrate_const_cnt) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ unsigned int i; ++ ++ for (i = 0; i < bitrate_const_cnt; i++) { ++ if (bt->bitrate == bitrate_const[i]) ++ break; ++ } ++ ++ if (i >= priv->bitrate_const_cnt) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, ++ const struct can_bittiming_const *btc, ++ const u32 *bitrate_const, ++ const unsigned int bitrate_const_cnt) ++{ ++ int err; ++ ++ /* Depending on the given can_bittiming parameter structure the CAN ++ * timing parameters are calculated based on the provided bitrate OR ++ * alternatively the CAN timing parameters (tq, prop_seg, etc.) are ++ * provided directly which are then checked and fixed up. ++ */ ++ if (!bt->tq && bt->bitrate && btc) ++ err = can_calc_bittiming(dev, bt, btc); ++ else if (bt->tq && !bt->bitrate && btc) ++ err = can_fixup_bittiming(dev, bt, btc); ++ else if (!bt->tq && bt->bitrate && bitrate_const) ++ err = can_validate_bitrate(dev, bt, bitrate_const, ++ bitrate_const_cnt); ++ else ++ err = -EINVAL; ++ ++ return err; ++} ++ ++static void can_update_state_error_stats(struct net_device *dev, ++ enum can_state new_state) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ if (new_state <= priv->state) ++ return; ++ ++ switch (new_state) { ++ case CAN_STATE_ERROR_WARNING: ++ priv->can_stats.error_warning++; ++ break; ++ case CAN_STATE_ERROR_PASSIVE: ++ priv->can_stats.error_passive++; ++ break; ++ case CAN_STATE_BUS_OFF: ++ priv->can_stats.bus_off++; ++ break; ++ default: ++ break; ++ } ++} ++ ++static int can_tx_state_to_frame(struct net_device *dev, enum can_state state) ++{ ++ switch (state) { ++ case CAN_STATE_ERROR_ACTIVE: ++ return CAN_ERR_CRTL_ACTIVE; ++ case CAN_STATE_ERROR_WARNING: ++ return CAN_ERR_CRTL_TX_WARNING; ++ case CAN_STATE_ERROR_PASSIVE: ++ return CAN_ERR_CRTL_TX_PASSIVE; ++ default: ++ return 0; ++ } ++} ++ ++static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) ++{ ++ switch (state) { ++ case CAN_STATE_ERROR_ACTIVE: ++ return CAN_ERR_CRTL_ACTIVE; ++ case CAN_STATE_ERROR_WARNING: ++ return CAN_ERR_CRTL_RX_WARNING; ++ case CAN_STATE_ERROR_PASSIVE: ++ return CAN_ERR_CRTL_RX_PASSIVE; ++ default: ++ return 0; ++ } ++} ++ ++static const char *can_get_state_str(const enum can_state state) ++{ ++ switch (state) { ++ case CAN_STATE_ERROR_ACTIVE: ++ return "Error Active"; ++ case CAN_STATE_ERROR_WARNING: ++ return "Error Warning"; ++ case CAN_STATE_ERROR_PASSIVE: ++ return "Error Passive"; ++ case CAN_STATE_BUS_OFF: ++ return "Bus Off"; ++ case CAN_STATE_STOPPED: ++ return "Stopped"; ++ case CAN_STATE_SLEEPING: ++ return "Sleeping"; ++ default: ++ return ""; ++ } ++ ++ return ""; ++} ++ ++void can_change_state(struct net_device *dev, struct can_frame *cf, ++ enum can_state tx_state, enum can_state rx_state) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ enum can_state new_state = max(tx_state, rx_state); ++ ++ if (unlikely(new_state == priv->state)) { ++ netdev_warn(dev, "%s: oops, state did not change", __func__); ++ return; ++ } ++ ++ netdev_dbg(dev, "Controller changed from %s State (%d) into %s State (%d).\n", ++ can_get_state_str(priv->state), priv->state, ++ can_get_state_str(new_state), new_state); ++ ++ can_update_state_error_stats(dev, new_state); ++ priv->state = new_state; ++ ++ if (!cf) ++ return; ++ ++ if (unlikely(new_state == CAN_STATE_BUS_OFF)) { ++ cf->can_id |= CAN_ERR_BUSOFF; ++ return; ++ } ++ ++ cf->can_id |= CAN_ERR_CRTL; ++ cf->data[1] |= tx_state >= rx_state ? ++ can_tx_state_to_frame(dev, tx_state) : 0; ++ cf->data[1] |= tx_state <= rx_state ? ++ can_rx_state_to_frame(dev, rx_state) : 0; ++} ++EXPORT_SYMBOL_GPL(can_change_state); ++ ++/* Local echo of CAN messages ++ * ++ * CAN network devices *should* support a local echo functionality ++ * (see Documentation/networking/can.rst). To test the handling of CAN ++ * interfaces that do not support the local echo both driver types are ++ * implemented. In the case that the driver does not support the echo ++ * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core ++ * to perform the echo as a fallback solution. ++ */ ++static void can_flush_echo_skb(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ struct net_device_stats *stats = &dev->stats; ++ int i; ++ ++ for (i = 0; i < priv->echo_skb_max; i++) { ++ if (priv->echo_skb[i]) { ++ kfree_skb(priv->echo_skb[i]); ++ priv->echo_skb[i] = NULL; ++ stats->tx_dropped++; ++ stats->tx_aborted_errors++; ++ } ++ } ++} ++ ++/* Put the skb on the stack to be looped backed locally lateron ++ * ++ * The function is typically called in the start_xmit function ++ * of the device driver. The driver must protect access to ++ * priv->echo_skb, if necessary. ++ */ ++int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, ++ unsigned int idx) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ BUG_ON(idx >= priv->echo_skb_max); ++ ++ /* check flag whether this packet has to be looped back */ ++ if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || ++ (skb->protocol != htons(ETH_P_CAN) && ++ skb->protocol != htons(ETH_P_CANFD))) { ++ kfree_skb(skb); ++ return 0; ++ } ++ ++ if (!priv->echo_skb[idx]) { ++ skb = can_create_echo_skb(skb); ++ if (!skb) ++ return -ENOMEM; ++ ++ /* make settings for echo to reduce code in irq context */ ++ skb->pkt_type = PACKET_BROADCAST; ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ skb->dev = dev; ++ ++ /* save this skb for tx interrupt echo handling */ ++ priv->echo_skb[idx] = skb; ++ } else { ++ /* locking problem with netif_stop_queue() ?? */ ++ netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx); ++ kfree_skb(skb); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(can_put_echo_skb); ++ ++struct sk_buff * ++__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ if (idx >= priv->echo_skb_max) { ++ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", ++ __func__, idx, priv->echo_skb_max); ++ return NULL; ++ } ++ ++ if (priv->echo_skb[idx]) { ++ /* Using "struct canfd_frame::len" for the frame ++ * length is supported on both CAN and CANFD frames. ++ */ ++ struct sk_buff *skb = priv->echo_skb[idx]; ++ struct canfd_frame *cf = (struct canfd_frame *)skb->data; ++ ++ /* get the real payload length for netdev statistics */ ++ if (cf->can_id & CAN_RTR_FLAG) ++ *len_ptr = 0; ++ else ++ *len_ptr = cf->len; ++ ++ priv->echo_skb[idx] = NULL; ++ ++ return skb; ++ } ++ ++ return NULL; ++} ++ ++/* Get the skb from the stack and loop it back locally ++ * ++ * The function is typically called when the TX done interrupt ++ * is handled in the device driver. The driver must protect ++ * access to priv->echo_skb, if necessary. ++ */ ++unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) ++{ ++ struct sk_buff *skb; ++ u8 len; ++ ++ skb = __can_get_echo_skb(dev, idx, &len); ++ if (!skb) ++ return 0; ++ ++ skb_get(skb); ++ if (netif_rx(skb) == NET_RX_SUCCESS) ++ dev_consume_skb_any(skb); ++ else ++ dev_kfree_skb_any(skb); ++ ++ return len; ++} ++EXPORT_SYMBOL_GPL(can_get_echo_skb); ++ ++/* Remove the skb from the stack and free it. ++ * ++ * The function is typically called when TX failed. ++ */ ++void can_free_echo_skb(struct net_device *dev, unsigned int idx) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ BUG_ON(idx >= priv->echo_skb_max); ++ ++ if (priv->echo_skb[idx]) { ++ dev_kfree_skb_any(priv->echo_skb[idx]); ++ priv->echo_skb[idx] = NULL; ++ } ++} ++EXPORT_SYMBOL_GPL(can_free_echo_skb); ++ ++/* CAN device restart for bus-off recovery */ ++static void can_restart(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ struct net_device_stats *stats = &dev->stats; ++ struct sk_buff *skb; ++ struct can_frame *cf; ++ int err; ++ ++ BUG_ON(netif_carrier_ok(dev)); ++ ++ /* No synchronization needed because the device is bus-off and ++ * no messages can come in or go out. ++ */ ++ can_flush_echo_skb(dev); ++ ++ /* send restart message upstream */ ++ skb = alloc_can_err_skb(dev, &cf); ++ if (!skb) ++ goto restart; ++ ++ cf->can_id |= CAN_ERR_RESTARTED; ++ ++ stats->rx_packets++; ++ stats->rx_bytes += cf->can_dlc; ++ ++ netif_rx_ni(skb); ++ ++restart: ++ netdev_dbg(dev, "restarted\n"); ++ priv->can_stats.restarts++; ++ ++ /* Now restart the device */ ++ err = priv->do_set_mode(dev, CAN_MODE_START); ++ ++ netif_carrier_on(dev); ++ if (err) ++ netdev_err(dev, "Error %d during restart", err); ++} ++ ++static void can_restart_work(struct work_struct *work) ++{ ++ struct delayed_work *dwork = to_delayed_work(work); ++ struct can_priv *priv = container_of(dwork, struct can_priv, ++ restart_work); ++ ++ can_restart(priv->dev); ++} ++ ++int can_restart_now(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ /* A manual restart is only permitted if automatic restart is ++ * disabled and the device is in the bus-off state ++ */ ++ if (priv->restart_ms) ++ return -EINVAL; ++ if (priv->state != CAN_STATE_BUS_OFF) ++ return -EBUSY; ++ ++ cancel_delayed_work_sync(&priv->restart_work); ++ can_restart(dev); ++ ++ return 0; ++} ++ ++/* CAN bus-off ++ * ++ * This functions should be called when the device goes bus-off to ++ * tell the netif layer that no more packets can be sent or received. ++ * If enabled, a timer is started to trigger bus-off recovery. ++ */ ++void can_bus_off(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ if (priv->restart_ms) ++ netdev_info(dev, "bus-off, scheduling restart in %d ms\n", ++ priv->restart_ms); ++ else ++ netdev_info(dev, "bus-off\n"); ++ ++ netif_carrier_off(dev); ++ ++ if (priv->restart_ms) ++ schedule_delayed_work(&priv->restart_work, ++ msecs_to_jiffies(priv->restart_ms)); ++} ++EXPORT_SYMBOL_GPL(can_bus_off); ++ ++static void can_setup(struct net_device *dev) ++{ ++ dev->type = ARPHRD_CAN; ++ dev->mtu = CAN_MTU; ++ dev->hard_header_len = 0; ++ dev->addr_len = 0; ++ dev->tx_queue_len = 10; ++ ++ /* New-style flags. */ ++ dev->flags = IFF_NOARP; ++ dev->features = NETIF_F_HW_CSUM; ++} ++ ++struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) ++{ ++ struct sk_buff *skb; ++ ++ skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + ++ sizeof(struct can_frame)); ++ if (unlikely(!skb)) ++ return NULL; ++ ++ skb->protocol = htons(ETH_P_CAN); ++ skb->pkt_type = PACKET_BROADCAST; ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ ++ skb_reset_mac_header(skb); ++ skb_reset_network_header(skb); ++ skb_reset_transport_header(skb); ++ ++ can_skb_reserve(skb); ++ can_skb_prv(skb)->ifindex = dev->ifindex; ++ can_skb_prv(skb)->skbcnt = 0; ++ ++ *cf = skb_put_zero(skb, sizeof(struct can_frame)); ++ ++ return skb; ++} ++EXPORT_SYMBOL_GPL(alloc_can_skb); ++ ++struct sk_buff *alloc_canfd_skb(struct net_device *dev, ++ struct canfd_frame **cfd) ++{ ++ struct sk_buff *skb; ++ ++ skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + ++ sizeof(struct canfd_frame)); ++ if (unlikely(!skb)) ++ return NULL; ++ ++ skb->protocol = htons(ETH_P_CANFD); ++ skb->pkt_type = PACKET_BROADCAST; ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ ++ skb_reset_mac_header(skb); ++ skb_reset_network_header(skb); ++ skb_reset_transport_header(skb); ++ ++ can_skb_reserve(skb); ++ can_skb_prv(skb)->ifindex = dev->ifindex; ++ can_skb_prv(skb)->skbcnt = 0; ++ ++ *cfd = skb_put_zero(skb, sizeof(struct canfd_frame)); ++ ++ return skb; ++} ++EXPORT_SYMBOL_GPL(alloc_canfd_skb); ++ ++struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) ++{ ++ struct sk_buff *skb; ++ ++ skb = alloc_can_skb(dev, cf); ++ if (unlikely(!skb)) ++ return NULL; ++ ++ (*cf)->can_id = CAN_ERR_FLAG; ++ (*cf)->can_dlc = CAN_ERR_DLC; ++ ++ return skb; ++} ++EXPORT_SYMBOL_GPL(alloc_can_err_skb); ++ ++/* Allocate and setup space for the CAN network device */ ++struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, ++ unsigned int txqs, unsigned int rxqs) ++{ ++ struct can_ml_priv *can_ml; ++ struct net_device *dev; ++ struct can_priv *priv; ++ int size; ++ ++ /* We put the driver's priv, the CAN mid layer priv and the ++ * echo skb into the netdevice's priv. The memory layout for ++ * the netdev_priv is like this: ++ * ++ * +-------------------------+ ++ * | driver's priv | ++ * +-------------------------+ ++ * | struct can_ml_priv | ++ * +-------------------------+ ++ * | array of struct sk_buff | ++ * +-------------------------+ ++ */ ++ ++ size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv); ++ ++ if (echo_skb_max) ++ size = ALIGN(size, sizeof(struct sk_buff *)) + ++ echo_skb_max * sizeof(struct sk_buff *); ++ ++ dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup, ++ txqs, rxqs); ++ if (!dev) ++ return NULL; ++ ++ priv = netdev_priv(dev); ++ priv->dev = dev; ++ ++ can_ml = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); ++ ++ if (echo_skb_max) { ++ priv->echo_skb_max = echo_skb_max; ++ priv->echo_skb = (void *)priv + ++ (size - echo_skb_max * sizeof(struct sk_buff *)); ++ } ++ ++ priv->state = CAN_STATE_STOPPED; ++ ++ INIT_DELAYED_WORK(&priv->restart_work, can_restart_work); ++ ++ return dev; ++} ++EXPORT_SYMBOL_GPL(alloc_candev_mqs); ++ ++/* Free space of the CAN network device */ ++void free_candev(struct net_device *dev) ++{ ++ free_netdev(dev); ++} ++EXPORT_SYMBOL_GPL(free_candev); ++ ++/* changing MTU and control mode for CAN/CANFD devices */ ++int can_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ /* Do not allow changing the MTU while running */ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ ++ /* allow change of MTU according to the CANFD ability of the device */ ++ switch (new_mtu) { ++ case CAN_MTU: ++ /* 'CANFD-only' controllers can not switch to CAN_MTU */ ++ if (priv->ctrlmode_static & CAN_CTRLMODE_FD) ++ return -EINVAL; ++ ++ priv->ctrlmode &= ~CAN_CTRLMODE_FD; ++ break; ++ ++ case CANFD_MTU: ++ /* check for potential CANFD ability */ ++ if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) && ++ !(priv->ctrlmode_static & CAN_CTRLMODE_FD)) ++ return -EINVAL; ++ ++ priv->ctrlmode |= CAN_CTRLMODE_FD; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ dev->mtu = new_mtu; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(can_change_mtu); ++ ++/* Common open function when the device gets opened. ++ * ++ * This function should be called in the open function of the device ++ * driver. ++ */ ++int open_candev(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ if (!priv->bittiming.bitrate) { ++ netdev_err(dev, "bit-timing not yet defined\n"); ++ return -EINVAL; ++ } ++ ++ /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ ++ if ((priv->ctrlmode & CAN_CTRLMODE_FD) && ++ (!priv->data_bittiming.bitrate || ++ priv->data_bittiming.bitrate < priv->bittiming.bitrate)) { ++ netdev_err(dev, "incorrect/missing data bit-timing\n"); ++ return -EINVAL; ++ } ++ ++ /* Switch carrier on if device was stopped while in bus-off state */ ++ if (!netif_carrier_ok(dev)) ++ netif_carrier_on(dev); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(open_candev); ++ ++#ifdef CONFIG_OF ++/* Common function that can be used to understand the limitation of ++ * a transceiver when it provides no means to determine these limitations ++ * at runtime. ++ */ ++void of_can_transceiver(struct net_device *dev) ++{ ++ struct device_node *dn; ++ struct can_priv *priv = netdev_priv(dev); ++ struct device_node *np = dev->dev.parent->of_node; ++ int ret; ++ ++ dn = of_get_child_by_name(np, "can-transceiver"); ++ if (!dn) ++ return; ++ ++ ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max); ++ of_node_put(dn); ++ if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max)) ++ netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n"); ++} ++EXPORT_SYMBOL_GPL(of_can_transceiver); ++#endif ++ ++/* Common close function for cleanup before the device gets closed. ++ * ++ * This function should be called in the close function of the device ++ * driver. ++ */ ++void close_candev(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ cancel_delayed_work_sync(&priv->restart_work); ++ can_flush_echo_skb(dev); ++} ++EXPORT_SYMBOL_GPL(close_candev); ++ ++/* CAN netlink interface */ ++static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { ++ [IFLA_CAN_STATE] = { .type = NLA_U32 }, ++ [IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) }, ++ [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 }, ++ [IFLA_CAN_RESTART] = { .type = NLA_U32 }, ++ [IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) }, ++ [IFLA_CAN_BITTIMING_CONST] ++ = { .len = sizeof(struct can_bittiming_const) }, ++ [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, ++ [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, ++ [IFLA_CAN_DATA_BITTIMING] ++ = { .len = sizeof(struct can_bittiming) }, ++ [IFLA_CAN_DATA_BITTIMING_CONST] ++ = { .len = sizeof(struct can_bittiming_const) }, ++ [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, ++}; ++ ++static int can_validate(struct nlattr *tb[], struct nlattr *data[], ++ struct netlink_ext_ack *extack) ++{ ++ bool is_can_fd = false; ++ ++ /* Make sure that valid CAN FD configurations always consist of ++ * - nominal/arbitration bittiming ++ * - data bittiming ++ * - control mode with CAN_CTRLMODE_FD set ++ */ ++ ++ if (!data) ++ return 0; ++ ++ if (data[IFLA_CAN_CTRLMODE]) { ++ struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); ++ ++ is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD; ++ } ++ ++ if (is_can_fd) { ++ if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING]) ++ return -EOPNOTSUPP; ++ } ++ ++ if (data[IFLA_CAN_DATA_BITTIMING]) { ++ if (!is_can_fd || !data[IFLA_CAN_BITTIMING]) ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int can_changelink(struct net_device *dev, struct nlattr *tb[], ++ struct nlattr *data[], ++ struct netlink_ext_ack *extack) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ int err; ++ ++ /* We need synchronization with dev->stop() */ ++ ASSERT_RTNL(); ++ ++ if (data[IFLA_CAN_BITTIMING]) { ++ struct can_bittiming bt; ++ ++ /* Do not allow changing bittiming while running */ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ ++ /* Calculate bittiming parameters based on ++ * bittiming_const if set, otherwise pass bitrate ++ * directly via do_set_bitrate(). Bail out if neither ++ * is given. ++ */ ++ if (!priv->bittiming_const && !priv->do_set_bittiming) ++ return -EOPNOTSUPP; ++ ++ memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); ++ err = can_get_bittiming(dev, &bt, ++ priv->bittiming_const, ++ priv->bitrate_const, ++ priv->bitrate_const_cnt); ++ if (err) ++ return err; ++ ++ if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) { ++ netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n", ++ priv->bitrate_max); ++ return -EINVAL; ++ } ++ ++ memcpy(&priv->bittiming, &bt, sizeof(bt)); ++ ++ if (priv->do_set_bittiming) { ++ /* Finally, set the bit-timing registers */ ++ err = priv->do_set_bittiming(dev); ++ if (err) ++ return err; ++ } ++ } ++ ++ if (data[IFLA_CAN_CTRLMODE]) { ++ struct can_ctrlmode *cm; ++ u32 ctrlstatic; ++ u32 maskedflags; ++ ++ /* Do not allow changing controller mode while running */ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ cm = nla_data(data[IFLA_CAN_CTRLMODE]); ++ ctrlstatic = priv->ctrlmode_static; ++ maskedflags = cm->flags & cm->mask; ++ ++ /* check whether provided bits are allowed to be passed */ ++ if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic)) ++ return -EOPNOTSUPP; ++ ++ /* do not check for static fd-non-iso if 'fd' is disabled */ ++ if (!(maskedflags & CAN_CTRLMODE_FD)) ++ ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO; ++ ++ /* make sure static options are provided by configuration */ ++ if ((maskedflags & ctrlstatic) != ctrlstatic) ++ return -EOPNOTSUPP; ++ ++ /* clear bits to be modified and copy the flag values */ ++ priv->ctrlmode &= ~cm->mask; ++ priv->ctrlmode |= maskedflags; ++ ++ /* CAN_CTRLMODE_FD can only be set when driver supports FD */ ++ if (priv->ctrlmode & CAN_CTRLMODE_FD) ++ dev->mtu = CANFD_MTU; ++ else ++ dev->mtu = CAN_MTU; ++ } ++ ++ if (data[IFLA_CAN_RESTART_MS]) { ++ /* Do not allow changing restart delay while running */ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); ++ } ++ ++ if (data[IFLA_CAN_RESTART]) { ++ /* Do not allow a restart while not running */ ++ if (!(dev->flags & IFF_UP)) ++ return -EINVAL; ++ err = can_restart_now(dev); ++ if (err) ++ return err; ++ } ++ ++ if (data[IFLA_CAN_DATA_BITTIMING]) { ++ struct can_bittiming dbt; ++ ++ /* Do not allow changing bittiming while running */ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ ++ /* Calculate bittiming parameters based on ++ * data_bittiming_const if set, otherwise pass bitrate ++ * directly via do_set_bitrate(). Bail out if neither ++ * is given. ++ */ ++ if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) ++ return -EOPNOTSUPP; ++ ++ memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), ++ sizeof(dbt)); ++ err = can_get_bittiming(dev, &dbt, ++ priv->data_bittiming_const, ++ priv->data_bitrate_const, ++ priv->data_bitrate_const_cnt); ++ if (err) ++ return err; ++ ++ if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { ++ netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n", ++ priv->bitrate_max); ++ return -EINVAL; ++ } ++ ++ memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); ++ ++ if (priv->do_set_data_bittiming) { ++ /* Finally, set the bit-timing registers */ ++ err = priv->do_set_data_bittiming(dev); ++ if (err) ++ return err; ++ } ++ } ++ ++ if (data[IFLA_CAN_TERMINATION]) { ++ const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]); ++ const unsigned int num_term = priv->termination_const_cnt; ++ unsigned int i; ++ ++ if (!priv->do_set_termination) ++ return -EOPNOTSUPP; ++ ++ /* check whether given value is supported by the interface */ ++ for (i = 0; i < num_term; i++) { ++ if (termval == priv->termination_const[i]) ++ break; ++ } ++ if (i >= num_term) ++ return -EINVAL; ++ ++ /* Finally, set the termination value */ ++ err = priv->do_set_termination(dev, termval); ++ if (err) ++ return err; ++ ++ priv->termination = termval; ++ } ++ ++ return 0; ++} ++ ++static size_t can_get_size(const struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ size_t size = 0; ++ ++ if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ ++ size += nla_total_size(sizeof(struct can_bittiming)); ++ if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ ++ size += nla_total_size(sizeof(struct can_bittiming_const)); ++ size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ ++ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ ++ size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ ++ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ ++ if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ ++ size += nla_total_size(sizeof(struct can_berr_counter)); ++ if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ ++ size += nla_total_size(sizeof(struct can_bittiming)); ++ if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ ++ size += nla_total_size(sizeof(struct can_bittiming_const)); ++ if (priv->termination_const) { ++ size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */ ++ size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */ ++ priv->termination_const_cnt); ++ } ++ if (priv->bitrate_const) /* IFLA_CAN_BITRATE_CONST */ ++ size += nla_total_size(sizeof(*priv->bitrate_const) * ++ priv->bitrate_const_cnt); ++ if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ ++ size += nla_total_size(sizeof(*priv->data_bitrate_const) * ++ priv->data_bitrate_const_cnt); ++ size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */ ++ ++ return size; ++} ++ ++static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ struct can_ctrlmode cm = {.flags = priv->ctrlmode}; ++ struct can_berr_counter bec = { }; ++ enum can_state state = priv->state; ++ ++ if (priv->do_get_state) ++ priv->do_get_state(dev, &state); ++ ++ if ((priv->bittiming.bitrate && ++ nla_put(skb, IFLA_CAN_BITTIMING, ++ sizeof(priv->bittiming), &priv->bittiming)) || ++ ++ (priv->bittiming_const && ++ nla_put(skb, IFLA_CAN_BITTIMING_CONST, ++ sizeof(*priv->bittiming_const), priv->bittiming_const)) || ++ ++ nla_put(skb, IFLA_CAN_CLOCK, sizeof(priv->clock), &priv->clock) || ++ nla_put_u32(skb, IFLA_CAN_STATE, state) || ++ nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || ++ nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || ++ ++ (priv->do_get_berr_counter && ++ !priv->do_get_berr_counter(dev, &bec) && ++ nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || ++ ++ (priv->data_bittiming.bitrate && ++ nla_put(skb, IFLA_CAN_DATA_BITTIMING, ++ sizeof(priv->data_bittiming), &priv->data_bittiming)) || ++ ++ (priv->data_bittiming_const && ++ nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, ++ sizeof(*priv->data_bittiming_const), ++ priv->data_bittiming_const)) || ++ ++ (priv->termination_const && ++ (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) || ++ nla_put(skb, IFLA_CAN_TERMINATION_CONST, ++ sizeof(*priv->termination_const) * ++ priv->termination_const_cnt, ++ priv->termination_const))) || ++ ++ (priv->bitrate_const && ++ nla_put(skb, IFLA_CAN_BITRATE_CONST, ++ sizeof(*priv->bitrate_const) * ++ priv->bitrate_const_cnt, ++ priv->bitrate_const)) || ++ ++ (priv->data_bitrate_const && ++ nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST, ++ sizeof(*priv->data_bitrate_const) * ++ priv->data_bitrate_const_cnt, ++ priv->data_bitrate_const)) || ++ ++ (nla_put(skb, IFLA_CAN_BITRATE_MAX, ++ sizeof(priv->bitrate_max), ++ &priv->bitrate_max)) ++ ) ++ ++ return -EMSGSIZE; ++ ++ return 0; ++} ++ ++static size_t can_get_xstats_size(const struct net_device *dev) ++{ ++ return sizeof(struct can_device_stats); ++} ++ ++static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ if (nla_put(skb, IFLA_INFO_XSTATS, ++ sizeof(priv->can_stats), &priv->can_stats)) ++ goto nla_put_failure; ++ return 0; ++ ++nla_put_failure: ++ return -EMSGSIZE; ++} ++ ++static int can_newlink(struct net *src_net, struct net_device *dev, ++ struct nlattr *tb[], struct nlattr *data[], ++ struct netlink_ext_ack *extack) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static void can_dellink(struct net_device *dev, struct list_head *head) ++{ ++} ++ ++static struct rtnl_link_ops can_link_ops __read_mostly = { ++ .kind = "can", ++ .netns_refund = true, ++ .maxtype = IFLA_CAN_MAX, ++ .policy = can_policy, ++ .setup = can_setup, ++ .validate = can_validate, ++ .newlink = can_newlink, ++ .changelink = can_changelink, ++ .dellink = can_dellink, ++ .get_size = can_get_size, ++ .fill_info = can_fill_info, ++ .get_xstats_size = can_get_xstats_size, ++ .fill_xstats = can_fill_xstats, ++}; ++ ++/* Register the CAN network device */ ++int register_candev(struct net_device *dev) ++{ ++ struct can_priv *priv = netdev_priv(dev); ++ ++ /* Ensure termination_const, termination_const_cnt and ++ * do_set_termination consistency. All must be either set or ++ * unset. ++ */ ++ if ((!priv->termination_const != !priv->termination_const_cnt) || ++ (!priv->termination_const != !priv->do_set_termination)) ++ return -EINVAL; ++ ++ if (!priv->bitrate_const != !priv->bitrate_const_cnt) ++ return -EINVAL; ++ ++ if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt) ++ return -EINVAL; ++ ++ dev->rtnl_link_ops = &can_link_ops; ++ netif_carrier_off(dev); ++ ++ return register_netdev(dev); ++} ++EXPORT_SYMBOL_GPL(register_candev); ++ ++/* Unregister the CAN network device */ ++void unregister_candev(struct net_device *dev) ++{ ++ unregister_netdev(dev); ++} ++EXPORT_SYMBOL_GPL(unregister_candev); ++ ++/* Test if a network device is a candev based device ++ * and return the can_priv* if so. ++ */ ++struct can_priv *safe_candev_priv(struct net_device *dev) ++{ ++ if (dev->type != ARPHRD_CAN || dev->rtnl_link_ops != &can_link_ops) ++ return NULL; ++ ++ return netdev_priv(dev); ++} ++EXPORT_SYMBOL_GPL(safe_candev_priv); ++ ++static __init int can_dev_init(void) ++{ ++ int err; ++ ++ can_led_notifier_init(); ++ ++ err = rtnl_link_register(&can_link_ops); ++ if (!err) ++ pr_info(MOD_DESC "\n"); ++ ++ return err; ++} ++module_init(can_dev_init); ++ ++static __exit void can_dev_exit(void) ++{ ++ rtnl_link_unregister(&can_link_ops); ++ ++ can_led_notifier_exit(); ++} ++module_exit(can_dev_exit); ++ ++MODULE_ALIAS_RTNL_LINK("can"); +diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c +new file mode 100644 +index 0000000000000..6e95193b215ba +--- /dev/null ++++ b/drivers/net/can/dev/rx-offload.c +@@ -0,0 +1,376 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2014 Protonic Holland, ++ * David Jander ++ * Copyright (C) 2014-2017 Pengutronix, ++ * Marc Kleine-Budde ++ */ ++ ++#include ++#include ++ ++struct can_rx_offload_cb { ++ u32 timestamp; ++}; ++ ++static inline struct can_rx_offload_cb * ++can_rx_offload_get_cb(struct sk_buff *skb) ++{ ++ BUILD_BUG_ON(sizeof(struct can_rx_offload_cb) > sizeof(skb->cb)); ++ ++ return (struct can_rx_offload_cb *)skb->cb; ++} ++ ++static inline bool ++can_rx_offload_le(struct can_rx_offload *offload, ++ unsigned int a, unsigned int b) ++{ ++ if (offload->inc) ++ return a <= b; ++ else ++ return a >= b; ++} ++ ++static inline unsigned int ++can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val) ++{ ++ if (offload->inc) ++ return (*val)++; ++ else ++ return (*val)--; ++} ++ ++static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota) ++{ ++ struct can_rx_offload *offload = container_of(napi, ++ struct can_rx_offload, ++ napi); ++ struct net_device *dev = offload->dev; ++ struct net_device_stats *stats = &dev->stats; ++ struct sk_buff *skb; ++ int work_done = 0; ++ ++ while ((work_done < quota) && ++ (skb = skb_dequeue(&offload->skb_queue))) { ++ struct can_frame *cf = (struct can_frame *)skb->data; ++ ++ work_done++; ++ stats->rx_packets++; ++ stats->rx_bytes += cf->can_dlc; ++ netif_receive_skb(skb); ++ } ++ ++ if (work_done < quota) { ++ napi_complete_done(napi, work_done); ++ ++ /* Check if there was another interrupt */ ++ if (!skb_queue_empty(&offload->skb_queue)) ++ napi_reschedule(&offload->napi); ++ } ++ ++ can_led_event(offload->dev, CAN_LED_EVENT_RX); ++ ++ return work_done; ++} ++ ++static inline void ++__skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new, ++ int (*compare)(struct sk_buff *a, struct sk_buff *b)) ++{ ++ struct sk_buff *pos, *insert = NULL; ++ ++ skb_queue_reverse_walk(head, pos) { ++ const struct can_rx_offload_cb *cb_pos, *cb_new; ++ ++ cb_pos = can_rx_offload_get_cb(pos); ++ cb_new = can_rx_offload_get_cb(new); ++ ++ netdev_dbg(new->dev, ++ "%s: pos=0x%08x, new=0x%08x, diff=%10d, queue_len=%d\n", ++ __func__, ++ cb_pos->timestamp, cb_new->timestamp, ++ cb_new->timestamp - cb_pos->timestamp, ++ skb_queue_len(head)); ++ ++ if (compare(pos, new) < 0) ++ continue; ++ insert = pos; ++ break; ++ } ++ if (!insert) ++ __skb_queue_head(head, new); ++ else ++ __skb_queue_after(head, insert, new); ++} ++ ++static int can_rx_offload_compare(struct sk_buff *a, struct sk_buff *b) ++{ ++ const struct can_rx_offload_cb *cb_a, *cb_b; ++ ++ cb_a = can_rx_offload_get_cb(a); ++ cb_b = can_rx_offload_get_cb(b); ++ ++ /* Subtract two u32 and return result as int, to keep ++ * difference steady around the u32 overflow. ++ */ ++ return cb_b->timestamp - cb_a->timestamp; ++} ++ ++/** ++ * can_rx_offload_offload_one() - Read one CAN frame from HW ++ * @offload: pointer to rx_offload context ++ * @n: number of mailbox to read ++ * ++ * The task of this function is to read a CAN frame from mailbox @n ++ * from the device and return the mailbox's content as a struct ++ * sk_buff. ++ * ++ * If the struct can_rx_offload::skb_queue exceeds the maximal queue ++ * length (struct can_rx_offload::skb_queue_len_max) or no skb can be ++ * allocated, the mailbox contents is discarded by reading it into an ++ * overflow buffer. This way the mailbox is marked as free by the ++ * driver. ++ * ++ * Return: A pointer to skb containing the CAN frame on success. ++ * ++ * NULL if the mailbox @n is empty. ++ * ++ * ERR_PTR() in case of an error ++ */ ++static struct sk_buff * ++can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) ++{ ++ struct sk_buff *skb; ++ struct can_rx_offload_cb *cb; ++ bool drop = false; ++ u32 timestamp; ++ ++ /* If queue is full drop frame */ ++ if (unlikely(skb_queue_len(&offload->skb_queue) > ++ offload->skb_queue_len_max)) ++ drop = true; ++ ++ skb = offload->mailbox_read(offload, n, ×tamp, drop); ++ /* Mailbox was empty. */ ++ if (unlikely(!skb)) ++ return NULL; ++ ++ /* There was a problem reading the mailbox, propagate ++ * error value. ++ */ ++ if (unlikely(IS_ERR(skb))) { ++ offload->dev->stats.rx_dropped++; ++ offload->dev->stats.rx_fifo_errors++; ++ ++ return skb; ++ } ++ ++ /* Mailbox was read. */ ++ cb = can_rx_offload_get_cb(skb); ++ cb->timestamp = timestamp; ++ ++ return skb; ++} ++ ++int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, ++ u64 pending) ++{ ++ struct sk_buff_head skb_queue; ++ unsigned int i; ++ ++ __skb_queue_head_init(&skb_queue); ++ ++ for (i = offload->mb_first; ++ can_rx_offload_le(offload, i, offload->mb_last); ++ can_rx_offload_inc(offload, &i)) { ++ struct sk_buff *skb; ++ ++ if (!(pending & BIT_ULL(i))) ++ continue; ++ ++ skb = can_rx_offload_offload_one(offload, i); ++ if (IS_ERR_OR_NULL(skb)) ++ continue; ++ ++ __skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare); ++ } ++ ++ if (!skb_queue_empty(&skb_queue)) { ++ unsigned long flags; ++ u32 queue_len; ++ ++ spin_lock_irqsave(&offload->skb_queue.lock, flags); ++ skb_queue_splice_tail(&skb_queue, &offload->skb_queue); ++ spin_unlock_irqrestore(&offload->skb_queue.lock, flags); ++ ++ queue_len = skb_queue_len(&offload->skb_queue); ++ if (queue_len > offload->skb_queue_len_max / 8) ++ netdev_dbg(offload->dev, "%s: queue_len=%d\n", ++ __func__, queue_len); ++ ++ can_rx_offload_schedule(offload); ++ } ++ ++ return skb_queue_len(&skb_queue); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_timestamp); ++ ++int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) ++{ ++ struct sk_buff *skb; ++ int received = 0; ++ ++ while (1) { ++ skb = can_rx_offload_offload_one(offload, 0); ++ if (IS_ERR(skb)) ++ continue; ++ if (!skb) ++ break; ++ ++ skb_queue_tail(&offload->skb_queue, skb); ++ received++; ++ } ++ ++ if (received) ++ can_rx_offload_schedule(offload); ++ ++ return received; ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); ++ ++int can_rx_offload_queue_sorted(struct can_rx_offload *offload, ++ struct sk_buff *skb, u32 timestamp) ++{ ++ struct can_rx_offload_cb *cb; ++ unsigned long flags; ++ ++ if (skb_queue_len(&offload->skb_queue) > ++ offload->skb_queue_len_max) { ++ dev_kfree_skb_any(skb); ++ return -ENOBUFS; ++ } ++ ++ cb = can_rx_offload_get_cb(skb); ++ cb->timestamp = timestamp; ++ ++ spin_lock_irqsave(&offload->skb_queue.lock, flags); ++ __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare); ++ spin_unlock_irqrestore(&offload->skb_queue.lock, flags); ++ ++ can_rx_offload_schedule(offload); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); ++ ++unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, ++ unsigned int idx, u32 timestamp) ++{ ++ struct net_device *dev = offload->dev; ++ struct net_device_stats *stats = &dev->stats; ++ struct sk_buff *skb; ++ u8 len; ++ int err; ++ ++ skb = __can_get_echo_skb(dev, idx, &len); ++ if (!skb) ++ return 0; ++ ++ err = can_rx_offload_queue_sorted(offload, skb, timestamp); ++ if (err) { ++ stats->rx_errors++; ++ stats->tx_fifo_errors++; ++ } ++ ++ return len; ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb); ++ ++int can_rx_offload_queue_tail(struct can_rx_offload *offload, ++ struct sk_buff *skb) ++{ ++ if (skb_queue_len(&offload->skb_queue) > ++ offload->skb_queue_len_max) { ++ dev_kfree_skb_any(skb); ++ return -ENOBUFS; ++ } ++ ++ skb_queue_tail(&offload->skb_queue, skb); ++ can_rx_offload_schedule(offload); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); ++ ++static int can_rx_offload_init_queue(struct net_device *dev, ++ struct can_rx_offload *offload, ++ unsigned int weight) ++{ ++ offload->dev = dev; ++ ++ /* Limit queue len to 4x the weight (rounted to next power of two) */ ++ offload->skb_queue_len_max = 2 << fls(weight); ++ offload->skb_queue_len_max *= 4; ++ skb_queue_head_init(&offload->skb_queue); ++ ++ netif_napi_add(dev, &offload->napi, can_rx_offload_napi_poll, weight); ++ ++ dev_dbg(dev->dev.parent, "%s: skb_queue_len_max=%d\n", ++ __func__, offload->skb_queue_len_max); ++ ++ return 0; ++} ++ ++int can_rx_offload_add_timestamp(struct net_device *dev, ++ struct can_rx_offload *offload) ++{ ++ unsigned int weight; ++ ++ if (offload->mb_first > BITS_PER_LONG_LONG || ++ offload->mb_last > BITS_PER_LONG_LONG || !offload->mailbox_read) ++ return -EINVAL; ++ ++ if (offload->mb_first < offload->mb_last) { ++ offload->inc = true; ++ weight = offload->mb_last - offload->mb_first; ++ } else { ++ offload->inc = false; ++ weight = offload->mb_first - offload->mb_last; ++ } ++ ++ return can_rx_offload_init_queue(dev, offload, weight); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_add_timestamp); ++ ++int can_rx_offload_add_fifo(struct net_device *dev, ++ struct can_rx_offload *offload, unsigned int weight) ++{ ++ if (!offload->mailbox_read) ++ return -EINVAL; ++ ++ return can_rx_offload_init_queue(dev, offload, weight); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_add_fifo); ++ ++int can_rx_offload_add_manual(struct net_device *dev, ++ struct can_rx_offload *offload, ++ unsigned int weight) ++{ ++ if (offload->mailbox_read) ++ return -EINVAL; ++ ++ return can_rx_offload_init_queue(dev, offload, weight); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_add_manual); ++ ++void can_rx_offload_enable(struct can_rx_offload *offload) ++{ ++ napi_enable(&offload->napi); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_enable); ++ ++void can_rx_offload_del(struct can_rx_offload *offload) ++{ ++ netif_napi_del(&offload->napi); ++ skb_queue_purge(&offload->skb_queue); ++} ++EXPORT_SYMBOL_GPL(can_rx_offload_del); +diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c +index 01f5b6e03a2dd..f169d9090e52f 100644 +--- a/drivers/net/can/m_can/tcan4x5x.c ++++ b/drivers/net/can/m_can/tcan4x5x.c +@@ -88,7 +88,7 @@ + + #define TCAN4X5X_MRAM_START 0x8000 + #define TCAN4X5X_MCAN_OFFSET 0x1000 +-#define TCAN4X5X_MAX_REGISTER 0x8fff ++#define TCAN4X5X_MAX_REGISTER 0x8ffc + + #define TCAN4X5X_CLEAR_ALL_INT 0xffffffff + #define TCAN4X5X_SET_ALL_INT 0xffffffff +diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c +deleted file mode 100644 +index 6e95193b215ba..0000000000000 +--- a/drivers/net/can/rx-offload.c ++++ /dev/null +@@ -1,376 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* Copyright (c) 2014 Protonic Holland, +- * David Jander +- * Copyright (C) 2014-2017 Pengutronix, +- * Marc Kleine-Budde +- */ +- +-#include +-#include +- +-struct can_rx_offload_cb { +- u32 timestamp; +-}; +- +-static inline struct can_rx_offload_cb * +-can_rx_offload_get_cb(struct sk_buff *skb) +-{ +- BUILD_BUG_ON(sizeof(struct can_rx_offload_cb) > sizeof(skb->cb)); +- +- return (struct can_rx_offload_cb *)skb->cb; +-} +- +-static inline bool +-can_rx_offload_le(struct can_rx_offload *offload, +- unsigned int a, unsigned int b) +-{ +- if (offload->inc) +- return a <= b; +- else +- return a >= b; +-} +- +-static inline unsigned int +-can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val) +-{ +- if (offload->inc) +- return (*val)++; +- else +- return (*val)--; +-} +- +-static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota) +-{ +- struct can_rx_offload *offload = container_of(napi, +- struct can_rx_offload, +- napi); +- struct net_device *dev = offload->dev; +- struct net_device_stats *stats = &dev->stats; +- struct sk_buff *skb; +- int work_done = 0; +- +- while ((work_done < quota) && +- (skb = skb_dequeue(&offload->skb_queue))) { +- struct can_frame *cf = (struct can_frame *)skb->data; +- +- work_done++; +- stats->rx_packets++; +- stats->rx_bytes += cf->can_dlc; +- netif_receive_skb(skb); +- } +- +- if (work_done < quota) { +- napi_complete_done(napi, work_done); +- +- /* Check if there was another interrupt */ +- if (!skb_queue_empty(&offload->skb_queue)) +- napi_reschedule(&offload->napi); +- } +- +- can_led_event(offload->dev, CAN_LED_EVENT_RX); +- +- return work_done; +-} +- +-static inline void +-__skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new, +- int (*compare)(struct sk_buff *a, struct sk_buff *b)) +-{ +- struct sk_buff *pos, *insert = NULL; +- +- skb_queue_reverse_walk(head, pos) { +- const struct can_rx_offload_cb *cb_pos, *cb_new; +- +- cb_pos = can_rx_offload_get_cb(pos); +- cb_new = can_rx_offload_get_cb(new); +- +- netdev_dbg(new->dev, +- "%s: pos=0x%08x, new=0x%08x, diff=%10d, queue_len=%d\n", +- __func__, +- cb_pos->timestamp, cb_new->timestamp, +- cb_new->timestamp - cb_pos->timestamp, +- skb_queue_len(head)); +- +- if (compare(pos, new) < 0) +- continue; +- insert = pos; +- break; +- } +- if (!insert) +- __skb_queue_head(head, new); +- else +- __skb_queue_after(head, insert, new); +-} +- +-static int can_rx_offload_compare(struct sk_buff *a, struct sk_buff *b) +-{ +- const struct can_rx_offload_cb *cb_a, *cb_b; +- +- cb_a = can_rx_offload_get_cb(a); +- cb_b = can_rx_offload_get_cb(b); +- +- /* Subtract two u32 and return result as int, to keep +- * difference steady around the u32 overflow. +- */ +- return cb_b->timestamp - cb_a->timestamp; +-} +- +-/** +- * can_rx_offload_offload_one() - Read one CAN frame from HW +- * @offload: pointer to rx_offload context +- * @n: number of mailbox to read +- * +- * The task of this function is to read a CAN frame from mailbox @n +- * from the device and return the mailbox's content as a struct +- * sk_buff. +- * +- * If the struct can_rx_offload::skb_queue exceeds the maximal queue +- * length (struct can_rx_offload::skb_queue_len_max) or no skb can be +- * allocated, the mailbox contents is discarded by reading it into an +- * overflow buffer. This way the mailbox is marked as free by the +- * driver. +- * +- * Return: A pointer to skb containing the CAN frame on success. +- * +- * NULL if the mailbox @n is empty. +- * +- * ERR_PTR() in case of an error +- */ +-static struct sk_buff * +-can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) +-{ +- struct sk_buff *skb; +- struct can_rx_offload_cb *cb; +- bool drop = false; +- u32 timestamp; +- +- /* If queue is full drop frame */ +- if (unlikely(skb_queue_len(&offload->skb_queue) > +- offload->skb_queue_len_max)) +- drop = true; +- +- skb = offload->mailbox_read(offload, n, ×tamp, drop); +- /* Mailbox was empty. */ +- if (unlikely(!skb)) +- return NULL; +- +- /* There was a problem reading the mailbox, propagate +- * error value. +- */ +- if (unlikely(IS_ERR(skb))) { +- offload->dev->stats.rx_dropped++; +- offload->dev->stats.rx_fifo_errors++; +- +- return skb; +- } +- +- /* Mailbox was read. */ +- cb = can_rx_offload_get_cb(skb); +- cb->timestamp = timestamp; +- +- return skb; +-} +- +-int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, +- u64 pending) +-{ +- struct sk_buff_head skb_queue; +- unsigned int i; +- +- __skb_queue_head_init(&skb_queue); +- +- for (i = offload->mb_first; +- can_rx_offload_le(offload, i, offload->mb_last); +- can_rx_offload_inc(offload, &i)) { +- struct sk_buff *skb; +- +- if (!(pending & BIT_ULL(i))) +- continue; +- +- skb = can_rx_offload_offload_one(offload, i); +- if (IS_ERR_OR_NULL(skb)) +- continue; +- +- __skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare); +- } +- +- if (!skb_queue_empty(&skb_queue)) { +- unsigned long flags; +- u32 queue_len; +- +- spin_lock_irqsave(&offload->skb_queue.lock, flags); +- skb_queue_splice_tail(&skb_queue, &offload->skb_queue); +- spin_unlock_irqrestore(&offload->skb_queue.lock, flags); +- +- queue_len = skb_queue_len(&offload->skb_queue); +- if (queue_len > offload->skb_queue_len_max / 8) +- netdev_dbg(offload->dev, "%s: queue_len=%d\n", +- __func__, queue_len); +- +- can_rx_offload_schedule(offload); +- } +- +- return skb_queue_len(&skb_queue); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_timestamp); +- +-int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) +-{ +- struct sk_buff *skb; +- int received = 0; +- +- while (1) { +- skb = can_rx_offload_offload_one(offload, 0); +- if (IS_ERR(skb)) +- continue; +- if (!skb) +- break; +- +- skb_queue_tail(&offload->skb_queue, skb); +- received++; +- } +- +- if (received) +- can_rx_offload_schedule(offload); +- +- return received; +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); +- +-int can_rx_offload_queue_sorted(struct can_rx_offload *offload, +- struct sk_buff *skb, u32 timestamp) +-{ +- struct can_rx_offload_cb *cb; +- unsigned long flags; +- +- if (skb_queue_len(&offload->skb_queue) > +- offload->skb_queue_len_max) { +- dev_kfree_skb_any(skb); +- return -ENOBUFS; +- } +- +- cb = can_rx_offload_get_cb(skb); +- cb->timestamp = timestamp; +- +- spin_lock_irqsave(&offload->skb_queue.lock, flags); +- __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare); +- spin_unlock_irqrestore(&offload->skb_queue.lock, flags); +- +- can_rx_offload_schedule(offload); +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); +- +-unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, +- unsigned int idx, u32 timestamp) +-{ +- struct net_device *dev = offload->dev; +- struct net_device_stats *stats = &dev->stats; +- struct sk_buff *skb; +- u8 len; +- int err; +- +- skb = __can_get_echo_skb(dev, idx, &len); +- if (!skb) +- return 0; +- +- err = can_rx_offload_queue_sorted(offload, skb, timestamp); +- if (err) { +- stats->rx_errors++; +- stats->tx_fifo_errors++; +- } +- +- return len; +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb); +- +-int can_rx_offload_queue_tail(struct can_rx_offload *offload, +- struct sk_buff *skb) +-{ +- if (skb_queue_len(&offload->skb_queue) > +- offload->skb_queue_len_max) { +- dev_kfree_skb_any(skb); +- return -ENOBUFS; +- } +- +- skb_queue_tail(&offload->skb_queue, skb); +- can_rx_offload_schedule(offload); +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); +- +-static int can_rx_offload_init_queue(struct net_device *dev, +- struct can_rx_offload *offload, +- unsigned int weight) +-{ +- offload->dev = dev; +- +- /* Limit queue len to 4x the weight (rounted to next power of two) */ +- offload->skb_queue_len_max = 2 << fls(weight); +- offload->skb_queue_len_max *= 4; +- skb_queue_head_init(&offload->skb_queue); +- +- netif_napi_add(dev, &offload->napi, can_rx_offload_napi_poll, weight); +- +- dev_dbg(dev->dev.parent, "%s: skb_queue_len_max=%d\n", +- __func__, offload->skb_queue_len_max); +- +- return 0; +-} +- +-int can_rx_offload_add_timestamp(struct net_device *dev, +- struct can_rx_offload *offload) +-{ +- unsigned int weight; +- +- if (offload->mb_first > BITS_PER_LONG_LONG || +- offload->mb_last > BITS_PER_LONG_LONG || !offload->mailbox_read) +- return -EINVAL; +- +- if (offload->mb_first < offload->mb_last) { +- offload->inc = true; +- weight = offload->mb_last - offload->mb_first; +- } else { +- offload->inc = false; +- weight = offload->mb_first - offload->mb_last; +- } +- +- return can_rx_offload_init_queue(dev, offload, weight); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_add_timestamp); +- +-int can_rx_offload_add_fifo(struct net_device *dev, +- struct can_rx_offload *offload, unsigned int weight) +-{ +- if (!offload->mailbox_read) +- return -EINVAL; +- +- return can_rx_offload_init_queue(dev, offload, weight); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_add_fifo); +- +-int can_rx_offload_add_manual(struct net_device *dev, +- struct can_rx_offload *offload, +- unsigned int weight) +-{ +- if (offload->mailbox_read) +- return -EINVAL; +- +- return can_rx_offload_init_queue(dev, offload, weight); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_add_manual); +- +-void can_rx_offload_enable(struct can_rx_offload *offload) +-{ +- napi_enable(&offload->napi); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_enable); +- +-void can_rx_offload_del(struct can_rx_offload *offload) +-{ +- netif_napi_del(&offload->napi); +- skb_queue_purge(&offload->skb_queue); +-} +-EXPORT_SYMBOL_GPL(can_rx_offload_del); +diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c +index b4a39f0449ba4..6471a71c2ee6d 100644 +--- a/drivers/net/can/slcan.c ++++ b/drivers/net/can/slcan.c +@@ -516,6 +516,7 @@ static struct slcan *slc_alloc(void) + int i; + char name[IFNAMSIZ]; + struct net_device *dev = NULL; ++ struct can_ml_priv *can_ml; + struct slcan *sl; + int size; + +@@ -538,7 +539,8 @@ static struct slcan *slc_alloc(void) + + dev->base_addr = i; + sl = netdev_priv(dev); +- dev->ml_priv = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); ++ can_ml = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); + + /* Initialize channel control data */ + sl->magic = SLCAN_MAGIC; +diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c +index 39ca14b0585dc..067705e2850b3 100644 +--- a/drivers/net/can/vcan.c ++++ b/drivers/net/can/vcan.c +@@ -153,7 +153,7 @@ static void vcan_setup(struct net_device *dev) + dev->addr_len = 0; + dev->tx_queue_len = 0; + dev->flags = IFF_NOARP; +- dev->ml_priv = netdev_priv(dev); ++ can_set_ml_priv(dev, netdev_priv(dev)); + + /* set flags according to driver capabilities */ + if (echo) +diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c +index b1baa4ac1d537..7000c6cd1e48b 100644 +--- a/drivers/net/can/vxcan.c ++++ b/drivers/net/can/vxcan.c +@@ -141,6 +141,8 @@ static const struct net_device_ops vxcan_netdev_ops = { + + static void vxcan_setup(struct net_device *dev) + { ++ struct can_ml_priv *can_ml; ++ + dev->type = ARPHRD_CAN; + dev->mtu = CANFD_MTU; + dev->hard_header_len = 0; +@@ -149,7 +151,9 @@ static void vxcan_setup(struct net_device *dev) + dev->flags = (IFF_NOARP|IFF_ECHO); + dev->netdev_ops = &vxcan_netdev_ops; + dev->needs_free_netdev = true; +- dev->ml_priv = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); ++ ++ can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); + } + + /* forward declaration for rtnl_create_link() */ +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c +index 8f70a3909929a..4af0cd9530de6 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c +@@ -71,8 +71,10 @@ static int aq_ndev_open(struct net_device *ndev) + goto err_exit; + + err = aq_nic_start(aq_nic); +- if (err < 0) ++ if (err < 0) { ++ aq_nic_stop(aq_nic); + goto err_exit; ++ } + + err_exit: + if (err < 0) +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index d1f7b51cab620..f5333fc27e14f 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -1153,7 +1153,7 @@ static void mvpp2_interrupts_unmask(void *arg) + u32 val; + + /* If the thread isn't used, don't do anything */ +- if (smp_processor_id() > port->priv->nthreads) ++ if (smp_processor_id() >= port->priv->nthreads) + return; + + val = MVPP2_CAUSE_MISC_SUM_MASK | +@@ -2287,7 +2287,7 @@ static void mvpp2_txq_sent_counter_clear(void *arg) + int queue; + + /* If the thread isn't used, don't do anything */ +- if (smp_processor_id() > port->priv->nthreads) ++ if (smp_processor_id() >= port->priv->nthreads) + return; + + for (queue = 0; queue < port->ntxqs; queue++) { +diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h +index 8e0e9350c3831..42e5a8b8d3240 100644 +--- a/drivers/net/ipa/gsi_reg.h ++++ b/drivers/net/ipa/gsi_reg.h +@@ -48,16 +48,6 @@ + #define GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(ee) \ + (0x0000c01c + 0x1000 * (ee)) + +-#define GSI_INTER_EE_SRC_CH_IRQ_CLR_OFFSET \ +- GSI_INTER_EE_N_SRC_CH_IRQ_CLR_OFFSET(GSI_EE_AP) +-#define GSI_INTER_EE_N_SRC_CH_IRQ_CLR_OFFSET(ee) \ +- (0x0000c028 + 0x1000 * (ee)) +- +-#define GSI_INTER_EE_SRC_EV_CH_IRQ_CLR_OFFSET \ +- GSI_INTER_EE_N_SRC_EV_CH_IRQ_CLR_OFFSET(GSI_EE_AP) +-#define GSI_INTER_EE_N_SRC_EV_CH_IRQ_CLR_OFFSET(ee) \ +- (0x0000c02c + 0x1000 * (ee)) +- + #define GSI_CH_C_CNTXT_0_OFFSET(ch) \ + GSI_EE_N_CH_C_CNTXT_0_OFFSET((ch), GSI_EE_AP) + #define GSI_EE_N_CH_C_CNTXT_0_OFFSET(ch, ee) \ +diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c +index d92dd3f09b735..46d8b7336d8f2 100644 +--- a/drivers/net/ipa/ipa_cmd.c ++++ b/drivers/net/ipa/ipa_cmd.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + + /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +- * Copyright (C) 2019-2020 Linaro Ltd. ++ * Copyright (C) 2019-2021 Linaro Ltd. + */ + + #include +@@ -244,11 +244,15 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa, + if (ipa->version != IPA_VERSION_3_5_1) + bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK); + BUILD_BUG_ON(bit_count > 32); +- offset_max = ~0 >> (32 - bit_count); ++ offset_max = ~0U >> (32 - bit_count); + ++ /* Make sure the offset can be represented by the field(s) ++ * that holds it. Also make sure the offset is not outside ++ * the overall IPA memory range. ++ */ + if (offset > offset_max || ipa->mem_offset > offset_max - offset) { + dev_err(dev, "%s offset too large 0x%04x + 0x%04x > 0x%04x)\n", +- ipa->mem_offset + offset, offset_max); ++ name, ipa->mem_offset, offset, offset_max); + return false; + } + +@@ -261,12 +265,24 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa) + const char *name; + u32 offset; + +- offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version); +- name = "filter/route hash flush"; +- if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) +- return false; ++ /* If hashed tables are supported, ensure the hash flush register ++ * offset will fit in a register write IPA immediate command. ++ */ ++ if (ipa->version != IPA_VERSION_4_2) { ++ offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version); ++ name = "filter/route hash flush"; ++ if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) ++ return false; ++ } + +- offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT); ++ /* Each endpoint can have a status endpoint associated with it, ++ * and this is recorded in an endpoint register. If the modem ++ * crashes, we reset the status endpoint for all modem endpoints ++ * using a register write IPA immediate command. Make sure the ++ * worst case (highest endpoint number) offset of that endpoint ++ * fits in the register write command field(s) that must hold it. ++ */ ++ offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1); + name = "maximal endpoint status"; + if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) + return false; +diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c +index e7972e88ffe0b..9bbecf4d159b4 100644 +--- a/drivers/net/netdevsim/dev.c ++++ b/drivers/net/netdevsim/dev.c +@@ -1008,23 +1008,25 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, + nsim_dev->fw_update_status = true; + nsim_dev->fw_update_overwrite_mask = 0; + +- nsim_dev->fib_data = nsim_fib_create(devlink, extack); +- if (IS_ERR(nsim_dev->fib_data)) +- return PTR_ERR(nsim_dev->fib_data); +- + nsim_devlink_param_load_driverinit_values(devlink); + + err = nsim_dev_dummy_region_init(nsim_dev, devlink); + if (err) +- goto err_fib_destroy; ++ return err; + + err = nsim_dev_traps_init(devlink); + if (err) + goto err_dummy_region_exit; + ++ nsim_dev->fib_data = nsim_fib_create(devlink, extack); ++ if (IS_ERR(nsim_dev->fib_data)) { ++ err = PTR_ERR(nsim_dev->fib_data); ++ goto err_traps_exit; ++ } ++ + err = nsim_dev_health_init(nsim_dev, devlink); + if (err) +- goto err_traps_exit; ++ goto err_fib_destroy; + + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + if (err) +@@ -1039,12 +1041,12 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, + + err_health_exit: + nsim_dev_health_exit(nsim_dev); ++err_fib_destroy: ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_traps_exit: + nsim_dev_traps_exit(devlink); + err_dummy_region_exit: + nsim_dev_dummy_region_exit(nsim_dev); +-err_fib_destroy: +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + return err; + } + +@@ -1076,15 +1078,9 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + if (err) + goto err_devlink_free; + +- nsim_dev->fib_data = nsim_fib_create(devlink, NULL); +- if (IS_ERR(nsim_dev->fib_data)) { +- err = PTR_ERR(nsim_dev->fib_data); +- goto err_resources_unregister; +- } +- + err = devlink_register(devlink, &nsim_bus_dev->dev); + if (err) +- goto err_fib_destroy; ++ goto err_resources_unregister; + + err = devlink_params_register(devlink, nsim_devlink_params, + ARRAY_SIZE(nsim_devlink_params)); +@@ -1104,9 +1100,15 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + if (err) + goto err_traps_exit; + ++ nsim_dev->fib_data = nsim_fib_create(devlink, NULL); ++ if (IS_ERR(nsim_dev->fib_data)) { ++ err = PTR_ERR(nsim_dev->fib_data); ++ goto err_debugfs_exit; ++ } ++ + err = nsim_dev_health_init(nsim_dev, devlink); + if (err) +- goto err_debugfs_exit; ++ goto err_fib_destroy; + + err = nsim_bpf_dev_init(nsim_dev); + if (err) +@@ -1124,6 +1126,8 @@ err_bpf_dev_exit: + nsim_bpf_dev_exit(nsim_dev); + err_health_exit: + nsim_dev_health_exit(nsim_dev); ++err_fib_destroy: ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_debugfs_exit: + nsim_dev_debugfs_exit(nsim_dev); + err_traps_exit: +@@ -1135,8 +1139,6 @@ err_params_unregister: + ARRAY_SIZE(nsim_devlink_params)); + err_dl_unregister: + devlink_unregister(devlink); +-err_fib_destroy: +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_resources_unregister: + devlink_resources_unregister(devlink, NULL); + err_devlink_free: +@@ -1153,10 +1155,10 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) + debugfs_remove(nsim_dev->take_snapshot); + nsim_dev_port_del_all(nsim_dev); + nsim_dev_health_exit(nsim_dev); ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + nsim_dev_traps_exit(devlink); + nsim_dev_dummy_region_exit(nsim_dev); + mutex_destroy(&nsim_dev->port_list_lock); +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + } + + void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev) +diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c +index 36600b0a0ab06..1ee4c8a906320 100644 +--- a/drivers/net/wan/lmc/lmc_main.c ++++ b/drivers/net/wan/lmc/lmc_main.c +@@ -901,6 +901,8 @@ static int lmc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + break; + default: + printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name); ++ unregister_hdlc_device(dev); ++ return -EIO; + break; + } + +diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +index e6135795719a1..e7072fc4f487a 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +@@ -576,13 +576,13 @@ static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) + case WMI_TDLS_TEARDOWN_REASON_TX: + case WMI_TDLS_TEARDOWN_REASON_RSSI: + case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: ++ rcu_read_lock(); + station = ieee80211_find_sta_by_ifaddr(ar->hw, + ev->peer_macaddr.addr, + NULL); + if (!station) { + ath10k_warn(ar, "did not find station from tdls peer event"); +- kfree(tb); +- return; ++ goto exit; + } + arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); + ieee80211_tdls_oper_request( +@@ -593,6 +593,9 @@ static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) + ); + break; + } ++ ++exit: ++ rcu_read_unlock(); + kfree(tb); + } + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index ee0edd9185604..e9e6b0c4de220 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6317,17 +6317,20 @@ static int __ath11k_mac_register(struct ath11k *ar) + ret = ath11k_regd_update(ar, true); + if (ret) { + ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret); +- goto err_free_if_combs; ++ goto err_unregister_hw; + } + + ret = ath11k_debugfs_register(ar); + if (ret) { + ath11k_err(ar->ab, "debugfs registration failed: %d\n", ret); +- goto err_free_if_combs; ++ goto err_unregister_hw; + } + + return 0; + ++err_unregister_hw: ++ ieee80211_unregister_hw(ar->hw); ++ + err_free_if_combs: + kfree(ar->hw->wiphy->iface_combinations[0].limits); + kfree(ar->hw->wiphy->iface_combinations); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 0ee421f30aa24..23e6422c2251b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5611,7 +5611,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif, + return false; + } + +-static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) ++static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif, ++ const struct brcmf_event_msg *e) + { + u32 event = e->event_code; + u16 flags = e->flags; +@@ -5620,6 +5621,8 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) + (event == BRCMF_E_DISASSOC_IND) || + ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) { + brcmf_dbg(CONN, "Processing link down\n"); ++ clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state); ++ clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state); + return true; + } + return false; +@@ -6067,7 +6070,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, + } else + brcmf_bss_connect_done(cfg, ndev, e, true); + brcmf_net_setcarrier(ifp, true); +- } else if (brcmf_is_linkdown(e)) { ++ } else if (brcmf_is_linkdown(ifp->vif, e)) { + brcmf_dbg(CONN, "Linkdown\n"); + if (!brcmf_is_ibssmode(ifp->vif) && + test_bit(BRCMF_VIF_STATUS_CONNECTED, +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index 1a222469b5b4e..bb990be7c870b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -2026,7 +2026,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, + int ret; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + +- spin_lock_irqsave(&trans_pcie->reg_lock, *flags); ++ spin_lock_bh(&trans_pcie->reg_lock); + + if (trans_pcie->cmd_hold_nic_awake) + goto out; +@@ -2111,7 +2111,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, + } + + err: +- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + return false; + } + +@@ -2149,7 +2149,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, + * scheduled on different CPUs (after we drop reg_lock). + */ + out: +- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + } + + static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, +@@ -2403,11 +2403,10 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, + u32 mask, u32 value) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +- unsigned long flags; + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock_bh(&trans_pcie->reg_lock); + __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + } + + static const char *get_csr_string(int cmd) +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +index baa83a0b85934..8c7138247869a 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +@@ -78,7 +78,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, + struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id]; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; +- unsigned long flags; + void *dup_buf = NULL; + dma_addr_t phys_addr; + int i, cmd_pos, idx; +@@ -291,11 +290,11 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + /* Increment and update queue's write index */ + txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr); + iwl_txq_inc_wr_ptr(trans, txq); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + + out: + spin_unlock_bh(&txq->lock); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index ed54d04e43964..50133c09a7805 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -321,12 +321,10 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) + txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr); + + if (txq->read_ptr == txq->write_ptr) { +- unsigned long flags; +- +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + if (txq_id == trans->txqs.cmd.q_id) + iwl_pcie_clear_cmd_in_flight(trans); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + } + } + +@@ -931,7 +929,6 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_txq *txq = trans->txqs.txq[txq_id]; +- unsigned long flags; + int nfreed = 0; + u16 r; + +@@ -962,9 +959,10 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) + } + + if (txq->read_ptr == txq->write_ptr) { +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ /* BHs are also disabled due to txq->lock */ ++ spin_lock(&trans_pcie->reg_lock); + iwl_pcie_clear_cmd_in_flight(trans); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + } + + iwl_pcie_txq_progress(txq); +@@ -1173,7 +1171,6 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, + struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id]; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; +- unsigned long flags; + void *dup_buf = NULL; + dma_addr_t phys_addr; + int idx; +@@ -1416,20 +1413,19 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + ret = iwl_pcie_set_cmd_in_flight(trans, cmd); + if (ret < 0) { + idx = ret; +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); +- goto out; ++ goto unlock_reg; + } + + /* Increment and update queue's write index */ + txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr); + iwl_pcie_txq_inc_wr_ptr(trans, txq); + +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); +- ++ unlock_reg: ++ spin_unlock(&trans_pcie->reg_lock); + out: + spin_unlock_bh(&txq->lock); + free_dup_buf: +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index da2e7415be8fe..f9615f76f1734 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -720,8 +720,8 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + regval = (!polarity_inverse ? 0x1 : 0x2); + } + +- rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, +- regval); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, ++ regval); + break; + case COEX_SWITCH_CTRL_BY_PTA: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); +@@ -731,8 +731,8 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + PTA_CTRL_PIN); + + regval = (!polarity_inverse ? 0x2 : 0x1); +- rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, +- regval); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, ++ regval); + break; + case COEX_SWITCH_CTRL_BY_ANTDIV: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); +@@ -758,11 +758,11 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + } + + if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) { +- rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); +- rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); ++ rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); ++ rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } else { +- rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); +- rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); ++ rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); ++ rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } + } + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 8b0485ada315b..d658c6e8263af 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -1098,11 +1098,11 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue) + cmd->rbytes_done += ret; + } + ++ nvmet_tcp_unmap_pdu_iovec(cmd); + if (queue->data_digest) { + nvmet_tcp_prep_recv_ddgst(cmd); + return 0; + } +- nvmet_tcp_unmap_pdu_iovec(cmd); + + if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED) && + cmd->rbytes_done == cmd->req.transfer_len) { +diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c +index aa1a1c850d057..53a0badc6b035 100644 +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -3727,12 +3727,15 @@ static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) + static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) + { + struct rockchip_pinctrl *info = dev_get_drvdata(dev); +- int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, +- rk3288_grf_gpio6c_iomux | +- GPIO6C6_SEL_WRITE_ENABLE); ++ int ret; + +- if (ret) +- return ret; ++ if (info->ctrl->type == RK3288) { ++ ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, ++ rk3288_grf_gpio6c_iomux | ++ GPIO6C6_SEL_WRITE_ENABLE); ++ if (ret) ++ return ret; ++ } + + return pinctrl_force_default(info->pctl_dev); + } +diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h +index 1cff7c69d4483..1e94586c7eb21 100644 +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -116,7 +116,6 @@ + (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ + QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) + #endif +-#endif + + #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ + ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ +@@ -244,6 +243,7 @@ struct ctio_to_2xxx { + #ifndef CTIO_RET_TYPE + #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ + #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ ++#endif + + struct fcp_hdr { + uint8_t r_ctl; +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index e2e5356a997de..19bc8c923fce5 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -1269,8 +1269,8 @@ static int st_open(struct inode *inode, struct file *filp) + spin_lock(&st_use_lock); + if (STp->in_use) { + spin_unlock(&st_use_lock); +- scsi_tape_put(STp); + DEBC_printk(STp, "Device already in use.\n"); ++ scsi_tape_put(STp); + return (-EBUSY); + } + +diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c +index 751a49f6534f4..be76fddbf524b 100644 +--- a/drivers/soc/qcom/qcom-geni-se.c ++++ b/drivers/soc/qcom/qcom-geni-se.c +@@ -3,7 +3,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -91,14 +90,11 @@ struct geni_wrapper { + struct device *dev; + void __iomem *base; + struct clk_bulk_data ahb_clks[NUM_AHB_CLKS]; +- struct geni_icc_path to_core; + }; + + static const char * const icc_path_names[] = {"qup-core", "qup-config", + "qup-memory"}; + +-static struct geni_wrapper *earlycon_wrapper; +- + #define QUP_HW_VER_REG 0x4 + + /* Common SE registers */ +@@ -828,44 +824,11 @@ int geni_icc_disable(struct geni_se *se) + } + EXPORT_SYMBOL(geni_icc_disable); + +-void geni_remove_earlycon_icc_vote(void) +-{ +- struct platform_device *pdev; +- struct geni_wrapper *wrapper; +- struct device_node *parent; +- struct device_node *child; +- +- if (!earlycon_wrapper) +- return; +- +- wrapper = earlycon_wrapper; +- parent = of_get_next_parent(wrapper->dev->of_node); +- for_each_child_of_node(parent, child) { +- if (!of_device_is_compatible(child, "qcom,geni-se-qup")) +- continue; +- +- pdev = of_find_device_by_node(child); +- if (!pdev) +- continue; +- +- wrapper = platform_get_drvdata(pdev); +- icc_put(wrapper->to_core.path); +- wrapper->to_core.path = NULL; +- +- } +- of_node_put(parent); +- +- earlycon_wrapper = NULL; +-} +-EXPORT_SYMBOL(geni_remove_earlycon_icc_vote); +- + static int geni_se_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + struct resource *res; + struct geni_wrapper *wrapper; +- struct console __maybe_unused *bcon; +- bool __maybe_unused has_earlycon = false; + int ret; + + wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL); +@@ -888,43 +851,6 @@ static int geni_se_probe(struct platform_device *pdev) + } + } + +-#ifdef CONFIG_SERIAL_EARLYCON +- for_each_console(bcon) { +- if (!strcmp(bcon->name, "qcom_geni")) { +- has_earlycon = true; +- break; +- } +- } +- if (!has_earlycon) +- goto exit; +- +- wrapper->to_core.path = devm_of_icc_get(dev, "qup-core"); +- if (IS_ERR(wrapper->to_core.path)) +- return PTR_ERR(wrapper->to_core.path); +- /* +- * Put minmal BW request on core clocks on behalf of early console. +- * The vote will be removed earlycon exit function. +- * +- * Note: We are putting vote on each QUP wrapper instead only to which +- * earlycon is connected because QUP core clock of different wrapper +- * share same voltage domain. If core1 is put to 0, then core2 will +- * also run at 0, if not voted. Default ICC vote will be removed ASA +- * we touch any of the core clock. +- * core1 = core2 = max(core1, core2) +- */ +- ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW, +- GENI_DEFAULT_BW); +- if (ret) { +- dev_err(&pdev->dev, "%s: ICC BW voting failed for core: %d\n", +- __func__, ret); +- return ret; +- } +- +- if (of_get_compatible_child(pdev->dev.of_node, "qcom,geni-debug-uart")) +- earlycon_wrapper = wrapper; +- of_node_put(pdev->dev.of_node); +-exit: +-#endif + dev_set_drvdata(dev, wrapper); + dev_dbg(dev, "GENI SE Driver probed\n"); + return devm_of_platform_populate(dev); +diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c +index d740c47827751..2f20bd56ec6ca 100644 +--- a/drivers/staging/comedi/drivers/cb_pcidas.c ++++ b/drivers/staging/comedi/drivers/cb_pcidas.c +@@ -1281,7 +1281,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, + devpriv->amcc + AMCC_OP_REG_INTCSR); + + ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED, +- dev->board_name, dev); ++ "cb_pcidas", dev); + if (ret) { + dev_dbg(dev->class_dev, "unable to allocate irq %d\n", + pcidev->irq); +diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c +index fa987bb0e7cd4..6d3ba399a7f0b 100644 +--- a/drivers/staging/comedi/drivers/cb_pcidas64.c ++++ b/drivers/staging/comedi/drivers/cb_pcidas64.c +@@ -4035,7 +4035,7 @@ static int auto_attach(struct comedi_device *dev, + init_stc_registers(dev); + + retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, +- dev->board_name, dev); ++ "cb_pcidas64", dev); + if (retval) { + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", + pcidev->irq); +diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h +index b84f00b8d18bc..4cabaf21c1ca0 100644 +--- a/drivers/staging/rtl8192e/rtllib.h ++++ b/drivers/staging/rtl8192e/rtllib.h +@@ -1105,7 +1105,7 @@ struct rtllib_network { + bool bWithAironetIE; + bool bCkipSupported; + bool bCcxRmEnable; +- u16 CcxRmState[2]; ++ u8 CcxRmState[2]; + bool bMBssidValid; + u8 MBssidMask; + u8 MBssid[ETH_ALEN]; +diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c +index d31b5e1c8df47..63752233e551f 100644 +--- a/drivers/staging/rtl8192e/rtllib_rx.c ++++ b/drivers/staging/rtl8192e/rtllib_rx.c +@@ -1968,7 +1968,7 @@ static void rtllib_parse_mife_generic(struct rtllib_device *ieee, + info_element->data[2] == 0x96 && + info_element->data[3] == 0x01) { + if (info_element->len == 6) { +- memcpy(network->CcxRmState, &info_element[4], 2); ++ memcpy(network->CcxRmState, &info_element->data[4], 2); + if (network->CcxRmState[0] != 0) + network->bCcxRmEnable = true; + else +diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c +index a6f371fc9af27..f52708f310e03 100644 +--- a/drivers/thermal/thermal_sysfs.c ++++ b/drivers/thermal/thermal_sysfs.c +@@ -754,6 +754,9 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, + { + struct cooling_dev_stats *stats = cdev->stats; + ++ if (!stats) ++ return; ++ + spin_lock(&stats->lock); + + if (stats->state == new_state) +diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c +index 291649f028213..0d85b55ea8233 100644 +--- a/drivers/tty/serial/qcom_geni_serial.c ++++ b/drivers/tty/serial/qcom_geni_serial.c +@@ -1177,12 +1177,6 @@ static inline void qcom_geni_serial_enable_early_read(struct geni_se *se, + struct console *con) { } + #endif + +-static int qcom_geni_serial_earlycon_exit(struct console *con) +-{ +- geni_remove_earlycon_icc_vote(); +- return 0; +-} +- + static struct qcom_geni_private_data earlycon_private_data; + + static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, +@@ -1233,7 +1227,6 @@ static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, + writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); + + dev->con->write = qcom_geni_serial_earlycon_write; +- dev->con->exit = qcom_geni_serial_earlycon_exit; + dev->con->setup = NULL; + qcom_geni_serial_enable_early_read(&se, dev->con); + +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 2f4e5174e78c8..e79359326411a 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -147,17 +147,29 @@ static inline int acm_set_control(struct acm *acm, int control) + #define acm_send_break(acm, ms) \ + acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) + +-static void acm_kill_urbs(struct acm *acm) ++static void acm_poison_urbs(struct acm *acm) + { + int i; + +- usb_kill_urb(acm->ctrlurb); ++ usb_poison_urb(acm->ctrlurb); + for (i = 0; i < ACM_NW; i++) +- usb_kill_urb(acm->wb[i].urb); ++ usb_poison_urb(acm->wb[i].urb); + for (i = 0; i < acm->rx_buflimit; i++) +- usb_kill_urb(acm->read_urbs[i]); ++ usb_poison_urb(acm->read_urbs[i]); + } + ++static void acm_unpoison_urbs(struct acm *acm) ++{ ++ int i; ++ ++ for (i = 0; i < acm->rx_buflimit; i++) ++ usb_unpoison_urb(acm->read_urbs[i]); ++ for (i = 0; i < ACM_NW; i++) ++ usb_unpoison_urb(acm->wb[i].urb); ++ usb_unpoison_urb(acm->ctrlurb); ++} ++ ++ + /* + * Write buffer management. + * All of these assume proper locks taken by the caller. +@@ -226,9 +238,10 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) + + rc = usb_submit_urb(wb->urb, GFP_ATOMIC); + if (rc < 0) { +- dev_err(&acm->data->dev, +- "%s - usb_submit_urb(write bulk) failed: %d\n", +- __func__, rc); ++ if (rc != -EPERM) ++ dev_err(&acm->data->dev, ++ "%s - usb_submit_urb(write bulk) failed: %d\n", ++ __func__, rc); + acm_write_done(acm, wb); + } + return rc; +@@ -313,8 +326,10 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) + acm->iocount.dsr++; + if (difference & ACM_CTRL_DCD) + acm->iocount.dcd++; +- if (newctrl & ACM_CTRL_BRK) ++ if (newctrl & ACM_CTRL_BRK) { + acm->iocount.brk++; ++ tty_insert_flip_char(&acm->port, 0, TTY_BREAK); ++ } + if (newctrl & ACM_CTRL_RI) + acm->iocount.rng++; + if (newctrl & ACM_CTRL_FRAMING) +@@ -480,11 +495,6 @@ static void acm_read_bulk_callback(struct urb *urb) + dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", + rb->index, urb->actual_length, status); + +- if (!acm->dev) { +- dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__); +- return; +- } +- + switch (status) { + case 0: + usb_mark_last_busy(acm->dev); +@@ -649,7 +659,8 @@ static void acm_port_dtr_rts(struct tty_port *port, int raise) + + res = acm_set_control(acm, val); + if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE)) +- dev_err(&acm->control->dev, "failed to set dtr/rts\n"); ++ /* This is broken in too many devices to spam the logs */ ++ dev_dbg(&acm->control->dev, "failed to set dtr/rts\n"); + } + + static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) +@@ -731,6 +742,7 @@ static void acm_port_shutdown(struct tty_port *port) + * Need to grab write_lock to prevent race with resume, but no need to + * hold it due to the tty-port initialised flag. + */ ++ acm_poison_urbs(acm); + spin_lock_irq(&acm->write_lock); + spin_unlock_irq(&acm->write_lock); + +@@ -747,7 +759,8 @@ static void acm_port_shutdown(struct tty_port *port) + usb_autopm_put_interface_async(acm->control); + } + +- acm_kill_urbs(acm); ++ acm_unpoison_urbs(acm); ++ + } + + static void acm_tty_cleanup(struct tty_struct *tty) +@@ -1503,12 +1516,16 @@ skip_countries: + + return 0; + alloc_fail6: ++ if (!acm->combined_interfaces) { ++ /* Clear driver data so that disconnect() returns early. */ ++ usb_set_intfdata(data_interface, NULL); ++ usb_driver_release_interface(&acm_driver, data_interface); ++ } + if (acm->country_codes) { + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&acm->control->dev, + &dev_attr_iCountryCodeRelDate); +- kfree(acm->country_codes); + } + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); + alloc_fail5: +@@ -1540,8 +1557,14 @@ static void acm_disconnect(struct usb_interface *intf) + if (!acm) + return; + +- mutex_lock(&acm->mutex); + acm->disconnected = true; ++ /* ++ * there is a circular dependency. acm_softint() can resubmit ++ * the URBs in error handling so we need to block any ++ * submission right away ++ */ ++ acm_poison_urbs(acm); ++ mutex_lock(&acm->mutex); + if (acm->country_codes) { + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); +@@ -1560,7 +1583,6 @@ static void acm_disconnect(struct usb_interface *intf) + tty_kref_put(tty); + } + +- acm_kill_urbs(acm); + cancel_delayed_work_sync(&acm->dwork); + + tty_unregister_device(acm_tty_driver, acm->minor); +@@ -1602,7 +1624,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) + if (cnt) + return 0; + +- acm_kill_urbs(acm); ++ acm_poison_urbs(acm); + cancel_delayed_work_sync(&acm->dwork); + acm->urbs_in_error_delay = 0; + +@@ -1615,6 +1637,7 @@ static int acm_resume(struct usb_interface *intf) + struct urb *urb; + int rv = 0; + ++ acm_unpoison_urbs(acm); + spin_lock_irq(&acm->write_lock); + + if (--acm->susp_count) +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 6ade3daf78584..76ac5d6555ae4 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -498,6 +498,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* DJI CineSSD */ + { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Fibocom L850-GL LTE Modem */ ++ { USB_DEVICE(0x2cb7, 0x0007), .driver_info = ++ USB_QUIRK_IGNORE_REMOTE_WAKEUP }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c +index fc3269f5faf19..1a9789ec5847f 100644 +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -4322,7 +4322,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) + if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) + goto unlock; + +- if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) ++ if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || ++ hsotg->flags.b.port_connect_status == 0) + goto skip_power_saving; + + /* +@@ -5398,7 +5399,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) + dwc2_writel(hsotg, hprt0, HPRT0); + + /* Wait for the HPRT0.PrtSusp register field to be set */ +- if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) ++ if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000)) + dev_warn(hsotg->dev, "Suspend wasn't generated\n"); + + /* +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index bae6a70664c80..598daed8086f6 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -118,6 +118,8 @@ static const struct property_entry dwc3_pci_intel_properties[] = { + static const struct property_entry dwc3_pci_mrfld_properties[] = { + PROPERTY_ENTRY_STRING("dr_mode", "otg"), + PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), ++ PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), ++ PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + {} + }; +diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c +index c00c4fa139b88..8bd077fb1190f 100644 +--- a/drivers/usb/dwc3/dwc3-qcom.c ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -244,6 +244,9 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) + struct device *dev = qcom->dev; + int ret; + ++ if (has_acpi_companion(dev)) ++ return 0; ++ + qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); + if (IS_ERR(qcom->icc_path_ddr)) { + dev_err(dev, "failed to get usb-ddr path: %ld\n", +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 2a86ad4b12b34..65ff41e3a18eb 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -791,10 +791,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) + reg &= ~DWC3_DALEPENA_EP(dep->number); + dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + +- dep->stream_capable = false; +- dep->type = 0; +- dep->flags = 0; +- + /* Clear out the ep descriptors for non-ep0 */ + if (dep->number > 1) { + dep->endpoint.comp_desc = NULL; +@@ -803,6 +799,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) + + dwc3_remove_requests(dwc, dep); + ++ dep->stream_capable = false; ++ dep->type = 0; ++ dep->flags = 0; ++ + return 0; + } + +diff --git a/drivers/usb/gadget/udc/amd5536udc_pci.c b/drivers/usb/gadget/udc/amd5536udc_pci.c +index 8d387e0e4d91f..c80f9bd51b750 100644 +--- a/drivers/usb/gadget/udc/amd5536udc_pci.c ++++ b/drivers/usb/gadget/udc/amd5536udc_pci.c +@@ -153,6 +153,11 @@ static int udc_pci_probe( + pci_set_master(pdev); + pci_try_set_mwi(pdev); + ++ dev->phys_addr = resource; ++ dev->irq = pdev->irq; ++ dev->pdev = pdev; ++ dev->dev = &pdev->dev; ++ + /* init dma pools */ + if (use_dma) { + retval = init_dma_pools(dev); +@@ -160,11 +165,6 @@ static int udc_pci_probe( + goto err_dma; + } + +- dev->phys_addr = resource; +- dev->irq = pdev->irq; +- dev->pdev = pdev; +- dev->dev = &pdev->dev; +- + /* general probing */ + if (udc_probe(dev)) { + retval = -ENODEV; +diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c +index fe010cc61f19b..2f27dc0d9c6bd 100644 +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -397,6 +397,13 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci->quirks |= XHCI_SPURIOUS_SUCCESS; + if (mtk->lpm_support) + xhci->quirks |= XHCI_LPM_SUPPORT; ++ ++ /* ++ * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, ++ * and it's 3 when support it. ++ */ ++ if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4) ++ xhci->quirks |= XHCI_BROKEN_STREAMS; + } + + /* called during probe() after chip reset completes */ +@@ -548,7 +555,8 @@ static int xhci_mtk_probe(struct platform_device *pdev) + if (ret) + goto put_usb3_hcd; + +- if (HCC_MAX_PSA(xhci->hcc_params) >= 4) ++ if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && ++ !(xhci->quirks & XHCI_BROKEN_STREAMS)) + xhci->shared_hcd->can_do_streams = 1; + + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); +diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c +index 3209b5ddd30c9..a20a8380ca0c9 100644 +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -594,6 +594,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + pr_err("invalid port number %d\n", wIndex); + goto error; + } ++ if (wValue >= 32) ++ goto error; + if (hcd->speed == HCD_USB3) { + if ((vhci_hcd->port_status[rhport] & + USB_SS_PORT_STAT_POWER) != 0) { +diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig +index 40a223381ab61..0f28bf99efebc 100644 +--- a/drivers/vfio/pci/Kconfig ++++ b/drivers/vfio/pci/Kconfig +@@ -42,7 +42,7 @@ config VFIO_PCI_IGD + + config VFIO_PCI_NVLINK2 + def_bool y +- depends on VFIO_PCI && PPC_POWERNV ++ depends on VFIO_PCI && PPC_POWERNV && SPAPR_TCE_IOMMU + help + VFIO PCI support for P9 Witherspoon machine with NVIDIA V100 GPUs + +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index a262e12c6dc26..5ccb0705beae1 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -332,8 +332,8 @@ static void vhost_vq_reset(struct vhost_dev *dev, + vq->error_ctx = NULL; + vq->kick = NULL; + vq->log_ctx = NULL; +- vhost_reset_is_le(vq); + vhost_disable_cross_endian(vq); ++ vhost_reset_is_le(vq); + vq->busyloop_timeout = 0; + vq->umem = NULL; + vq->iotlb = NULL; +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 8d1ae973041ae..26581194fdf81 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -1344,6 +1344,9 @@ static void fbcon_cursor(struct vc_data *vc, int mode) + + ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; + ++ if (!ops->cursor) ++ return; ++ + if (mode & CM_SOFTBACK) { + mode &= ~CM_SOFTBACK; + y = softback_lines; +diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c +index c8b0ae676809b..4dc9077dd2ac0 100644 +--- a/drivers/video/fbdev/hyperv_fb.c ++++ b/drivers/video/fbdev/hyperv_fb.c +@@ -1031,7 +1031,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) + PCI_DEVICE_ID_HYPERV_VIDEO, NULL); + if (!pdev) { + pr_err("Unable to find PCI Hyper-V video\n"); +- kfree(info->apertures); + return -ENODEV; + } + +@@ -1129,7 +1128,6 @@ getmem_done: + } else { + pci_dev_put(pdev); + } +- kfree(info->apertures); + + return 0; + +@@ -1141,7 +1139,6 @@ err2: + err1: + if (!gen2vm) + pci_dev_put(pdev); +- kfree(info->apertures); + + return -ENOMEM; + } +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index 1d640b1456375..1afd60fcd7723 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -626,27 +626,41 @@ int ext4_claim_free_clusters(struct ext4_sb_info *sbi, + + /** + * ext4_should_retry_alloc() - check if a block allocation should be retried +- * @sb: super block +- * @retries: number of attemps has been made ++ * @sb: superblock ++ * @retries: number of retry attempts made so far + * +- * ext4_should_retry_alloc() is called when ENOSPC is returned, and if +- * it is profitable to retry the operation, this function will wait +- * for the current or committing transaction to complete, and then +- * return TRUE. We will only retry once. ++ * ext4_should_retry_alloc() is called when ENOSPC is returned while ++ * attempting to allocate blocks. If there's an indication that a pending ++ * journal transaction might free some space and allow another attempt to ++ * succeed, this function will wait for the current or committing transaction ++ * to complete and then return TRUE. + */ + int ext4_should_retry_alloc(struct super_block *sb, int *retries) + { +- if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) || +- (*retries)++ > 1 || +- !EXT4_SB(sb)->s_journal) ++ struct ext4_sb_info *sbi = EXT4_SB(sb); ++ ++ if (!sbi->s_journal) + return 0; + +- smp_mb(); +- if (EXT4_SB(sb)->s_mb_free_pending == 0) ++ if (++(*retries) > 3) { ++ percpu_counter_inc(&sbi->s_sra_exceeded_retry_limit); + return 0; ++ } + ++ /* ++ * if there's no indication that blocks are about to be freed it's ++ * possible we just missed a transaction commit that did so ++ */ ++ smp_mb(); ++ if (sbi->s_mb_free_pending == 0) ++ return ext4_has_free_clusters(sbi, 1, 0); ++ ++ /* ++ * it's possible we've just missed a transaction commit here, ++ * so ignore the returned status ++ */ + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); +- jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); ++ (void) jbd2_journal_force_commit_nested(sbi->s_journal); + return 1; + } + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index b92acb6603139..7cae226b000f7 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1474,6 +1474,7 @@ struct ext4_sb_info { + struct percpu_counter s_freeinodes_counter; + struct percpu_counter s_dirs_counter; + struct percpu_counter s_dirtyclusters_counter; ++ struct percpu_counter s_sra_exceeded_retry_limit; + struct blockgroup_lock *s_blockgroup_lock; + struct proc_dir_entry *s_proc; + struct kobject s_kobj; +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index c2b8ba343bb4b..3f11c948feb02 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1937,13 +1937,13 @@ static int __ext4_journalled_writepage(struct page *page, + if (!ret) + ret = err; + +- if (!ext4_has_inline_data(inode)) +- ext4_walk_page_buffers(NULL, page_bufs, 0, len, +- NULL, bput_one); + ext4_set_inode_state(inode, EXT4_STATE_JDATA); + out: + unlock_page(page); + out_no_pagelock: ++ if (!inline_data && page_bufs) ++ ext4_walk_page_buffers(NULL, page_bufs, 0, len, ++ NULL, bput_one); + brelse(inode_bh); + return ret; + } +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 6c7eba426a678..ab7baf5299176 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3788,14 +3788,14 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + */ + retval = -ENOENT; + if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) +- goto end_rename; ++ goto release_bh; + + new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, + &new.de, &new.inlined); + if (IS_ERR(new.bh)) { + retval = PTR_ERR(new.bh); + new.bh = NULL; +- goto end_rename; ++ goto release_bh; + } + if (new.bh) { + if (!new.inode) { +@@ -3812,15 +3812,13 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits); + if (IS_ERR(handle)) { + retval = PTR_ERR(handle); +- handle = NULL; +- goto end_rename; ++ goto release_bh; + } + } else { + whiteout = ext4_whiteout_for_rename(&old, credits, &handle); + if (IS_ERR(whiteout)) { + retval = PTR_ERR(whiteout); +- whiteout = NULL; +- goto end_rename; ++ goto release_bh; + } + } + +@@ -3957,16 +3955,18 @@ end_rename: + ext4_resetent(handle, &old, + old.inode->i_ino, old_file_type); + drop_nlink(whiteout); ++ ext4_orphan_add(handle, whiteout); + } + unlock_new_inode(whiteout); ++ ext4_journal_stop(handle); + iput(whiteout); +- ++ } else { ++ ext4_journal_stop(handle); + } ++release_bh: + brelse(old.dir_bh); + brelse(old.bh); + brelse(new.bh); +- if (handle) +- ext4_journal_stop(handle); + return retval; + } + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index e30bf8f342c2a..594300d315ef2 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1226,6 +1226,7 @@ static void ext4_put_super(struct super_block *sb) + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); + percpu_counter_destroy(&sbi->s_dirtyclusters_counter); ++ percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit); + percpu_free_rwsem(&sbi->s_writepages_rwsem); + #ifdef CONFIG_QUOTA + for (i = 0; i < EXT4_MAXQUOTAS; i++) +@@ -5019,6 +5020,9 @@ no_journal: + if (!err) + err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0, + GFP_KERNEL); ++ if (!err) ++ err = percpu_counter_init(&sbi->s_sra_exceeded_retry_limit, 0, ++ GFP_KERNEL); + if (!err) + err = percpu_init_rwsem(&sbi->s_writepages_rwsem); + +@@ -5131,6 +5135,7 @@ failed_mount6: + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); + percpu_counter_destroy(&sbi->s_dirtyclusters_counter); ++ percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit); + percpu_free_rwsem(&sbi->s_writepages_rwsem); + failed_mount5: + ext4_ext_release(sb); +diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c +index 4e27fe6ed3ae6..f24bef3be48a3 100644 +--- a/fs/ext4/sysfs.c ++++ b/fs/ext4/sysfs.c +@@ -24,6 +24,7 @@ typedef enum { + attr_session_write_kbytes, + attr_lifetime_write_kbytes, + attr_reserved_clusters, ++ attr_sra_exceeded_retry_limit, + attr_inode_readahead, + attr_trigger_test_error, + attr_first_error_time, +@@ -208,6 +209,7 @@ EXT4_ATTR_FUNC(delayed_allocation_blocks, 0444); + EXT4_ATTR_FUNC(session_write_kbytes, 0444); + EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444); + EXT4_ATTR_FUNC(reserved_clusters, 0644); ++EXT4_ATTR_FUNC(sra_exceeded_retry_limit, 0444); + + EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, + ext4_sb_info, s_inode_readahead_blks); +@@ -257,6 +259,7 @@ static struct attribute *ext4_attrs[] = { + ATTR_LIST(session_write_kbytes), + ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(reserved_clusters), ++ ATTR_LIST(sra_exceeded_retry_limit), + ATTR_LIST(inode_readahead_blks), + ATTR_LIST(inode_goal), + ATTR_LIST(mb_stats), +@@ -380,6 +383,10 @@ static ssize_t ext4_attr_show(struct kobject *kobj, + return snprintf(buf, PAGE_SIZE, "%llu\n", + (unsigned long long) + atomic64_read(&sbi->s_resv_clusters)); ++ case attr_sra_exceeded_retry_limit: ++ return snprintf(buf, PAGE_SIZE, "%llu\n", ++ (unsigned long long) ++ percpu_counter_sum(&sbi->s_sra_exceeded_retry_limit)); + case attr_inode_readahead: + case attr_pointer_ui: + if (!ptr) +diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c +index d2c0e58c6416f..3d83c9e128487 100644 +--- a/fs/fuse/virtio_fs.c ++++ b/fs/fuse/virtio_fs.c +@@ -1324,8 +1324,15 @@ static int virtio_fs_fill_super(struct super_block *sb, struct fs_context *fsc) + + /* virtiofs allocates and installs its own fuse devices */ + ctx->fudptr = NULL; +- if (ctx->dax) ++ if (ctx->dax) { ++ if (!fs->dax_dev) { ++ err = -EINVAL; ++ pr_err("virtio-fs: dax can't be enabled as filesystem" ++ " device does not support it.\n"); ++ goto err_free_fuse_devs; ++ } + ctx->dax_dev = fs->dax_dev; ++ } + err = fuse_fill_super_common(sb, ctx); + if (err < 0) + goto err_free_fuse_devs; +diff --git a/fs/io_uring.c b/fs/io_uring.c +index dde290eb7dd0c..4ccf99cb8cdc0 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -4401,6 +4401,7 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock, + struct io_async_msghdr iomsg, *kmsg; + struct socket *sock; + unsigned flags; ++ int min_ret = 0; + int ret; + + sock = sock_from_file(req->file, &ret); +@@ -4421,12 +4422,15 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock, + kmsg = &iomsg; + } + +- flags = req->sr_msg.msg_flags; ++ flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; + if (flags & MSG_DONTWAIT) + req->flags |= REQ_F_NOWAIT; + else if (force_nonblock) + flags |= MSG_DONTWAIT; + ++ if (flags & MSG_WAITALL) ++ min_ret = iov_iter_count(&kmsg->msg.msg_iter); ++ + ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); + if (force_nonblock && ret == -EAGAIN) + return io_setup_async_msg(req, kmsg); +@@ -4436,7 +4440,7 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock, + if (kmsg->iov != kmsg->fast_iov) + kfree(kmsg->iov); + req->flags &= ~REQ_F_NEED_CLEANUP; +- if (ret < 0) ++ if (ret < min_ret) + req_set_fail_links(req); + __io_req_complete(req, ret, 0, cs); + return 0; +@@ -4450,6 +4454,7 @@ static int io_send(struct io_kiocb *req, bool force_nonblock, + struct iovec iov; + struct socket *sock; + unsigned flags; ++ int min_ret = 0; + int ret; + + sock = sock_from_file(req->file, &ret); +@@ -4465,12 +4470,15 @@ static int io_send(struct io_kiocb *req, bool force_nonblock, + msg.msg_controllen = 0; + msg.msg_namelen = 0; + +- flags = req->sr_msg.msg_flags; ++ flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; + if (flags & MSG_DONTWAIT) + req->flags |= REQ_F_NOWAIT; + else if (force_nonblock) + flags |= MSG_DONTWAIT; + ++ if (flags & MSG_WAITALL) ++ min_ret = iov_iter_count(&msg.msg_iter); ++ + msg.msg_flags = flags; + ret = sock_sendmsg(sock, &msg); + if (force_nonblock && ret == -EAGAIN) +@@ -4478,7 +4486,7 @@ static int io_send(struct io_kiocb *req, bool force_nonblock, + if (ret == -ERESTARTSYS) + ret = -EINTR; + +- if (ret < 0) ++ if (ret < min_ret) + req_set_fail_links(req); + __io_req_complete(req, ret, 0, cs); + return 0; +@@ -4630,6 +4638,7 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock, + struct socket *sock; + struct io_buffer *kbuf; + unsigned flags; ++ int min_ret = 0; + int ret, cflags = 0; + + sock = sock_from_file(req->file, &ret); +@@ -4659,12 +4668,15 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock, + 1, req->sr_msg.len); + } + +- flags = req->sr_msg.msg_flags; ++ flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; + if (flags & MSG_DONTWAIT) + req->flags |= REQ_F_NOWAIT; + else if (force_nonblock) + flags |= MSG_DONTWAIT; + ++ if (flags & MSG_WAITALL) ++ min_ret = iov_iter_count(&kmsg->msg.msg_iter); ++ + ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.umsg, + kmsg->uaddr, flags); + if (force_nonblock && ret == -EAGAIN) +@@ -4677,7 +4689,7 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock, + if (kmsg->iov != kmsg->fast_iov) + kfree(kmsg->iov); + req->flags &= ~REQ_F_NEED_CLEANUP; +- if (ret < 0) ++ if (ret < min_ret || ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))) + req_set_fail_links(req); + __io_req_complete(req, ret, cflags, cs); + return 0; +@@ -4693,6 +4705,7 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock, + struct socket *sock; + struct iovec iov; + unsigned flags; ++ int min_ret = 0; + int ret, cflags = 0; + + sock = sock_from_file(req->file, &ret); +@@ -4717,12 +4730,15 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock, + msg.msg_iocb = NULL; + msg.msg_flags = 0; + +- flags = req->sr_msg.msg_flags; ++ flags = req->sr_msg.msg_flags | MSG_NOSIGNAL; + if (flags & MSG_DONTWAIT) + req->flags |= REQ_F_NOWAIT; + else if (force_nonblock) + flags |= MSG_DONTWAIT; + ++ if (flags & MSG_WAITALL) ++ min_ret = iov_iter_count(&msg.msg_iter); ++ + ret = sock_recvmsg(sock, &msg, flags); + if (force_nonblock && ret == -EAGAIN) + return -EAGAIN; +@@ -4731,7 +4747,7 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock, + out_free: + if (req->flags & REQ_F_BUFFER_SELECTED) + cflags = io_put_recv_kbuf(req); +- if (ret < 0) ++ if (ret < min_ret || ((flags & MSG_WAITALL) && (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))) + req_set_fail_links(req); + __io_req_complete(req, ret, cflags, cs); + return 0; +@@ -6242,7 +6258,6 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer) + spin_unlock_irqrestore(&ctx->completion_lock, flags); + + if (prev) { +- req_set_fail_links(prev); + io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); + io_put_req_deferred(prev, 1); + } else { +diff --git a/fs/iomap/swapfile.c b/fs/iomap/swapfile.c +index a648dbf6991e4..a5e478de14174 100644 +--- a/fs/iomap/swapfile.c ++++ b/fs/iomap/swapfile.c +@@ -170,6 +170,16 @@ int iomap_swapfile_activate(struct swap_info_struct *sis, + return ret; + } + ++ /* ++ * If this swapfile doesn't contain even a single page-aligned ++ * contiguous range of blocks, reject this useless swapfile to ++ * prevent confusion later on. ++ */ ++ if (isi.nr_pages == 0) { ++ pr_warn("swapon: Cannot find a single usable page in file.\n"); ++ return -EINVAL; ++ } ++ + *pagespan = 1 + isi.highest_ppage - isi.lowest_ppage; + sis->max = isi.nr_pages; + sis->pages = isi.nr_pages - 1; +diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig +index dbbc583d62730..248f1459c0399 100644 +--- a/fs/nfsd/Kconfig ++++ b/fs/nfsd/Kconfig +@@ -73,6 +73,7 @@ config NFSD_V4 + select NFSD_V3 + select FS_POSIX_ACL + select SUNRPC_GSS ++ select CRYPTO + select CRYPTO_MD5 + select CRYPTO_SHA256 + select GRACE_PERIOD +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 052be5bf9ef50..7325592b456e5 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -1189,6 +1189,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) + switch (task->tk_status) { + case -EIO: + case -ETIMEDOUT: ++ case -EACCES: + nfsd4_mark_cb_down(clp, task->tk_status); + } + break; +diff --git a/fs/reiserfs/xattr.h b/fs/reiserfs/xattr.h +index c764352447ba1..81bec2c80b25c 100644 +--- a/fs/reiserfs/xattr.h ++++ b/fs/reiserfs/xattr.h +@@ -43,7 +43,7 @@ void reiserfs_security_free(struct reiserfs_security_handle *sec); + + static inline int reiserfs_xattrs_initialized(struct super_block *sb) + { +- return REISERFS_SB(sb)->priv_root != NULL; ++ return REISERFS_SB(sb)->priv_root && REISERFS_SB(sb)->xattr_root; + } + + #define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header)) +diff --git a/include/linux/acpi.h b/include/linux/acpi.h +index 9e173c6f312dc..fdb1d5262ce84 100644 +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -222,10 +222,14 @@ void __iomem *__acpi_map_table(unsigned long phys, unsigned long size); + void __acpi_unmap_table(void __iomem *map, unsigned long size); + int early_acpi_boot_init(void); + int acpi_boot_init (void); ++void acpi_boot_table_prepare (void); + void acpi_boot_table_init (void); + int acpi_mps_check (void); + int acpi_numa_init (void); + ++int acpi_locate_initial_tables (void); ++void acpi_reserve_initial_tables (void); ++void acpi_table_init_complete (void); + int acpi_table_init (void); + int acpi_table_parse(char *id, acpi_tbl_table_handler handler); + int __init acpi_table_parse_entries(char *id, unsigned long table_size, +@@ -807,9 +811,12 @@ static inline int acpi_boot_init(void) + return 0; + } + ++static inline void acpi_boot_table_prepare(void) ++{ ++} ++ + static inline void acpi_boot_table_init(void) + { +- return; + } + + static inline int acpi_mps_check(void) +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index dd236ef59db3e..b416bba3a62b5 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + struct bpf_verifier_env; + struct bpf_verifier_log; +@@ -556,7 +557,8 @@ struct bpf_tramp_progs { + * fentry = a set of program to run before calling original function + * fexit = a set of program to run after original function + */ +-int arch_prepare_bpf_trampoline(void *image, void *image_end, ++struct bpf_tramp_image; ++int arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, + const struct btf_func_model *m, u32 flags, + struct bpf_tramp_progs *tprogs, + void *orig_call); +@@ -565,6 +567,8 @@ u64 notrace __bpf_prog_enter(void); + void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start); + void notrace __bpf_prog_enter_sleepable(void); + void notrace __bpf_prog_exit_sleepable(void); ++void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr); ++void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr); + + struct bpf_ksym { + unsigned long start; +@@ -583,6 +587,18 @@ enum bpf_tramp_prog_type { + BPF_TRAMP_REPLACE, /* more than MAX */ + }; + ++struct bpf_tramp_image { ++ void *image; ++ struct bpf_ksym ksym; ++ struct percpu_ref pcref; ++ void *ip_after_call; ++ void *ip_epilogue; ++ union { ++ struct rcu_head rcu; ++ struct work_struct work; ++ }; ++}; ++ + struct bpf_trampoline { + /* hlist for trampoline_table */ + struct hlist_node hlist; +@@ -605,9 +621,8 @@ struct bpf_trampoline { + /* Number of attached programs. A counter per kind. */ + int progs_cnt[BPF_TRAMP_MAX]; + /* Executable image of trampoline */ +- void *image; ++ struct bpf_tramp_image *cur_image; + u64 selector; +- struct bpf_ksym ksym; + }; + + struct bpf_attach_target_info { +@@ -691,6 +706,8 @@ void bpf_image_ksym_add(void *data, struct bpf_ksym *ksym); + void bpf_image_ksym_del(struct bpf_ksym *ksym); + void bpf_ksym_add(struct bpf_ksym *ksym); + void bpf_ksym_del(struct bpf_ksym *ksym); ++int bpf_jit_charge_modmem(u32 pages); ++void bpf_jit_uncharge_modmem(u32 pages); + #else + static inline int bpf_trampoline_link_prog(struct bpf_prog *prog, + struct bpf_trampoline *tr) +@@ -780,7 +797,6 @@ struct bpf_prog_aux { + bool func_proto_unreliable; + bool sleepable; + bool tail_call_reachable; +- enum bpf_tramp_prog_type trampoline_prog_type; + struct hlist_node tramp_hlist; + /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */ + const struct btf_type *attach_func_proto; +diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h +index 2f5d731ae251d..8afa92d15a664 100644 +--- a/include/linux/can/can-ml.h ++++ b/include/linux/can/can-ml.h +@@ -44,6 +44,7 @@ + + #include + #include ++#include + + #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) + #define CAN_EFF_RCV_HASH_BITS 10 +@@ -65,4 +66,15 @@ struct can_ml_priv { + #endif + }; + ++static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev) ++{ ++ return netdev_get_ml_priv(dev, ML_PRIV_CAN); ++} ++ ++static inline void can_set_ml_priv(struct net_device *dev, ++ struct can_ml_priv *ml_priv) ++{ ++ netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN); ++} ++ + #endif /* CAN_ML_H */ +diff --git a/include/linux/extcon.h b/include/linux/extcon.h +index fd183fb9c20f7..0c19010da77fa 100644 +--- a/include/linux/extcon.h ++++ b/include/linux/extcon.h +@@ -271,6 +271,29 @@ static inline void devm_extcon_unregister_notifier(struct device *dev, + struct extcon_dev *edev, unsigned int id, + struct notifier_block *nb) { } + ++static inline int extcon_register_notifier_all(struct extcon_dev *edev, ++ struct notifier_block *nb) ++{ ++ return 0; ++} ++ ++static inline int extcon_unregister_notifier_all(struct extcon_dev *edev, ++ struct notifier_block *nb) ++{ ++ return 0; ++} ++ ++static inline int devm_extcon_register_notifier_all(struct device *dev, ++ struct extcon_dev *edev, ++ struct notifier_block *nb) ++{ ++ return 0; ++} ++ ++static inline void devm_extcon_unregister_notifier_all(struct device *dev, ++ struct extcon_dev *edev, ++ struct notifier_block *nb) { } ++ + static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) + { + return ERR_PTR(-ENODEV); +diff --git a/include/linux/firmware/intel/stratix10-svc-client.h b/include/linux/firmware/intel/stratix10-svc-client.h +index a93d85932eb92..f843c6a10cf36 100644 +--- a/include/linux/firmware/intel/stratix10-svc-client.h ++++ b/include/linux/firmware/intel/stratix10-svc-client.h +@@ -56,7 +56,7 @@ + * COMMAND_RECONFIG_FLAG_PARTIAL: + * Set to FPGA configuration type (full or partial). + */ +-#define COMMAND_RECONFIG_FLAG_PARTIAL 1 ++#define COMMAND_RECONFIG_FLAG_PARTIAL 0 + + /** + * Timeout settings for service clients: +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 8753e98a8d58a..e37480b5f4c0e 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1600,6 +1600,12 @@ enum netdev_priv_flags { + #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER + #define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK + ++/* Specifies the type of the struct net_device::ml_priv pointer */ ++enum netdev_ml_priv_type { ++ ML_PRIV_NONE, ++ ML_PRIV_CAN, ++}; ++ + /** + * struct net_device - The DEVICE structure. + * +@@ -1795,6 +1801,7 @@ enum netdev_priv_flags { + * @nd_net: Network namespace this network device is inside + * + * @ml_priv: Mid-layer private ++ * @ml_priv_type: Mid-layer private type + * @lstats: Loopback statistics + * @tstats: Tunnel statistics + * @dstats: Dummy statistics +@@ -2107,8 +2114,10 @@ struct net_device { + possible_net_t nd_net; + + /* mid-layer private */ ++ void *ml_priv; ++ enum netdev_ml_priv_type ml_priv_type; ++ + union { +- void *ml_priv; + struct pcpu_lstats __percpu *lstats; + struct pcpu_sw_netstats __percpu *tstats; + struct pcpu_dstats __percpu *dstats; +@@ -2298,6 +2307,29 @@ static inline void netdev_reset_rx_headroom(struct net_device *dev) + netdev_set_rx_headroom(dev, -1); + } + ++static inline void *netdev_get_ml_priv(struct net_device *dev, ++ enum netdev_ml_priv_type type) ++{ ++ if (dev->ml_priv_type != type) ++ return NULL; ++ ++ return dev->ml_priv; ++} ++ ++static inline void netdev_set_ml_priv(struct net_device *dev, ++ void *ml_priv, ++ enum netdev_ml_priv_type type) ++{ ++ WARN(dev->ml_priv_type && dev->ml_priv_type != type, ++ "Overwriting already set ml_priv_type (%u) with different ml_priv_type (%u)!\n", ++ dev->ml_priv_type, type); ++ WARN(!dev->ml_priv_type && dev->ml_priv, ++ "Overwriting already set ml_priv and ml_priv_type is ML_PRIV_NONE!\n"); ++ ++ dev->ml_priv = ml_priv; ++ dev->ml_priv_type = type; ++} ++ + /* + * Net namespace inlines + */ +diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h +index f7bbea3f09ca9..964cfe68f72cc 100644 +--- a/include/linux/qcom-geni-se.h ++++ b/include/linux/qcom-geni-se.h +@@ -462,7 +462,5 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag); + int geni_icc_enable(struct geni_se *se); + + int geni_icc_disable(struct geni_se *se); +- +-void geni_remove_earlycon_icc_vote(void); + #endif + #endif +diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h +index 850424e5d0306..6ecf2a0220dbe 100644 +--- a/include/linux/ww_mutex.h ++++ b/include/linux/ww_mutex.h +@@ -173,9 +173,10 @@ static inline void ww_acquire_done(struct ww_acquire_ctx *ctx) + */ + static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx) + { +-#ifdef CONFIG_DEBUG_MUTEXES ++#ifdef CONFIG_DEBUG_LOCK_ALLOC + mutex_release(&ctx->dep_map, _THIS_IP_); +- ++#endif ++#ifdef CONFIG_DEBUG_MUTEXES + DEBUG_LOCKS_WARN_ON(ctx->acquired); + if (!IS_ENABLED(CONFIG_PROVE_LOCKING)) + /* +diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c +index 4c3b543bb33b7..f527063864b55 100644 +--- a/kernel/bpf/bpf_struct_ops.c ++++ b/kernel/bpf/bpf_struct_ops.c +@@ -430,7 +430,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, + + tprogs[BPF_TRAMP_FENTRY].progs[0] = prog; + tprogs[BPF_TRAMP_FENTRY].nr_progs = 1; +- err = arch_prepare_bpf_trampoline(image, ++ err = arch_prepare_bpf_trampoline(NULL, image, + st_map->image + PAGE_SIZE, + &st_ops->func_models[i], 0, + tprogs, NULL); +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 55454d2278b17..182e162f8fd0b 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -825,7 +825,7 @@ static int __init bpf_jit_charge_init(void) + } + pure_initcall(bpf_jit_charge_init); + +-static int bpf_jit_charge_modmem(u32 pages) ++int bpf_jit_charge_modmem(u32 pages) + { + if (atomic_long_add_return(pages, &bpf_jit_current) > + (bpf_jit_limit >> PAGE_SHIFT)) { +@@ -838,7 +838,7 @@ static int bpf_jit_charge_modmem(u32 pages) + return 0; + } + +-static void bpf_jit_uncharge_modmem(u32 pages) ++void bpf_jit_uncharge_modmem(u32 pages) + { + atomic_long_sub(pages, &bpf_jit_current); + } +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index 35c5887d82ffe..986dabc3d11f0 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -57,19 +57,10 @@ void bpf_image_ksym_del(struct bpf_ksym *ksym) + PAGE_SIZE, true, ksym->name); + } + +-static void bpf_trampoline_ksym_add(struct bpf_trampoline *tr) +-{ +- struct bpf_ksym *ksym = &tr->ksym; +- +- snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu", tr->key); +- bpf_image_ksym_add(tr->image, ksym); +-} +- + static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) + { + struct bpf_trampoline *tr; + struct hlist_head *head; +- void *image; + int i; + + mutex_lock(&trampoline_mutex); +@@ -84,14 +75,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) + if (!tr) + goto out; + +- /* is_root was checked earlier. No need for bpf_jit_charge_modmem() */ +- image = bpf_jit_alloc_exec_page(); +- if (!image) { +- kfree(tr); +- tr = NULL; +- goto out; +- } +- + tr->key = key; + INIT_HLIST_NODE(&tr->hlist); + hlist_add_head(&tr->hlist, head); +@@ -99,9 +82,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key) + mutex_init(&tr->mutex); + for (i = 0; i < BPF_TRAMP_MAX; i++) + INIT_HLIST_HEAD(&tr->progs_hlist[i]); +- tr->image = image; +- INIT_LIST_HEAD_RCU(&tr->ksym.lnode); +- bpf_trampoline_ksym_add(tr); + out: + mutex_unlock(&trampoline_mutex); + return tr; +@@ -185,10 +165,142 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total) + return tprogs; + } + ++static void __bpf_tramp_image_put_deferred(struct work_struct *work) ++{ ++ struct bpf_tramp_image *im; ++ ++ im = container_of(work, struct bpf_tramp_image, work); ++ bpf_image_ksym_del(&im->ksym); ++ bpf_jit_free_exec(im->image); ++ bpf_jit_uncharge_modmem(1); ++ percpu_ref_exit(&im->pcref); ++ kfree_rcu(im, rcu); ++} ++ ++/* callback, fexit step 3 or fentry step 2 */ ++static void __bpf_tramp_image_put_rcu(struct rcu_head *rcu) ++{ ++ struct bpf_tramp_image *im; ++ ++ im = container_of(rcu, struct bpf_tramp_image, rcu); ++ INIT_WORK(&im->work, __bpf_tramp_image_put_deferred); ++ schedule_work(&im->work); ++} ++ ++/* callback, fexit step 2. Called after percpu_ref_kill confirms. */ ++static void __bpf_tramp_image_release(struct percpu_ref *pcref) ++{ ++ struct bpf_tramp_image *im; ++ ++ im = container_of(pcref, struct bpf_tramp_image, pcref); ++ call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu); ++} ++ ++/* callback, fexit or fentry step 1 */ ++static void __bpf_tramp_image_put_rcu_tasks(struct rcu_head *rcu) ++{ ++ struct bpf_tramp_image *im; ++ ++ im = container_of(rcu, struct bpf_tramp_image, rcu); ++ if (im->ip_after_call) ++ /* the case of fmod_ret/fexit trampoline and CONFIG_PREEMPTION=y */ ++ percpu_ref_kill(&im->pcref); ++ else ++ /* the case of fentry trampoline */ ++ call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu); ++} ++ ++static void bpf_tramp_image_put(struct bpf_tramp_image *im) ++{ ++ /* The trampoline image that calls original function is using: ++ * rcu_read_lock_trace to protect sleepable bpf progs ++ * rcu_read_lock to protect normal bpf progs ++ * percpu_ref to protect trampoline itself ++ * rcu tasks to protect trampoline asm not covered by percpu_ref ++ * (which are few asm insns before __bpf_tramp_enter and ++ * after __bpf_tramp_exit) ++ * ++ * The trampoline is unreachable before bpf_tramp_image_put(). ++ * ++ * First, patch the trampoline to avoid calling into fexit progs. ++ * The progs will be freed even if the original function is still ++ * executing or sleeping. ++ * In case of CONFIG_PREEMPT=y use call_rcu_tasks() to wait on ++ * first few asm instructions to execute and call into ++ * __bpf_tramp_enter->percpu_ref_get. ++ * Then use percpu_ref_kill to wait for the trampoline and the original ++ * function to finish. ++ * Then use call_rcu_tasks() to make sure few asm insns in ++ * the trampoline epilogue are done as well. ++ * ++ * In !PREEMPT case the task that got interrupted in the first asm ++ * insns won't go through an RCU quiescent state which the ++ * percpu_ref_kill will be waiting for. Hence the first ++ * call_rcu_tasks() is not necessary. ++ */ ++ if (im->ip_after_call) { ++ int err = bpf_arch_text_poke(im->ip_after_call, BPF_MOD_JUMP, ++ NULL, im->ip_epilogue); ++ WARN_ON(err); ++ if (IS_ENABLED(CONFIG_PREEMPTION)) ++ call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu_tasks); ++ else ++ percpu_ref_kill(&im->pcref); ++ return; ++ } ++ ++ /* The trampoline without fexit and fmod_ret progs doesn't call original ++ * function and doesn't use percpu_ref. ++ * Use call_rcu_tasks_trace() to wait for sleepable progs to finish. ++ * Then use call_rcu_tasks() to wait for the rest of trampoline asm ++ * and normal progs. ++ */ ++ call_rcu_tasks_trace(&im->rcu, __bpf_tramp_image_put_rcu_tasks); ++} ++ ++static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx) ++{ ++ struct bpf_tramp_image *im; ++ struct bpf_ksym *ksym; ++ void *image; ++ int err = -ENOMEM; ++ ++ im = kzalloc(sizeof(*im), GFP_KERNEL); ++ if (!im) ++ goto out; ++ ++ err = bpf_jit_charge_modmem(1); ++ if (err) ++ goto out_free_im; ++ ++ err = -ENOMEM; ++ im->image = image = bpf_jit_alloc_exec_page(); ++ if (!image) ++ goto out_uncharge; ++ ++ err = percpu_ref_init(&im->pcref, __bpf_tramp_image_release, 0, GFP_KERNEL); ++ if (err) ++ goto out_free_image; ++ ++ ksym = &im->ksym; ++ INIT_LIST_HEAD_RCU(&ksym->lnode); ++ snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu_%u", key, idx); ++ bpf_image_ksym_add(image, ksym); ++ return im; ++ ++out_free_image: ++ bpf_jit_free_exec(im->image); ++out_uncharge: ++ bpf_jit_uncharge_modmem(1); ++out_free_im: ++ kfree(im); ++out: ++ return ERR_PTR(err); ++} ++ + static int bpf_trampoline_update(struct bpf_trampoline *tr) + { +- void *old_image = tr->image + ((tr->selector + 1) & 1) * PAGE_SIZE/2; +- void *new_image = tr->image + (tr->selector & 1) * PAGE_SIZE/2; ++ struct bpf_tramp_image *im; + struct bpf_tramp_progs *tprogs; + u32 flags = BPF_TRAMP_F_RESTORE_REGS; + int err, total; +@@ -198,41 +310,42 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr) + return PTR_ERR(tprogs); + + if (total == 0) { +- err = unregister_fentry(tr, old_image); ++ err = unregister_fentry(tr, tr->cur_image->image); ++ bpf_tramp_image_put(tr->cur_image); ++ tr->cur_image = NULL; + tr->selector = 0; + goto out; + } + ++ im = bpf_tramp_image_alloc(tr->key, tr->selector); ++ if (IS_ERR(im)) { ++ err = PTR_ERR(im); ++ goto out; ++ } ++ + if (tprogs[BPF_TRAMP_FEXIT].nr_progs || + tprogs[BPF_TRAMP_MODIFY_RETURN].nr_progs) + flags = BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_SKIP_FRAME; + +- /* Though the second half of trampoline page is unused a task could be +- * preempted in the middle of the first half of trampoline and two +- * updates to trampoline would change the code from underneath the +- * preempted task. Hence wait for tasks to voluntarily schedule or go +- * to userspace. +- * The same trampoline can hold both sleepable and non-sleepable progs. +- * synchronize_rcu_tasks_trace() is needed to make sure all sleepable +- * programs finish executing. +- * Wait for these two grace periods together. +- */ +- synchronize_rcu_mult(call_rcu_tasks, call_rcu_tasks_trace); +- +- err = arch_prepare_bpf_trampoline(new_image, new_image + PAGE_SIZE / 2, ++ err = arch_prepare_bpf_trampoline(im, im->image, im->image + PAGE_SIZE, + &tr->func.model, flags, tprogs, + tr->func.addr); + if (err < 0) + goto out; + +- if (tr->selector) ++ WARN_ON(tr->cur_image && tr->selector == 0); ++ WARN_ON(!tr->cur_image && tr->selector); ++ if (tr->cur_image) + /* progs already running at this address */ +- err = modify_fentry(tr, old_image, new_image); ++ err = modify_fentry(tr, tr->cur_image->image, im->image); + else + /* first time registering */ +- err = register_fentry(tr, new_image); ++ err = register_fentry(tr, im->image); + if (err) + goto out; ++ if (tr->cur_image) ++ bpf_tramp_image_put(tr->cur_image); ++ tr->cur_image = im; + tr->selector++; + out: + kfree(tprogs); +@@ -364,17 +477,12 @@ void bpf_trampoline_put(struct bpf_trampoline *tr) + goto out; + if (WARN_ON_ONCE(!hlist_empty(&tr->progs_hlist[BPF_TRAMP_FEXIT]))) + goto out; +- bpf_image_ksym_del(&tr->ksym); +- /* This code will be executed when all bpf progs (both sleepable and +- * non-sleepable) went through +- * bpf_prog_put()->call_rcu[_tasks_trace]()->bpf_prog_free_deferred(). +- * Hence no need for another synchronize_rcu_tasks_trace() here, +- * but synchronize_rcu_tasks() is still needed, since trampoline +- * may not have had any sleepable programs and we need to wait +- * for tasks to get out of trampoline code before freeing it. ++ /* This code will be executed even when the last bpf_tramp_image ++ * is alive. All progs are detached from the trampoline and the ++ * trampoline image is patched with jmp into epilogue to skip ++ * fexit progs. The fentry-only trampoline will be freed via ++ * multiple rcu callbacks. + */ +- synchronize_rcu_tasks(); +- bpf_jit_free_exec(tr->image); + hlist_del(&tr->hlist); + kfree(tr); + out: +@@ -433,8 +541,18 @@ void notrace __bpf_prog_exit_sleepable(void) + rcu_read_unlock_trace(); + } + ++void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr) ++{ ++ percpu_ref_get(&tr->pcref); ++} ++ ++void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr) ++{ ++ percpu_ref_put(&tr->pcref); ++} ++ + int __weak +-arch_prepare_bpf_trampoline(void *image, void *image_end, ++arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, + const struct btf_func_model *m, u32 flags, + struct bpf_tramp_progs *tprogs, + void *orig_call) +diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c +index 5352ce50a97e3..2c25b830203cd 100644 +--- a/kernel/locking/mutex.c ++++ b/kernel/locking/mutex.c +@@ -636,7 +636,7 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) + */ + static __always_inline bool + mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, +- const bool use_ww_ctx, struct mutex_waiter *waiter) ++ struct mutex_waiter *waiter) + { + if (!waiter) { + /* +@@ -712,7 +712,7 @@ fail: + #else + static __always_inline bool + mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, +- const bool use_ww_ctx, struct mutex_waiter *waiter) ++ struct mutex_waiter *waiter) + { + return false; + } +@@ -932,6 +932,9 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + struct ww_mutex *ww; + int ret; + ++ if (!use_ww_ctx) ++ ww_ctx = NULL; ++ + might_sleep(); + + #ifdef CONFIG_DEBUG_MUTEXES +@@ -939,7 +942,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + #endif + + ww = container_of(lock, struct ww_mutex, base); +- if (use_ww_ctx && ww_ctx) { ++ if (ww_ctx) { + if (unlikely(ww_ctx == READ_ONCE(ww->ctx))) + return -EALREADY; + +@@ -956,10 +959,10 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); + + if (__mutex_trylock(lock) || +- mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, NULL)) { ++ mutex_optimistic_spin(lock, ww_ctx, NULL)) { + /* got the lock, yay! */ + lock_acquired(&lock->dep_map, ip); +- if (use_ww_ctx && ww_ctx) ++ if (ww_ctx) + ww_mutex_set_context_fastpath(ww, ww_ctx); + preempt_enable(); + return 0; +@@ -970,7 +973,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + * After waiting to acquire the wait_lock, try again. + */ + if (__mutex_trylock(lock)) { +- if (use_ww_ctx && ww_ctx) ++ if (ww_ctx) + __ww_mutex_check_waiters(lock, ww_ctx); + + goto skip_wait; +@@ -1023,7 +1026,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + goto err; + } + +- if (use_ww_ctx && ww_ctx) { ++ if (ww_ctx) { + ret = __ww_mutex_check_kill(lock, &waiter, ww_ctx); + if (ret) + goto err; +@@ -1036,7 +1039,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + * ww_mutex needs to always recheck its position since its waiter + * list is not FIFO ordered. + */ +- if ((use_ww_ctx && ww_ctx) || !first) { ++ if (ww_ctx || !first) { + first = __mutex_waiter_is_first(lock, &waiter); + if (first) + __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); +@@ -1049,7 +1052,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + * or we must see its unlock and acquire. + */ + if (__mutex_trylock(lock) || +- (first && mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx, &waiter))) ++ (first && mutex_optimistic_spin(lock, ww_ctx, &waiter))) + break; + + spin_lock(&lock->wait_lock); +@@ -1058,7 +1061,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + acquired: + __set_current_state(TASK_RUNNING); + +- if (use_ww_ctx && ww_ctx) { ++ if (ww_ctx) { + /* + * Wound-Wait; we stole the lock (!first_waiter), check the + * waiters as anyone might want to wound us. +@@ -1078,7 +1081,7 @@ skip_wait: + /* got the lock - cleanup and rejoice! */ + lock_acquired(&lock->dep_map, ip); + +- if (use_ww_ctx && ww_ctx) ++ if (ww_ctx) + ww_mutex_lock_acquired(ww, ww_ctx); + + spin_unlock(&lock->wait_lock); +diff --git a/kernel/static_call.c b/kernel/static_call.c +index 49efbdc5b4800..f59089a122319 100644 +--- a/kernel/static_call.c ++++ b/kernel/static_call.c +@@ -149,6 +149,7 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func) + }; + + for (site_mod = &first; site_mod; site_mod = site_mod->next) { ++ bool init = system_state < SYSTEM_RUNNING; + struct module *mod = site_mod->mod; + + if (!site_mod->sites) { +@@ -168,6 +169,7 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func) + if (mod) { + stop = mod->static_call_sites + + mod->num_static_call_sites; ++ init = mod->state == MODULE_STATE_COMING; + } + #endif + +@@ -175,16 +177,8 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func) + site < stop && static_call_key(site) == key; site++) { + void *site_addr = static_call_addr(site); + +- if (static_call_is_init(site)) { +- /* +- * Don't write to call sites which were in +- * initmem and have since been freed. +- */ +- if (!mod && system_state >= SYSTEM_RUNNING) +- continue; +- if (mod && !within_module_init((unsigned long)site_addr, mod)) +- continue; +- } ++ if (!init && static_call_is_init(site)) ++ continue; + + if (!kernel_text_address((unsigned long)site_addr)) { + /* +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index ee4be813ba85b..8bfa4e78d8951 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2984,7 +2984,8 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer, + + size = nr_entries * sizeof(unsigned long); + event = __trace_buffer_lock_reserve(buffer, TRACE_STACK, +- sizeof(*entry) + size, flags, pc); ++ (sizeof(*entry) - sizeof(entry->caller)) + size, ++ flags, pc); + if (!event) + goto out; + entry = ring_buffer_event_data(event); +diff --git a/mm/memory.c b/mm/memory.c +index 4d565d7c80169..b70bd3ba33888 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -154,7 +154,7 @@ static int __init init_zero_pfn(void) + zero_pfn = page_to_pfn(ZERO_PAGE(0)); + return 0; + } +-core_initcall(init_zero_pfn); ++early_initcall(init_zero_pfn); + + void mm_trace_rss_stat(struct mm_struct *mm, int member, long count) + { +diff --git a/net/9p/client.c b/net/9p/client.c +index 09f1ec589b80b..eb42bbb72f523 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -1617,10 +1617,6 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, + } + + p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); +- if (!count) { +- p9_tag_remove(clnt, req); +- return 0; +- } + + if (non_zc) { + int n = copy_to_iter(dataptr, count, to); +diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c +index 1d48708c5a2eb..c94b212d8e7ca 100644 +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1576,8 +1576,8 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + struct sk_buff *skb; + struct net_device *dev; + struct ddpehdr *ddp; +- int size; +- struct atalk_route *rt; ++ int size, hard_header_len; ++ struct atalk_route *rt, *rt_lo = NULL; + int err; + + if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) +@@ -1640,7 +1640,22 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", + sk, size, dev->name); + +- size += dev->hard_header_len; ++ hard_header_len = dev->hard_header_len; ++ /* Leave room for loopback hardware header if necessary */ ++ if (usat->sat_addr.s_node == ATADDR_BCAST && ++ (dev->flags & IFF_LOOPBACK || !(rt->flags & RTF_GATEWAY))) { ++ struct atalk_addr at_lo; ++ ++ at_lo.s_node = 0; ++ at_lo.s_net = 0; ++ ++ rt_lo = atrtr_find(&at_lo); ++ ++ if (rt_lo && rt_lo->dev->hard_header_len > hard_header_len) ++ hard_header_len = rt_lo->dev->hard_header_len; ++ } ++ ++ size += hard_header_len; + release_sock(sk); + skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); + lock_sock(sk); +@@ -1648,7 +1663,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + goto out; + + skb_reserve(skb, ddp_dl->header_length); +- skb_reserve(skb, dev->hard_header_len); ++ skb_reserve(skb, hard_header_len); + skb->dev = dev; + + SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); +@@ -1699,18 +1714,12 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + /* loop back */ + skb_orphan(skb); + if (ddp->deh_dnode == ATADDR_BCAST) { +- struct atalk_addr at_lo; +- +- at_lo.s_node = 0; +- at_lo.s_net = 0; +- +- rt = atrtr_find(&at_lo); +- if (!rt) { ++ if (!rt_lo) { + kfree_skb(skb); + err = -ENETUNREACH; + goto out; + } +- dev = rt->dev; ++ dev = rt_lo->dev; + skb->dev = dev; + } + ddp_dl->request(ddp_dl, skb, dev->dev_addr); +diff --git a/net/can/af_can.c b/net/can/af_can.c +index 4c343b43067f6..1c95ede2c9a6e 100644 +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -304,8 +304,8 @@ static struct can_dev_rcv_lists *can_dev_rcv_lists_find(struct net *net, + struct net_device *dev) + { + if (dev) { +- struct can_ml_priv *ml_priv = dev->ml_priv; +- return &ml_priv->dev_rcv_lists; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ return &can_ml->dev_rcv_lists; + } else { + return net->can.rx_alldev_list; + } +@@ -790,25 +790,6 @@ void can_proto_unregister(const struct can_proto *cp) + } + EXPORT_SYMBOL(can_proto_unregister); + +-/* af_can notifier to create/remove CAN netdevice specific structs */ +-static int can_notifier(struct notifier_block *nb, unsigned long msg, +- void *ptr) +-{ +- struct net_device *dev = netdev_notifier_info_to_dev(ptr); +- +- if (dev->type != ARPHRD_CAN) +- return NOTIFY_DONE; +- +- switch (msg) { +- case NETDEV_REGISTER: +- WARN(!dev->ml_priv, +- "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n"); +- break; +- } +- +- return NOTIFY_DONE; +-} +- + static int can_pernet_init(struct net *net) + { + spin_lock_init(&net->can.rcvlists_lock); +@@ -876,11 +857,6 @@ static const struct net_proto_family can_family_ops = { + .owner = THIS_MODULE, + }; + +-/* notifier block for netdevice event */ +-static struct notifier_block can_netdev_notifier __read_mostly = { +- .notifier_call = can_notifier, +-}; +- + static struct pernet_operations can_pernet_ops __read_mostly = { + .init = can_pernet_init, + .exit = can_pernet_exit, +@@ -911,17 +887,12 @@ static __init int can_init(void) + err = sock_register(&can_family_ops); + if (err) + goto out_sock; +- err = register_netdevice_notifier(&can_netdev_notifier); +- if (err) +- goto out_notifier; + + dev_add_pack(&can_packet); + dev_add_pack(&canfd_packet); + + return 0; + +-out_notifier: +- sock_unregister(PF_CAN); + out_sock: + unregister_pernet_subsys(&can_pernet_ops); + out_pernet: +@@ -935,7 +906,6 @@ static __exit void can_exit(void) + /* protocol unregister */ + dev_remove_pack(&canfd_packet); + dev_remove_pack(&can_packet); +- unregister_netdevice_notifier(&can_netdev_notifier); + sock_unregister(PF_CAN); + + unregister_pernet_subsys(&can_pernet_ops); +diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c +index 137054bff9ec7..e52330f628c9f 100644 +--- a/net/can/j1939/main.c ++++ b/net/can/j1939/main.c +@@ -140,9 +140,9 @@ static struct j1939_priv *j1939_priv_create(struct net_device *ndev) + static inline void j1939_priv_set(struct net_device *ndev, + struct j1939_priv *priv) + { +- struct can_ml_priv *can_ml_priv = ndev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + +- can_ml_priv->j1939_priv = priv; ++ can_ml->j1939_priv = priv; + } + + static void __j1939_priv_release(struct kref *kref) +@@ -211,12 +211,9 @@ static void __j1939_rx_release(struct kref *kref) + /* get pointer to priv without increasing ref counter */ + static inline struct j1939_priv *j1939_ndev_to_priv(struct net_device *ndev) + { +- struct can_ml_priv *can_ml_priv = ndev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + +- if (!can_ml_priv) +- return NULL; +- +- return can_ml_priv->j1939_priv; ++ return can_ml->j1939_priv; + } + + static struct j1939_priv *j1939_priv_get_by_ndev_locked(struct net_device *ndev) +@@ -225,9 +222,6 @@ static struct j1939_priv *j1939_priv_get_by_ndev_locked(struct net_device *ndev) + + lockdep_assert_held(&j1939_netdev_lock); + +- if (ndev->type != ARPHRD_CAN) +- return NULL; +- + priv = j1939_ndev_to_priv(ndev); + if (priv) + j1939_priv_get(priv); +@@ -348,15 +342,16 @@ static int j1939_netdev_notify(struct notifier_block *nb, + unsigned long msg, void *data) + { + struct net_device *ndev = netdev_notifier_info_to_dev(data); ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + struct j1939_priv *priv; + ++ if (!can_ml) ++ goto notify_done; ++ + priv = j1939_priv_get_by_ndev(ndev); + if (!priv) + goto notify_done; + +- if (ndev->type != ARPHRD_CAN) +- goto notify_put; +- + switch (msg) { + case NETDEV_DOWN: + j1939_cancel_active_session(priv, NULL); +@@ -365,7 +360,6 @@ static int j1939_netdev_notify(struct notifier_block *nb, + break; + } + +-notify_put: + j1939_priv_put(priv); + + notify_done: +diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c +index f23966526a885..56aa66147d5ac 100644 +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -12,6 +12,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -453,6 +454,7 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) + j1939_jsk_del(priv, jsk); + j1939_local_ecu_put(priv, jsk->addr.src_name, jsk->addr.sa); + } else { ++ struct can_ml_priv *can_ml; + struct net_device *ndev; + + ndev = dev_get_by_index(net, addr->can_ifindex); +@@ -461,15 +463,8 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) + goto out_release_sock; + } + +- if (ndev->type != ARPHRD_CAN) { +- dev_put(ndev); +- ret = -ENODEV; +- goto out_release_sock; +- } +- +- if (!ndev->ml_priv) { +- netdev_warn_once(ndev, +- "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n"); ++ can_ml = can_get_ml_priv(ndev); ++ if (!can_ml) { + dev_put(ndev); + ret = -ENODEV; + goto out_release_sock; +diff --git a/net/can/proc.c b/net/can/proc.c +index 5ea8695f507eb..b15760b5c1cce 100644 +--- a/net/can/proc.c ++++ b/net/can/proc.c +@@ -322,8 +322,11 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v) + + /* receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) +- can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) ++ can_rcvlist_proc_show_one(m, idx, dev, ++ &can_ml->dev_rcv_lists); + } + + rcu_read_unlock(); +@@ -375,8 +378,10 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) + + /* sff receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) { +- dev_rcv_lists = dev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) { ++ dev_rcv_lists = &can_ml->dev_rcv_lists; + can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_sff, + ARRAY_SIZE(dev_rcv_lists->rx_sff)); + } +@@ -406,8 +411,10 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) + + /* eff receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) { +- dev_rcv_lists = dev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) { ++ dev_rcv_lists = &can_ml->dev_rcv_lists; + can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_eff, + ARRAY_SIZE(dev_rcv_lists->rx_eff)); + } +diff --git a/net/core/filter.c b/net/core/filter.c +index f0a19a48c0481..9358bc4a3711f 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -3552,11 +3552,7 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff, + return 0; + } + +-static u32 __bpf_skb_max_len(const struct sk_buff *skb) +-{ +- return skb->dev ? skb->dev->mtu + skb->dev->hard_header_len : +- SKB_MAX_ALLOC; +-} ++#define BPF_SKB_MAX_LEN SKB_MAX_ALLOC + + BPF_CALL_4(sk_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, + u32, mode, u64, flags) +@@ -3605,7 +3601,7 @@ BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, + { + u32 len_cur, len_diff_abs = abs(len_diff); + u32 len_min = bpf_skb_net_base_len(skb); +- u32 len_max = __bpf_skb_max_len(skb); ++ u32 len_max = BPF_SKB_MAX_LEN; + __be16 proto = skb->protocol; + bool shrink = len_diff < 0; + u32 off; +@@ -3688,7 +3684,7 @@ static int bpf_skb_trim_rcsum(struct sk_buff *skb, unsigned int new_len) + static inline int __bpf_skb_change_tail(struct sk_buff *skb, u32 new_len, + u64 flags) + { +- u32 max_len = __bpf_skb_max_len(skb); ++ u32 max_len = BPF_SKB_MAX_LEN; + u32 min_len = __bpf_skb_min_len(skb); + int ret; + +@@ -3764,7 +3760,7 @@ static const struct bpf_func_proto sk_skb_change_tail_proto = { + static inline int __bpf_skb_change_head(struct sk_buff *skb, u32 head_room, + u64 flags) + { +- u32 max_len = __bpf_skb_max_len(skb); ++ u32 max_len = BPF_SKB_MAX_LEN; + u32 new_len = skb->len + head_room; + int ret; + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index c79be25b2e0c2..d48b37b15b276 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1050,6 +1050,9 @@ proto_again: + key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; + } + ++ __skb_flow_dissect_ipv4(skb, flow_dissector, ++ target_container, data, iph); ++ + if (ip_is_fragment(iph)) { + key_control->flags |= FLOW_DIS_IS_FRAGMENT; + +@@ -1066,9 +1069,6 @@ proto_again: + } + } + +- __skb_flow_dissect_ipv4(skb, flow_dissector, +- target_container, data, iph); +- + break; + } + case htons(ETH_P_IPV6): { +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index bd4678db9d76b..6dff64374bfe1 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -1825,11 +1825,14 @@ static int + svcauth_gss_release(struct svc_rqst *rqstp) + { + struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data; +- struct rpc_gss_wire_cred *gc = &gsd->clcred; ++ struct rpc_gss_wire_cred *gc; + struct xdr_buf *resbuf = &rqstp->rq_res; + int stat = -EINVAL; + struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); + ++ if (!gsd) ++ goto out; ++ gc = &gsd->clcred; + if (gc->gc_proc != RPC_GSS_PROC_DATA) + goto out; + /* Release can be called twice, but we only wrap once. */ +@@ -1870,10 +1873,10 @@ out_err: + if (rqstp->rq_cred.cr_group_info) + put_group_info(rqstp->rq_cred.cr_group_info); + rqstp->rq_cred.cr_group_info = NULL; +- if (gsd->rsci) ++ if (gsd && gsd->rsci) { + cache_put(&gsd->rsci->h, sn->rsc_cache); +- gsd->rsci = NULL; +- ++ gsd->rsci = NULL; ++ } + return stat; + } + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index d244616d28d88..4c8b281c39921 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -1023,8 +1023,12 @@ static int azx_prepare(struct device *dev) + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip; + ++ if (!azx_is_pm_ready(card)) ++ return 0; ++ + chip = card->private_data; + chip->pm_prepared = 1; ++ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + + flush_work(&azx_bus(chip)->unsol_work); + +@@ -1039,7 +1043,11 @@ static void azx_complete(struct device *dev) + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip; + ++ if (!azx_is_pm_ready(card)) ++ return; ++ + chip = card->private_data; ++ snd_power_change_state(card, SNDRV_CTL_POWER_D0); + chip->pm_prepared = 0; + } + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 316b9b4ccb32d..58946d069ee59 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5256,7 +5256,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) + case 0x10ec0274: + case 0x10ec0294: + alc_process_coef_fw(codec, coef0274); +- msleep(80); ++ msleep(850); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x00f0) == 0x00f0; + break; +@@ -5440,6 +5440,7 @@ static void alc_update_headset_jack_cb(struct hda_codec *codec, + struct hda_jack_callback *jack) + { + snd_hda_gen_hp_automute(codec, jack); ++ alc_update_headset_mode(codec); + } + + static void alc_probe_headset_mode(struct hda_codec *codec) +@@ -8057,6 +8058,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x87f2, "HP ProBook 640 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 210fcbedf2413..4d82d24c7828d 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -401,7 +401,7 @@ static const struct regmap_config cs42l42_regmap = { + }; + + static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, false); +-static DECLARE_TLV_DB_SCALE(mixer_tlv, -6200, 100, false); ++static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true); + + static const char * const cs42l42_hpf_freq_text[] = { + "1.86Hz", "120Hz", "235Hz", "466Hz" +@@ -458,7 +458,7 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = { + CS42L42_DAC_HPF_EN_SHIFT, true, false), + SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL, + CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT, +- 0x3e, 1, mixer_tlv) ++ 0x3f, 1, mixer_tlv) + }; + + static int cs42l42_hpdrv_evt(struct snd_soc_dapm_widget *w, +@@ -691,24 +691,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + CS42L42_CLK_OASRC_SEL_MASK, + CS42L42_CLK_OASRC_SEL_12 << + CS42L42_CLK_OASRC_SEL_SHIFT); +- /* channel 1 on low LRCLK, 32 bit */ +- snd_soc_component_update_bits(component, +- CS42L42_ASP_RX_DAI0_CH1_AP_RES, +- CS42L42_ASP_RX_CH_AP_MASK | +- CS42L42_ASP_RX_CH_RES_MASK, +- (CS42L42_ASP_RX_CH_AP_LOW << +- CS42L42_ASP_RX_CH_AP_SHIFT) | +- (CS42L42_ASP_RX_CH_RES_32 << +- CS42L42_ASP_RX_CH_RES_SHIFT)); +- /* Channel 2 on high LRCLK, 32 bit */ +- snd_soc_component_update_bits(component, +- CS42L42_ASP_RX_DAI0_CH2_AP_RES, +- CS42L42_ASP_RX_CH_AP_MASK | +- CS42L42_ASP_RX_CH_RES_MASK, +- (CS42L42_ASP_RX_CH_AP_HI << +- CS42L42_ASP_RX_CH_AP_SHIFT) | +- (CS42L42_ASP_RX_CH_RES_32 << +- CS42L42_ASP_RX_CH_RES_SHIFT)); + if (pll_ratio_table[i].mclk_src_sel == 0) { + /* Pass the clock straight through */ + snd_soc_component_update_bits(component, +@@ -797,27 +779,23 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + /* Bitclock/frame inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: ++ asp_cfg_val |= CS42L42_ASP_SCPOL_NOR << CS42L42_ASP_SCPOL_SHIFT; + break; + case SND_SOC_DAIFMT_NB_IF: +- asp_cfg_val |= CS42L42_ASP_POL_INV << +- CS42L42_ASP_LCPOL_IN_SHIFT; ++ asp_cfg_val |= CS42L42_ASP_SCPOL_NOR << CS42L42_ASP_SCPOL_SHIFT; ++ asp_cfg_val |= CS42L42_ASP_LCPOL_INV << CS42L42_ASP_LCPOL_SHIFT; + break; + case SND_SOC_DAIFMT_IB_NF: +- asp_cfg_val |= CS42L42_ASP_POL_INV << +- CS42L42_ASP_SCPOL_IN_DAC_SHIFT; + break; + case SND_SOC_DAIFMT_IB_IF: +- asp_cfg_val |= CS42L42_ASP_POL_INV << +- CS42L42_ASP_LCPOL_IN_SHIFT; +- asp_cfg_val |= CS42L42_ASP_POL_INV << +- CS42L42_ASP_SCPOL_IN_DAC_SHIFT; ++ asp_cfg_val |= CS42L42_ASP_LCPOL_INV << CS42L42_ASP_LCPOL_SHIFT; + break; + } + +- snd_soc_component_update_bits(component, CS42L42_ASP_CLK_CFG, +- CS42L42_ASP_MODE_MASK | +- CS42L42_ASP_SCPOL_IN_DAC_MASK | +- CS42L42_ASP_LCPOL_IN_MASK, asp_cfg_val); ++ snd_soc_component_update_bits(component, CS42L42_ASP_CLK_CFG, CS42L42_ASP_MODE_MASK | ++ CS42L42_ASP_SCPOL_MASK | ++ CS42L42_ASP_LCPOL_MASK, ++ asp_cfg_val); + + return 0; + } +@@ -828,14 +806,29 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, + { + struct snd_soc_component *component = dai->component; + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); +- int retval; ++ unsigned int width = (params_width(params) / 8) - 1; ++ unsigned int val = 0; + + cs42l42->srate = params_rate(params); +- cs42l42->swidth = params_width(params); + +- retval = cs42l42_pll_config(component); ++ switch(substream->stream) { ++ case SNDRV_PCM_STREAM_PLAYBACK: ++ val |= width << CS42L42_ASP_RX_CH_RES_SHIFT; ++ /* channel 1 on low LRCLK */ ++ snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_CH1_AP_RES, ++ CS42L42_ASP_RX_CH_AP_MASK | ++ CS42L42_ASP_RX_CH_RES_MASK, val); ++ /* Channel 2 on high LRCLK */ ++ val |= CS42L42_ASP_RX_CH_AP_HI << CS42L42_ASP_RX_CH_AP_SHIFT; ++ snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_CH2_AP_RES, ++ CS42L42_ASP_RX_CH_AP_MASK | ++ CS42L42_ASP_RX_CH_RES_MASK, val); ++ break; ++ default: ++ break; ++ } + +- return retval; ++ return cs42l42_pll_config(component); + } + + static int cs42l42_set_sysclk(struct snd_soc_dai *dai, +@@ -900,9 +893,9 @@ static int cs42l42_mute(struct snd_soc_dai *dai, int mute, int direction) + return 0; + } + +-#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ +- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ +- SNDRV_PCM_FMTBIT_S32_LE) ++#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ ++ SNDRV_PCM_FMTBIT_S24_LE |\ ++ SNDRV_PCM_FMTBIT_S32_LE ) + + + static const struct snd_soc_dai_ops cs42l42_ops = { +@@ -1801,7 +1794,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); + } +- mdelay(3); ++ usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); + + /* Request IRQ */ + ret = devm_request_threaded_irq(&i2c_client->dev, +@@ -1926,6 +1919,7 @@ static int cs42l42_runtime_resume(struct device *dev) + } + + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); ++ usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); + + regcache_cache_only(cs42l42->regmap, false); + regcache_sync(cs42l42->regmap); +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 9e3cc528dcff0..866d7c873e3c9 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -258,11 +258,12 @@ + #define CS42L42_ASP_SLAVE_MODE 0x00 + #define CS42L42_ASP_MODE_SHIFT 4 + #define CS42L42_ASP_MODE_MASK (1 << CS42L42_ASP_MODE_SHIFT) +-#define CS42L42_ASP_SCPOL_IN_DAC_SHIFT 2 +-#define CS42L42_ASP_SCPOL_IN_DAC_MASK (1 << CS42L42_ASP_SCPOL_IN_DAC_SHIFT) +-#define CS42L42_ASP_LCPOL_IN_SHIFT 0 +-#define CS42L42_ASP_LCPOL_IN_MASK (1 << CS42L42_ASP_LCPOL_IN_SHIFT) +-#define CS42L42_ASP_POL_INV 1 ++#define CS42L42_ASP_SCPOL_SHIFT 2 ++#define CS42L42_ASP_SCPOL_MASK (3 << CS42L42_ASP_SCPOL_SHIFT) ++#define CS42L42_ASP_SCPOL_NOR 3 ++#define CS42L42_ASP_LCPOL_SHIFT 0 ++#define CS42L42_ASP_LCPOL_MASK (3 << CS42L42_ASP_LCPOL_SHIFT) ++#define CS42L42_ASP_LCPOL_INV 3 + + #define CS42L42_ASP_FRM_CFG (CS42L42_PAGE_12 + 0x08) + #define CS42L42_ASP_STP_SHIFT 4 +@@ -739,6 +740,7 @@ + #define CS42L42_FRAC2_VAL(val) (((val) & 0xff0000) >> 16) + + #define CS42L42_NUM_SUPPLIES 5 ++#define CS42L42_BOOT_TIME_US 3000 + + static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { + "VA", +@@ -756,7 +758,6 @@ struct cs42l42_private { + struct completion pdn_done; + u32 sclk; + u32 srate; +- u32 swidth; + u8 plug_state; + u8 hs_type; + u8 ts_inv; +diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c +index bd5d230c5df2f..609459077f9d9 100644 +--- a/sound/soc/codecs/es8316.c ++++ b/sound/soc/codecs/es8316.c +@@ -63,13 +63,8 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv, + 1, 1, TLV_DB_SCALE_ITEM(0, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(250, 0, 0), + 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0), +- 4, 4, TLV_DB_SCALE_ITEM(700, 0, 0), +- 5, 5, TLV_DB_SCALE_ITEM(1000, 0, 0), +- 6, 6, TLV_DB_SCALE_ITEM(1300, 0, 0), +- 7, 7, TLV_DB_SCALE_ITEM(1600, 0, 0), +- 8, 8, TLV_DB_SCALE_ITEM(1800, 0, 0), +- 9, 9, TLV_DB_SCALE_ITEM(2100, 0, 0), +- 10, 10, TLV_DB_SCALE_ITEM(2400, 0, 0), ++ 4, 7, TLV_DB_SCALE_ITEM(700, 300, 0), ++ 8, 10, TLV_DB_SCALE_ITEM(1800, 300, 0), + ); + + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpout_vol_tlv, +diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c +index 3db07293c70b6..2627910060dc1 100644 +--- a/sound/soc/codecs/rt1015.c ++++ b/sound/soc/codecs/rt1015.c +@@ -209,6 +209,7 @@ static bool rt1015_volatile_register(struct device *dev, unsigned int reg) + case RT1015_VENDOR_ID: + case RT1015_DEVICE_ID: + case RT1015_PRO_ALT: ++ case RT1015_MAN_I2C: + case RT1015_DAC3: + case RT1015_VBAT_TEST_OUT1: + case RT1015_VBAT_TEST_OUT2: +diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c +index 1414ad15d01cf..a5674c227b3a6 100644 +--- a/sound/soc/codecs/rt5640.c ++++ b/sound/soc/codecs/rt5640.c +@@ -339,9 +339,9 @@ static bool rt5640_readable_register(struct device *dev, unsigned int reg) + } + + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); +-static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); ++static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0); + static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); +-static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); ++static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000); + static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); + + /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ +diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c +index d198e191fb0c9..e59fdc81dbd45 100644 +--- a/sound/soc/codecs/rt5651.c ++++ b/sound/soc/codecs/rt5651.c +@@ -285,9 +285,9 @@ static bool rt5651_readable_register(struct device *dev, unsigned int reg) + } + + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); +-static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); ++static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0); + static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); +-static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); ++static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000); + static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); + + /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ +diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c +index 41e5917b16a5e..91a4ef7f620ca 100644 +--- a/sound/soc/codecs/rt5659.c ++++ b/sound/soc/codecs/rt5659.c +@@ -3426,12 +3426,17 @@ static int rt5659_set_component_sysclk(struct snd_soc_component *component, int + { + struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component); + unsigned int reg_val = 0; ++ int ret; + + if (freq == rt5659->sysclk && clk_id == rt5659->sysclk_src) + return 0; + + switch (clk_id) { + case RT5659_SCLK_S_MCLK: ++ ret = clk_set_rate(rt5659->mclk, freq); ++ if (ret) ++ return ret; ++ + reg_val |= RT5659_SCLK_SRC_MCLK; + break; + case RT5659_SCLK_S_PLL1: +diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c +index a9b1b4180c471..93d86f7558e0a 100644 +--- a/sound/soc/codecs/rt711.c ++++ b/sound/soc/codecs/rt711.c +@@ -895,6 +895,13 @@ static int rt711_probe(struct snd_soc_component *component) + return 0; + } + ++static void rt711_remove(struct snd_soc_component *component) ++{ ++ struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); ++ ++ regcache_cache_only(rt711->regmap, true); ++} ++ + static const struct snd_soc_component_driver soc_codec_dev_rt711 = { + .probe = rt711_probe, + .set_bias_level = rt711_set_bias_level, +@@ -905,6 +912,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = { + .dapm_routes = rt711_audio_map, + .num_dapm_routes = ARRAY_SIZE(rt711_audio_map), + .set_jack = rt711_set_jack_detect, ++ .remove = rt711_remove, + }; + + static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, +diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c +index 4d6ff81146228..4c0e87e22b97b 100644 +--- a/sound/soc/codecs/sgtl5000.c ++++ b/sound/soc/codecs/sgtl5000.c +@@ -71,7 +71,7 @@ static const struct reg_default sgtl5000_reg_defaults[] = { + { SGTL5000_DAP_EQ_BASS_BAND4, 0x002f }, + { SGTL5000_DAP_MAIN_CHAN, 0x8000 }, + { SGTL5000_DAP_MIX_CHAN, 0x0000 }, +- { SGTL5000_DAP_AVC_CTRL, 0x0510 }, ++ { SGTL5000_DAP_AVC_CTRL, 0x5100 }, + { SGTL5000_DAP_AVC_THRESHOLD, 0x1473 }, + { SGTL5000_DAP_AVC_ATTACK, 0x0028 }, + { SGTL5000_DAP_AVC_DECAY, 0x0050 }, +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 05a085f6dc7ce..bf65cba232e67 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1581,6 +1582,9 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour) + if (card->long_name) + return 0; /* long name already set by driver or from DMI */ + ++ if (!is_acpi_device_node(card->dev->fwnode)) ++ return 0; ++ + /* make up dmi long name as: vendor-product-version-board */ + vendor = dmi_get_system_info(DMI_BOARD_VENDOR); + if (!vendor || !is_dmi_valid(vendor)) { +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 10b3a8006bdb3..5ab2a4580bfb2 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1521,6 +1521,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) + case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ + case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */ + case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */ ++ case USB_ID(0x046d, 0x084c): /* Logitech ConferenceCam Connect */ + return true; + } + +diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh +index 058c746ee3006..b11d8e6b5bc14 100755 +--- a/tools/testing/selftests/net/forwarding/tc_flower.sh ++++ b/tools/testing/selftests/net/forwarding/tc_flower.sh +@@ -3,7 +3,7 @@ + + ALL_TESTS="match_dst_mac_test match_src_mac_test match_dst_ip_test \ + match_src_ip_test match_ip_flags_test match_pcp_test match_vlan_test \ +- match_ip_tos_test match_indev_test" ++ match_ip_tos_test match_indev_test match_ip_ttl_test" + NUM_NETIFS=2 + source tc_common.sh + source lib.sh +@@ -310,6 +310,42 @@ match_ip_tos_test() + log_test "ip_tos match ($tcflags)" + } + ++match_ip_ttl_test() ++{ ++ RET=0 ++ ++ tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ ++ $tcflags dst_ip 192.0.2.2 ip_ttl 63 action drop ++ tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ ++ $tcflags dst_ip 192.0.2.2 action drop ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=63" -q ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=63,mf,frag=256" -q ++ ++ tc_check_packets "dev $h2 ingress" 102 1 ++ check_fail $? "Matched on the wrong filter (no check on ttl)" ++ ++ tc_check_packets "dev $h2 ingress" 101 2 ++ check_err $? "Did not match on correct filter (ttl=63)" ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=255" -q ++ ++ tc_check_packets "dev $h2 ingress" 101 3 ++ check_fail $? "Matched on a wrong filter (ttl=63)" ++ ++ tc_check_packets "dev $h2 ingress" 102 1 ++ check_err $? "Did not match on correct filter (no check on ttl)" ++ ++ tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower ++ tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower ++ ++ log_test "ip_ttl match ($tcflags)" ++} ++ + match_indev_test() + { + RET=0 diff --git a/patch/kernel/archive/sunxi-5.10/patch-5.10.28-29.patch b/patch/kernel/archive/sunxi-5.10/patch-5.10.28-29.patch new file mode 100644 index 0000000000..629ca7de4f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/patch-5.10.28-29.patch @@ -0,0 +1,1006 @@ +diff --git a/Makefile b/Makefile +index cb76f64abb6da..1d4a50ebe3b77 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 10 +-SUBLEVEL = 28 ++SUBLEVEL = 29 + EXTRAVERSION = + NAME = Dare mighty things + +@@ -1083,6 +1083,17 @@ ifdef CONFIG_STACK_VALIDATION + endif + endif + ++PHONY += resolve_btfids_clean ++ ++resolve_btfids_O = $(abspath $(objtree))/tools/bpf/resolve_btfids ++ ++# tools/bpf/resolve_btfids directory might not exist ++# in output directory, skip its clean in that case ++resolve_btfids_clean: ++ifneq ($(wildcard $(resolve_btfids_O)),) ++ $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean ++endif ++ + ifdef CONFIG_BPF + ifdef CONFIG_DEBUG_INFO_BTF + ifeq ($(has_libelf),1) +@@ -1500,7 +1511,7 @@ vmlinuxclean: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean + $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) + +-clean: archclean vmlinuxclean ++clean: archclean vmlinuxclean resolve_btfids_clean + + # mrproper - Delete all generated files, including .config + # +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 4c22980241377..f09a61cac2dc9 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -40,6 +40,9 @@ + ethernet1 = &cpsw_emac1; + spi0 = &spi0; + spi1 = &spi1; ++ mmc0 = &mmc1; ++ mmc1 = &mmc2; ++ mmc2 = &mmc3; + }; + + cpus { +diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c +index 8b5b8e6bc9d9a..dd5bfed52031d 100644 +--- a/arch/ia64/kernel/err_inject.c ++++ b/arch/ia64/kernel/err_inject.c +@@ -59,7 +59,7 @@ show_##name(struct device *dev, struct device_attribute *attr, \ + char *buf) \ + { \ + u32 cpu=dev->id; \ +- return sprintf(buf, "%lx\n", name[cpu]); \ ++ return sprintf(buf, "%llx\n", name[cpu]); \ + } + + #define store(name) \ +@@ -86,9 +86,9 @@ store_call_start(struct device *dev, struct device_attribute *attr, + + #ifdef ERR_INJ_DEBUG + printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); +- printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]); +- printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); +- printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", ++ printk(KERN_DEBUG "err_type_info=%llx,\n", err_type_info[cpu]); ++ printk(KERN_DEBUG "err_struct_info=%llx,\n", err_struct_info[cpu]); ++ printk(KERN_DEBUG "err_data_buffer=%llx, %llx, %llx.\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3); +@@ -117,8 +117,8 @@ store_call_start(struct device *dev, struct device_attribute *attr, + + #ifdef ERR_INJ_DEBUG + printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); +- printk(KERN_DEBUG "capabilities=%lx,\n", capabilities[cpu]); +- printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); ++ printk(KERN_DEBUG "capabilities=%llx,\n", capabilities[cpu]); ++ printk(KERN_DEBUG "resources=%llx\n", resources[cpu]); + #endif + return size; + } +@@ -131,7 +131,7 @@ show_virtual_to_phys(struct device *dev, struct device_attribute *attr, + char *buf) + { + unsigned int cpu=dev->id; +- return sprintf(buf, "%lx\n", phys_addr[cpu]); ++ return sprintf(buf, "%llx\n", phys_addr[cpu]); + } + + static ssize_t +@@ -145,7 +145,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr, + ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL); + if (ret<=0) { + #ifdef ERR_INJ_DEBUG +- printk("Virtual address %lx is not existing.\n",virt_addr); ++ printk("Virtual address %llx is not existing.\n", virt_addr); + #endif + return -EINVAL; + } +@@ -163,7 +163,7 @@ show_err_data_buffer(struct device *dev, + { + unsigned int cpu=dev->id; + +- return sprintf(buf, "%lx, %lx, %lx\n", ++ return sprintf(buf, "%llx, %llx, %llx\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3); +@@ -178,13 +178,13 @@ store_err_data_buffer(struct device *dev, + int ret; + + #ifdef ERR_INJ_DEBUG +- printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n", ++ printk("write err_data_buffer=[%llx,%llx,%llx] on cpu%d\n", + err_data_buffer[cpu].data1, + err_data_buffer[cpu].data2, + err_data_buffer[cpu].data3, + cpu); + #endif +- ret=sscanf(buf, "%lx, %lx, %lx", ++ ret = sscanf(buf, "%llx, %llx, %llx", + &err_data_buffer[cpu].data1, + &err_data_buffer[cpu].data2, + &err_data_buffer[cpu].data3); +diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c +index 2703f7795672d..bd0a51dc345af 100644 +--- a/arch/ia64/kernel/mca.c ++++ b/arch/ia64/kernel/mca.c +@@ -1822,7 +1822,7 @@ ia64_mca_cpu_init(void *cpu_data) + data = mca_bootmem(); + first_time = 0; + } else +- data = (void *)__get_free_pages(GFP_KERNEL, ++ data = (void *)__get_free_pages(GFP_ATOMIC, + get_order(sz)); + if (!data) + panic("Could not allocate MCA memory for cpu %d\n", +diff --git a/arch/x86/Makefile b/arch/x86/Makefile +index 0a6d497221e49..9c86f2dc16b1d 100644 +--- a/arch/x86/Makefile ++++ b/arch/x86/Makefile +@@ -34,7 +34,7 @@ M16_CFLAGS := $(call cc-option, -m16, $(CODE16GCC_CFLAGS)) + REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \ + -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ + -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ +- -mno-mmx -mno-sse ++ -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) + + REALMODE_CFLAGS += -ffreestanding + REALMODE_CFLAGS += -fno-stack-protector +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index 023ac12f54a29..a11796bbb9cee 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1476,7 +1476,16 @@ emit_jmp: + } + + if (image) { +- if (unlikely(proglen + ilen > oldproglen)) { ++ /* ++ * When populating the image, assert that: ++ * ++ * i) We do not write beyond the allocated space, and ++ * ii) addrs[i] did not change from the prior run, in order ++ * to validate assumptions made for computing branch ++ * displacements. ++ */ ++ if (unlikely(proglen + ilen > oldproglen || ++ proglen + ilen != addrs[i])) { + pr_err("bpf_jit: fatal error\n"); + return -EFAULT; + } +@@ -2038,7 +2047,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) + extra_pass = true; + goto skip_init_addrs; + } +- addrs = kmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); ++ addrs = kvmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); + if (!addrs) { + prog = orig_prog; + goto out_addrs; +@@ -2128,7 +2137,7 @@ out_image: + if (image) + bpf_prog_fill_jited_linfo(prog, addrs + 1); + out_addrs: +- kfree(addrs); ++ kvfree(addrs); + kfree(jit_data); + prog->aux->jit_data = NULL; + } +diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c +index 96fde03aa9877..2cf4d217840d8 100644 +--- a/arch/x86/net/bpf_jit_comp32.c ++++ b/arch/x86/net/bpf_jit_comp32.c +@@ -2278,7 +2278,16 @@ notyet: + } + + if (image) { +- if (unlikely(proglen + ilen > oldproglen)) { ++ /* ++ * When populating the image, assert that: ++ * ++ * i) We do not write beyond the allocated space, and ++ * ii) addrs[i] did not change from the prior run, in order ++ * to validate assumptions made for computing branch ++ * displacements. ++ */ ++ if (unlikely(proglen + ilen > oldproglen || ++ proglen + ilen != addrs[i])) { + pr_err("bpf_jit: fatal error\n"); + return -EFAULT; + } +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 45f5530666d3f..16e389dce1118 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -3044,7 +3044,9 @@ static int sysc_remove(struct platform_device *pdev) + + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); +- reset_control_assert(ddata->rsts); ++ ++ if (!reset_control_status(ddata->rsts)) ++ reset_control_assert(ddata->rsts); + + unprepare: + sysc_unprepare(ddata); +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c +index f176a6f3eff66..e58670a61df4b 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_power.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c +@@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu) + /* Set up the limits management */ + if (adreno_is_a530(adreno_gpu)) + a530_lm_setup(gpu); +- else ++ else if (adreno_is_a540(adreno_gpu)) + a540_lm_setup(gpu); + + /* Set up SP/TP power collpase */ +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +index d93c44f6996db..e69ea810e18d9 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +@@ -43,6 +43,8 @@ + #define DPU_DEBUGFS_DIR "msm_dpu" + #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" + ++#define MIN_IB_BW 400000000ULL /* Min ib vote 400MB */ ++ + static int dpu_kms_hw_init(struct msm_kms *kms); + static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); + +@@ -929,6 +931,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) + DPU_DEBUG("REG_DMA is not defined"); + } + ++ if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) ++ dpu_kms_parse_data_bus_icc_path(dpu_kms); ++ + pm_runtime_get_sync(&dpu_kms->pdev->dev); + + dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); +@@ -1030,9 +1035,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) + + dpu_vbif_init_memtypes(dpu_kms); + +- if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) +- dpu_kms_parse_data_bus_icc_path(dpu_kms); +- + pm_runtime_put_sync(&dpu_kms->pdev->dev); + + return 0; +@@ -1189,10 +1191,10 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) + + ddev = dpu_kms->dev; + ++ WARN_ON(!(dpu_kms->num_paths)); + /* Min vote of BW is required before turning on AXI clk */ + for (i = 0; i < dpu_kms->num_paths; i++) +- icc_set_bw(dpu_kms->path[i], 0, +- dpu_kms->catalog->perf.min_dram_ib); ++ icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); + + rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); + if (rc) { +diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +index c1f6708367ae9..c1c41846b6b2b 100644 +--- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +@@ -325,7 +325,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll) + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); +- pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); ++ pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); + pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ + pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); +diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c +index ad2703698b052..cd59a59180385 100644 +--- a/drivers/gpu/drm/msm/msm_fence.c ++++ b/drivers/gpu/drm/msm/msm_fence.c +@@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, + int ret; + + if (fence > fctx->last_fence) { +- DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", ++ DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", + fctx->name, fence, fctx->last_fence); + return -EINVAL; + } +diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c +index ec475087fbf93..39f841b424883 100644 +--- a/drivers/isdn/hardware/mISDN/mISDNipac.c ++++ b/drivers/isdn/hardware/mISDN/mISDNipac.c +@@ -694,7 +694,7 @@ isac_release(struct isac_hw *isac) + { + if (isac->type & IPAC_TYPE_ISACX) + WriteISAC(isac, ISACX_MASK, 0xff); +- else ++ else if (isac->type != 0) + WriteISAC(isac, ISAC_MASK, 0xff); + if (isac->dch.timer.function != NULL) { + del_timer(&isac->dch.timer); +diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c +index d1e4d42e497d8..3712e1786091f 100644 +--- a/drivers/net/ethernet/marvell/pxa168_eth.c ++++ b/drivers/net/ethernet/marvell/pxa168_eth.c +@@ -1544,8 +1544,8 @@ static int pxa168_eth_remove(struct platform_device *pdev) + clk_disable_unprepare(pep->clk); + mdiobus_unregister(pep->smi_bus); + mdiobus_free(pep->smi_bus); +- unregister_netdev(dev); + cancel_work_sync(&pep->tx_timeout_task); ++ unregister_netdev(dev); + free_netdev(dev); + return 0; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index e2006c6053c9c..9a12df43becc4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -2326,8 +2326,9 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5e_params *params, + { + switch (params->rq_wq_type) { + case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: +- return order_base_2(MLX5E_UMR_WQEBBS) + +- mlx5e_get_rq_log_wq_sz(rqp->rqc); ++ return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, ++ order_base_2(MLX5E_UMR_WQEBBS) + ++ mlx5e_get_rq_log_wq_sz(rqp->rqc)); + default: /* MLX5_WQ_TYPE_CYCLIC */ + return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; + } +diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c +index 46d8b7336d8f2..a47378b7d9b2f 100644 +--- a/drivers/net/ipa/ipa_cmd.c ++++ b/drivers/net/ipa/ipa_cmd.c +@@ -175,21 +175,23 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, + : field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK); + if (mem->offset > offset_max || + ipa->mem_offset > offset_max - mem->offset) { +- dev_err(dev, "IPv%c %s%s table region offset too large " +- "(0x%04x + 0x%04x > 0x%04x)\n", +- ipv6 ? '6' : '4', hashed ? "hashed " : "", +- route ? "route" : "filter", +- ipa->mem_offset, mem->offset, offset_max); ++ dev_err(dev, "IPv%c %s%s table region offset too large\n", ++ ipv6 ? '6' : '4', hashed ? "hashed " : "", ++ route ? "route" : "filter"); ++ dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", ++ ipa->mem_offset, mem->offset, offset_max); ++ + return false; + } + + if (mem->offset > ipa->mem_size || + mem->size > ipa->mem_size - mem->offset) { +- dev_err(dev, "IPv%c %s%s table region out of range " +- "(0x%04x + 0x%04x > 0x%04x)\n", +- ipv6 ? '6' : '4', hashed ? "hashed " : "", +- route ? "route" : "filter", +- mem->offset, mem->size, ipa->mem_size); ++ dev_err(dev, "IPv%c %s%s table region out of range\n", ++ ipv6 ? '6' : '4', hashed ? "hashed " : "", ++ route ? "route" : "filter"); ++ dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", ++ mem->offset, mem->size, ipa->mem_size); ++ + return false; + } + +@@ -205,22 +207,36 @@ static bool ipa_cmd_header_valid(struct ipa *ipa) + u32 size_max; + u32 size; + ++ /* In ipa_cmd_hdr_init_local_add() we record the offset and size ++ * of the header table memory area. Make sure the offset and size ++ * fit in the fields that need to hold them, and that the entire ++ * range is within the overall IPA memory range. ++ */ + offset_max = field_max(HDR_INIT_LOCAL_FLAGS_HDR_ADDR_FMASK); + if (mem->offset > offset_max || + ipa->mem_offset > offset_max - mem->offset) { +- dev_err(dev, "header table region offset too large " +- "(0x%04x + 0x%04x > 0x%04x)\n", +- ipa->mem_offset + mem->offset, offset_max); ++ dev_err(dev, "header table region offset too large\n"); ++ dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", ++ ipa->mem_offset, mem->offset, offset_max); ++ + return false; + } + + size_max = field_max(HDR_INIT_LOCAL_FLAGS_TABLE_SIZE_FMASK); + size = ipa->mem[IPA_MEM_MODEM_HEADER].size; + size += ipa->mem[IPA_MEM_AP_HEADER].size; +- if (mem->offset > ipa->mem_size || size > ipa->mem_size - mem->offset) { +- dev_err(dev, "header table region out of range " +- "(0x%04x + 0x%04x > 0x%04x)\n", +- mem->offset, size, ipa->mem_size); ++ ++ if (size > size_max) { ++ dev_err(dev, "header table region size too large\n"); ++ dev_err(dev, " (0x%04x > 0x%08x)\n", size, size_max); ++ ++ return false; ++ } ++ if (size > ipa->mem_size || mem->offset > ipa->mem_size - size) { ++ dev_err(dev, "header table region out of range\n"); ++ dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n", ++ mem->offset, size, ipa->mem_size); ++ + return false; + } + +diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c +index 86261970bd8f3..8a0cd5bf00657 100644 +--- a/drivers/platform/x86/intel-hid.c ++++ b/drivers/platform/x86/intel-hid.c +@@ -86,6 +86,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Tablet Gen 2", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), ++ }, ++ }, + { } + }; + +diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c +index 3e5fe66333f13..e06b36e87a33f 100644 +--- a/drivers/platform/x86/intel_pmc_core.c ++++ b/drivers/platform/x86/intel_pmc_core.c +@@ -863,34 +863,45 @@ out_unlock: + } + DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); + +-static ssize_t pmc_core_ltr_ignore_write(struct file *file, +- const char __user *userbuf, +- size_t count, loff_t *ppos) ++static int pmc_core_send_ltr_ignore(u32 value) + { + struct pmc_dev *pmcdev = &pmc; + const struct pmc_reg_map *map = pmcdev->map; +- u32 val, buf_size, fd; +- int err; +- +- buf_size = count < 64 ? count : 64; +- +- err = kstrtou32_from_user(userbuf, buf_size, 10, &val); +- if (err) +- return err; ++ u32 reg; ++ int err = 0; + + mutex_lock(&pmcdev->lock); + +- if (val > map->ltr_ignore_max) { ++ if (value > map->ltr_ignore_max) { + err = -EINVAL; + goto out_unlock; + } + +- fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); +- fd |= (1U << val); +- pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd); ++ reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); ++ reg |= BIT(value); ++ pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg); + + out_unlock: + mutex_unlock(&pmcdev->lock); ++ ++ return err; ++} ++ ++static ssize_t pmc_core_ltr_ignore_write(struct file *file, ++ const char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ u32 buf_size, value; ++ int err; ++ ++ buf_size = min_t(u32, count, 64); ++ ++ err = kstrtou32_from_user(userbuf, buf_size, 10, &value); ++ if (err) ++ return err; ++ ++ err = pmc_core_send_ltr_ignore(value); ++ + return err == 0 ? count : err; + } + +@@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev) + pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); + dmi_check_system(pmc_core_dmi_table); + ++ /* ++ * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when ++ * a cable is attached. Tell the PMC to ignore it. ++ */ ++ if (pmcdev->map == &tgl_reg_map) { ++ dev_dbg(&pdev->dev, "ignoring GBE LTR\n"); ++ pmc_core_send_ltr_ignore(3); ++ } ++ + pmc_core_dbgfs_register(pmcdev); + + device_initialized = true; +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 69402758b99c3..3b0acaeb20cf7 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -4079,13 +4079,19 @@ static bool hotkey_notify_6xxx(const u32 hkey, + + case TP_HKEY_EV_KEY_NUMLOCK: + case TP_HKEY_EV_KEY_FN: +- case TP_HKEY_EV_KEY_FN_ESC: + /* key press events, we just ignore them as long as the EC + * is still reporting them in the normal keyboard stream */ + *send_acpi_ev = false; + *ignore_acpi_ev = true; + return true; + ++ case TP_HKEY_EV_KEY_FN_ESC: ++ /* Get the media key status to foce the status LED to update */ ++ acpi_evalf(hkey_handle, NULL, "GMKS", "v"); ++ *send_acpi_ev = false; ++ *ignore_acpi_ev = true; ++ return true; ++ + case TP_HKEY_EV_TABLET_CHANGED: + tpacpi_input_send_tabletsw(); + hotkey_tablet_mode_notify_change(); +diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c +index beb5f74944cdf..08f4cf0ad9e3c 100644 +--- a/drivers/ptp/ptp_qoriq.c ++++ b/drivers/ptp/ptp_qoriq.c +@@ -189,15 +189,16 @@ int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) + tmr_add = ptp_qoriq->tmr_add; + adj = tmr_add; + +- /* calculate diff as adj*(scaled_ppm/65536)/1000000 +- * and round() to the nearest integer ++ /* ++ * Calculate diff and round() to the nearest integer ++ * ++ * diff = adj * (ppb / 1000000000) ++ * = adj * scaled_ppm / 65536000000 + */ +- adj *= scaled_ppm; +- diff = div_u64(adj, 8000000); +- diff = (diff >> 13) + ((diff >> 12) & 1); ++ diff = mul_u64_u64_div_u64(adj, scaled_ppm, 32768000000); ++ diff = DIV64_U64_ROUND_UP(diff, 2); + + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; +- + ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add); + + return 0; +diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c +index 4e37fa9b409d5..723a51a3f4316 100644 +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -939,6 +939,14 @@ new_bio: + + return 0; + fail: ++ if (bio) ++ bio_put(bio); ++ while (req->bio) { ++ bio = req->bio; ++ req->bio = bio->bi_next; ++ bio_put(bio); ++ } ++ req->biotail = NULL; + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } + +diff --git a/fs/block_dev.c b/fs/block_dev.c +index fe201b757baa4..6516051807b89 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -1404,13 +1404,13 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) + + lockdep_assert_held(&bdev->bd_mutex); + +- clear_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state); +- + rescan: + ret = blk_drop_partitions(bdev); + if (ret) + return ret; + ++ clear_bit(GD_NEED_PART_SCAN, &disk->state); ++ + /* + * Historically we only set the capacity to zero for devices that + * support partitions (independ of actually having partitions created). +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index be46fab4c96d8..da057570bb93d 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -164,6 +164,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, + goto posix_open_ret; + } + } else { ++ cifs_revalidate_mapping(*pinode); + cifs_fattr_to_inode(*pinode, &fattr); + } + +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index db22d686c61ff..be3df90bb2bcc 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -745,8 +745,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + } + } + spin_unlock(&cifs_tcp_ses_lock); +- cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); +- return false; ++ cifs_dbg(FYI, "No file id matched, oplock break ignored\n"); ++ return true; + } + + void +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 4ccf99cb8cdc0..0de27e75460d1 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -1489,7 +1489,7 @@ static void io_queue_async_work(struct io_kiocb *req) + io_queue_linked_timeout(link); + } + +-static void io_kill_timeout(struct io_kiocb *req) ++static void io_kill_timeout(struct io_kiocb *req, int status) + { + struct io_timeout_data *io = req->async_data; + int ret; +@@ -1499,7 +1499,7 @@ static void io_kill_timeout(struct io_kiocb *req) + atomic_set(&req->ctx->cq_timeouts, + atomic_read(&req->ctx->cq_timeouts) + 1); + list_del_init(&req->timeout.list); +- io_cqring_fill_event(req, 0); ++ io_cqring_fill_event(req, status); + io_put_req_deferred(req, 1); + } + } +@@ -1516,7 +1516,7 @@ static bool io_kill_timeouts(struct io_ring_ctx *ctx, struct task_struct *tsk, + spin_lock_irq(&ctx->completion_lock); + list_for_each_entry_safe(req, tmp, &ctx->timeout_list, timeout.list) { + if (io_match_task(req, tsk, files)) { +- io_kill_timeout(req); ++ io_kill_timeout(req, -ECANCELED); + canceled++; + } + } +@@ -1568,7 +1568,7 @@ static void io_flush_timeouts(struct io_ring_ctx *ctx) + break; + + list_del_init(&req->timeout.list); +- io_kill_timeout(req); ++ io_kill_timeout(req, 0); + } while (!list_empty(&ctx->timeout_list)); + + ctx->cq_last_tm_flush = seq; +diff --git a/init/Kconfig b/init/Kconfig +index d559abf38c905..fc4c9f416fadb 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -114,8 +114,7 @@ config INIT_ENV_ARG_LIMIT + + config COMPILE_TEST + bool "Compile also drivers which will not load" +- depends on !UML +- default n ++ depends on HAS_IOMEM + help + Some drivers can be compiled on a different platform than they are + intended to be run on. Despite they cannot be loaded there (or even +diff --git a/lib/math/div64.c b/lib/math/div64.c +index 3952a07130d88..edd1090c9edb1 100644 +--- a/lib/math/div64.c ++++ b/lib/math/div64.c +@@ -230,4 +230,5 @@ u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c) + + return res + div64_u64(a * b, c); + } ++EXPORT_SYMBOL(mul_u64_u64_div_u64); + #endif +diff --git a/net/mac80211/aead_api.c b/net/mac80211/aead_api.c +index d7b3d905d5353..b00d6f5b33f40 100644 +--- a/net/mac80211/aead_api.c ++++ b/net/mac80211/aead_api.c +@@ -23,6 +23,7 @@ int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, + struct aead_request *aead_req; + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); + u8 *__aad; ++ int ret; + + aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); + if (!aead_req) +@@ -40,10 +41,10 @@ int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, + aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); + aead_request_set_ad(aead_req, sg[0].length); + +- crypto_aead_encrypt(aead_req); ++ ret = crypto_aead_encrypt(aead_req); + kfree_sensitive(aead_req); + +- return 0; ++ return ret; + } + + int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, +diff --git a/net/mac80211/aes_gmac.c b/net/mac80211/aes_gmac.c +index 6f3b3a0cc10a4..512cab073f2e8 100644 +--- a/net/mac80211/aes_gmac.c ++++ b/net/mac80211/aes_gmac.c +@@ -22,6 +22,7 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, + struct aead_request *aead_req; + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); + const __le16 *fc; ++ int ret; + + if (data_len < GMAC_MIC_LEN) + return -EINVAL; +@@ -59,10 +60,10 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, + aead_request_set_crypt(aead_req, sg, sg, 0, iv); + aead_request_set_ad(aead_req, GMAC_AAD_LEN + data_len); + +- crypto_aead_encrypt(aead_req); ++ ret = crypto_aead_encrypt(aead_req); + kfree_sensitive(aead_req); + +- return 0; ++ return ret; + } + + struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index 523380aed92eb..19c093bb3876e 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -982,8 +982,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) + continue; + + if (!dflt_chandef.chan) { ++ /* ++ * Assign the first enabled channel to dflt_chandef ++ * from the list of channels ++ */ ++ for (i = 0; i < sband->n_channels; i++) ++ if (!(sband->channels[i].flags & ++ IEEE80211_CHAN_DISABLED)) ++ break; ++ /* if none found then use the first anyway */ ++ if (i == sband->n_channels) ++ i = 0; + cfg80211_chandef_create(&dflt_chandef, +- &sband->channels[0], ++ &sband->channels[i], + NL80211_CHAN_NO_HT); + /* init channel we're on */ + if (!local->use_chanctx && !local->_oper_chandef.chan) { +diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c +index 5b05487a60d21..db11e403d8187 100644 +--- a/net/netfilter/nf_conntrack_proto_gre.c ++++ b/net/netfilter/nf_conntrack_proto_gre.c +@@ -218,9 +218,6 @@ int nf_conntrack_gre_packet(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + const struct nf_hook_state *state) + { +- if (state->pf != NFPROTO_IPV4) +- return -NF_ACCEPT; +- + if (!nf_ct_is_confirmed(ct)) { + unsigned int *timeouts = nf_ct_timeout_lookup(ct); + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 978a968d7aeda..2e76935db2c88 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -6573,6 +6573,9 @@ static int nft_register_flowtable_net_hooks(struct net *net, + + list_for_each_entry(hook, hook_list, list) { + list_for_each_entry(ft, &table->flowtables, list) { ++ if (!nft_is_active_next(net, ft)) ++ continue; ++ + list_for_each_entry(hook2, &ft->hook_list, list) { + if (hook->ops.dev == hook2->ops.dev && + hook->ops.pf == hook2->ops.pf) { +diff --git a/tools/bpf/resolve_btfids/.gitignore b/tools/bpf/resolve_btfids/.gitignore +index a026df7dc2809..16913fffc9859 100644 +--- a/tools/bpf/resolve_btfids/.gitignore ++++ b/tools/bpf/resolve_btfids/.gitignore +@@ -1,4 +1,3 @@ +-/FEATURE-DUMP.libbpf +-/bpf_helper_defs.h + /fixdep + /resolve_btfids ++/libbpf/ +diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile +index bf656432ad736..bb9fa8de7e625 100644 +--- a/tools/bpf/resolve_btfids/Makefile ++++ b/tools/bpf/resolve_btfids/Makefile +@@ -2,11 +2,7 @@ + include ../../scripts/Makefile.include + include ../../scripts/Makefile.arch + +-ifeq ($(srctree),) +-srctree := $(patsubst %/,%,$(dir $(CURDIR))) +-srctree := $(patsubst %/,%,$(dir $(srctree))) +-srctree := $(patsubst %/,%,$(dir $(srctree))) +-endif ++srctree := $(abspath $(CURDIR)/../../../) + + ifeq ($(V),1) + Q = +@@ -22,28 +18,29 @@ AR = $(HOSTAR) + CC = $(HOSTCC) + LD = $(HOSTLD) + ARCH = $(HOSTARCH) ++RM ?= rm + + OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ + + LIBBPF_SRC := $(srctree)/tools/lib/bpf/ + SUBCMD_SRC := $(srctree)/tools/lib/subcmd/ + +-BPFOBJ := $(OUTPUT)/libbpf.a +-SUBCMDOBJ := $(OUTPUT)/libsubcmd.a ++BPFOBJ := $(OUTPUT)/libbpf/libbpf.a ++SUBCMDOBJ := $(OUTPUT)/libsubcmd/libsubcmd.a + + BINARY := $(OUTPUT)/resolve_btfids + BINARY_IN := $(BINARY)-in.o + + all: $(BINARY) + +-$(OUTPUT): ++$(OUTPUT) $(OUTPUT)/libbpf $(OUTPUT)/libsubcmd: + $(call msg,MKDIR,,$@) +- $(Q)mkdir -p $(OUTPUT) ++ $(Q)mkdir -p $(@) + +-$(SUBCMDOBJ): fixdep FORCE +- $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(OUTPUT) ++$(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/libsubcmd ++ $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) + +-$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT) ++$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf + $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) + + CFLAGS := -g \ +@@ -57,24 +54,27 @@ LIBS = -lelf -lz + export srctree OUTPUT CFLAGS Q + include $(srctree)/tools/build/Makefile.include + +-$(BINARY_IN): fixdep FORCE ++$(BINARY_IN): fixdep FORCE | $(OUTPUT) + $(Q)$(MAKE) $(build)=resolve_btfids + + $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN) + $(call msg,LINK,$@) + $(Q)$(CC) $(BINARY_IN) $(LDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) + +-libsubcmd-clean: +- $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(OUTPUT) clean +- +-libbpf-clean: +- $(Q)$(MAKE) -C $(LIBBPF_SRC) OUTPUT=$(OUTPUT) clean ++clean_objects := $(wildcard $(OUTPUT)/*.o \ ++ $(OUTPUT)/.*.o.cmd \ ++ $(OUTPUT)/.*.o.d \ ++ $(OUTPUT)/libbpf \ ++ $(OUTPUT)/libsubcmd \ ++ $(OUTPUT)/resolve_btfids) + +-clean: libsubcmd-clean libbpf-clean fixdep-clean ++ifneq ($(clean_objects),) ++clean: fixdep-clean + $(call msg,CLEAN,$(BINARY)) +- $(Q)$(RM) -f $(BINARY); \ +- $(RM) -rf $(if $(OUTPUT),$(OUTPUT),.)/feature; \ +- find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) ++ $(Q)$(RM) -rf $(clean_objects) ++else ++clean: ++endif + + tags: + $(call msg,GEN,,tags) +diff --git a/tools/testing/kunit/kunit_config.py b/tools/testing/kunit/kunit_config.py +index 02ffc3a3e5dc7..b30e9d6db6b40 100644 +--- a/tools/testing/kunit/kunit_config.py ++++ b/tools/testing/kunit/kunit_config.py +@@ -12,7 +12,7 @@ import re + CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' + CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$' + +-KconfigEntryBase = collections.namedtuple('KconfigEntry', ['name', 'value']) ++KconfigEntryBase = collections.namedtuple('KconfigEntryBase', ['name', 'value']) + + class KconfigEntry(KconfigEntryBase): + +diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S +index f95074c9b48b7..07f14e279a904 100644 +--- a/tools/testing/selftests/arm64/fp/sve-test.S ++++ b/tools/testing/selftests/arm64/fp/sve-test.S +@@ -284,16 +284,28 @@ endfunction + // Set up test pattern in the FFR + // x0: pid + // x2: generation ++// ++// We need to generate a canonical FFR value, which consists of a number of ++// low "1" bits, followed by a number of zeros. This gives us 17 unique values ++// per 16 bits of FFR, so we create a 4 bit signature out of the PID and ++// generation, and use that as the initial number of ones in the pattern. ++// We fill the upper lanes of FFR with zeros. + // Beware: corrupts P0. + function setup_ffr + mov x4, x30 + +- bl pattern ++ and w0, w0, #0x3 ++ bfi w0, w2, #2, #2 ++ mov w1, #1 ++ lsl w1, w1, w0 ++ sub w1, w1, #1 ++ + ldr x0, =ffrref +- ldr x1, =scratch +- rdvl x2, #1 +- lsr x2, x2, #3 +- bl memcpy ++ strh w1, [x0], 2 ++ rdvl x1, #1 ++ lsr x1, x1, #3 ++ sub x1, x1, #2 ++ bl memclr + + mov x0, #0 + ldr x1, =ffrref +diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile +index e63f316327080..2cf32e6b376e1 100644 +--- a/tools/testing/selftests/vm/Makefile ++++ b/tools/testing/selftests/vm/Makefile +@@ -99,7 +99,7 @@ endef + ifeq ($(CAN_BUILD_I386),1) + $(BINARIES_32): CFLAGS += -m32 + $(BINARIES_32): LDLIBS += -lrt -ldl -lm +-$(BINARIES_32): %_32: %.c ++$(BINARIES_32): $(OUTPUT)/%_32: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@ + $(foreach t,$(TARGETS),$(eval $(call gen-target-rule-32,$(t)))) + endif +@@ -107,7 +107,7 @@ endif + ifeq ($(CAN_BUILD_X86_64),1) + $(BINARIES_64): CFLAGS += -m64 + $(BINARIES_64): LDLIBS += -lrt -ldl +-$(BINARIES_64): %_64: %.c ++$(BINARIES_64): $(OUTPUT)/%_64: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@ + $(foreach t,$(TARGETS),$(eval $(call gen-target-rule-64,$(t)))) + endif