commit: 5966beb581a34d5772cb017b28b45820cb94bc79 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Fri Dec 27 14:09:02 2024 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Fri Dec 27 14:09:02 2024 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5966beb5
Linux patch 6.1.122 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1121_linux-6.1.122.patch | 2438 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2442 insertions(+) diff --git a/0000_README b/0000_README index e4617888..d4e666e1 100644 --- a/0000_README +++ b/0000_README @@ -531,6 +531,10 @@ Patch: 1120_linux-6.1.121.patch From: https://www.kernel.org Desc: Linux 6.1.121 +Patch: 1121_linux-6.1.122.patch +From: https://www.kernel.org +Desc: Linux 6.1.122 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1121_linux-6.1.122.patch b/1121_linux-6.1.122.patch new file mode 100644 index 00000000..7d8fcd67 --- /dev/null +++ b/1121_linux-6.1.122.patch @@ -0,0 +1,2438 @@ +diff --git a/Makefile b/Makefile +index ddb75912d2a84a..23af31992b8191 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 121 ++SUBLEVEL = 122 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile +index 92d005958dfb23..ff172cbe5881a0 100644 +--- a/arch/hexagon/Makefile ++++ b/arch/hexagon/Makefile +@@ -32,3 +32,9 @@ KBUILD_LDFLAGS += $(ldflags-y) + TIR_NAME := r19 + KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__ + KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME) ++ ++# Disable HexagonConstExtenders pass for LLVM versions prior to 19.1.0 ++# https://github.com/llvm/llvm-project/issues/99714 ++ifneq ($(call clang-min-version, 190100),y) ++KBUILD_CFLAGS += -mllvm -hexagon-cext=false ++endif +diff --git a/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts b/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts +index c945f8565d5434..fb180cb2b8e2ca 100644 +--- a/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts ++++ b/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts +@@ -33,6 +33,7 @@ msi: msi-controller@2ff00000 { + compatible = "loongson,pch-msi-1.0"; + reg = <0 0x2ff00000 0 0x8>; + interrupt-controller; ++ #interrupt-cells = <1>; + msi-controller; + loongson,msi-base-vec = <64>; + loongson,msi-num-vecs = <192>; +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index 3818c85cf964e5..43b1df7ec18357 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -33,6 +33,26 @@ + u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly; + EXPORT_SYMBOL_GPL(kvm_cpu_caps); + ++struct cpuid_xstate_sizes { ++ u32 eax; ++ u32 ebx; ++ u32 ecx; ++}; ++ ++static struct cpuid_xstate_sizes xstate_sizes[XFEATURE_MAX] __ro_after_init; ++ ++void __init kvm_init_xstate_sizes(void) ++{ ++ u32 ign; ++ int i; ++ ++ for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes); i++) { ++ struct cpuid_xstate_sizes *xs = &xstate_sizes[i]; ++ ++ cpuid_count(0xD, i, &xs->eax, &xs->ebx, &xs->ecx, &ign); ++ } ++} ++ + u32 xstate_required_size(u64 xstate_bv, bool compacted) + { + int feature_bit = 0; +@@ -41,14 +61,15 @@ u32 xstate_required_size(u64 xstate_bv, bool compacted) + xstate_bv &= XFEATURE_MASK_EXTEND; + while (xstate_bv) { + if (xstate_bv & 0x1) { +- u32 eax, ebx, ecx, edx, offset; +- cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx); ++ struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit]; ++ u32 offset; ++ + /* ECX[1]: 64B alignment in compacted form */ + if (compacted) +- offset = (ecx & 0x2) ? ALIGN(ret, 64) : ret; ++ offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret; + else +- offset = ebx; +- ret = max(ret, offset + eax); ++ offset = xs->ebx; ++ ret = max(ret, offset + xs->eax); + } + + xstate_bv >>= 1; +diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h +index 18fd2e845989a7..4be98e1c4cd7c8 100644 +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -32,6 +32,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, + bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, + u32 *ecx, u32 *edx, bool exact_only); + ++void __init kvm_init_xstate_sizes(void); + u32 xstate_required_size(u64 xstate_bv, bool compacted); + + int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 4e778ba6a5d474..19ce8199f34748 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -9712,7 +9712,7 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu) + { + u64 ret = vcpu->run->hypercall.ret; + +- if (!is_64_bit_mode(vcpu)) ++ if (!is_64_bit_hypercall(vcpu)) + ret = (u32)ret; + kvm_rax_write(vcpu, ret); + ++vcpu->stat.hypercalls; +@@ -13820,6 +13820,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit); + + static int __init kvm_x86_init(void) + { ++ kvm_init_xstate_sizes(); ++ + kvm_mmu_x86_module_init(); + mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible(); + return 0; +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 966aab902d19a6..b83181357f36d1 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -530,6 +530,12 @@ static ssize_t backing_dev_store(struct device *dev, + } + + nr_pages = i_size_read(inode) >> PAGE_SHIFT; ++ /* Refuse to use zero sized device (also prevents self reference) */ ++ if (!nr_pages) { ++ err = -EINVAL; ++ goto out; ++ } ++ + bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long); + bitmap = kvzalloc(bitmap_sz, GFP_KERNEL); + if (!bitmap) { +@@ -1162,12 +1168,16 @@ static void zram_meta_free(struct zram *zram, u64 disksize) + size_t num_pages = disksize >> PAGE_SHIFT; + size_t index; + ++ if (!zram->table) ++ return; ++ + /* Free all pages that are still in this zram device */ + for (index = 0; index < num_pages; index++) + zram_free_page(zram, index); + + zs_destroy_pool(zram->mem_pool); + vfree(zram->table); ++ zram->table = NULL; + } + + static bool zram_meta_alloc(struct zram *zram, u64 disksize) +@@ -1716,11 +1726,6 @@ static void zram_reset_device(struct zram *zram) + + zram->limit_pages = 0; + +- if (!init_done(zram)) { +- up_write(&zram->init_lock); +- return; +- } +- + set_capacity_and_notify(zram->disk, 0); + part_stat_set_all(zram->disk->part0, 0); + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 5b7d848a6f01be..0e03c4908050b8 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -974,6 +974,7 @@ static int cxl_port_setup_targets(struct cxl_port *port, + struct cxl_region_params *p = &cxlr->params; + struct cxl_decoder *cxld = cxl_rr->decoder; + struct cxl_switch_decoder *cxlsd; ++ struct cxl_port *iter = port; + u16 eig, peig; + u8 eiw, peiw; + +@@ -990,16 +991,26 @@ static int cxl_port_setup_targets(struct cxl_port *port, + + cxlsd = to_cxl_switch_decoder(&cxld->dev); + if (cxl_rr->nr_targets_set) { +- int i, distance; ++ int i, distance = 1; ++ struct cxl_region_ref *cxl_rr_iter; + + /* +- * Passthrough decoders impose no distance requirements between +- * peers ++ * The "distance" between peer downstream ports represents which ++ * endpoint positions in the region interleave a given port can ++ * host. ++ * ++ * For example, at the root of a hierarchy the distance is ++ * always 1 as every index targets a different host-bridge. At ++ * each subsequent switch level those ports map every Nth region ++ * position where N is the width of the switch == distance. + */ +- if (cxl_rr->nr_targets == 1) +- distance = 0; +- else +- distance = p->nr_targets / cxl_rr->nr_targets; ++ do { ++ cxl_rr_iter = cxl_rr_load(iter, cxlr); ++ distance *= cxl_rr_iter->nr_targets; ++ iter = to_cxl_port(iter->dev.parent); ++ } while (!is_cxl_root(iter)); ++ distance *= cxlrd->cxlsd.cxld.interleave_ways; ++ + for (i = 0; i < cxl_rr->nr_targets_set; i++) + if (ep->dport == cxlsd->target[i]) { + rc = check_last_peer(cxled, ep, cxl_rr, +diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c +index 2bcdb935a3ac4d..ef99174d81ced1 100644 +--- a/drivers/dma-buf/udmabuf.c ++++ b/drivers/dma-buf/udmabuf.c +@@ -164,7 +164,7 @@ static const struct dma_buf_ops udmabuf_ops = { + }; + + #define SEALS_WANTED (F_SEAL_SHRINK) +-#define SEALS_DENIED (F_SEAL_WRITE) ++#define SEALS_DENIED (F_SEAL_WRITE|F_SEAL_FUTURE_WRITE) + + static long udmabuf_create(struct miscdevice *device, + struct udmabuf_create_list *head, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +index f34bc9bb7045a0..7f1e92110dd1f8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +@@ -150,7 +150,6 @@ void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds, + + void amdgpu_job_free_resources(struct amdgpu_job *job) + { +- struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); + struct dma_fence *f; + unsigned i; + +@@ -163,7 +162,7 @@ void amdgpu_job_free_resources(struct amdgpu_job *job) + f = NULL; + + for (i = 0; i < job->num_ibs; ++i) +- amdgpu_ib_free(ring->adev, &job->ibs[i], f); ++ amdgpu_ib_free(NULL, &job->ibs[i], f); + } + + static void amdgpu_job_free_cb(struct drm_sched_job *s_job) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index 49a47807c42d6d..16be61abd998a5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -1060,10 +1060,9 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, + * next command submission. + */ + if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv) { +- uint32_t mem_type = bo->tbo.resource->mem_type; +- +- if (!(bo->preferred_domains & +- amdgpu_mem_type_to_domain(mem_type))) ++ if (bo->tbo.resource && ++ !(bo->preferred_domains & ++ amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type))) + amdgpu_vm_bo_evicted(&bo_va->base); + else + amdgpu_vm_bo_idle(&bo_va->base); +diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c +index 304004fb80aa9e..8e6ec75dc6875f 100644 +--- a/drivers/gpu/drm/drm_modes.c ++++ b/drivers/gpu/drm/drm_modes.c +@@ -808,14 +808,11 @@ EXPORT_SYMBOL(drm_mode_set_name); + */ + int drm_mode_vrefresh(const struct drm_display_mode *mode) + { +- unsigned int num, den; ++ unsigned int num = 1, den = 1; + + if (mode->htotal == 0 || mode->vtotal == 0) + return 0; + +- num = mode->clock; +- den = mode->htotal * mode->vtotal; +- + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + num *= 2; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) +@@ -823,6 +820,12 @@ int drm_mode_vrefresh(const struct drm_display_mode *mode) + if (mode->vscan > 1) + den *= mode->vscan; + ++ if (check_mul_overflow(mode->clock, num, &num)) ++ return 0; ++ ++ if (check_mul_overflow(mode->htotal * mode->vtotal, den, &den)) ++ return 0; ++ + return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den); + } + EXPORT_SYMBOL(drm_mode_vrefresh); +diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h +index 107f465a27b9e5..458320d28e2740 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h ++++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h +@@ -339,6 +339,11 @@ struct intel_engine_guc_stats { + * @start_gt_clk: GT clock time of last idle to active transition. + */ + u64 start_gt_clk; ++ ++ /** ++ * @total: The last value of total returned ++ */ ++ u64 total; + }; + + struct intel_engine_cs { +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +index 56df4c4a8a1a84..2e0eb6cb8eabff 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +@@ -1213,6 +1213,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine, + } while (++i < 6); + } + ++static void __set_engine_usage_record(struct intel_engine_cs *engine, ++ u32 last_in, u32 id, u32 total) ++{ ++ struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine); ++ ++#define record_write(map_, field_, val_) \ ++ iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_) ++ ++ record_write(&rec_map, last_switch_in_stamp, last_in); ++ record_write(&rec_map, current_context_index, id); ++ record_write(&rec_map, total_runtime, total); ++ ++#undef record_write ++} ++ + static void guc_update_engine_gt_clks(struct intel_engine_cs *engine) + { + struct intel_engine_guc_stats *stats = &engine->stats.guc; +@@ -1331,9 +1346,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now) + total += intel_gt_clock_interval_to_ns(gt, clk); + } + ++ if (total > stats->total) ++ stats->total = total; ++ + spin_unlock_irqrestore(&guc->timestamp.lock, flags); + +- return ns_to_ktime(total); ++ return ns_to_ktime(stats->total); + } + + static void __reset_guc_busyness_stats(struct intel_guc *guc) +@@ -1350,8 +1368,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc) + + guc_update_pm_timestamp(guc, &unused); + for_each_engine(engine, gt, id) { ++ struct intel_engine_guc_stats *stats = &engine->stats.guc; ++ + guc_update_engine_gt_clks(engine); +- engine->stats.guc.prev_total = 0; ++ ++ /* ++ * If resetting a running context, accumulate the active ++ * time as well since there will be no context switch. ++ */ ++ if (stats->running) { ++ u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk; ++ ++ stats->total_gt_clks += clk; ++ } ++ stats->prev_total = 0; ++ stats->running = 0; + } + + spin_unlock_irqrestore(&guc->timestamp.lock, flags); +@@ -1404,6 +1435,9 @@ static void guc_timestamp_ping(struct work_struct *wrk) + + static int guc_action_enable_usage_stats(struct intel_guc *guc) + { ++ struct intel_gt *gt = guc_to_gt(guc); ++ struct intel_engine_cs *engine; ++ enum intel_engine_id id; + u32 offset = intel_guc_engine_usage_offset(guc); + u32 action[] = { + INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF, +@@ -1411,6 +1445,9 @@ static int guc_action_enable_usage_stats(struct intel_guc *guc) + 0, + }; + ++ for_each_engine(engine, gt, id) ++ __set_engine_usage_record(engine, 0, 0xffffffff, 0); ++ + return intel_guc_send(guc, action, ARRAY_SIZE(action)); + } + +diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c b/drivers/gpu/drm/panel/panel-novatek-nt35950.c +index ec2780be74d109..a92a7cd697f445 100644 +--- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c ++++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c +@@ -577,9 +577,9 @@ static int nt35950_probe(struct mipi_dsi_device *dsi) + return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n"); + + nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info); +- if (!nt->dsi[1]) { ++ if (IS_ERR(nt->dsi[1])) { + dev_err(dev, "Cannot get secondary DSI node\n"); +- return -ENODEV; ++ return PTR_ERR(nt->dsi[1]); + } + num_dsis++; + } +diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c +index d35b60c0611486..77017d9518267c 100644 +--- a/drivers/hv/hv_kvp.c ++++ b/drivers/hv/hv_kvp.c +@@ -767,6 +767,12 @@ hv_kvp_init(struct hv_util_service *srv) + */ + kvp_transaction.state = HVUTIL_DEVICE_INIT; + ++ return 0; ++} ++ ++int ++hv_kvp_init_transport(void) ++{ + hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL, + kvp_on_msg, kvp_on_reset); + if (!hvt) +diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c +index 0d2184be169125..397f4c8fa46c31 100644 +--- a/drivers/hv/hv_snapshot.c ++++ b/drivers/hv/hv_snapshot.c +@@ -388,6 +388,12 @@ hv_vss_init(struct hv_util_service *srv) + */ + vss_transaction.state = HVUTIL_DEVICE_INIT; + ++ return 0; ++} ++ ++int ++hv_vss_init_transport(void) ++{ + hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL, + vss_on_msg, vss_on_reset); + if (!hvt) { +diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c +index 835e6039c18678..ad6c066fd2b758 100644 +--- a/drivers/hv/hv_util.c ++++ b/drivers/hv/hv_util.c +@@ -141,6 +141,7 @@ static struct hv_util_service util_heartbeat = { + static struct hv_util_service util_kvp = { + .util_cb = hv_kvp_onchannelcallback, + .util_init = hv_kvp_init, ++ .util_init_transport = hv_kvp_init_transport, + .util_pre_suspend = hv_kvp_pre_suspend, + .util_pre_resume = hv_kvp_pre_resume, + .util_deinit = hv_kvp_deinit, +@@ -149,6 +150,7 @@ static struct hv_util_service util_kvp = { + static struct hv_util_service util_vss = { + .util_cb = hv_vss_onchannelcallback, + .util_init = hv_vss_init, ++ .util_init_transport = hv_vss_init_transport, + .util_pre_suspend = hv_vss_pre_suspend, + .util_pre_resume = hv_vss_pre_resume, + .util_deinit = hv_vss_deinit, +@@ -592,6 +594,13 @@ static int util_probe(struct hv_device *dev, + if (ret) + goto error; + ++ if (srv->util_init_transport) { ++ ret = srv->util_init_transport(); ++ if (ret) { ++ vmbus_close(dev->channel); ++ goto error; ++ } ++ } + return 0; + + error: +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index dc673edf053c3b..ab12e21bf5fc7b 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -365,12 +365,14 @@ void vmbus_on_event(unsigned long data); + void vmbus_on_msg_dpc(unsigned long data); + + int hv_kvp_init(struct hv_util_service *srv); ++int hv_kvp_init_transport(void); + void hv_kvp_deinit(void); + int hv_kvp_pre_suspend(void); + int hv_kvp_pre_resume(void); + void hv_kvp_onchannelcallback(void *context); + + int hv_vss_init(struct hv_util_service *srv); ++int hv_vss_init_transport(void); + void hv_vss_deinit(void); + int hv_vss_pre_suspend(void); + int hv_vss_pre_resume(void); +diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c +index b9a93ee9c23642..aaba9521ebefea 100644 +--- a/drivers/hwmon/tmp513.c ++++ b/drivers/hwmon/tmp513.c +@@ -19,15 +19,20 @@ + * the Free Software Foundation; version 2 of the License. + */ + ++#include <linux/bitops.h> ++#include <linux/bug.h> ++#include <linux/device.h> + #include <linux/err.h> + #include <linux/hwmon.h> + #include <linux/i2c.h> + #include <linux/init.h> +-#include <linux/kernel.h> ++#include <linux/math.h> + #include <linux/module.h> ++#include <linux/property.h> + #include <linux/regmap.h> + #include <linux/slab.h> +-#include <linux/util_macros.h> ++#include <linux/types.h> ++#include <linux/units.h> + + // Common register definition + #define TMP51X_SHUNT_CONFIG 0x00 +@@ -100,8 +105,8 @@ + #define TMP51X_REMOTE_TEMP_LIMIT_2_POS 8 + #define TMP513_REMOTE_TEMP_LIMIT_3_POS 7 + +-#define TMP51X_VBUS_RANGE_32V 32000000 +-#define TMP51X_VBUS_RANGE_16V 16000000 ++#define TMP51X_VBUS_RANGE_32V (32 * MICRO) ++#define TMP51X_VBUS_RANGE_16V (16 * MICRO) + + // Max and Min value + #define MAX_BUS_VOLTAGE_32_LIMIT 32764 +@@ -173,7 +178,7 @@ struct tmp51x_data { + struct regmap *regmap; + }; + +-// Set the shift based on the gain 8=4, 4=3, 2=2, 1=1 ++// Set the shift based on the gain: 8 -> 1, 4 -> 2, 2 -> 3, 1 -> 4 + static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data) + { + return 5 - ffs(data->pga_gain); +@@ -195,8 +200,10 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos, + * 2's complement number shifted by one to four depending + * on the pga gain setting. 1lsb = 10uV + */ +- *val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data)); +- *val = DIV_ROUND_CLOSEST(*val * 10000, data->shunt_uohms); ++ *val = sign_extend32(regval, ++ reg == TMP51X_SHUNT_CURRENT_RESULT ? ++ 16 - tmp51x_get_pga_shift(data) : 15); ++ *val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms); + break; + case TMP51X_BUS_VOLTAGE_RESULT: + case TMP51X_BUS_VOLTAGE_H_LIMIT: +@@ -211,8 +218,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos, + break; + case TMP51X_BUS_CURRENT_RESULT: + // Current = (ShuntVoltage * CalibrationRegister) / 4096 +- *val = sign_extend32(regval, 16) * data->curr_lsb_ua; +- *val = DIV_ROUND_CLOSEST(*val, 1000); ++ *val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua; ++ *val = DIV_ROUND_CLOSEST(*val, MILLI); + break; + case TMP51X_LOCAL_TEMP_RESULT: + case TMP51X_REMOTE_TEMP_RESULT_1: +@@ -223,7 +230,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos, + case TMP51X_REMOTE_TEMP_LIMIT_2: + case TMP513_REMOTE_TEMP_LIMIT_3: + // 1lsb = 0.0625 degrees centigrade +- *val = sign_extend32(regval, 16) >> TMP51X_TEMP_SHIFT; ++ *val = sign_extend32(regval, 15) >> TMP51X_TEMP_SHIFT; + *val = DIV_ROUND_CLOSEST(*val * 625, 10); + break; + case TMP51X_N_FACTOR_AND_HYST_1: +@@ -252,7 +259,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val) + * The user enter current value and we convert it to + * voltage. 1lsb = 10uV + */ +- val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10000); ++ val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI); + max_val = U16_MAX >> tmp51x_get_pga_shift(data); + regval = clamp_val(val, -max_val, max_val); + break; +@@ -542,18 +549,16 @@ static int tmp51x_calibrate(struct tmp51x_data *data) + if (data->shunt_uohms == 0) + return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 0); + +- max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * 1000 * 1000, +- data->shunt_uohms); ++ max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * MICRO, data->shunt_uohms); + + /* + * Calculate the minimal bit resolution for the current and the power. + * Those values will be used during register interpretation. + */ +- data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * 1000, 32767); ++ data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * MILLI, 32767); + data->pwr_lsb_uw = 20 * data->curr_lsb_ua; + +- div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, +- 1000 * 1000); ++ div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, MICRO); + + return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, + DIV_ROUND_CLOSEST(40960, div)); +@@ -628,9 +633,9 @@ static int tmp51x_vbus_range_to_reg(struct device *dev, + } else if (data->vbus_range_uvolt == TMP51X_VBUS_RANGE_16V) { + data->shunt_config &= ~TMP51X_BUS_VOLTAGE_MASK; + } else { +- dev_err(dev, "ti,bus-range-microvolt is invalid: %u\n", +- data->vbus_range_uvolt); +- return -EINVAL; ++ return dev_err_probe(dev, -EINVAL, ++ "ti,bus-range-microvolt is invalid: %u\n", ++ data->vbus_range_uvolt); + } + return 0; + } +@@ -646,8 +651,8 @@ static int tmp51x_pga_gain_to_reg(struct device *dev, struct tmp51x_data *data) + } else if (data->pga_gain == 1) { + data->shunt_config |= CURRENT_SENSE_VOLTAGE_40_MASK; + } else { +- dev_err(dev, "ti,pga-gain is invalid: %u\n", data->pga_gain); +- return -EINVAL; ++ return dev_err_probe(dev, -EINVAL, ++ "ti,pga-gain is invalid: %u\n", data->pga_gain); + } + return 0; + } +@@ -679,10 +684,10 @@ static int tmp51x_read_properties(struct device *dev, struct tmp51x_data *data) + memcpy(data->nfactor, nfactor, (data->id == tmp513) ? 3 : 2); + + // Check if shunt value is compatible with pga-gain +- if (data->shunt_uohms > data->pga_gain * 40 * 1000 * 1000) { +- dev_err(dev, "shunt-resistor: %u too big for pga_gain: %u\n", +- data->shunt_uohms, data->pga_gain); +- return -EINVAL; ++ if (data->shunt_uohms > data->pga_gain * 40 * MICRO) { ++ return dev_err_probe(dev, -EINVAL, ++ "shunt-resistor: %u too big for pga_gain: %u\n", ++ data->shunt_uohms, data->pga_gain); + } + + return 0; +@@ -726,22 +731,17 @@ static int tmp51x_probe(struct i2c_client *client) + data->id = i2c_match_id(tmp51x_id, client)->driver_data; + + ret = tmp51x_configure(dev, data); +- if (ret < 0) { +- dev_err(dev, "error configuring the device: %d\n", ret); +- return ret; +- } ++ if (ret < 0) ++ return dev_err_probe(dev, ret, "error configuring the device\n"); + + data->regmap = devm_regmap_init_i2c(client, &tmp51x_regmap_config); +- if (IS_ERR(data->regmap)) { +- dev_err(dev, "failed to allocate register map\n"); +- return PTR_ERR(data->regmap); +- } ++ if (IS_ERR(data->regmap)) ++ return dev_err_probe(dev, PTR_ERR(data->regmap), ++ "failed to allocate register map\n"); + + ret = tmp51x_init(data); +- if (ret < 0) { +- dev_err(dev, "error configuring the device: %d\n", ret); +- return -ENODEV; +- } ++ if (ret < 0) ++ return dev_err_probe(dev, ret, "error configuring the device\n"); + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, + data, +diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c +index d2c09b0fdf5275..ab87bef50402e0 100644 +--- a/drivers/i2c/busses/i2c-pnx.c ++++ b/drivers/i2c/busses/i2c-pnx.c +@@ -95,7 +95,7 @@ enum { + + static inline int wait_timeout(struct i2c_pnx_algo_data *data) + { +- long timeout = data->timeout; ++ long timeout = jiffies_to_msecs(data->timeout); + while (timeout > 0 && + (ioread32(I2C_REG_STS(data)) & mstatus_active)) { + mdelay(1); +@@ -106,7 +106,7 @@ static inline int wait_timeout(struct i2c_pnx_algo_data *data) + + static inline int wait_reset(struct i2c_pnx_algo_data *data) + { +- long timeout = data->timeout; ++ long timeout = jiffies_to_msecs(data->timeout); + while (timeout > 0 && + (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) { + mdelay(1); +diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c +index b9959621cc5d75..6f8ce656183cdc 100644 +--- a/drivers/i2c/busses/i2c-riic.c ++++ b/drivers/i2c/busses/i2c-riic.c +@@ -325,7 +325,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) + if (brl <= (0x1F + 3)) + break; + +- total_ticks /= 2; ++ total_ticks = DIV_ROUND_UP(total_ticks, 2); + rate /= 2; + } + +diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c +index 62d236bfe93776..3d6af49e91804f 100644 +--- a/drivers/mmc/host/sdhci-tegra.c ++++ b/drivers/mmc/host/sdhci-tegra.c +@@ -1520,7 +1520,6 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | + SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_NO_HISPD_BIT | +- SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | + SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER, +diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c +index b4381cd4197928..3f4e8bac40c198 100644 +--- a/drivers/net/ethernet/broadcom/bgmac-platform.c ++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c +@@ -171,6 +171,7 @@ static int platform_phy_connect(struct bgmac *bgmac) + static int bgmac_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; ++ struct device_node *phy_node; + struct bgmac *bgmac; + struct resource *regs; + int ret; +@@ -236,7 +237,9 @@ static int bgmac_probe(struct platform_device *pdev) + bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset; + bgmac->get_bus_clock = platform_bgmac_get_bus_clock; + bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32; +- if (of_parse_phandle(np, "phy-handle", 0)) { ++ phy_node = of_parse_phandle(np, "phy-handle", 0); ++ if (phy_node) { ++ of_node_put(phy_node); + bgmac->phy_connect = platform_phy_connect; + } else { + bgmac->phy_connect = bgmac_phy_connect_direct; +diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c +index 1e55b12fee5168..5c9f462ac93572 100644 +--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c +@@ -346,8 +346,9 @@ static struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl, + * driver. Once driver synthesizes cpl_pass_accpet_req the skb will go + * through the regular cpl_pass_accept_req processing in TOM. + */ +- skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) +- - pktshift, GFP_ATOMIC); ++ skb = alloc_skb(size_add(gl->tot_len, ++ sizeof(struct cpl_pass_accept_req)) - ++ pktshift, GFP_ATOMIC); + if (unlikely(!skb)) + return NULL; + __skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req) +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c +index 2d6906aba2a250..af6100e5d9b919 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c +@@ -172,6 +172,7 @@ static int create_txqs(struct hinic_dev *nic_dev) + hinic_sq_dbgfs_uninit(nic_dev); + + devm_kfree(&netdev->dev, nic_dev->txqs); ++ nic_dev->txqs = NULL; + return err; + } + +@@ -268,6 +269,7 @@ static int create_rxqs(struct hinic_dev *nic_dev) + hinic_rq_dbgfs_uninit(nic_dev); + + devm_kfree(&netdev->dev, nic_dev->rxqs); ++ nic_dev->rxqs = NULL; + return err; + } + +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index 310a36356f568e..71dbdac38020b2 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -1161,7 +1161,7 @@ void ocelot_ifh_set_basic(void *ifh, struct ocelot *ocelot, int port, + + memset(ifh, 0, OCELOT_TAG_LEN); + ocelot_ifh_set_bypass(ifh, 1); +- ocelot_ifh_set_src(ifh, BIT_ULL(ocelot->num_phys_ports)); ++ ocelot_ifh_set_src(ifh, ocelot->num_phys_ports); + ocelot_ifh_set_dest(ifh, BIT_ULL(port)); + ocelot_ifh_set_qos_class(ifh, qos_class); + ocelot_ifh_set_tag_type(ifh, tag_type); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +index d7370fb60a168d..928ef293399071 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +@@ -828,8 +828,8 @@ static int ionic_get_module_eeprom(struct net_device *netdev, + len = min_t(u32, sizeof(xcvr->sprom), ee->len); + + do { +- memcpy(data, xcvr->sprom, len); +- memcpy(tbuf, xcvr->sprom, len); ++ memcpy(data, &xcvr->sprom[ee->offset], len); ++ memcpy(tbuf, &xcvr->sprom[ee->offset], len); + + /* Let's make sure we got a consistent copy */ + if (!memcmp(data, tbuf, len)) +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +index 14865fc245dae7..b746944bcd2aee 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -3484,8 +3484,8 @@ int ionic_lif_register(struct ionic_lif *lif) + /* only register LIF0 for now */ + err = register_netdev(lif->netdev); + if (err) { +- dev_err(lif->ionic->dev, "Cannot register net device, aborting\n"); +- ionic_lif_unregister_phc(lif); ++ dev_err(lif->ionic->dev, "Cannot register net device: %d, aborting\n", err); ++ ionic_lif_unregister(lif); + return err; + } + +diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c +index b782c35c4ac144..8ada397bc357b0 100644 +--- a/drivers/net/mdio/fwnode_mdio.c ++++ b/drivers/net/mdio/fwnode_mdio.c +@@ -38,6 +38,7 @@ fwnode_find_pse_control(struct fwnode_handle *fwnode) + static struct mii_timestamper * + fwnode_find_mii_timestamper(struct fwnode_handle *fwnode) + { ++ struct mii_timestamper *mii_ts; + struct of_phandle_args arg; + int err; + +@@ -51,10 +52,16 @@ fwnode_find_mii_timestamper(struct fwnode_handle *fwnode) + else if (err) + return ERR_PTR(err); + +- if (arg.args_count != 1) +- return ERR_PTR(-EINVAL); ++ if (arg.args_count != 1) { ++ mii_ts = ERR_PTR(-EINVAL); ++ goto put_node; ++ } ++ ++ mii_ts = register_mii_timestamper(arg.np, arg.args[0]); + +- return register_mii_timestamper(arg.np, arg.args[0]); ++put_node: ++ of_node_put(arg.np); ++ return mii_ts; + } + + int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio, +diff --git a/drivers/net/netdevsim/health.c b/drivers/net/netdevsim/health.c +index aa77af4a68df6f..bc44462c70e264 100644 +--- a/drivers/net/netdevsim/health.c ++++ b/drivers/net/netdevsim/health.c +@@ -203,6 +203,8 @@ static ssize_t nsim_dev_health_break_write(struct file *file, + char *break_msg; + int err; + ++ if (count == 0 || count > PAGE_SIZE) ++ return -EINVAL; + break_msg = memdup_user_nul(data, count); + if (IS_ERR(break_msg)) + return PTR_ERR(break_msg); +diff --git a/drivers/of/address.c b/drivers/of/address.c +index 67763e5b8c0efd..18498619177c65 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -595,7 +595,7 @@ struct device_node *__of_get_dma_parent(const struct device_node *np) + if (ret < 0) + return of_get_parent(np); + +- return of_node_get(args.np); ++ return args.np; + } + #endif + +diff --git a/drivers/of/base.c b/drivers/of/base.c +index f849bbb9ef8c78..e1b2b9275e6874 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1597,8 +1597,10 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + map_len--; + + /* Check if not found */ +- if (!new) ++ if (!new) { ++ ret = -EINVAL; + goto put; ++ } + + if (!of_device_is_available(new)) + match = 0; +@@ -1608,17 +1610,20 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + goto put; + + /* Check for malformed properties */ +- if (WARN_ON(new_size > MAX_PHANDLE_ARGS)) +- goto put; +- if (map_len < new_size) ++ if (WARN_ON(new_size > MAX_PHANDLE_ARGS) || ++ map_len < new_size) { ++ ret = -EINVAL; + goto put; ++ } + + /* Move forward by new node's #<list>-cells amount */ + map += new_size; + map_len -= new_size; + } +- if (!match) ++ if (!match) { ++ ret = -ENOENT; + goto put; ++ } + + /* Get the <list>-map-pass-thru property (optional) */ + pass = of_get_property(cur, pass_name, NULL); +diff --git a/drivers/of/irq.c b/drivers/of/irq.c +index 8c402690d10983..8d77566eae1a84 100644 +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -111,6 +111,7 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_ph + else + np = of_find_node_by_phandle(be32_to_cpup(imap)); + imap++; ++ len--; + + /* Check if not found */ + if (!np) { +@@ -354,6 +355,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar + return of_irq_parse_oldworld(device, index, out_irq); + + /* Get the reg property (if any) */ ++ addr_len = 0; + addr = of_get_property(device, "reg", &addr_len); + + /* Prevent out-of-bounds read in case of longer interrupt parent address size */ +diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c +index d3924a44db02f8..fd3020a399cf93 100644 +--- a/drivers/pci/controller/pci-host-common.c ++++ b/drivers/pci/controller/pci-host-common.c +@@ -73,10 +73,6 @@ int pci_host_common_probe(struct platform_device *pdev) + if (IS_ERR(cfg)) + return PTR_ERR(cfg); + +- /* Do not reassign resources if probe only */ +- if (!pci_has_flag(PCI_PROBE_ONLY)) +- pci_add_flags(PCI_REASSIGN_ALL_BUS); +- + bridge->sysdata = cfg; + bridge->ops = (struct pci_ops *)&ops->pci_ops; + bridge->msi_domain = true; +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index 5c35884c226e6b..a1dd614bdc3240 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -870,6 +870,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + dev_set_msi_domain(&vmd->bus->dev, + dev_get_msi_domain(&vmd->dev->dev)); + ++ WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, ++ "domain"), "Can't create symlink to domain\n"); ++ + vmd_acpi_begin(); + + pci_scan_child_bus(vmd->bus); +@@ -907,9 +910,6 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + pci_bus_add_devices(vmd->bus); + + vmd_acpi_end(); +- +- WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, +- "domain"), "Can't create symlink to domain\n"); + return 0; + } + +@@ -985,8 +985,8 @@ static void vmd_remove(struct pci_dev *dev) + { + struct vmd_dev *vmd = pci_get_drvdata(dev); + +- sysfs_remove_link(&vmd->dev->dev.kobj, "domain"); + pci_stop_root_bus(vmd->bus); ++ sysfs_remove_link(&vmd->dev->dev.kobj, "domain"); + pci_remove_root_bus(vmd->bus); + vmd_cleanup_srcu(vmd); + vmd_detach_resources(vmd); +diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c +index 5426f450ce9196..1b59e6fc7439df 100644 +--- a/drivers/pci/pcie/aer.c ++++ b/drivers/pci/pcie/aer.c +@@ -1384,6 +1384,22 @@ static int aer_probe(struct pcie_device *dev) + return 0; + } + ++static int aer_suspend(struct pcie_device *dev) ++{ ++ struct aer_rpc *rpc = get_service_data(dev); ++ ++ aer_disable_rootport(rpc); ++ return 0; ++} ++ ++static int aer_resume(struct pcie_device *dev) ++{ ++ struct aer_rpc *rpc = get_service_data(dev); ++ ++ aer_enable_rootport(rpc); ++ return 0; ++} ++ + /** + * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP + * @dev: pointer to Root Port, RCEC, or RCiEP +@@ -1455,6 +1471,8 @@ static struct pcie_port_service_driver aerdriver = { + .service = PCIE_PORT_SERVICE_AER, + + .probe = aer_probe, ++ .suspend = aer_suspend, ++ .resume = aer_resume, + .remove = aer_remove, + }; + +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index 5c1ab9ee65eb32..fbb47954a96cd8 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -3082,20 +3082,18 @@ int pci_host_probe(struct pci_host_bridge *bridge) + + bus = bridge->bus; + ++ /* If we must preserve the resource configuration, claim now */ ++ if (bridge->preserve_config) ++ pci_bus_claim_resources(bus); ++ + /* +- * We insert PCI resources into the iomem_resource and +- * ioport_resource trees in either pci_bus_claim_resources() +- * or pci_bus_assign_resources(). ++ * Assign whatever was left unassigned. If we didn't claim above, ++ * this will reassign everything. + */ +- if (pci_has_flag(PCI_PROBE_ONLY)) { +- pci_bus_claim_resources(bus); +- } else { +- pci_bus_size_bridges(bus); +- pci_bus_assign_resources(bus); ++ pci_assign_unassigned_root_bus_resources(bus); + +- list_for_each_entry(child, &bus->children, node) +- pcie_bus_configure_settings(child); +- } ++ list_for_each_entry(child, &bus->children, node) ++ pcie_bus_configure_settings(child); + + pci_bus_add_devices(bus); + return 0; +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index d0da564ac94bf4..2b3df65005ca86 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5008,6 +5008,10 @@ static const struct pci_dev_acs_enabled { + { PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_BROADCOM, 0x1760, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_BROADCOM, 0x1761, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs }, + /* Amazon Annapurna Labs */ + { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs }, +diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c +index 053be5c5e0cad4..eff920de31c245 100644 +--- a/drivers/platform/x86/p2sb.c ++++ b/drivers/platform/x86/p2sb.c +@@ -42,8 +42,9 @@ struct p2sb_res_cache { + }; + + static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; ++static bool p2sb_hidden_by_bios; + +-static int p2sb_get_devfn(unsigned int *devfn) ++static void p2sb_get_devfn(unsigned int *devfn) + { + unsigned int fn = P2SB_DEVFN_DEFAULT; + const struct x86_cpu_id *id; +@@ -53,7 +54,6 @@ static int p2sb_get_devfn(unsigned int *devfn) + fn = (unsigned int)id->driver_data; + + *devfn = fn; +- return 0; + } + + static bool p2sb_valid_resource(const struct resource *res) +@@ -97,6 +97,12 @@ static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) + + static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) + { ++ /* ++ * The BIOS prevents the P2SB device from being enumerated by the PCI ++ * subsystem, so we need to unhide and hide it back to lookup the BAR. ++ */ ++ pci_bus_write_config_dword(bus, devfn, P2SBC, 0); ++ + /* Scan the P2SB device and cache its BAR0 */ + p2sb_scan_and_cache_devfn(bus, devfn); + +@@ -104,6 +110,8 @@ static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) + if (devfn == P2SB_DEVFN_GOLDMONT) + p2sb_scan_and_cache_devfn(bus, SPI_DEVFN_GOLDMONT); + ++ pci_bus_write_config_dword(bus, devfn, P2SBC, P2SBC_HIDE); ++ + if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res)) + return -ENOENT; + +@@ -129,12 +137,10 @@ static int p2sb_cache_resources(void) + u32 value = P2SBC_HIDE; + struct pci_bus *bus; + u16 class; +- int ret; ++ int ret = 0; + + /* Get devfn for P2SB device itself */ +- ret = p2sb_get_devfn(&devfn_p2sb); +- if (ret) +- return ret; ++ p2sb_get_devfn(&devfn_p2sb); + + bus = p2sb_get_bus(NULL); + if (!bus) +@@ -154,22 +160,53 @@ static int p2sb_cache_resources(void) + */ + pci_lock_rescan_remove(); + ++ pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); ++ p2sb_hidden_by_bios = value & P2SBC_HIDE; ++ + /* +- * The BIOS prevents the P2SB device from being enumerated by the PCI +- * subsystem, so we need to unhide and hide it back to lookup the BAR. +- * Unhide the P2SB device here, if needed. ++ * If the BIOS does not hide the P2SB device then its resources ++ * are accesilble. Cache them only if the P2SB device is hidden. + */ +- pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); +- if (value & P2SBC_HIDE) +- pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); ++ if (p2sb_hidden_by_bios) ++ ret = p2sb_scan_and_cache(bus, devfn_p2sb); + +- ret = p2sb_scan_and_cache(bus, devfn_p2sb); ++ pci_unlock_rescan_remove(); + +- /* Hide the P2SB device, if it was hidden */ +- if (value & P2SBC_HIDE) +- pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE); ++ return ret; ++} + +- pci_unlock_rescan_remove(); ++static int p2sb_read_from_cache(struct pci_bus *bus, unsigned int devfn, ++ struct resource *mem) ++{ ++ struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)]; ++ ++ if (cache->bus_dev_id != bus->dev.id) ++ return -ENODEV; ++ ++ if (!p2sb_valid_resource(&cache->res)) ++ return -ENOENT; ++ ++ memcpy(mem, &cache->res, sizeof(*mem)); ++ ++ return 0; ++} ++ ++static int p2sb_read_from_dev(struct pci_bus *bus, unsigned int devfn, ++ struct resource *mem) ++{ ++ struct pci_dev *pdev; ++ int ret = 0; ++ ++ pdev = pci_get_slot(bus, devfn); ++ if (!pdev) ++ return -ENODEV; ++ ++ if (p2sb_valid_resource(pci_resource_n(pdev, 0))) ++ p2sb_read_bar0(pdev, mem); ++ else ++ ret = -ENOENT; ++ ++ pci_dev_put(pdev); + + return ret; + } +@@ -190,28 +227,17 @@ static int p2sb_cache_resources(void) + */ + int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) + { +- struct p2sb_res_cache *cache; +- int ret; +- + bus = p2sb_get_bus(bus); + if (!bus) + return -ENODEV; + +- if (!devfn) { +- ret = p2sb_get_devfn(&devfn); +- if (ret) +- return ret; +- } ++ if (!devfn) ++ p2sb_get_devfn(&devfn); + +- cache = &p2sb_resources[PCI_FUNC(devfn)]; +- if (cache->bus_dev_id != bus->dev.id) +- return -ENODEV; ++ if (p2sb_hidden_by_bios) ++ return p2sb_read_from_cache(bus, devfn, mem); + +- if (!p2sb_valid_resource(&cache->res)) +- return -ENOENT; +- +- memcpy(mem, &cache->res, sizeof(*mem)); +- return 0; ++ return p2sb_read_from_dev(bus, devfn, mem); + } + EXPORT_SYMBOL_GPL(p2sb_bar); + +diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c +index d996782a710642..7a73f5e4a1fc70 100644 +--- a/drivers/sh/clk/core.c ++++ b/drivers/sh/clk/core.c +@@ -295,7 +295,7 @@ int clk_enable(struct clk *clk) + int ret; + + if (!clk) +- return -EINVAL; ++ return 0; + + spin_lock_irqsave(&clock_lock, flags); + ret = __clk_enable(clk); +diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c +index c5e4fa478e643f..c592032657a1e8 100644 +--- a/drivers/thunderbolt/tb.c ++++ b/drivers/thunderbolt/tb.c +@@ -1093,6 +1093,37 @@ static void tb_exit_redrive(struct tb_port *port) + } + } + ++static void tb_switch_enter_redrive(struct tb_switch *sw) ++{ ++ struct tb_port *port; ++ ++ tb_switch_for_each_port(sw, port) ++ tb_enter_redrive(port); ++} ++ ++/* ++ * Called during system and runtime suspend to forcefully exit redrive ++ * mode without querying whether the resource is available. ++ */ ++static void tb_switch_exit_redrive(struct tb_switch *sw) ++{ ++ struct tb_port *port; ++ ++ if (!(sw->quirks & QUIRK_KEEP_POWER_IN_DP_REDRIVE)) ++ return; ++ ++ tb_switch_for_each_port(sw, port) { ++ if (!tb_port_is_dpin(port)) ++ continue; ++ ++ if (port->redrive) { ++ port->redrive = false; ++ pm_runtime_put(&sw->dev); ++ tb_port_dbg(port, "exit redrive mode\n"); ++ } ++ } ++} ++ + static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port) + { + struct tb_port *in, *out; +@@ -1548,6 +1579,7 @@ static int tb_start(struct tb *tb) + tb_create_usb3_tunnels(tb->root_switch); + /* Add DP IN resources for the root switch */ + tb_add_dp_resources(tb->root_switch); ++ tb_switch_enter_redrive(tb->root_switch); + /* Make the discovered switches available to the userspace */ + device_for_each_child(&tb->root_switch->dev, NULL, + tb_scan_finalize_switch); +@@ -1563,6 +1595,7 @@ static int tb_suspend_noirq(struct tb *tb) + + tb_dbg(tb, "suspending...\n"); + tb_disconnect_and_release_dp(tb); ++ tb_switch_exit_redrive(tb->root_switch); + tb_switch_suspend(tb->root_switch, false); + tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */ + tb_dbg(tb, "suspend finished\n"); +@@ -1665,6 +1698,7 @@ static int tb_resume_noirq(struct tb *tb) + tb_dbg(tb, "tunnels restarted, sleeping for 100ms\n"); + msleep(100); + } ++ tb_switch_enter_redrive(tb->root_switch); + /* Allow tb_handle_hotplug to progress events */ + tcm->hotplug_active = true; + tb_dbg(tb, "resume finished\n"); +@@ -1728,6 +1762,12 @@ static int tb_runtime_suspend(struct tb *tb) + struct tb_cm *tcm = tb_priv(tb); + + mutex_lock(&tb->lock); ++ /* ++ * The below call only releases DP resources to allow exiting and ++ * re-entering redrive mode. ++ */ ++ tb_disconnect_and_release_dp(tb); ++ tb_switch_exit_redrive(tb->root_switch); + tb_switch_suspend(tb->root_switch, true); + tcm->hotplug_active = false; + mutex_unlock(&tb->lock); +@@ -1759,6 +1799,7 @@ static int tb_runtime_resume(struct tb *tb) + tb_restore_children(tb->root_switch); + list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list) + tb_tunnel_restart(tunnel); ++ tb_switch_enter_redrive(tb->root_switch); + tcm->hotplug_active = true; + mutex_unlock(&tb->lock); + +diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h +index 81a9c9d6be08b9..57d47348dc193b 100644 +--- a/drivers/usb/cdns3/core.h ++++ b/drivers/usb/cdns3/core.h +@@ -44,6 +44,7 @@ struct cdns3_platform_data { + bool suspend, bool wakeup); + unsigned long quirks; + #define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0) ++#define CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE BIT(1) + }; + + /** +diff --git a/drivers/usb/cdns3/drd.c b/drivers/usb/cdns3/drd.c +index 33ba30f79b3371..8e19ee72c1207c 100644 +--- a/drivers/usb/cdns3/drd.c ++++ b/drivers/usb/cdns3/drd.c +@@ -385,7 +385,7 @@ static irqreturn_t cdns_drd_irq(int irq, void *data) + int cdns_drd_init(struct cdns *cdns) + { + void __iomem *regs; +- u32 state; ++ u32 state, reg; + int ret; + + regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res); +@@ -429,6 +429,14 @@ int cdns_drd_init(struct cdns *cdns) + cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) + &cdns->otg_v1_regs->ien; + writel(1, &cdns->otg_v1_regs->simulate); ++ ++ if (cdns->pdata && ++ (cdns->pdata->quirks & CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE)) { ++ reg = readl(&cdns->otg_v1_regs->susp_ctrl); ++ reg |= SUSP_CTRL_SUSPEND_RESIDENCY_ENABLE; ++ writel(reg, &cdns->otg_v1_regs->susp_ctrl); ++ } ++ + cdns->version = CDNS3_CONTROLLER_V1; + } else { + dev_err(cdns->dev, "not supporte DID=0x%08x\n", state); +diff --git a/drivers/usb/cdns3/drd.h b/drivers/usb/cdns3/drd.h +index d72370c321d392..1e2aee14d6293a 100644 +--- a/drivers/usb/cdns3/drd.h ++++ b/drivers/usb/cdns3/drd.h +@@ -193,6 +193,9 @@ struct cdns_otg_irq_regs { + /* OTGREFCLK - bitmasks */ + #define OTGREFCLK_STB_CLK_SWITCH_EN BIT(31) + ++/* SUPS_CTRL - bitmasks */ ++#define SUSP_CTRL_SUSPEND_RESIDENCY_ENABLE BIT(17) ++ + /* OVERRIDE - bitmasks */ + #define OVERRIDE_IDPULLUP BIT(0) + /* Only for CDNS3_CONTROLLER_V0 version */ +diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c +index cb29f9fae2f230..1c8141d80e25d2 100644 +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -886,10 +886,10 @@ static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep, + } + + /* DMA sg buffer */ +- for_each_sg(ureq->sg, sg, ureq->num_sgs, i) { ++ for_each_sg(ureq->sg, sg, ureq->num_mapped_sgs, i) { + dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc, + sg_dma_address(sg) + sg->offset, sg_dma_len(sg), +- sg_is_last(sg)); ++ (i == (ureq->num_mapped_sgs - 1))); + desc_count += hs_ep->desc_count; + } + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index ec737fcd2c40c2..6d80ed3cc540e0 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -625,6 +625,8 @@ static void option_instat_callback(struct urb *urb); + #define MEIGSMART_PRODUCT_SRM825L 0x4d22 + /* MeiG Smart SLM320 based on UNISOC UIS8910 */ + #define MEIGSMART_PRODUCT_SLM320 0x4d41 ++/* MeiG Smart SLM770A based on ASR1803 */ ++#define MEIGSMART_PRODUCT_SLM770A 0x4d57 + + /* Device flags */ + +@@ -1395,6 +1397,12 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c0, 0xff), /* Telit FE910C04 (rmnet) */ ++ .driver_info = RSVD(0) | NCTRL(3) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c4, 0xff), /* Telit FE910C04 (rmnet) */ ++ .driver_info = RSVD(0) | NCTRL(3) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ ++ .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +@@ -2247,6 +2255,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7127, 0xff, 0x00, 0x00), + .driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7129, 0xff, 0x00, 0x00), /* MediaTek T7XX */ ++ .driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) }, + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MPL200), + .driver_info = RSVD(1) | RSVD(4) }, +@@ -2375,6 +2385,18 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Golbal EDU */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for WWAN Ready */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for WWAN Ready */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for WWAN Ready */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for WWAN Ready */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, +@@ -2382,9 +2404,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ ++ .driver_info = NCTRL(1) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ ++ .driver_info = NCTRL(3) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index 28f5df3b70c8ac..bf3822b25c58f6 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -1433,6 +1433,11 @@ static int check_extent_item(struct extent_buffer *leaf, + dref_offset, fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid data ref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + inline_refs += btrfs_extent_data_ref_count(leaf, dref); + break; + /* Contains parent bytenr and ref count */ +@@ -1445,6 +1450,11 @@ static int check_extent_item(struct extent_buffer *leaf, + inline_offset, fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid shared data ref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + inline_refs += btrfs_shared_data_ref_count(leaf, sref); + break; + default: +@@ -1496,8 +1506,18 @@ static int check_simple_keyed_refs(struct extent_buffer *leaf, + { + u32 expect_item_size = 0; + +- if (key->type == BTRFS_SHARED_DATA_REF_KEY) ++ if (key->type == BTRFS_SHARED_DATA_REF_KEY) { ++ struct btrfs_shared_data_ref *sref; ++ ++ sref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref); ++ if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid shared data backref count, should have non-zero value"); ++ return -EUCLEAN; ++ } ++ + expect_item_size = sizeof(struct btrfs_shared_data_ref); ++ } + + if (unlikely(btrfs_item_size(leaf, slot) != expect_item_size)) { + generic_err(leaf, slot, +@@ -1557,6 +1577,11 @@ static int check_extent_data_ref(struct extent_buffer *leaf, + offset, leaf->fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid extent data backref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + } + return 0; + } +diff --git a/fs/ceph/super.c b/fs/ceph/super.c +index e292d5c6058ed1..bd15991166c270 100644 +--- a/fs/ceph/super.c ++++ b/fs/ceph/super.c +@@ -420,6 +420,8 @@ static int ceph_parse_mount_param(struct fs_context *fc, + + switch (token) { + case Opt_snapdirname: ++ if (strlen(param->string) > NAME_MAX) ++ return invalfc(fc, "snapdirname too long"); + kfree(fsopt->snapdir_name); + fsopt->snapdir_name = param->string; + param->string = NULL; +diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c +index 939e5e242b985b..b3dc7ff42400fe 100644 +--- a/fs/efivarfs/inode.c ++++ b/fs/efivarfs/inode.c +@@ -47,7 +47,7 @@ struct inode *efivarfs_get_inode(struct super_block *sb, + * + * VariableName-12345678-1234-1234-1234-1234567891bc + */ +-bool efivarfs_valid_name(const char *str, int len) ++static bool efivarfs_valid_name(const char *str, int len) + { + const char *s = str + len - EFI_VARIABLE_GUID_LEN; + +diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h +index 8ebf3a6a8aa2d6..dcb973d8736cd6 100644 +--- a/fs/efivarfs/internal.h ++++ b/fs/efivarfs/internal.h +@@ -50,7 +50,6 @@ bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, + + extern const struct file_operations efivarfs_file_operations; + extern const struct inode_operations efivarfs_dir_inode_operations; +-extern bool efivarfs_valid_name(const char *str, int len); + extern struct inode *efivarfs_get_inode(struct super_block *sb, + const struct inode *dir, int mode, dev_t dev, + bool is_removable); +diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c +index 77c7615bba5e13..b8c4641ed152b0 100644 +--- a/fs/efivarfs/super.c ++++ b/fs/efivarfs/super.c +@@ -64,9 +64,6 @@ static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr) + const unsigned char *s = qstr->name; + unsigned int len = qstr->len; + +- if (!efivarfs_valid_name(s, len)) +- return -EINVAL; +- + while (len-- > EFI_VARIABLE_GUID_LEN) + hash = partial_name_hash(*s++, hash); + +diff --git a/fs/eventpoll.c b/fs/eventpoll.c +index f296ffb57d0528..6101dbe2834484 100644 +--- a/fs/eventpoll.c ++++ b/fs/eventpoll.c +@@ -1237,7 +1237,10 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v + break; + } + } +- wake_up(&ep->wq); ++ if (sync) ++ wake_up_sync(&ep->wq); ++ else ++ wake_up(&ep->wq); + } + if (waitqueue_active(&ep->poll_wait)) + pwake++; +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index c96d2e76156e8b..f6828693201982 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1196,7 +1196,7 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, + enum pnfs_iomode *iomode) + { + /* Serialise LAYOUTGET/LAYOUTRETURN */ +- if (atomic_read(&lo->plh_outstanding) != 0) ++ if (atomic_read(&lo->plh_outstanding) != 0 && lo->plh_return_seq == 0) + return false; + if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) + return false; +diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c +index 13d943df871dd0..abe3d5e1d84cd1 100644 +--- a/fs/nilfs2/btnode.c ++++ b/fs/nilfs2/btnode.c +@@ -35,6 +35,7 @@ void nilfs_init_btnc_inode(struct inode *btnc_inode) + ii->i_flags = 0; + memset(&ii->i_bmap_data, 0, sizeof(struct nilfs_bmap)); + mapping_set_gfp_mask(btnc_inode->i_mapping, GFP_NOFS); ++ btnc_inode->i_mapping->a_ops = &nilfs_buffer_cache_aops; + } + + void nilfs_btnode_cache_clear(struct address_space *btnc) +diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c +index 2f612288ea4517..8cdb1dc76f612e 100644 +--- a/fs/nilfs2/gcinode.c ++++ b/fs/nilfs2/gcinode.c +@@ -163,7 +163,7 @@ int nilfs_init_gcinode(struct inode *inode) + + inode->i_mode = S_IFREG; + mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); +- inode->i_mapping->a_ops = &empty_aops; ++ inode->i_mapping->a_ops = &nilfs_buffer_cache_aops; + + ii->i_flags = 0; + nilfs_bmap_init_gc(ii->i_bmap); +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 8eb4288d46fe03..072998626155e0 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -309,6 +309,10 @@ const struct address_space_operations nilfs_aops = { + .is_partially_uptodate = block_is_partially_uptodate, + }; + ++const struct address_space_operations nilfs_buffer_cache_aops = { ++ .invalidate_folio = block_invalidate_folio, ++}; ++ + static int nilfs_insert_inode_locked(struct inode *inode, + struct nilfs_root *root, + unsigned long ino) +@@ -614,8 +618,14 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, + inode = nilfs_iget_locked(sb, root, ino); + if (unlikely(!inode)) + return ERR_PTR(-ENOMEM); +- if (!(inode->i_state & I_NEW)) ++ ++ if (!(inode->i_state & I_NEW)) { ++ if (!inode->i_nlink) { ++ iput(inode); ++ return ERR_PTR(-ESTALE); ++ } + return inode; ++ } + + err = __nilfs_read_inode(sb, root, ino, inode); + if (unlikely(err)) { +@@ -748,6 +758,7 @@ struct inode *nilfs_iget_for_shadow(struct inode *inode) + NILFS_I(s_inode)->i_flags = 0; + memset(NILFS_I(s_inode)->i_bmap, 0, sizeof(struct nilfs_bmap)); + mapping_set_gfp_mask(s_inode->i_mapping, GFP_NOFS); ++ s_inode->i_mapping->a_ops = &nilfs_buffer_cache_aops; + + err = nilfs_attach_btree_node_cache(s_inode); + if (unlikely(err)) { +diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c +index ffaca278acd3cb..a14f6342a025ba 100644 +--- a/fs/nilfs2/namei.c ++++ b/fs/nilfs2/namei.c +@@ -67,6 +67,11 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) + inode = NULL; + } else { + inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino); ++ if (inode == ERR_PTR(-ESTALE)) { ++ nilfs_error(dir->i_sb, ++ "deleted inode referenced: %lu", ino); ++ return ERR_PTR(-EIO); ++ } + } + + return d_splice_alias(inode, dentry); +diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h +index ee27bb370d776d..5a880b4edf3dbd 100644 +--- a/fs/nilfs2/nilfs.h ++++ b/fs/nilfs2/nilfs.h +@@ -379,6 +379,7 @@ extern const struct file_operations nilfs_dir_operations; + extern const struct inode_operations nilfs_file_inode_operations; + extern const struct file_operations nilfs_file_operations; + extern const struct address_space_operations nilfs_aops; ++extern const struct address_space_operations nilfs_buffer_cache_aops; + extern const struct inode_operations nilfs_dir_inode_operations; + extern const struct inode_operations nilfs_special_inode_operations; + extern const struct inode_operations nilfs_symlink_inode_operations; +diff --git a/fs/udf/directory.c b/fs/udf/directory.c +index 04169e428fdfa1..76dd2e35e09817 100644 +--- a/fs/udf/directory.c ++++ b/fs/udf/directory.c +@@ -170,7 +170,7 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter) + static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter) + { + iter->loffset++; +- if (iter->loffset < iter->elen >> iter->dir->i_blkbits) ++ if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits)) + return 0; + + iter->loffset = 0; +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 811d59cf891ba9..afc20437090157 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -1567,6 +1567,7 @@ struct hv_util_service { + void *channel; + void (*util_cb)(void *); + int (*util_init)(struct hv_util_service *); ++ int (*util_init_transport)(void); + void (*util_deinit)(void); + int (*util_pre_suspend)(void); + int (*util_pre_resume)(void); +diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h +index a8f3058448eaa1..e0dec1bf917a4f 100644 +--- a/include/linux/io_uring.h ++++ b/include/linux/io_uring.h +@@ -50,10 +50,8 @@ bool io_is_uring_fops(struct file *file); + + static inline void io_uring_files_cancel(void) + { +- if (current->io_uring) { +- io_uring_unreg_ringfd(); ++ if (current->io_uring) + __io_uring_cancel(false); +- } + } + static inline void io_uring_task_cancel(void) + { +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 9e58e5400d7832..28f91982402aa1 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1996,14 +1996,13 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma); + * These helpers provide future and backwards compatibility + * for accessing popular PCI BAR info + */ +-#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) +-#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end) +-#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags) +-#define pci_resource_len(dev,bar) \ +- ((pci_resource_end((dev), (bar)) == 0) ? 0 : \ +- \ +- (pci_resource_end((dev), (bar)) - \ +- pci_resource_start((dev), (bar)) + 1)) ++#define pci_resource_n(dev, bar) (&(dev)->resource[(bar)]) ++#define pci_resource_start(dev, bar) (pci_resource_n(dev, bar)->start) ++#define pci_resource_end(dev, bar) (pci_resource_n(dev, bar)->end) ++#define pci_resource_flags(dev, bar) (pci_resource_n(dev, bar)->flags) ++#define pci_resource_len(dev,bar) \ ++ (pci_resource_end((dev), (bar)) ? \ ++ resource_size(pci_resource_n((dev), (bar))) : 0) + + /* + * Similar to the helpers above, these manipulate per-pci_dev +diff --git a/include/linux/wait.h b/include/linux/wait.h +index a0307b516b099e..bc06a315653a76 100644 +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -224,6 +224,7 @@ void __wake_up_pollfree(struct wait_queue_head *wq_head); + #define wake_up_all(x) __wake_up(x, TASK_NORMAL, 0, NULL) + #define wake_up_locked(x) __wake_up_locked((x), TASK_NORMAL, 1) + #define wake_up_all_locked(x) __wake_up_locked((x), TASK_NORMAL, 0) ++#define wake_up_sync(x) __wake_up_sync(x, TASK_NORMAL) + + #define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL) + #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL) +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 0b136166326789..9b58ba4616d40b 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -434,13 +434,17 @@ static void io_prep_async_link(struct io_kiocb *req) + } + } + +-void io_queue_iowq(struct io_kiocb *req, bool *dont_use) ++static void io_queue_iowq(struct io_kiocb *req) + { + struct io_kiocb *link = io_prep_linked_timeout(req); + struct io_uring_task *tctx = req->task->io_uring; + + BUG_ON(!tctx); +- BUG_ON(!tctx->io_wq); ++ ++ if ((current->flags & PF_KTHREAD) || !tctx->io_wq) { ++ io_req_task_queue_fail(req, -ECANCELED); ++ return; ++ } + + /* init ->work of the whole link before punting */ + io_prep_async_link(req); +@@ -1909,7 +1913,7 @@ static void io_queue_async(struct io_kiocb *req, int ret) + break; + case IO_APOLL_ABORTED: + io_kbuf_recycle(req, 0); +- io_queue_iowq(req, NULL); ++ io_queue_iowq(req); + break; + case IO_APOLL_OK: + break; +@@ -1958,7 +1962,7 @@ static void io_queue_sqe_fallback(struct io_kiocb *req) + if (unlikely(req->ctx->drain_active)) + io_drain_req(req); + else +- io_queue_iowq(req, NULL); ++ io_queue_iowq(req); + } + } + +@@ -3085,6 +3089,7 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd) + + void __io_uring_cancel(bool cancel_all) + { ++ io_uring_unreg_ringfd(); + io_uring_cancel_generic(cancel_all, NULL); + } + +diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h +index 3b87f5421eb628..a1f679b8199ea0 100644 +--- a/io_uring/io_uring.h ++++ b/io_uring/io_uring.h +@@ -54,7 +54,6 @@ static inline bool io_req_ffs_set(struct io_kiocb *req) + void __io_req_task_work_add(struct io_kiocb *req, bool allow_local); + bool io_alloc_async_data(struct io_kiocb *req); + void io_req_task_queue(struct io_kiocb *req); +-void io_queue_iowq(struct io_kiocb *req, bool *dont_use); + void io_req_task_complete(struct io_kiocb *req, bool *locked); + void io_req_task_queue_fail(struct io_kiocb *req, int ret); + void io_req_task_submit(struct io_kiocb *req, bool *locked); +diff --git a/io_uring/rw.c b/io_uring/rw.c +index 9d6e17a244ae79..692663bd864fbd 100644 +--- a/io_uring/rw.c ++++ b/io_uring/rw.c +@@ -167,12 +167,6 @@ static inline loff_t *io_kiocb_update_pos(struct io_kiocb *req) + return NULL; + } + +-static void io_req_task_queue_reissue(struct io_kiocb *req) +-{ +- req->io_task_work.func = io_queue_iowq; +- io_req_task_work_add(req); +-} +- + #ifdef CONFIG_BLOCK + static bool io_resubmit_prep(struct io_kiocb *req) + { +@@ -341,7 +335,7 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret, + if (req->flags & REQ_F_REISSUE) { + req->flags &= ~REQ_F_REISSUE; + if (io_resubmit_prep(req)) +- io_req_task_queue_reissue(req); ++ return -EAGAIN; + else + io_req_task_queue_fail(req, final_ret); + } +@@ -691,7 +685,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode) + return 0; + } + +-int io_read(struct io_kiocb *req, unsigned int issue_flags) ++static int __io_read(struct io_kiocb *req, unsigned int issue_flags) + { + struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); + struct io_rw_state __s, *s = &__s; +@@ -757,6 +751,14 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags) + + ret = io_iter_do_read(rw, &s->iter); + ++ /* ++ * Some file systems like to return -EOPNOTSUPP for an IOCB_NOWAIT ++ * issue, even though they should be returning -EAGAIN. To be safe, ++ * retry from blocking context for either. ++ */ ++ if (ret == -EOPNOTSUPP && force_nonblock) ++ ret = -EAGAIN; ++ + if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) { + req->flags &= ~REQ_F_REISSUE; + /* if we can poll, just do that */ +@@ -836,7 +838,18 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags) + /* it's faster to check here then delegate to kfree */ + if (iovec) + kfree(iovec); +- return kiocb_done(req, ret, issue_flags); ++ return ret; ++} ++ ++int io_read(struct io_kiocb *req, unsigned int issue_flags) ++{ ++ int ret; ++ ++ ret = __io_read(req, issue_flags); ++ if (ret >= 0) ++ return kiocb_done(req, ret, issue_flags); ++ ++ return ret; + } + + static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb) +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 24859d96450505..75e654c91c247a 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -242,19 +242,16 @@ int trace_event_get_offsets(struct trace_event_call *call) + return tail->offset + tail->size; + } + +-/* +- * Check if the referenced field is an array and return true, +- * as arrays are OK to dereference. +- */ +-static bool test_field(const char *fmt, struct trace_event_call *call) ++ ++static struct trace_event_fields *find_event_field(const char *fmt, ++ struct trace_event_call *call) + { + struct trace_event_fields *field = call->class->fields_array; +- const char *array_descriptor; + const char *p = fmt; + int len; + + if (!(len = str_has_prefix(fmt, "REC->"))) +- return false; ++ return NULL; + fmt += len; + for (p = fmt; *p; p++) { + if (!isalnum(*p) && *p != '_') +@@ -263,16 +260,120 @@ static bool test_field(const char *fmt, struct trace_event_call *call) + len = p - fmt; + + for (; field->type; field++) { +- if (strncmp(field->name, fmt, len) || +- field->name[len]) ++ if (strncmp(field->name, fmt, len) || field->name[len]) + continue; +- array_descriptor = strchr(field->type, '['); +- /* This is an array and is OK to dereference. */ +- return array_descriptor != NULL; ++ ++ return field; ++ } ++ return NULL; ++} ++ ++/* ++ * Check if the referenced field is an array and return true, ++ * as arrays are OK to dereference. ++ */ ++static bool test_field(const char *fmt, struct trace_event_call *call) ++{ ++ struct trace_event_fields *field; ++ ++ field = find_event_field(fmt, call); ++ if (!field) ++ return false; ++ ++ /* This is an array and is OK to dereference. */ ++ return strchr(field->type, '[') != NULL; ++} ++ ++/* Look for a string within an argument */ ++static bool find_print_string(const char *arg, const char *str, const char *end) ++{ ++ const char *r; ++ ++ r = strstr(arg, str); ++ return r && r < end; ++} ++ ++/* Return true if the argument pointer is safe */ ++static bool process_pointer(const char *fmt, int len, struct trace_event_call *call) ++{ ++ const char *r, *e, *a; ++ ++ e = fmt + len; ++ ++ /* Find the REC-> in the argument */ ++ r = strstr(fmt, "REC->"); ++ if (r && r < e) { ++ /* ++ * Addresses of events on the buffer, or an array on the buffer is ++ * OK to dereference. There's ways to fool this, but ++ * this is to catch common mistakes, not malicious code. ++ */ ++ a = strchr(fmt, '&'); ++ if ((a && (a < r)) || test_field(r, call)) ++ return true; ++ } else if (find_print_string(fmt, "__get_dynamic_array(", e)) { ++ return true; ++ } else if (find_print_string(fmt, "__get_rel_dynamic_array(", e)) { ++ return true; ++ } else if (find_print_string(fmt, "__get_dynamic_array_len(", e)) { ++ return true; ++ } else if (find_print_string(fmt, "__get_rel_dynamic_array_len(", e)) { ++ return true; ++ } else if (find_print_string(fmt, "__get_sockaddr(", e)) { ++ return true; ++ } else if (find_print_string(fmt, "__get_rel_sockaddr(", e)) { ++ return true; + } + return false; + } + ++/* Return true if the string is safe */ ++static bool process_string(const char *fmt, int len, struct trace_event_call *call) ++{ ++ const char *r, *e, *s; ++ ++ e = fmt + len; ++ ++ /* ++ * There are several helper functions that return strings. ++ * If the argument contains a function, then assume its field is valid. ++ * It is considered that the argument has a function if it has: ++ * alphanumeric or '_' before a parenthesis. ++ */ ++ s = fmt; ++ do { ++ r = strstr(s, "("); ++ if (!r || r >= e) ++ break; ++ for (int i = 1; r - i >= s; i++) { ++ char ch = *(r - i); ++ if (isspace(ch)) ++ continue; ++ if (isalnum(ch) || ch == '_') ++ return true; ++ /* Anything else, this isn't a function */ ++ break; ++ } ++ /* A function could be wrapped in parethesis, try the next one */ ++ s = r + 1; ++ } while (s < e); ++ ++ /* ++ * If there's any strings in the argument consider this arg OK as it ++ * could be: REC->field ? "foo" : "bar" and we don't want to get into ++ * verifying that logic here. ++ */ ++ if (find_print_string(fmt, "\"", e)) ++ return true; ++ ++ /* Dereferenced strings are also valid like any other pointer */ ++ if (process_pointer(fmt, len, call)) ++ return true; ++ ++ /* Make sure the field is found, and consider it OK for now if it is */ ++ return find_event_field(fmt, call) != NULL; ++} ++ + /* + * Examine the print fmt of the event looking for unsafe dereference + * pointers using %p* that could be recorded in the trace event and +@@ -282,13 +383,14 @@ static bool test_field(const char *fmt, struct trace_event_call *call) + static void test_event_printk(struct trace_event_call *call) + { + u64 dereference_flags = 0; ++ u64 string_flags = 0; + bool first = true; +- const char *fmt, *c, *r, *a; ++ const char *fmt; + int parens = 0; + char in_quote = 0; + int start_arg = 0; + int arg = 0; +- int i; ++ int i, e; + + fmt = call->print_fmt; + +@@ -372,8 +474,16 @@ static void test_event_printk(struct trace_event_call *call) + star = true; + continue; + } +- if ((fmt[i + j] == 's') && star) +- arg++; ++ if ((fmt[i + j] == 's')) { ++ if (star) ++ arg++; ++ if (WARN_ONCE(arg == 63, ++ "Too many args for event: %s", ++ trace_event_name(call))) ++ return; ++ dereference_flags |= 1ULL << arg; ++ string_flags |= 1ULL << arg; ++ } + break; + } + break; +@@ -401,42 +511,47 @@ static void test_event_printk(struct trace_event_call *call) + case ',': + if (in_quote || parens) + continue; ++ e = i; + i++; + while (isspace(fmt[i])) + i++; +- start_arg = i; +- if (!(dereference_flags & (1ULL << arg))) +- goto next_arg; + +- /* Find the REC-> in the argument */ +- c = strchr(fmt + i, ','); +- r = strstr(fmt + i, "REC->"); +- if (r && (!c || r < c)) { +- /* +- * Addresses of events on the buffer, +- * or an array on the buffer is +- * OK to dereference. +- * There's ways to fool this, but +- * this is to catch common mistakes, +- * not malicious code. +- */ +- a = strchr(fmt + i, '&'); +- if ((a && (a < r)) || test_field(r, call)) ++ /* ++ * If start_arg is zero, then this is the start of the ++ * first argument. The processing of the argument happens ++ * when the end of the argument is found, as it needs to ++ * handle paranthesis and such. ++ */ ++ if (!start_arg) { ++ start_arg = i; ++ /* Balance out the i++ in the for loop */ ++ i--; ++ continue; ++ } ++ ++ if (dereference_flags & (1ULL << arg)) { ++ if (string_flags & (1ULL << arg)) { ++ if (process_string(fmt + start_arg, e - start_arg, call)) ++ dereference_flags &= ~(1ULL << arg); ++ } else if (process_pointer(fmt + start_arg, e - start_arg, call)) + dereference_flags &= ~(1ULL << arg); +- } else if ((r = strstr(fmt + i, "__get_dynamic_array(")) && +- (!c || r < c)) { +- dereference_flags &= ~(1ULL << arg); +- } else if ((r = strstr(fmt + i, "__get_sockaddr(")) && +- (!c || r < c)) { +- dereference_flags &= ~(1ULL << arg); + } + +- next_arg: +- i--; ++ start_arg = i; + arg++; ++ /* Balance out the i++ in the for loop */ ++ i--; + } + } + ++ if (dereference_flags & (1ULL << arg)) { ++ if (string_flags & (1ULL << arg)) { ++ if (process_string(fmt + start_arg, i - start_arg, call)) ++ dereference_flags &= ~(1ULL << arg); ++ } else if (process_pointer(fmt + start_arg, i - start_arg, call)) ++ dereference_flags &= ~(1ULL << arg); ++ } ++ + /* + * If you triggered the below warning, the trace event reported + * uses an unsafe dereference pointer %p*. As the data stored +diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c +index 902ff2f3bc72b5..5cc35b553a0488 100644 +--- a/net/netfilter/ipset/ip_set_list_set.c ++++ b/net/netfilter/ipset/ip_set_list_set.c +@@ -611,6 +611,8 @@ init_list_set(struct net *net, struct ip_set *set, u32 size) + return true; + } + ++static struct lock_class_key list_set_lockdep_key; ++ + static int + list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + u32 flags) +@@ -627,6 +629,7 @@ list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + if (size < IP_SET_LIST_MIN_SIZE) + size = IP_SET_LIST_MIN_SIZE; + ++ lockdep_set_class(&set->lock, &list_set_lockdep_key); + set->variant = &set_variant; + set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem), + __alignof__(struct set_elem)); +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 73e8caeffd47e6..eee9ebad35a5ca 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1541,7 +1541,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + b->backlogs[idx] -= len; + b->tin_backlog -= len; + sch->qstats.backlog -= len; +- qdisc_tree_reduce_backlog(sch, 1, len); + + flow->dropped++; + b->tin_dropped++; +@@ -1552,6 +1551,7 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; ++ qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c +index 3ac3e5c80b6ffb..e38cf34287018b 100644 +--- a/net/sched/sch_choke.c ++++ b/net/sched/sch_choke.c +@@ -123,10 +123,10 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx, + if (idx == q->tail) + choke_zap_tail_holes(q); + ++ --sch->q.qlen; + qdisc_qstats_backlog_dec(sch, skb); + qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb)); + qdisc_drop(skb, sch, to_free); +- --sch->q.qlen; + } + + struct choke_skb_cb { +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 868e722aef064e..e2bdd6aa3d89ca 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -1988,6 +1988,8 @@ static int smc_listen_prfx_check(struct smc_sock *new_smc, + if (pclc->hdr.typev1 == SMC_TYPE_N) + return 0; + pclc_prfx = smc_clc_proposal_get_prefix(pclc); ++ if (!pclc_prfx) ++ return -EPROTO; + if (smc_clc_prfx_match(newclcsock, pclc_prfx)) + return SMC_CLC_DECL_DIFFPREFIX; + +@@ -2094,6 +2096,8 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc, + pclc_smcd = smc_get_clc_msg_smcd(pclc); + smc_v2_ext = smc_get_clc_v2_ext(pclc); + smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext); ++ if (!pclc_smcd || !smc_v2_ext || !smcd_v2_ext) ++ goto not_found; + + mutex_lock(&smcd_dev_list.mutex); + if (pclc_smcd->ism.chid) +@@ -2153,7 +2157,9 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc, + int rc = 0; + + /* check if ISM V1 is available */ +- if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1)) ++ if (!(ini->smcd_version & SMC_V1) || ++ !smcd_indicated(ini->smc_type_v1) || ++ !pclc_smcd) + goto not_found; + ini->is_smcd = true; /* prepare ISM check */ + ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid); +@@ -2789,6 +2795,13 @@ static __poll_t smc_poll(struct file *file, struct socket *sock, + } else { + sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); ++ ++ if (sk->sk_state != SMC_INIT) { ++ /* Race breaker the same way as tcp_poll(). */ ++ smp_mb__after_atomic(); ++ if (atomic_read(&smc->conn.sndbuf_space)) ++ mask |= EPOLLOUT | EPOLLWRNORM; ++ } + } + if (atomic_read(&smc->conn.bytes_to_rcv)) + mask |= EPOLLIN | EPOLLRDNORM; +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index 867df452281528..a48fdc83fe6b2c 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -354,6 +354,10 @@ static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc) + + v2_ext = smc_get_clc_v2_ext(pclc); + pclc_prfx = smc_clc_proposal_get_prefix(pclc); ++ if (!pclc_prfx || ++ pclc_prfx->ipv6_prefixes_cnt > SMC_CLC_MAX_V6_PREFIX) ++ return false; ++ + if (hdr->version == SMC_V1) { + if (hdr->typev1 == SMC_TYPE_N) + return false; +@@ -749,6 +753,11 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, + SMC_CLC_RECV_BUF_LEN : datlen; + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen); + len = sock_recvmsg(smc->clcsock, &msg, krflags); ++ if (len < recvlen) { ++ smc->sk.sk_err = EPROTO; ++ reason_code = -EPROTO; ++ goto out; ++ } + datlen -= len; + } + if (clcm->type == SMC_CLC_DECLINE) { +diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h +index 5fee545c9a1096..0f6102cd5de170 100644 +--- a/net/smc/smc_clc.h ++++ b/net/smc/smc_clc.h +@@ -303,8 +303,12 @@ struct smc_clc_msg_decline_v2 { /* clc decline message */ + static inline struct smc_clc_msg_proposal_prefix * + smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc) + { ++ u16 offset = ntohs(pclc->iparea_offset); ++ ++ if (offset > sizeof(struct smc_clc_msg_smcd)) ++ return NULL; + return (struct smc_clc_msg_proposal_prefix *) +- ((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset)); ++ ((u8 *)pclc + sizeof(*pclc) + offset); + } + + static inline bool smcr_indicated(int smc_type) +@@ -357,9 +361,15 @@ smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop) + static inline struct smc_clc_smcd_v2_extension * + smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext) + { ++ u16 max_offset = offsetof(struct smc_clc_msg_proposal_area, pclc_smcd_v2_ext) - ++ offsetof(struct smc_clc_msg_proposal_area, pclc_v2_ext) - ++ offsetof(struct smc_clc_v2_extension, hdr) - ++ offsetofend(struct smc_clnt_opts_area_hdr, smcd_v2_ext_offset); ++ + if (!prop_v2ext) + return NULL; +- if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset)) ++ if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) || ++ ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) > max_offset) + return NULL; + + return (struct smc_clc_smcd_v2_extension *) +diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c +index 10d79cb55528d0..890785d4f6b69b 100644 +--- a/net/smc/smc_core.c ++++ b/net/smc/smc_core.c +@@ -1726,7 +1726,9 @@ void smcr_link_down_cond_sched(struct smc_link *lnk) + { + if (smc_link_downing(&lnk->state)) { + trace_smcr_link_down(lnk, __builtin_return_address(0)); +- schedule_work(&lnk->link_down_wrk); ++ smcr_link_hold(lnk); /* smcr_link_put in link_down_wrk */ ++ if (!schedule_work(&lnk->link_down_wrk)) ++ smcr_link_put(lnk); + } + } + +@@ -1758,11 +1760,14 @@ static void smc_link_down_work(struct work_struct *work) + struct smc_link_group *lgr = link->lgr; + + if (list_empty(&lgr->list)) +- return; ++ goto out; + wake_up_all(&lgr->llc_msg_waiter); + mutex_lock(&lgr->llc_conf_mutex); + smcr_link_down(link); + mutex_unlock(&lgr->llc_conf_mutex); ++ ++out: ++ smcr_link_put(link); /* smcr_link_hold by schedulers of link_down_work */ + } + + static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev, +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index d03de37e3578c3..9cd85ab19c553f 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -267,6 +267,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "0000000000070000"), ++ }, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ RT711_JD2_100K), ++ }, + { + .callback = sof_sdw_quirk_cb, + .matches = { +@@ -378,6 +387,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B8C"), ++ }, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ RT711_JD2), ++ }, + { + .callback = sof_sdw_quirk_cb, + .matches = { +diff --git a/tools/testing/selftests/bpf/sdt.h b/tools/testing/selftests/bpf/sdt.h +index ca0162b4dc5752..1fcfa5160231de 100644 +--- a/tools/testing/selftests/bpf/sdt.h ++++ b/tools/testing/selftests/bpf/sdt.h +@@ -102,6 +102,8 @@ + # define STAP_SDT_ARG_CONSTRAINT nZr + # elif defined __arm__ + # define STAP_SDT_ARG_CONSTRAINT g ++# elif defined __loongarch__ ++# define STAP_SDT_ARG_CONSTRAINT nmr + # else + # define STAP_SDT_ARG_CONSTRAINT nor + # endif
